@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/bun/index.js
CHANGED
|
@@ -151,6 +151,17 @@ import { mkdirSync } from "fs";
|
|
|
151
151
|
|
|
152
152
|
// src/git.ts
|
|
153
153
|
import { execSync } from "child_process";
|
|
154
|
+
|
|
155
|
+
// src/hosted.ts
|
|
156
|
+
var _hostedMode = false;
|
|
157
|
+
function enableHostedMode() {
|
|
158
|
+
_hostedMode = true;
|
|
159
|
+
}
|
|
160
|
+
function isHostedMode() {
|
|
161
|
+
return _hostedMode;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// src/git.ts
|
|
154
165
|
function normalizeRemoteUrl(url2) {
|
|
155
166
|
let normalized = url2.trim();
|
|
156
167
|
const sshMatch = normalized.match(/^[\w.-]+@([\w.-]+):(.+)$/);
|
|
@@ -175,6 +186,7 @@ function clearGitRemoteCache() {
|
|
|
175
186
|
gitRemoteCache.clear();
|
|
176
187
|
}
|
|
177
188
|
function getGitRemote(path) {
|
|
189
|
+
if (isHostedMode()) return null;
|
|
178
190
|
const cached2 = gitRemoteCache.get(path);
|
|
179
191
|
if (cached2 !== void 0) return cached2;
|
|
180
192
|
try {
|
|
@@ -922,7 +934,7 @@ function close() {
|
|
|
922
934
|
instance = void 0;
|
|
923
935
|
}
|
|
924
936
|
}
|
|
925
|
-
function ensureProject(path, name) {
|
|
937
|
+
function ensureProject(path, name, suppliedGitRemote) {
|
|
926
938
|
if (!process.env.LORE_DB_PATH && /^\/test\//.test(path)) {
|
|
927
939
|
throw new Error(
|
|
928
940
|
`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.`
|
|
@@ -931,22 +943,22 @@ function ensureProject(path, name) {
|
|
|
931
943
|
const existing = db().query("SELECT id, git_remote FROM projects WHERE path = ?").get(path);
|
|
932
944
|
if (existing) {
|
|
933
945
|
if (!existing.git_remote) {
|
|
934
|
-
const
|
|
935
|
-
if (
|
|
946
|
+
const resolvedRemote = suppliedGitRemote ?? getGitRemote(path);
|
|
947
|
+
if (resolvedRemote) {
|
|
936
948
|
const conflict = db().query(
|
|
937
949
|
"SELECT id FROM projects WHERE git_remote = ? AND id != ? LIMIT 1"
|
|
938
|
-
).get(
|
|
950
|
+
).get(resolvedRemote, existing.id);
|
|
939
951
|
if (conflict) {
|
|
940
952
|
mergeProjectInternal(conflict.id, existing.id);
|
|
941
953
|
}
|
|
942
|
-
db().query("UPDATE projects SET git_remote = ? WHERE id = ?").run(
|
|
954
|
+
db().query("UPDATE projects SET git_remote = ? WHERE id = ?").run(resolvedRemote, existing.id);
|
|
943
955
|
}
|
|
944
956
|
}
|
|
945
957
|
return existing.id;
|
|
946
958
|
}
|
|
947
959
|
const alias = db().query("SELECT project_id FROM project_path_aliases WHERE path = ?").get(path);
|
|
948
960
|
if (alias) return alias.project_id;
|
|
949
|
-
const gitRemote = getGitRemote(path);
|
|
961
|
+
const gitRemote = suppliedGitRemote ?? getGitRemote(path);
|
|
950
962
|
if (gitRemote) {
|
|
951
963
|
const byRemote = db().query("SELECT id FROM projects WHERE git_remote = ? LIMIT 1").get(gitRemote);
|
|
952
964
|
if (byRemote) {
|
|
@@ -974,6 +986,20 @@ function projectId(path) {
|
|
|
974
986
|
const alias = db().query("SELECT project_id FROM project_path_aliases WHERE path = ?").get(path);
|
|
975
987
|
return alias?.project_id;
|
|
976
988
|
}
|
|
989
|
+
function resolveProjectByRemoteOrPath(gitRemote, path) {
|
|
990
|
+
if (gitRemote) {
|
|
991
|
+
const row = db().query("SELECT id FROM projects WHERE git_remote = ? LIMIT 1").get(gitRemote);
|
|
992
|
+
if (row) return row.id;
|
|
993
|
+
}
|
|
994
|
+
if (path) {
|
|
995
|
+
return projectId(path) ?? null;
|
|
996
|
+
}
|
|
997
|
+
return null;
|
|
998
|
+
}
|
|
999
|
+
function projectPath(id) {
|
|
1000
|
+
const row = db().query("SELECT path FROM projects WHERE id = ?").get(id);
|
|
1001
|
+
return row?.path ?? null;
|
|
1002
|
+
}
|
|
977
1003
|
function projectName(id) {
|
|
978
1004
|
const row = db().query("SELECT name FROM projects WHERE id = ?").get(id);
|
|
979
1005
|
return row?.name ?? null;
|
|
@@ -982,13 +1008,13 @@ function isFirstRun() {
|
|
|
982
1008
|
const row = db().query("SELECT COUNT(*) as count FROM projects").get();
|
|
983
1009
|
return row.count === 0;
|
|
984
1010
|
}
|
|
985
|
-
function getLastImportAt(
|
|
986
|
-
const id = ensureProject(
|
|
1011
|
+
function getLastImportAt(projectPath2) {
|
|
1012
|
+
const id = ensureProject(projectPath2);
|
|
987
1013
|
const row = db().query("SELECT last_import_at FROM projects WHERE id = ?").get(id);
|
|
988
1014
|
return row?.last_import_at ?? null;
|
|
989
1015
|
}
|
|
990
|
-
function setLastImportAt(
|
|
991
|
-
const id = ensureProject(
|
|
1016
|
+
function setLastImportAt(projectPath2, timestamp) {
|
|
1017
|
+
const id = ensureProject(projectPath2);
|
|
992
1018
|
db().query("UPDATE projects SET last_import_at = ? WHERE id = ?").run(timestamp, id);
|
|
993
1019
|
}
|
|
994
1020
|
function loadForceMinLayer(sessionID) {
|
|
@@ -26586,19 +26612,11 @@ var LoreConfig = external_exports.object({
|
|
|
26586
26612
|
* cost-aware formula from targetCacheReadCostPerTurn. 0 = disabled
|
|
26587
26613
|
* (no cap, use full context). Default: undefined (use cost-aware auto). */
|
|
26588
26614
|
maxLayer0Tokens: external_exports.number().min(0).optional(),
|
|
26589
|
-
/**
|
|
26590
|
-
|
|
26591
|
-
|
|
26592
|
-
* For opus-4-6 ($6.25/M write): $1.00 → 160K cap.
|
|
26593
|
-
* For sonnet-4 ($3.75/M write): $1.00 → 267K (effectively uncapped at 200K).
|
|
26594
|
-
* The cap is further adjusted dynamically per session based on observed
|
|
26595
|
-
* bust rate (EMA) and break frequency. Default: 1.00. Set to 0 to disable. */
|
|
26596
|
-
targetBustCost: external_exports.number().min(0).default(1),
|
|
26597
|
-
/** Direct override for the total-context token cap at layer 1+. When set,
|
|
26598
|
-
* bypasses the cost-aware formula from targetBustCost. 0 = disabled.
|
|
26599
|
-
* Default: undefined (use cost-aware auto). */
|
|
26615
|
+
/** @deprecated Ignored. Tier-based bust-vs-continue replaces static cap. */
|
|
26616
|
+
targetBustCost: external_exports.number().min(0).default(1).optional(),
|
|
26617
|
+
/** @deprecated Ignored. Tier-based bust-vs-continue replaces static cap. */
|
|
26600
26618
|
maxContextTokens: external_exports.number().min(0).optional()
|
|
26601
|
-
}).default({ distilled: 0.25, raw: 0.4, output: 0.25, ltm: 0.05, targetCacheReadCostPerTurn: 0.1
|
|
26619
|
+
}).default({ distilled: 0.25, raw: 0.4, output: 0.25, ltm: 0.05, targetCacheReadCostPerTurn: 0.1 }),
|
|
26602
26620
|
/**
|
|
26603
26621
|
* Cold-cache idle-resume handling.
|
|
26604
26622
|
*
|
|
@@ -26774,11 +26792,13 @@ function config2() {
|
|
|
26774
26792
|
return current;
|
|
26775
26793
|
}
|
|
26776
26794
|
async function load(directory) {
|
|
26777
|
-
|
|
26778
|
-
|
|
26779
|
-
|
|
26780
|
-
|
|
26781
|
-
|
|
26795
|
+
if (!isHostedMode()) {
|
|
26796
|
+
const path = join5(directory, ".lore.json");
|
|
26797
|
+
if (existsSync2(path)) {
|
|
26798
|
+
const raw = JSON.parse(readFileSync(path, "utf8"));
|
|
26799
|
+
current = LoreConfig.parse(raw);
|
|
26800
|
+
return current;
|
|
26801
|
+
}
|
|
26782
26802
|
}
|
|
26783
26803
|
current = LoreConfig.parse({});
|
|
26784
26804
|
return current;
|
|
@@ -26818,6 +26838,14 @@ function vendorRegistration() {
|
|
|
26818
26838
|
|
|
26819
26839
|
// src/embedding.ts
|
|
26820
26840
|
var EMBED_TIMEOUT_MS = 1e4;
|
|
26841
|
+
var LOCAL_MAX_CHARS = 4096 * 4;
|
|
26842
|
+
function safeLocalTruncate(text4) {
|
|
26843
|
+
if (text4.length <= LOCAL_MAX_CHARS) return text4;
|
|
26844
|
+
let end = LOCAL_MAX_CHARS;
|
|
26845
|
+
const code2 = text4.charCodeAt(end - 1);
|
|
26846
|
+
if (code2 >= 55296 && code2 <= 56319) end--;
|
|
26847
|
+
return text4.slice(0, end);
|
|
26848
|
+
}
|
|
26821
26849
|
var VOYAGE_API_URL = "https://api.voyageai.com/v1/embeddings";
|
|
26822
26850
|
var VoyageProvider = class {
|
|
26823
26851
|
maxBatchSize = 128;
|
|
@@ -27000,8 +27028,9 @@ var LocalProvider = class {
|
|
|
27000
27028
|
localProviderKnownBroken = true;
|
|
27001
27029
|
if (!localProviderErrorLogged) {
|
|
27002
27030
|
localProviderErrorLogged = true;
|
|
27003
|
-
|
|
27004
|
-
`local embedding provider failed to init: ${msg.error}. Set VOYAGE_API_KEY/OPENAI_API_KEY for automatic remote fallback
|
|
27031
|
+
error(
|
|
27032
|
+
`local embedding provider failed to init: ${msg.error}. Set VOYAGE_API_KEY/OPENAI_API_KEY for automatic remote fallback.`,
|
|
27033
|
+
new Error(`embedding worker init failed: ${msg.error}`)
|
|
27005
27034
|
);
|
|
27006
27035
|
}
|
|
27007
27036
|
for (const [, p2] of this.pendingRequests) {
|
|
@@ -27016,6 +27045,7 @@ var LocalProvider = class {
|
|
|
27016
27045
|
this.worker.on("error", (err) => {
|
|
27017
27046
|
this.workerInitError = err.message;
|
|
27018
27047
|
this.workerReady = false;
|
|
27048
|
+
error("embedding worker crashed:", err);
|
|
27019
27049
|
for (const [, p2] of this.pendingRequests) {
|
|
27020
27050
|
p2.reject(new LocalProviderUnavailableError(err));
|
|
27021
27051
|
}
|
|
@@ -27025,6 +27055,10 @@ var LocalProvider = class {
|
|
|
27025
27055
|
this.worker.on("exit", (code2) => {
|
|
27026
27056
|
if (code2 !== 0 && !this.workerInitError) {
|
|
27027
27057
|
this.workerInitError = `embedding worker exited with code ${code2}`;
|
|
27058
|
+
error(
|
|
27059
|
+
this.workerInitError,
|
|
27060
|
+
new Error(this.workerInitError)
|
|
27061
|
+
);
|
|
27028
27062
|
}
|
|
27029
27063
|
this.workerReady = false;
|
|
27030
27064
|
for (const [, p2] of this.pendingRequests) {
|
|
@@ -27055,8 +27089,9 @@ var LocalProvider = class {
|
|
|
27055
27089
|
}
|
|
27056
27090
|
async embed(texts, inputType) {
|
|
27057
27091
|
await this.ensureWorker();
|
|
27092
|
+
const truncated = texts.map(safeLocalTruncate);
|
|
27058
27093
|
const prefix = inputType === "document" ? "search_document: " : "search_query: ";
|
|
27059
|
-
const prefixed =
|
|
27094
|
+
const prefixed = truncated.map((t2) => prefix + t2);
|
|
27060
27095
|
const id = this.nextRequestId++;
|
|
27061
27096
|
const priority = inputType === "query" && texts.length === 1 ? "high" : "normal";
|
|
27062
27097
|
return new Promise((resolve, reject) => {
|
|
@@ -27284,27 +27319,30 @@ function vectorSearchAllDistillations(queryEmbedding, projectId2, limit = 20) {
|
|
|
27284
27319
|
return scored.slice(0, limit);
|
|
27285
27320
|
}
|
|
27286
27321
|
function embedKnowledgeEntry(id, title, content3) {
|
|
27322
|
+
if (!isAvailable()) return;
|
|
27287
27323
|
const text4 = `${title}
|
|
27288
27324
|
${content3}`;
|
|
27289
27325
|
embed([text4], "document").then(([vec]) => {
|
|
27290
27326
|
db().query("UPDATE knowledge SET embedding = ? WHERE id = ?").run(toBlob(vec), id);
|
|
27291
27327
|
}).catch((err) => {
|
|
27292
|
-
|
|
27328
|
+
error("embedding failed for knowledge entry", id, ":", err);
|
|
27293
27329
|
});
|
|
27294
27330
|
}
|
|
27295
27331
|
function embedDistillation(id, observations) {
|
|
27332
|
+
if (!isAvailable()) return;
|
|
27296
27333
|
embed([observations], "document").then(([vec]) => {
|
|
27297
27334
|
db().query("UPDATE distillations SET embedding = ? WHERE id = ?").run(toBlob(vec), id);
|
|
27298
27335
|
}).catch((err) => {
|
|
27299
|
-
|
|
27336
|
+
error("embedding failed for distillation", id, ":", err);
|
|
27300
27337
|
});
|
|
27301
27338
|
}
|
|
27302
27339
|
function embedTemporalMessage(id, content3) {
|
|
27340
|
+
if (!isAvailable()) return;
|
|
27303
27341
|
if (content3.length < 50) return;
|
|
27304
27342
|
embed([content3], "document").then(([vec]) => {
|
|
27305
27343
|
db().query("UPDATE temporal_messages SET embedding = ? WHERE id = ?").run(toBlob(vec), id);
|
|
27306
27344
|
}).catch((err) => {
|
|
27307
|
-
|
|
27345
|
+
error("embedding failed for temporal message", id, ":", err);
|
|
27308
27346
|
});
|
|
27309
27347
|
}
|
|
27310
27348
|
function vectorSearchTemporal(queryEmbedding, projectId2, limit = 10, sessionId) {
|
|
@@ -27424,6 +27462,7 @@ ${r.content}` }));
|
|
|
27424
27462
|
}
|
|
27425
27463
|
} catch (err) {
|
|
27426
27464
|
error(`embedding backfill batch failed (${batch.length} items):`, err);
|
|
27465
|
+
if (err instanceof LocalProviderUnavailableError) break;
|
|
27427
27466
|
}
|
|
27428
27467
|
}
|
|
27429
27468
|
if (embedded > 0) {
|
|
@@ -27457,6 +27496,7 @@ async function backfillDistillationEmbeddings() {
|
|
|
27457
27496
|
}
|
|
27458
27497
|
} catch (err) {
|
|
27459
27498
|
error(`distillation embedding backfill batch failed (${batch.length} items):`, err);
|
|
27499
|
+
if (err instanceof LocalProviderUnavailableError) break;
|
|
27460
27500
|
}
|
|
27461
27501
|
if (embedded >= nextProgressAt) {
|
|
27462
27502
|
info(`embedding distillations: ${embedded}/${rows.length}\u2026`);
|
|
@@ -27546,14 +27586,14 @@ function store(input) {
|
|
|
27546
27586
|
embedTemporalMessage(input.info.id, content3);
|
|
27547
27587
|
}
|
|
27548
27588
|
}
|
|
27549
|
-
function undistilled(
|
|
27550
|
-
const pid = ensureProject(
|
|
27589
|
+
function undistilled(projectPath2, sessionID) {
|
|
27590
|
+
const pid = ensureProject(projectPath2);
|
|
27551
27591
|
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";
|
|
27552
27592
|
const params = sessionID ? [pid, sessionID] : [pid];
|
|
27553
27593
|
return db().query(query).all(...params);
|
|
27554
27594
|
}
|
|
27555
|
-
function bySession(
|
|
27556
|
-
const pid = ensureProject(
|
|
27595
|
+
function bySession(projectPath2, sessionID) {
|
|
27596
|
+
const pid = ensureProject(projectPath2);
|
|
27557
27597
|
return db().query(
|
|
27558
27598
|
"SELECT * FROM temporal_messages WHERE project_id = ? AND session_id = ? ORDER BY created_at ASC"
|
|
27559
27599
|
).all(pid, sessionID);
|
|
@@ -27629,26 +27669,26 @@ function temporalCnorm(timestamps, now = Date.now()) {
|
|
|
27629
27669
|
const maxVariance = (n - 1) / (n * n);
|
|
27630
27670
|
return maxVariance === 0 ? 0 : variance / maxVariance;
|
|
27631
27671
|
}
|
|
27632
|
-
function count(
|
|
27633
|
-
const pid = ensureProject(
|
|
27672
|
+
function count(projectPath2, sessionID) {
|
|
27673
|
+
const pid = ensureProject(projectPath2);
|
|
27634
27674
|
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 = ?";
|
|
27635
27675
|
const params = sessionID ? [pid, sessionID] : [pid];
|
|
27636
27676
|
return db().query(query).get(...params).count;
|
|
27637
27677
|
}
|
|
27638
|
-
function hasMessages(
|
|
27639
|
-
const pid = ensureProject(
|
|
27678
|
+
function hasMessages(projectPath2, sessionID) {
|
|
27679
|
+
const pid = ensureProject(projectPath2);
|
|
27640
27680
|
return !!db().query(
|
|
27641
27681
|
"SELECT 1 FROM temporal_messages WHERE project_id = ? AND session_id = ? LIMIT 1"
|
|
27642
27682
|
).get(pid, sessionID);
|
|
27643
27683
|
}
|
|
27644
|
-
function undistilledCount(
|
|
27645
|
-
const pid = ensureProject(
|
|
27684
|
+
function undistilledCount(projectPath2, sessionID) {
|
|
27685
|
+
const pid = ensureProject(projectPath2);
|
|
27646
27686
|
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";
|
|
27647
27687
|
const params = sessionID ? [pid, sessionID] : [pid];
|
|
27648
27688
|
return db().query(query).get(...params).count;
|
|
27649
27689
|
}
|
|
27650
|
-
function undistilledTokens(
|
|
27651
|
-
const pid = ensureProject(
|
|
27690
|
+
function undistilledTokens(projectPath2, sessionID) {
|
|
27691
|
+
const pid = ensureProject(projectPath2);
|
|
27652
27692
|
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";
|
|
27653
27693
|
const params = sessionID ? [pid, sessionID] : [pid];
|
|
27654
27694
|
return db().query(query).get(...params).total;
|
|
@@ -28169,14 +28209,16 @@ function listMarkdownFiles(dir) {
|
|
|
28169
28209
|
function contentHash(content3) {
|
|
28170
28210
|
return sha256(content3);
|
|
28171
28211
|
}
|
|
28172
|
-
function hasLatDir(
|
|
28173
|
-
|
|
28212
|
+
function hasLatDir(projectPath2) {
|
|
28213
|
+
if (isHostedMode()) return false;
|
|
28214
|
+
const latDir = join6(projectPath2, "lat.md");
|
|
28174
28215
|
return existsSync3(latDir) && statSync2(latDir).isDirectory();
|
|
28175
28216
|
}
|
|
28176
|
-
function refresh(
|
|
28177
|
-
|
|
28217
|
+
function refresh(projectPath2) {
|
|
28218
|
+
if (isHostedMode()) return 0;
|
|
28219
|
+
const latDir = join6(projectPath2, "lat.md");
|
|
28178
28220
|
if (!existsSync3(latDir) || !statSync2(latDir).isDirectory()) return 0;
|
|
28179
|
-
const pid = ensureProject(
|
|
28221
|
+
const pid = ensureProject(projectPath2);
|
|
28180
28222
|
const files = listMarkdownFiles(latDir);
|
|
28181
28223
|
let upserted = 0;
|
|
28182
28224
|
const seenFiles = /* @__PURE__ */ new Set();
|
|
@@ -28191,7 +28233,7 @@ function refresh(projectPath) {
|
|
|
28191
28233
|
} catch {
|
|
28192
28234
|
continue;
|
|
28193
28235
|
}
|
|
28194
|
-
const fileRel = relative(
|
|
28236
|
+
const fileRel = relative(projectPath2, filePath);
|
|
28195
28237
|
seenFiles.add(fileRel);
|
|
28196
28238
|
const hash2 = contentHash(content3);
|
|
28197
28239
|
const existing = db().query("SELECT content_hash FROM lat_sections WHERE project_id = ? AND file = ? LIMIT 1").get(pid, fileRel.replace(/\.md$/, ""));
|
|
@@ -28199,7 +28241,7 @@ function refresh(projectPath) {
|
|
|
28199
28241
|
continue;
|
|
28200
28242
|
}
|
|
28201
28243
|
db().query("DELETE FROM lat_sections WHERE project_id = ? AND file = ?").run(pid, fileRel.replace(/\.md$/, ""));
|
|
28202
|
-
const sections = parseSections(filePath, content3,
|
|
28244
|
+
const sections = parseSections(filePath, content3, projectPath2);
|
|
28203
28245
|
const now = Date.now();
|
|
28204
28246
|
for (const section of sections) {
|
|
28205
28247
|
upsertStmt.run(
|
|
@@ -28249,9 +28291,9 @@ function searchScored2(input) {
|
|
|
28249
28291
|
return [];
|
|
28250
28292
|
}
|
|
28251
28293
|
}
|
|
28252
|
-
function scoreForSession(
|
|
28253
|
-
if (!hasLatDir(
|
|
28254
|
-
const pid = ensureProject(
|
|
28294
|
+
function scoreForSession(projectPath2, sessionContext, maxTokens) {
|
|
28295
|
+
if (!hasLatDir(projectPath2)) return [];
|
|
28296
|
+
const pid = ensureProject(projectPath2);
|
|
28255
28297
|
const terms = extractTopTerms(sessionContext);
|
|
28256
28298
|
if (!terms.length) return [];
|
|
28257
28299
|
const q = terms.map((t2) => `${t2}*`).join(" OR ");
|
|
@@ -28283,8 +28325,8 @@ function scoreForSession(projectPath, sessionContext, maxTokens) {
|
|
|
28283
28325
|
}
|
|
28284
28326
|
return packed;
|
|
28285
28327
|
}
|
|
28286
|
-
function count2(
|
|
28287
|
-
const pid = ensureProject(
|
|
28328
|
+
function count2(projectPath2) {
|
|
28329
|
+
const pid = ensureProject(projectPath2);
|
|
28288
28330
|
const row = db().query("SELECT COUNT(*) as cnt FROM lat_sections WHERE project_id = ?").get(pid);
|
|
28289
28331
|
return row.cnt;
|
|
28290
28332
|
}
|
|
@@ -28411,8 +28453,8 @@ function findFuzzyDuplicate(input) {
|
|
|
28411
28453
|
}
|
|
28412
28454
|
return null;
|
|
28413
28455
|
}
|
|
28414
|
-
function forProject(
|
|
28415
|
-
const pid = ensureProject(
|
|
28456
|
+
function forProject(projectPath2, includeCross = true) {
|
|
28457
|
+
const pid = ensureProject(projectPath2);
|
|
28416
28458
|
if (includeCross) {
|
|
28417
28459
|
return db().query(
|
|
28418
28460
|
`SELECT ${KNOWLEDGE_COLS} FROM knowledge
|
|
@@ -28460,8 +28502,8 @@ function scoreEntriesFTS(sessionContext) {
|
|
|
28460
28502
|
return /* @__PURE__ */ new Map();
|
|
28461
28503
|
}
|
|
28462
28504
|
}
|
|
28463
|
-
async function forSession(
|
|
28464
|
-
const pid = ensureProject(
|
|
28505
|
+
async function forSession(projectPath2, sessionID, maxTokens, options) {
|
|
28506
|
+
const pid = ensureProject(projectPath2);
|
|
28465
28507
|
const categoryFilter = options?.categories;
|
|
28466
28508
|
const excludeFilter = options?.excludeCategories;
|
|
28467
28509
|
let categoryClause = "";
|
|
@@ -28565,9 +28607,9 @@ async function forSession(projectPath, sessionID, maxTokens, options) {
|
|
|
28565
28607
|
result.push(entry);
|
|
28566
28608
|
used += cost;
|
|
28567
28609
|
}
|
|
28568
|
-
if (hasLatDir(
|
|
28610
|
+
if (hasLatDir(projectPath2) && used < maxTokens) {
|
|
28569
28611
|
const latSections = scoreForSession(
|
|
28570
|
-
|
|
28612
|
+
projectPath2,
|
|
28571
28613
|
sessionContext,
|
|
28572
28614
|
maxTokens - used
|
|
28573
28615
|
);
|
|
@@ -28790,8 +28832,8 @@ function cleanDeadRefs() {
|
|
|
28790
28832
|
}
|
|
28791
28833
|
return cleaned;
|
|
28792
28834
|
}
|
|
28793
|
-
function check2(
|
|
28794
|
-
const entries = forProject(
|
|
28835
|
+
function check2(projectPath2) {
|
|
28836
|
+
const entries = forProject(projectPath2, false);
|
|
28795
28837
|
const issues = [];
|
|
28796
28838
|
for (const entry of entries) {
|
|
28797
28839
|
if (entry.content.length > 1200) {
|
|
@@ -28946,10 +28988,10 @@ function _dedup(entries, dryRun, embeddingThreshold = EMBEDDING_DEDUP_THRESHOLD)
|
|
|
28946
28988
|
const entryTitles = new Map(entries.map((e) => [e.id, e.title]));
|
|
28947
28989
|
return { clusters: result, totalRemoved, pairSimilarities, entryTitles };
|
|
28948
28990
|
}
|
|
28949
|
-
async function deduplicate(
|
|
28950
|
-
const pid = ensureProject(
|
|
28991
|
+
async function deduplicate(projectPath2, opts) {
|
|
28992
|
+
const pid = ensureProject(projectPath2);
|
|
28951
28993
|
const threshold = loadCalibratedThreshold(pid) ?? EMBEDDING_DEDUP_THRESHOLD;
|
|
28952
|
-
const entries = forProject(
|
|
28994
|
+
const entries = forProject(projectPath2, false);
|
|
28953
28995
|
return _dedup(entries, opts?.dryRun ?? true, threshold);
|
|
28954
28996
|
}
|
|
28955
28997
|
async function deduplicateGlobal(opts) {
|
|
@@ -29174,8 +29216,8 @@ function setCache(fp, entry) {
|
|
|
29174
29216
|
"INSERT INTO kv_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = ?"
|
|
29175
29217
|
).run(key, value, value);
|
|
29176
29218
|
}
|
|
29177
|
-
function clearLoreFileCache(
|
|
29178
|
-
db().query("DELETE FROM kv_meta WHERE key = ?").run(CACHE_PREFIX + join7(
|
|
29219
|
+
function clearLoreFileCache(projectPath2) {
|
|
29220
|
+
db().query("DELETE FROM kv_meta WHERE key = ?").run(CACHE_PREFIX + join7(projectPath2, LORE_FILE));
|
|
29179
29221
|
}
|
|
29180
29222
|
function splitFile(fileContent) {
|
|
29181
29223
|
const spans = [];
|
|
@@ -29251,8 +29293,8 @@ function hashSection(section) {
|
|
|
29251
29293
|
}
|
|
29252
29294
|
return (h3 >>> 0).toString(16).padStart(8, "0");
|
|
29253
29295
|
}
|
|
29254
|
-
function buildSection(
|
|
29255
|
-
const entries = forProject(
|
|
29296
|
+
function buildSection(projectPath2) {
|
|
29297
|
+
const entries = forProject(projectPath2, false);
|
|
29256
29298
|
if (!entries.length) {
|
|
29257
29299
|
return "\n";
|
|
29258
29300
|
}
|
|
@@ -29284,6 +29326,7 @@ function buildSection(projectPath) {
|
|
|
29284
29326
|
return out.join("\n");
|
|
29285
29327
|
}
|
|
29286
29328
|
function exportToFile(input) {
|
|
29329
|
+
if (isHostedMode()) return;
|
|
29287
29330
|
exportLoreFile(input.projectPath);
|
|
29288
29331
|
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";
|
|
29289
29332
|
const newSection = LORE_SECTION_START + pointerBody + LORE_SECTION_END + "\n";
|
|
@@ -29301,6 +29344,7 @@ function exportToFile(input) {
|
|
|
29301
29344
|
writeFileSync(input.filePath, result, "utf8");
|
|
29302
29345
|
}
|
|
29303
29346
|
function shouldImport(input) {
|
|
29347
|
+
if (isHostedMode()) return false;
|
|
29304
29348
|
if (!existsSync4(input.filePath)) return false;
|
|
29305
29349
|
const fileContent = readFileSync3(input.filePath, "utf8");
|
|
29306
29350
|
const { section } = splitFile(fileContent);
|
|
@@ -29310,7 +29354,7 @@ function shouldImport(input) {
|
|
|
29310
29354
|
const expected = buildSection(input.projectPath);
|
|
29311
29355
|
return hashSection(section) !== hashSection(expected);
|
|
29312
29356
|
}
|
|
29313
|
-
function _importEntries(entries,
|
|
29357
|
+
function _importEntries(entries, projectPath2) {
|
|
29314
29358
|
const seenIds = /* @__PURE__ */ new Set();
|
|
29315
29359
|
for (const entry of entries) {
|
|
29316
29360
|
if (entry.id !== null) {
|
|
@@ -29322,7 +29366,7 @@ function _importEntries(entries, projectPath) {
|
|
|
29322
29366
|
update(entry.id, { content: entry.content });
|
|
29323
29367
|
}
|
|
29324
29368
|
} else {
|
|
29325
|
-
const pid = ensureProject(
|
|
29369
|
+
const pid = ensureProject(projectPath2);
|
|
29326
29370
|
const fuzzyMatch = findFuzzyDuplicate({ title: entry.title, projectId: pid });
|
|
29327
29371
|
if (fuzzyMatch) {
|
|
29328
29372
|
if (fuzzyMatch.title !== entry.title || get(fuzzyMatch.id)?.content !== entry.content) {
|
|
@@ -29330,7 +29374,7 @@ function _importEntries(entries, projectPath) {
|
|
|
29330
29374
|
}
|
|
29331
29375
|
} else {
|
|
29332
29376
|
create({
|
|
29333
|
-
projectPath,
|
|
29377
|
+
projectPath: projectPath2,
|
|
29334
29378
|
category: entry.category,
|
|
29335
29379
|
title: entry.title,
|
|
29336
29380
|
content: entry.content,
|
|
@@ -29341,13 +29385,13 @@ function _importEntries(entries, projectPath) {
|
|
|
29341
29385
|
}
|
|
29342
29386
|
}
|
|
29343
29387
|
} else {
|
|
29344
|
-
const existing = forProject(
|
|
29388
|
+
const existing = forProject(projectPath2, false);
|
|
29345
29389
|
const titleMatch = existing.find(
|
|
29346
29390
|
(e) => e.title.toLowerCase() === entry.title.toLowerCase()
|
|
29347
29391
|
);
|
|
29348
29392
|
if (!titleMatch) {
|
|
29349
29393
|
create({
|
|
29350
|
-
projectPath,
|
|
29394
|
+
projectPath: projectPath2,
|
|
29351
29395
|
category: entry.category,
|
|
29352
29396
|
title: entry.title,
|
|
29353
29397
|
content: entry.content,
|
|
@@ -29359,6 +29403,7 @@ function _importEntries(entries, projectPath) {
|
|
|
29359
29403
|
}
|
|
29360
29404
|
}
|
|
29361
29405
|
function importFromFile(input) {
|
|
29406
|
+
if (isHostedMode()) return;
|
|
29362
29407
|
if (!existsSync4(input.filePath)) return;
|
|
29363
29408
|
const fileContent = readFileSync3(input.filePath, "utf8");
|
|
29364
29409
|
const { section } = splitFile(fileContent);
|
|
@@ -29367,14 +29412,16 @@ function importFromFile(input) {
|
|
|
29367
29412
|
if (!fileEntries.length) return;
|
|
29368
29413
|
_importEntries(fileEntries, input.projectPath);
|
|
29369
29414
|
}
|
|
29370
|
-
function loreFileExists(
|
|
29371
|
-
|
|
29415
|
+
function loreFileExists(projectPath2) {
|
|
29416
|
+
if (isHostedMode()) return false;
|
|
29417
|
+
return existsSync4(join7(projectPath2, LORE_FILE));
|
|
29372
29418
|
}
|
|
29373
|
-
function exportLoreFile(
|
|
29374
|
-
|
|
29419
|
+
function exportLoreFile(projectPath2) {
|
|
29420
|
+
if (isHostedMode()) return;
|
|
29421
|
+
const sectionBody = buildSection(projectPath2);
|
|
29375
29422
|
const content3 = LORE_FILE_HEADER + "\n" + sectionBody;
|
|
29376
29423
|
const contentHash2 = hashSection(content3);
|
|
29377
|
-
const fp = join7(
|
|
29424
|
+
const fp = join7(projectPath2, LORE_FILE);
|
|
29378
29425
|
const cached2 = getCache(fp);
|
|
29379
29426
|
if (cached2 && cached2.hash === contentHash2) {
|
|
29380
29427
|
return;
|
|
@@ -29383,8 +29430,9 @@ function exportLoreFile(projectPath) {
|
|
|
29383
29430
|
const { mtimeMs } = statSync3(fp);
|
|
29384
29431
|
setCache(fp, { mtimeMs, hash: contentHash2 });
|
|
29385
29432
|
}
|
|
29386
|
-
function shouldImportLoreFile(
|
|
29387
|
-
|
|
29433
|
+
function shouldImportLoreFile(projectPath2) {
|
|
29434
|
+
if (isHostedMode()) return false;
|
|
29435
|
+
const fp = join7(projectPath2, LORE_FILE);
|
|
29388
29436
|
if (!existsSync4(fp)) return false;
|
|
29389
29437
|
const { mtimeMs } = statSync3(fp);
|
|
29390
29438
|
const cached2 = getCache(fp);
|
|
@@ -29393,7 +29441,7 @@ function shouldImportLoreFile(projectPath) {
|
|
|
29393
29441
|
}
|
|
29394
29442
|
const fileContent = readFileSync3(fp, "utf8");
|
|
29395
29443
|
const fileHash = hashSection(fileContent);
|
|
29396
|
-
const expected = LORE_FILE_HEADER + "\n" + buildSection(
|
|
29444
|
+
const expected = LORE_FILE_HEADER + "\n" + buildSection(projectPath2);
|
|
29397
29445
|
const expectedHash = hashSection(expected);
|
|
29398
29446
|
if (fileHash === expectedHash) {
|
|
29399
29447
|
setCache(fp, { mtimeMs, hash: fileHash });
|
|
@@ -29401,13 +29449,14 @@ function shouldImportLoreFile(projectPath) {
|
|
|
29401
29449
|
}
|
|
29402
29450
|
return true;
|
|
29403
29451
|
}
|
|
29404
|
-
function importLoreFile(
|
|
29405
|
-
|
|
29452
|
+
function importLoreFile(projectPath2) {
|
|
29453
|
+
if (isHostedMode()) return;
|
|
29454
|
+
const fp = join7(projectPath2, LORE_FILE);
|
|
29406
29455
|
if (!existsSync4(fp)) return;
|
|
29407
29456
|
const fileContent = readFileSync3(fp, "utf8");
|
|
29408
29457
|
const fileEntries = parseEntriesFromSection(fileContent);
|
|
29409
29458
|
if (!fileEntries.length) return;
|
|
29410
|
-
_importEntries(fileEntries,
|
|
29459
|
+
_importEntries(fileEntries, projectPath2);
|
|
29411
29460
|
try {
|
|
29412
29461
|
const { mtimeMs } = statSync3(fp);
|
|
29413
29462
|
setCache(fp, { mtimeMs, hash: hashSection(fileContent) });
|
|
@@ -29426,8 +29475,8 @@ function listProjects() {
|
|
|
29426
29475
|
FROM projects p ORDER BY p.created_at DESC`
|
|
29427
29476
|
).all();
|
|
29428
29477
|
}
|
|
29429
|
-
function listSessions(
|
|
29430
|
-
const pid = ensureProject(
|
|
29478
|
+
function listSessions(projectPath2, limit = 50) {
|
|
29479
|
+
const pid = ensureProject(projectPath2);
|
|
29431
29480
|
return db().query(
|
|
29432
29481
|
`SELECT
|
|
29433
29482
|
session_id,
|
|
@@ -29446,8 +29495,8 @@ function listSessions(projectPath, limit = 50) {
|
|
|
29446
29495
|
LIMIT ?`
|
|
29447
29496
|
).all(pid, limit);
|
|
29448
29497
|
}
|
|
29449
|
-
function listDistillations(
|
|
29450
|
-
const pid = ensureProject(
|
|
29498
|
+
function listDistillations(projectPath2, opts) {
|
|
29499
|
+
const pid = ensureProject(projectPath2);
|
|
29451
29500
|
const limit = opts?.limit ?? 50;
|
|
29452
29501
|
if (opts?.sessionId) {
|
|
29453
29502
|
return db().query(
|
|
@@ -29496,8 +29545,8 @@ function globalStats() {
|
|
|
29496
29545
|
}
|
|
29497
29546
|
return { ...row, db_size_bytes };
|
|
29498
29547
|
}
|
|
29499
|
-
function countForProject(
|
|
29500
|
-
const pid = projectId(
|
|
29548
|
+
function countForProject(projectPath2) {
|
|
29549
|
+
const pid = projectId(projectPath2);
|
|
29501
29550
|
if (!pid)
|
|
29502
29551
|
return { knowledge: 0, messages: 0, distillations: 0, sessions: 0 };
|
|
29503
29552
|
const row = db().query(
|
|
@@ -29509,8 +29558,8 @@ function countForProject(projectPath) {
|
|
|
29509
29558
|
).get(pid, pid, pid, pid);
|
|
29510
29559
|
return row;
|
|
29511
29560
|
}
|
|
29512
|
-
function clearProject(
|
|
29513
|
-
const pid = ensureProject(
|
|
29561
|
+
function clearProject(projectPath2) {
|
|
29562
|
+
const pid = ensureProject(projectPath2);
|
|
29514
29563
|
const database = db();
|
|
29515
29564
|
const counts = {
|
|
29516
29565
|
knowledge: database.query(
|
|
@@ -29541,9 +29590,9 @@ function clearProject(projectPath) {
|
|
|
29541
29590
|
database.exec("ROLLBACK");
|
|
29542
29591
|
throw e;
|
|
29543
29592
|
}
|
|
29544
|
-
if (existsSync5(
|
|
29593
|
+
if (existsSync5(projectPath2)) {
|
|
29545
29594
|
try {
|
|
29546
|
-
exportLoreFile(
|
|
29595
|
+
exportLoreFile(projectPath2);
|
|
29547
29596
|
} catch {
|
|
29548
29597
|
}
|
|
29549
29598
|
}
|
|
@@ -29606,30 +29655,30 @@ function renameProject(projectId2, newName) {
|
|
|
29606
29655
|
const result = db().query("UPDATE projects SET name = ? WHERE id = ?").run(newName.trim(), projectId2);
|
|
29607
29656
|
return result.changes > 0;
|
|
29608
29657
|
}
|
|
29609
|
-
function clearKnowledge(
|
|
29610
|
-
const pid = ensureProject(
|
|
29658
|
+
function clearKnowledge(projectPath2) {
|
|
29659
|
+
const pid = ensureProject(projectPath2);
|
|
29611
29660
|
const count3 = db().query(
|
|
29612
29661
|
"SELECT COUNT(*) as c FROM knowledge WHERE project_id = ?"
|
|
29613
29662
|
).get(pid).c;
|
|
29614
29663
|
db().query("DELETE FROM knowledge WHERE project_id = ?").run(pid);
|
|
29615
|
-
if (existsSync5(
|
|
29664
|
+
if (existsSync5(projectPath2)) {
|
|
29616
29665
|
try {
|
|
29617
|
-
exportLoreFile(
|
|
29666
|
+
exportLoreFile(projectPath2);
|
|
29618
29667
|
} catch {
|
|
29619
29668
|
}
|
|
29620
29669
|
}
|
|
29621
29670
|
return count3;
|
|
29622
29671
|
}
|
|
29623
|
-
function clearTemporal(
|
|
29624
|
-
const pid = ensureProject(
|
|
29672
|
+
function clearTemporal(projectPath2) {
|
|
29673
|
+
const pid = ensureProject(projectPath2);
|
|
29625
29674
|
const count3 = db().query(
|
|
29626
29675
|
"SELECT COUNT(*) as c FROM temporal_messages WHERE project_id = ?"
|
|
29627
29676
|
).get(pid).c;
|
|
29628
29677
|
db().query("DELETE FROM temporal_messages WHERE project_id = ?").run(pid);
|
|
29629
29678
|
return count3;
|
|
29630
29679
|
}
|
|
29631
|
-
function clearDistillations(
|
|
29632
|
-
const pid = ensureProject(
|
|
29680
|
+
function clearDistillations(projectPath2) {
|
|
29681
|
+
const pid = ensureProject(projectPath2);
|
|
29633
29682
|
const count3 = db().query(
|
|
29634
29683
|
"SELECT COUNT(*) as c FROM distillations WHERE project_id = ?"
|
|
29635
29684
|
).get(pid).c;
|
|
@@ -29648,8 +29697,8 @@ function deleteDistillation(id) {
|
|
|
29648
29697
|
db().query("DELETE FROM distillations WHERE id = ?").run(id);
|
|
29649
29698
|
return true;
|
|
29650
29699
|
}
|
|
29651
|
-
function deleteSession(
|
|
29652
|
-
const pid = ensureProject(
|
|
29700
|
+
function deleteSession(projectPath2, sessionId) {
|
|
29701
|
+
const pid = ensureProject(projectPath2);
|
|
29653
29702
|
const database = db();
|
|
29654
29703
|
const msgCount = database.query(
|
|
29655
29704
|
"SELECT COUNT(*) as c FROM temporal_messages WHERE project_id = ? AND session_id = ?"
|
|
@@ -29879,57 +29928,41 @@ function estimateMessage(msg) {
|
|
|
29879
29928
|
}
|
|
29880
29929
|
var contextLimit = 2e5;
|
|
29881
29930
|
var outputReserved = 32e3;
|
|
29882
|
-
var
|
|
29883
|
-
var
|
|
29884
|
-
var
|
|
29885
|
-
|
|
29886
|
-
|
|
29887
|
-
|
|
29888
|
-
return Math.max(MIN_CONTEXT_FLOOR, Math.floor(targetBustCost / cacheWriteCostPerToken));
|
|
29889
|
-
}
|
|
29890
|
-
function setMaxContextTokens(tokens) {
|
|
29891
|
-
maxContextTokensCeiling = Math.max(0, Math.floor(tokens));
|
|
29931
|
+
var TIER_BOUNDARIES = [2e5, 5e5];
|
|
29932
|
+
var cacheWriteCostPerToken = 0;
|
|
29933
|
+
var cacheReadCostPerToken = 0;
|
|
29934
|
+
function setCachePricing(writeCost, readCost) {
|
|
29935
|
+
cacheWriteCostPerToken = Math.max(0, writeCost);
|
|
29936
|
+
cacheReadCostPerToken = Math.max(0, readCost);
|
|
29892
29937
|
}
|
|
29893
|
-
function
|
|
29894
|
-
return
|
|
29938
|
+
function getCachePricing() {
|
|
29939
|
+
return { write: cacheWriteCostPerToken, read: cacheReadCostPerToken };
|
|
29895
29940
|
}
|
|
29896
|
-
|
|
29941
|
+
var maxLayer0Tokens = 0;
|
|
29942
|
+
var MIN_LAYER0_FLOOR = 4e4;
|
|
29943
|
+
function shouldCompress(currentTokens, compressedTokens, consecutiveBusts, threshold = 0.85) {
|
|
29944
|
+
if (consecutiveBusts >= 5) return false;
|
|
29945
|
+
if (cacheWriteCostPerToken <= 0 || cacheReadCostPerToken <= 0) return false;
|
|
29946
|
+
const bustCost = compressedTokens * cacheWriteCostPerToken;
|
|
29947
|
+
const continueCost = currentTokens * cacheReadCostPerToken;
|
|
29948
|
+
return bustCost < threshold * continueCost;
|
|
29949
|
+
}
|
|
29950
|
+
function getTier(tokens) {
|
|
29951
|
+
if (tokens <= TIER_BOUNDARIES[0]) return 0;
|
|
29952
|
+
if (tokens <= TIER_BOUNDARIES[1]) return 1;
|
|
29953
|
+
return 2;
|
|
29954
|
+
}
|
|
29955
|
+
function recordCacheUsage(cacheWrite, cacheRead, inputTokens, sessionID) {
|
|
29897
29956
|
if (!sessionID) return;
|
|
29898
29957
|
const state = getSessionState(sessionID);
|
|
29899
|
-
const total = cacheWrite + cacheRead;
|
|
29900
|
-
if (total
|
|
29901
|
-
|
|
29902
|
-
|
|
29903
|
-
|
|
29904
|
-
|
|
29905
|
-
|
|
29906
|
-
|
|
29907
|
-
state.interBustIntervalEMA = state.interBustIntervalEMA < 0 ? interval : state.interBustIntervalEMA * 0.7 + interval * 0.3;
|
|
29908
|
-
}
|
|
29909
|
-
state.lastBustAt = now;
|
|
29910
|
-
}
|
|
29911
|
-
adaptContextCap(state);
|
|
29912
|
-
}
|
|
29913
|
-
function adaptContextCap(state) {
|
|
29914
|
-
if (maxContextTokensCeiling <= 0) return;
|
|
29915
|
-
const cap = state.dynamicContextCap > 0 ? state.dynamicContextCap : maxContextTokensCeiling;
|
|
29916
|
-
let newCap = cap;
|
|
29917
|
-
if (state.bustRateEMA > 0.8) {
|
|
29918
|
-
newCap = Math.floor(cap * 0.9);
|
|
29919
|
-
} else if (state.bustRateEMA < 0.3) {
|
|
29920
|
-
newCap = Math.floor(cap * 1.05);
|
|
29921
|
-
}
|
|
29922
|
-
if (state.interBustIntervalEMA > 0) {
|
|
29923
|
-
if (state.interBustIntervalEMA < 2 * 6e4) {
|
|
29924
|
-
newCap = Math.floor(newCap * 0.95);
|
|
29925
|
-
} else if (state.interBustIntervalEMA > 10 * 6e4) {
|
|
29926
|
-
newCap = Math.floor(newCap * 1.03);
|
|
29927
|
-
}
|
|
29928
|
-
}
|
|
29929
|
-
state.dynamicContextCap = Math.max(
|
|
29930
|
-
MIN_CONTEXT_FLOOR,
|
|
29931
|
-
Math.min(maxContextTokensCeiling, newCap)
|
|
29932
|
-
);
|
|
29958
|
+
const total = inputTokens > 0 ? inputTokens : cacheWrite + cacheRead;
|
|
29959
|
+
if (total > 0) {
|
|
29960
|
+
if (cacheWrite / total > 0.5) {
|
|
29961
|
+
state.consecutiveBusts++;
|
|
29962
|
+
} else {
|
|
29963
|
+
state.consecutiveBusts = 0;
|
|
29964
|
+
}
|
|
29965
|
+
}
|
|
29933
29966
|
}
|
|
29934
29967
|
var FIRST_TURN_OVERHEAD = 15e3;
|
|
29935
29968
|
var calibratedOverhead = null;
|
|
@@ -29950,10 +29983,7 @@ function makeSessionState() {
|
|
|
29950
29983
|
cameOutOfIdle: false,
|
|
29951
29984
|
postIdleCompact: false,
|
|
29952
29985
|
consecutiveHighLayer: 0,
|
|
29953
|
-
|
|
29954
|
-
interBustIntervalEMA: -1,
|
|
29955
|
-
lastBustAt: 0,
|
|
29956
|
-
dynamicContextCap: 0,
|
|
29986
|
+
consecutiveBusts: 0,
|
|
29957
29987
|
distillationSnapshot: null
|
|
29958
29988
|
};
|
|
29959
29989
|
}
|
|
@@ -29965,13 +29995,10 @@ function getSessionState(sessionID) {
|
|
|
29965
29995
|
state.forceMinLayer = loadForceMinLayer(sessionID);
|
|
29966
29996
|
const persisted = loadSessionTracking(sessionID);
|
|
29967
29997
|
if (persisted && persisted.lastTurnAt > 0) {
|
|
29968
|
-
state.dynamicContextCap = persisted.dynamicContextCap;
|
|
29969
|
-
state.bustRateEMA = persisted.bustRateEMA;
|
|
29970
|
-
state.interBustIntervalEMA = persisted.interBustIntervalEMA;
|
|
29971
29998
|
state.lastLayer = persisted.lastLayer;
|
|
29972
29999
|
state.lastKnownInput = persisted.lastKnownInput;
|
|
29973
30000
|
state.lastTurnAt = persisted.lastTurnAt;
|
|
29974
|
-
state.
|
|
30001
|
+
state.consecutiveBusts = persisted.dynamicContextCap;
|
|
29975
30002
|
}
|
|
29976
30003
|
sessionStates.set(sessionID, state);
|
|
29977
30004
|
}
|
|
@@ -30007,9 +30034,9 @@ function setModelLimits(limits) {
|
|
|
30007
30034
|
function setMaxLayer0Tokens(tokens) {
|
|
30008
30035
|
maxLayer0Tokens = Math.max(0, Math.floor(tokens));
|
|
30009
30036
|
}
|
|
30010
|
-
function computeLayer0Cap(targetCostPerTurn,
|
|
30011
|
-
if (targetCostPerTurn <= 0 ||
|
|
30012
|
-
const rawCap = Math.floor(targetCostPerTurn /
|
|
30037
|
+
function computeLayer0Cap(targetCostPerTurn, cacheReadCostPerToken2) {
|
|
30038
|
+
if (targetCostPerTurn <= 0 || cacheReadCostPerToken2 <= 0) return 0;
|
|
30039
|
+
const rawCap = Math.floor(targetCostPerTurn / cacheReadCostPerToken2);
|
|
30013
30040
|
return Math.max(rawCap, MIN_LAYER0_FLOOR);
|
|
30014
30041
|
}
|
|
30015
30042
|
function setLtmTokens(tokens, sessionID) {
|
|
@@ -30052,6 +30079,11 @@ function getLastTransformedCount(sessionID) {
|
|
|
30052
30079
|
function getLastTransformEstimate(sessionID) {
|
|
30053
30080
|
return sessionStates.get(sessionID)?.lastTransformEstimate ?? 0;
|
|
30054
30081
|
}
|
|
30082
|
+
function getLastLayer(sessionID) {
|
|
30083
|
+
if (sessionID) return sessionStates.get(sessionID)?.lastLayer ?? 0;
|
|
30084
|
+
const first = sessionStates.values().next().value;
|
|
30085
|
+
return first?.lastLayer ?? 0;
|
|
30086
|
+
}
|
|
30055
30087
|
function setForceMinLayer(layer, sessionID) {
|
|
30056
30088
|
if (sessionID) {
|
|
30057
30089
|
getSessionState(sessionID).forceMinLayer = layer;
|
|
@@ -30072,7 +30104,8 @@ function inspectSessionState(sessionID) {
|
|
|
30072
30104
|
cameOutOfIdle: state.cameOutOfIdle,
|
|
30073
30105
|
postIdleCompact: state.postIdleCompact,
|
|
30074
30106
|
lastTurnAt: state.lastTurnAt,
|
|
30075
|
-
distillationSnapshot: state.distillationSnapshot
|
|
30107
|
+
distillationSnapshot: state.distillationSnapshot,
|
|
30108
|
+
consecutiveBusts: state.consecutiveBusts
|
|
30076
30109
|
};
|
|
30077
30110
|
}
|
|
30078
30111
|
function setLastTurnAtForTest(sessionID, ms) {
|
|
@@ -30082,22 +30115,21 @@ function saveGradientState(sessionID) {
|
|
|
30082
30115
|
const state = sessionStates.get(sessionID);
|
|
30083
30116
|
if (!state) return;
|
|
30084
30117
|
saveSessionTracking(sessionID, {
|
|
30085
|
-
dynamicContextCap: state.dynamicContextCap,
|
|
30086
|
-
bustRateEMA: state.bustRateEMA,
|
|
30087
|
-
interBustIntervalEMA: state.interBustIntervalEMA,
|
|
30088
30118
|
lastLayer: state.lastLayer,
|
|
30089
30119
|
lastKnownInput: state.lastKnownInput,
|
|
30090
30120
|
lastTurnAt: state.lastTurnAt,
|
|
30091
|
-
|
|
30121
|
+
// Repurpose the dead dynamicContextCap column (v24, always 0 now)
|
|
30122
|
+
// to persist consecutiveBusts — avoids a new DB migration.
|
|
30123
|
+
dynamicContextCap: state.consecutiveBusts
|
|
30092
30124
|
});
|
|
30093
30125
|
}
|
|
30094
|
-
function loadDistillations(
|
|
30095
|
-
const pid = ensureProject(
|
|
30126
|
+
function loadDistillations(projectPath2, sessionID) {
|
|
30127
|
+
const pid = ensureProject(projectPath2);
|
|
30096
30128
|
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";
|
|
30097
30129
|
const params = sessionID ? [pid, sessionID] : [pid];
|
|
30098
30130
|
return db().query(query).all(...params);
|
|
30099
30131
|
}
|
|
30100
|
-
function loadDistillationsCached(
|
|
30132
|
+
function loadDistillationsCached(projectPath2, sessionID, messages, sessState) {
|
|
30101
30133
|
let lastUserMsgId = null;
|
|
30102
30134
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
30103
30135
|
if (messages[i].info.role === "user") {
|
|
@@ -30109,7 +30141,7 @@ function loadDistillationsCached(projectPath, sessionID, messages, sessState) {
|
|
|
30109
30141
|
if (snapshot && snapshot.lastUserMsgId === lastUserMsgId) {
|
|
30110
30142
|
return snapshot.rows;
|
|
30111
30143
|
}
|
|
30112
|
-
const rows = loadDistillations(
|
|
30144
|
+
const rows = loadDistillations(projectPath2, sessionID);
|
|
30113
30145
|
sessState.distillationSnapshot = { rows, lastUserMsgId };
|
|
30114
30146
|
info(
|
|
30115
30147
|
`distillation refresh: ${rows.length} rows (user msg ${lastUserMsgId?.substring(0, 16) ?? "none"})`
|
|
@@ -30533,8 +30565,7 @@ function transformInner(input) {
|
|
|
30533
30565
|
0,
|
|
30534
30566
|
contextLimit - outputReserved - overhead - sessLtmTokens
|
|
30535
30567
|
);
|
|
30536
|
-
const
|
|
30537
|
-
const usable = effectiveCap > 0 && usableRaw > effectiveCap ? effectiveCap : usableRaw;
|
|
30568
|
+
const usable = usableRaw;
|
|
30538
30569
|
const distilledBudget = Math.floor(usable * cfg.budget.distilled);
|
|
30539
30570
|
let rawBudget = Math.floor(usable * cfg.budget.raw);
|
|
30540
30571
|
let effectiveMinLayer = sessState.forceMinLayer;
|
|
@@ -30555,8 +30586,7 @@ function transformInner(input) {
|
|
|
30555
30586
|
if (postIdleCompact) {
|
|
30556
30587
|
sessState.postIdleCompact = false;
|
|
30557
30588
|
effectiveMinLayer = Math.max(effectiveMinLayer, 1);
|
|
30558
|
-
|
|
30559
|
-
rawBudget = Math.floor(usable * postIdleRawFraction);
|
|
30589
|
+
rawBudget = Math.floor(usable * 0.2);
|
|
30560
30590
|
info(
|
|
30561
30591
|
`post-idle compact: session=${sid} rawBudget=${rawBudget} (${Math.floor(usable * cfg.budget.raw)}\u2192${rawBudget})`
|
|
30562
30592
|
);
|
|
@@ -30590,6 +30620,28 @@ function transformInner(input) {
|
|
|
30590
30620
|
refreshLtm: false
|
|
30591
30621
|
};
|
|
30592
30622
|
}
|
|
30623
|
+
if (effectiveMinLayer === 0 && layer0Input > layer0Ceiling && layer0Input <= maxInput && sid) {
|
|
30624
|
+
const busts = getSessionState(sid).consecutiveBusts;
|
|
30625
|
+
const compressedEstimate = distilledBudget + rawBudget;
|
|
30626
|
+
if (!shouldCompress(Math.round(layer0Input), compressedEstimate, busts)) {
|
|
30627
|
+
const messageTokens = calibrated ? expectedInput - (sessLtmTokens - sessState.lastKnownLtm) : expectedInput - overhead - sessLtmTokens;
|
|
30628
|
+
info(
|
|
30629
|
+
`tier gate: session=${sid} skipping compression \u2014 bustCost not justified (input=${Math.round(layer0Input)} compressed=${compressedEstimate} busts=${busts})`
|
|
30630
|
+
);
|
|
30631
|
+
return {
|
|
30632
|
+
messages: input.messages,
|
|
30633
|
+
layer: 0,
|
|
30634
|
+
distilledTokens: 0,
|
|
30635
|
+
rawTokens: Math.max(0, messageTokens),
|
|
30636
|
+
totalTokens: Math.max(0, messageTokens),
|
|
30637
|
+
usable,
|
|
30638
|
+
distilledBudget,
|
|
30639
|
+
rawBudget,
|
|
30640
|
+
refreshLtm: false,
|
|
30641
|
+
unsustainable: busts >= 5
|
|
30642
|
+
};
|
|
30643
|
+
}
|
|
30644
|
+
}
|
|
30593
30645
|
const turnStart = currentTurnStart(input.messages);
|
|
30594
30646
|
const dedupMessages = deduplicateToolOutputs(input.messages, turnStart);
|
|
30595
30647
|
const distillations = sid ? loadDistillationsCached(input.projectPath, sid, input.messages, sessState) : [];
|
|
@@ -30673,6 +30725,7 @@ function transformInner(input) {
|
|
|
30673
30725
|
}
|
|
30674
30726
|
const nuclearRaw = [...olderMessages, ...currentTurn];
|
|
30675
30727
|
const nuclearRawTokens = olderTokens + currentTurnTokens;
|
|
30728
|
+
const unsustainable = sid ? getSessionState(sid).consecutiveBusts >= 5 : false;
|
|
30676
30729
|
return {
|
|
30677
30730
|
messages: [...nuclearPrefix, ...nuclearRaw],
|
|
30678
30731
|
layer: 4,
|
|
@@ -30682,7 +30735,8 @@ function transformInner(input) {
|
|
|
30682
30735
|
usable,
|
|
30683
30736
|
distilledBudget,
|
|
30684
30737
|
rawBudget,
|
|
30685
|
-
refreshLtm: true
|
|
30738
|
+
refreshLtm: true,
|
|
30739
|
+
unsustainable
|
|
30686
30740
|
};
|
|
30687
30741
|
}
|
|
30688
30742
|
function transform2(input) {
|
|
@@ -30707,7 +30761,7 @@ function transform2(input) {
|
|
|
30707
30761
|
state.consecutiveHighLayer = 0;
|
|
30708
30762
|
}
|
|
30709
30763
|
info(
|
|
30710
|
-
`gradient: session=${sid} layer=${result.layer} tokens=${result.totalTokens} (distilled=${result.distilledTokens} raw=${result.rawTokens}) usable=${result.usable}
|
|
30764
|
+
`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"}`
|
|
30711
30765
|
);
|
|
30712
30766
|
}
|
|
30713
30767
|
return result;
|
|
@@ -31093,18 +31147,18 @@ function parseDistillationResult(text4) {
|
|
|
31093
31147
|
if (!observations) return null;
|
|
31094
31148
|
return { observations };
|
|
31095
31149
|
}
|
|
31096
|
-
function latestObservations(
|
|
31097
|
-
const pid = ensureProject(
|
|
31150
|
+
function latestObservations(projectPath2, sessionID) {
|
|
31151
|
+
const pid = ensureProject(projectPath2);
|
|
31098
31152
|
const row = db().query(
|
|
31099
31153
|
"SELECT observations FROM distillations WHERE project_id = ? AND session_id = ? ORDER BY created_at DESC LIMIT 1"
|
|
31100
31154
|
).get(pid, sessionID);
|
|
31101
31155
|
return row?.observations || void 0;
|
|
31102
31156
|
}
|
|
31103
|
-
function latestMetaObservations(
|
|
31104
|
-
return latestMeta(
|
|
31157
|
+
function latestMetaObservations(projectPath2, sessionID) {
|
|
31158
|
+
return latestMeta(projectPath2, sessionID)?.observations;
|
|
31105
31159
|
}
|
|
31106
|
-
function latestMeta(
|
|
31107
|
-
const pid = ensureProject(
|
|
31160
|
+
function latestMeta(projectPath2, sessionID) {
|
|
31161
|
+
const pid = ensureProject(projectPath2);
|
|
31108
31162
|
const row = db().query(
|
|
31109
31163
|
`SELECT observations, generation FROM distillations
|
|
31110
31164
|
WHERE project_id = ? AND session_id = ? AND generation > 0
|
|
@@ -31122,8 +31176,8 @@ function parseSourceIds(raw) {
|
|
|
31122
31176
|
return [];
|
|
31123
31177
|
}
|
|
31124
31178
|
}
|
|
31125
|
-
function loadForSession(
|
|
31126
|
-
const pid = ensureProject(
|
|
31179
|
+
function loadForSession(projectPath2, sessionID, includeArchived = false) {
|
|
31180
|
+
const pid = ensureProject(projectPath2);
|
|
31127
31181
|
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";
|
|
31128
31182
|
const rows = db().query(sql).all(pid, sessionID);
|
|
31129
31183
|
return rows.map((r) => ({
|
|
@@ -31158,14 +31212,14 @@ function storeDistillation(input) {
|
|
|
31158
31212
|
);
|
|
31159
31213
|
return id;
|
|
31160
31214
|
}
|
|
31161
|
-
function gen0Count(
|
|
31162
|
-
const pid = ensureProject(
|
|
31215
|
+
function gen0Count(projectPath2, sessionID) {
|
|
31216
|
+
const pid = ensureProject(projectPath2);
|
|
31163
31217
|
return db().query(
|
|
31164
31218
|
"SELECT COUNT(*) as count FROM distillations WHERE project_id = ? AND session_id = ? AND generation = 0 AND archived = 0"
|
|
31165
31219
|
).get(pid, sessionID).count;
|
|
31166
31220
|
}
|
|
31167
|
-
function loadGen0(
|
|
31168
|
-
const pid = ensureProject(
|
|
31221
|
+
function loadGen0(projectPath2, sessionID) {
|
|
31222
|
+
const pid = ensureProject(projectPath2);
|
|
31169
31223
|
const rows = db().query(
|
|
31170
31224
|
"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"
|
|
31171
31225
|
).all(pid, sessionID);
|
|
@@ -31181,8 +31235,8 @@ function archiveDistillations(ids) {
|
|
|
31181
31235
|
`UPDATE distillations SET archived = 1 WHERE id IN (${placeholders})`
|
|
31182
31236
|
).run(...ids);
|
|
31183
31237
|
}
|
|
31184
|
-
function resetOrphans(
|
|
31185
|
-
const pid = ensureProject(
|
|
31238
|
+
function resetOrphans(projectPath2, sessionID) {
|
|
31239
|
+
const pid = ensureProject(projectPath2);
|
|
31186
31240
|
const rows = db().query(
|
|
31187
31241
|
"SELECT source_ids FROM distillations WHERE project_id = ? AND session_id = ?"
|
|
31188
31242
|
).all(pid, sessionID);
|
|
@@ -31814,11 +31868,11 @@ function clearProviders() {
|
|
|
31814
31868
|
}
|
|
31815
31869
|
|
|
31816
31870
|
// src/import/detect.ts
|
|
31817
|
-
function detectAll(
|
|
31871
|
+
function detectAll(projectPath2) {
|
|
31818
31872
|
const results = [];
|
|
31819
31873
|
for (const provider of getProviders()) {
|
|
31820
31874
|
try {
|
|
31821
|
-
const sessions = provider.detect(
|
|
31875
|
+
const sessions = provider.detect(projectPath2);
|
|
31822
31876
|
if (sessions.length > 0) {
|
|
31823
31877
|
results.push({
|
|
31824
31878
|
agentName: provider.name,
|
|
@@ -31907,8 +31961,8 @@ async function extractKnowledge(input) {
|
|
|
31907
31961
|
}
|
|
31908
31962
|
|
|
31909
31963
|
// src/import/history.ts
|
|
31910
|
-
function isImported(
|
|
31911
|
-
const projectId2 = ensureProject(
|
|
31964
|
+
function isImported(projectPath2, agentName, sourceId, sourceHash) {
|
|
31965
|
+
const projectId2 = ensureProject(projectPath2);
|
|
31912
31966
|
const row = db().query(
|
|
31913
31967
|
`SELECT * FROM import_history
|
|
31914
31968
|
WHERE project_id = ? AND agent_name = ? AND source_id = ?`
|
|
@@ -31917,8 +31971,8 @@ function isImported(projectPath, agentName, sourceId, sourceHash) {
|
|
|
31917
31971
|
if (row.source_hash !== sourceHash) return null;
|
|
31918
31972
|
return row;
|
|
31919
31973
|
}
|
|
31920
|
-
function recordImport(
|
|
31921
|
-
const projectId2 = ensureProject(
|
|
31974
|
+
function recordImport(projectPath2, agentName, sourceId, sourceHash, stats) {
|
|
31975
|
+
const projectId2 = ensureProject(projectPath2);
|
|
31922
31976
|
db().query(
|
|
31923
31977
|
`INSERT OR REPLACE INTO import_history
|
|
31924
31978
|
(id, project_id, agent_name, source_id, source_hash, entries_created, entries_updated, imported_at)
|
|
@@ -31934,8 +31988,8 @@ function recordImport(projectPath, agentName, sourceId, sourceHash, stats) {
|
|
|
31934
31988
|
Date.now()
|
|
31935
31989
|
);
|
|
31936
31990
|
}
|
|
31937
|
-
function listImports(
|
|
31938
|
-
const projectId2 = ensureProject(
|
|
31991
|
+
function listImports(projectPath2) {
|
|
31992
|
+
const projectId2 = ensureProject(projectPath2);
|
|
31939
31993
|
return db().query(
|
|
31940
31994
|
`SELECT * FROM import_history
|
|
31941
31995
|
WHERE project_id = ? AND source_id != '__declined__'
|
|
@@ -31953,8 +32007,8 @@ import { homedir as homedir2 } from "os";
|
|
|
31953
32007
|
var CLAUDE_DIR = join8(homedir2(), ".claude", "projects");
|
|
31954
32008
|
var MAX_TOOL_OUTPUT_CHARS = 500;
|
|
31955
32009
|
var DEFAULT_MAX_TOKENS = 12288;
|
|
31956
|
-
function manglePath(
|
|
31957
|
-
return
|
|
32010
|
+
function manglePath(projectPath2) {
|
|
32011
|
+
return projectPath2.replace(/\//g, "-");
|
|
31958
32012
|
}
|
|
31959
32013
|
function estimateTokens4(text4) {
|
|
31960
32014
|
return Math.ceil(text4.length / 3);
|
|
@@ -32068,8 +32122,8 @@ function getSessionMetadata(filePath) {
|
|
|
32068
32122
|
var claudeCodeProvider = {
|
|
32069
32123
|
name: "claude-code",
|
|
32070
32124
|
displayName: "Claude Code",
|
|
32071
|
-
detect(
|
|
32072
|
-
const mangled = manglePath(
|
|
32125
|
+
detect(projectPath2) {
|
|
32126
|
+
const mangled = manglePath(projectPath2);
|
|
32073
32127
|
const dir = join8(CLAUDE_DIR, mangled);
|
|
32074
32128
|
let entries;
|
|
32075
32129
|
try {
|
|
@@ -32267,7 +32321,7 @@ function getSessionMeta(filePath) {
|
|
|
32267
32321
|
var codexProvider = {
|
|
32268
32322
|
name: "codex",
|
|
32269
32323
|
displayName: "Codex",
|
|
32270
|
-
detect(
|
|
32324
|
+
detect(projectPath2) {
|
|
32271
32325
|
const sessions = [];
|
|
32272
32326
|
const allFiles = [
|
|
32273
32327
|
...findJsonlFiles(SESSIONS_DIR),
|
|
@@ -32276,7 +32330,7 @@ var codexProvider = {
|
|
|
32276
32330
|
for (const filePath of allFiles) {
|
|
32277
32331
|
const meta3 = getSessionMeta(filePath);
|
|
32278
32332
|
if (!meta3) continue;
|
|
32279
|
-
if (meta3.cwd !==
|
|
32333
|
+
if (meta3.cwd !== projectPath2) continue;
|
|
32280
32334
|
if (meta3.messageCount < 3) continue;
|
|
32281
32335
|
const ts = new Date(meta3.timestamp).getTime();
|
|
32282
32336
|
const estimatedTokens = Math.ceil(meta3.fileSize / 5);
|
|
@@ -32408,14 +32462,14 @@ function partsToConversationText(parts) {
|
|
|
32408
32462
|
var opencodeProvider = {
|
|
32409
32463
|
name: "opencode",
|
|
32410
32464
|
displayName: "OpenCode",
|
|
32411
|
-
detect(
|
|
32465
|
+
detect(projectPath2) {
|
|
32412
32466
|
const database = openDB();
|
|
32413
32467
|
if (!database) return [];
|
|
32414
32468
|
try {
|
|
32415
32469
|
if (!tableExists(database, "project") || !tableExists(database, "session") || !tableExists(database, "message")) {
|
|
32416
32470
|
return [];
|
|
32417
32471
|
}
|
|
32418
|
-
const project = database.query("SELECT id FROM project WHERE worktree = ?").get(
|
|
32472
|
+
const project = database.query("SELECT id FROM project WHERE worktree = ?").get(projectPath2);
|
|
32419
32473
|
if (!project) return [];
|
|
32420
32474
|
const sessions = database.query(
|
|
32421
32475
|
`SELECT s.id, s.title, s.time_created, s.time_updated,
|
|
@@ -32580,7 +32634,7 @@ function findGlobalStorageDirs() {
|
|
|
32580
32634
|
}
|
|
32581
32635
|
return dirs;
|
|
32582
32636
|
}
|
|
32583
|
-
function loadTaskHistory(storageDir,
|
|
32637
|
+
function loadTaskHistory(storageDir, projectPath2) {
|
|
32584
32638
|
const paths = [
|
|
32585
32639
|
join11(storageDir, "state", "taskHistory.json"),
|
|
32586
32640
|
join11(storageDir, "taskHistory.json")
|
|
@@ -32592,7 +32646,7 @@ function loadTaskHistory(storageDir, projectPath) {
|
|
|
32592
32646
|
const items = JSON.parse(raw);
|
|
32593
32647
|
if (!Array.isArray(items)) continue;
|
|
32594
32648
|
return items.filter(
|
|
32595
|
-
(item) => item.cwdOnTaskInitialization ===
|
|
32649
|
+
(item) => item.cwdOnTaskInitialization === projectPath2
|
|
32596
32650
|
);
|
|
32597
32651
|
} catch {
|
|
32598
32652
|
continue;
|
|
@@ -32645,11 +32699,11 @@ function messageToText(msg) {
|
|
|
32645
32699
|
var clineProvider = {
|
|
32646
32700
|
name: "cline",
|
|
32647
32701
|
displayName: "Cline",
|
|
32648
|
-
detect(
|
|
32702
|
+
detect(projectPath2) {
|
|
32649
32703
|
const sessions = [];
|
|
32650
32704
|
const storageDirs = findGlobalStorageDirs();
|
|
32651
32705
|
for (const storageDir of storageDirs) {
|
|
32652
|
-
const tasks = loadTaskHistory(storageDir,
|
|
32706
|
+
const tasks = loadTaskHistory(storageDir, projectPath2);
|
|
32653
32707
|
for (const task of tasks) {
|
|
32654
32708
|
const taskDir = join11(storageDir, "tasks", task.id);
|
|
32655
32709
|
if (!existsSync8(taskDir)) continue;
|
|
@@ -32797,11 +32851,11 @@ function historyItemToText(item) {
|
|
|
32797
32851
|
var continueProvider = {
|
|
32798
32852
|
name: "continue",
|
|
32799
32853
|
displayName: "Continue",
|
|
32800
|
-
detect(
|
|
32854
|
+
detect(projectPath2) {
|
|
32801
32855
|
const sessions = [];
|
|
32802
32856
|
const index2 = loadSessionIndex();
|
|
32803
32857
|
for (const meta3 of index2) {
|
|
32804
|
-
if (meta3.workspaceDirectory !==
|
|
32858
|
+
if (meta3.workspaceDirectory !== projectPath2) continue;
|
|
32805
32859
|
const session = loadSession(meta3.sessionId);
|
|
32806
32860
|
if (!session || !session.history || session.history.length < 3) continue;
|
|
32807
32861
|
const ts = new Date(meta3.dateCreated).getTime();
|
|
@@ -32833,7 +32887,7 @@ var continueProvider = {
|
|
|
32833
32887
|
if (existingIds.has(sessionId)) continue;
|
|
32834
32888
|
const session = loadSession(sessionId);
|
|
32835
32889
|
if (!session) continue;
|
|
32836
|
-
if (session.workspaceDirectory !==
|
|
32890
|
+
if (session.workspaceDirectory !== projectPath2) continue;
|
|
32837
32891
|
if (!session.history || session.history.length < 3) continue;
|
|
32838
32892
|
const dateStr = session.title ? truncate5(session.title, 60) : sessionId.slice(0, 8);
|
|
32839
32893
|
sessions.push({
|
|
@@ -32982,8 +33036,8 @@ function getSessionMeta2(filePath) {
|
|
|
32982
33036
|
var piProvider = {
|
|
32983
33037
|
name: "pi",
|
|
32984
33038
|
displayName: "Pi",
|
|
32985
|
-
detect(
|
|
32986
|
-
const encoded = encodeCwd(
|
|
33039
|
+
detect(projectPath2) {
|
|
33040
|
+
const encoded = encodeCwd(projectPath2);
|
|
32987
33041
|
const dir = join13(PI_DIR, encoded);
|
|
32988
33042
|
let entries;
|
|
32989
33043
|
try {
|
|
@@ -33121,8 +33175,8 @@ function parseAiderHistory(content3) {
|
|
|
33121
33175
|
var aiderProvider = {
|
|
33122
33176
|
name: "aider",
|
|
33123
33177
|
displayName: "Aider",
|
|
33124
|
-
detect(
|
|
33125
|
-
const filePath = join14(
|
|
33178
|
+
detect(projectPath2) {
|
|
33179
|
+
const filePath = join14(projectPath2, HISTORY_FILE);
|
|
33126
33180
|
if (!existsSync11(filePath)) return [];
|
|
33127
33181
|
let stat;
|
|
33128
33182
|
try {
|
|
@@ -33151,7 +33205,7 @@ var aiderProvider = {
|
|
|
33151
33205
|
}
|
|
33152
33206
|
];
|
|
33153
33207
|
},
|
|
33154
|
-
readChunks(
|
|
33208
|
+
readChunks(projectPath2, sessionIds, maxTokens = DEFAULT_MAX_TOKENS7) {
|
|
33155
33209
|
const chunks = [];
|
|
33156
33210
|
for (const filePath of sessionIds) {
|
|
33157
33211
|
let content3;
|
|
@@ -33446,7 +33500,7 @@ async function searchRecall(input) {
|
|
|
33446
33500
|
const {
|
|
33447
33501
|
query,
|
|
33448
33502
|
scope = "all",
|
|
33449
|
-
projectPath,
|
|
33503
|
+
projectPath: projectPath2,
|
|
33450
33504
|
sessionID,
|
|
33451
33505
|
knowledgeEnabled = true,
|
|
33452
33506
|
llm,
|
|
@@ -33473,7 +33527,7 @@ async function searchRecall(input) {
|
|
|
33473
33527
|
if (knowledgeEnabled && scope !== "session") {
|
|
33474
33528
|
try {
|
|
33475
33529
|
knowledgeResults.push(
|
|
33476
|
-
...searchScored3({ query: q, projectPath, limit })
|
|
33530
|
+
...searchScored3({ query: q, projectPath: projectPath2, limit })
|
|
33477
33531
|
);
|
|
33478
33532
|
} catch (err) {
|
|
33479
33533
|
error("recall: knowledge search failed:", err);
|
|
@@ -33484,7 +33538,7 @@ async function searchRecall(input) {
|
|
|
33484
33538
|
try {
|
|
33485
33539
|
distillationResults.push(
|
|
33486
33540
|
...searchDistillationsScored({
|
|
33487
|
-
projectPath,
|
|
33541
|
+
projectPath: projectPath2,
|
|
33488
33542
|
query: q,
|
|
33489
33543
|
sessionID: scope === "session" ? sessionID : void 0,
|
|
33490
33544
|
limit
|
|
@@ -33499,7 +33553,7 @@ async function searchRecall(input) {
|
|
|
33499
33553
|
try {
|
|
33500
33554
|
temporalResults.push(
|
|
33501
33555
|
...searchScored({
|
|
33502
|
-
projectPath,
|
|
33556
|
+
projectPath: projectPath2,
|
|
33503
33557
|
query: q,
|
|
33504
33558
|
sessionID: scope === "session" ? sessionID : void 0,
|
|
33505
33559
|
limit
|
|
@@ -33593,7 +33647,7 @@ async function searchRecall(input) {
|
|
|
33593
33647
|
}
|
|
33594
33648
|
}
|
|
33595
33649
|
if (scope !== "knowledge") {
|
|
33596
|
-
const pid = ensureProject(
|
|
33650
|
+
const pid = ensureProject(projectPath2);
|
|
33597
33651
|
const temporalVectorHits = vectorSearchTemporal(
|
|
33598
33652
|
queryVec,
|
|
33599
33653
|
pid,
|
|
@@ -33621,11 +33675,11 @@ async function searchRecall(input) {
|
|
|
33621
33675
|
info("recall: vector search failed:", err);
|
|
33622
33676
|
}
|
|
33623
33677
|
}
|
|
33624
|
-
if (scope !== "session" && hasLatDir(
|
|
33678
|
+
if (scope !== "session" && hasLatDir(projectPath2)) {
|
|
33625
33679
|
try {
|
|
33626
33680
|
const latResults = searchScored2({
|
|
33627
33681
|
query,
|
|
33628
|
-
projectPath,
|
|
33682
|
+
projectPath: projectPath2,
|
|
33629
33683
|
limit
|
|
33630
33684
|
});
|
|
33631
33685
|
if (latResults.length) {
|
|
@@ -33645,7 +33699,7 @@ async function searchRecall(input) {
|
|
|
33645
33699
|
try {
|
|
33646
33700
|
const crossProjectResults = searchScoredOtherProjects({
|
|
33647
33701
|
query,
|
|
33648
|
-
excludeProjectPath:
|
|
33702
|
+
excludeProjectPath: projectPath2,
|
|
33649
33703
|
limit
|
|
33650
33704
|
});
|
|
33651
33705
|
if (crossProjectResults.length) {
|
|
@@ -33835,7 +33889,6 @@ export {
|
|
|
33835
33889
|
clearGitRemoteCache,
|
|
33836
33890
|
clearLoreFileCache,
|
|
33837
33891
|
close,
|
|
33838
|
-
computeContextCap,
|
|
33839
33892
|
computeLayer0Cap,
|
|
33840
33893
|
config2 as config,
|
|
33841
33894
|
consolidationUser,
|
|
@@ -33851,6 +33904,7 @@ export {
|
|
|
33851
33904
|
distillationUser,
|
|
33852
33905
|
embedding_exports as embedding,
|
|
33853
33906
|
embedding_vendor_exports as embeddingVendor,
|
|
33907
|
+
enableHostedMode,
|
|
33854
33908
|
ensureProject,
|
|
33855
33909
|
exactTermMatchRank,
|
|
33856
33910
|
expandQuery,
|
|
@@ -33862,17 +33916,19 @@ export {
|
|
|
33862
33916
|
ftsQuery,
|
|
33863
33917
|
ftsQueryOr,
|
|
33864
33918
|
ftsQueryRelaxed,
|
|
33919
|
+
getCachePricing,
|
|
33865
33920
|
getGitRemote,
|
|
33866
33921
|
getInstanceId,
|
|
33867
33922
|
getKV,
|
|
33868
33923
|
getLastImportAt,
|
|
33924
|
+
getLastLayer,
|
|
33869
33925
|
getLastTransformEstimate,
|
|
33870
33926
|
getLastTransformedCount,
|
|
33871
33927
|
getLastTurnAt,
|
|
33872
33928
|
getLtmBudget,
|
|
33873
33929
|
getLtmTokens,
|
|
33874
|
-
getMaxContextTokens,
|
|
33875
33930
|
getMeta,
|
|
33931
|
+
getTier,
|
|
33876
33932
|
h,
|
|
33877
33933
|
importFromFile,
|
|
33878
33934
|
importLoreFile,
|
|
@@ -33880,6 +33936,7 @@ export {
|
|
|
33880
33936
|
inspectSessionState,
|
|
33881
33937
|
instruction_detect_exports as instructionDetect,
|
|
33882
33938
|
isFirstRun,
|
|
33939
|
+
isHostedMode,
|
|
33883
33940
|
isReasoningPart,
|
|
33884
33941
|
isTextPart,
|
|
33885
33942
|
isToolPart,
|
|
@@ -33905,10 +33962,13 @@ export {
|
|
|
33905
33962
|
pattern_extract_exports as patternExtract,
|
|
33906
33963
|
projectId,
|
|
33907
33964
|
projectName,
|
|
33965
|
+
projectPath,
|
|
33908
33966
|
recallById,
|
|
33909
33967
|
reciprocalRankFusion,
|
|
33968
|
+
recordCacheUsage,
|
|
33910
33969
|
recursiveUser,
|
|
33911
33970
|
renderMarkdown,
|
|
33971
|
+
resolveProjectByRemoteOrPath,
|
|
33912
33972
|
root2 as root,
|
|
33913
33973
|
runRecall,
|
|
33914
33974
|
sanitizeSurrogates,
|
|
@@ -33918,15 +33978,16 @@ export {
|
|
|
33918
33978
|
saveSessionTracking,
|
|
33919
33979
|
searchRecall,
|
|
33920
33980
|
serialize,
|
|
33981
|
+
setCachePricing,
|
|
33921
33982
|
setForceMinLayer,
|
|
33922
33983
|
setKV,
|
|
33923
33984
|
setLastImportAt,
|
|
33924
33985
|
setLastTurnAtForTest,
|
|
33925
33986
|
setLtmTokens,
|
|
33926
|
-
setMaxContextTokens,
|
|
33927
33987
|
setMaxLayer0Tokens,
|
|
33928
33988
|
setMeta,
|
|
33929
33989
|
setModelLimits,
|
|
33990
|
+
shouldCompress,
|
|
33930
33991
|
shouldImport,
|
|
33931
33992
|
shouldImportLoreFile,
|
|
33932
33993
|
strong2 as strong,
|
|
@@ -33936,7 +33997,6 @@ export {
|
|
|
33936
33997
|
transform2 as transform,
|
|
33937
33998
|
ul,
|
|
33938
33999
|
unescapeMarkdown,
|
|
33939
|
-
updateBustRate,
|
|
33940
34000
|
worker_model_exports as workerModel,
|
|
33941
34001
|
workerSessionIDs
|
|
33942
34002
|
};
|