@loreai/core 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bun/agents-file.d.ts.map +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 +4 -1
- 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 +236 -152
- 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.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 +4 -1
- 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 +236 -152
- 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.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 +4 -1
- 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 +10 -5
- package/src/db.ts +39 -6
- package/src/embedding.ts +43 -5
- package/src/git.ts +4 -0
- package/src/gradient.ts +44 -0
- package/src/hosted.ts +46 -0
- package/src/index.ts +4 -0
- 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) {
|
|
@@ -26774,11 +26800,13 @@ function config2() {
|
|
|
26774
26800
|
return current;
|
|
26775
26801
|
}
|
|
26776
26802
|
async function load(directory) {
|
|
26777
|
-
|
|
26778
|
-
|
|
26779
|
-
|
|
26780
|
-
|
|
26781
|
-
|
|
26803
|
+
if (!isHostedMode()) {
|
|
26804
|
+
const path = join5(directory, ".lore.json");
|
|
26805
|
+
if (existsSync2(path)) {
|
|
26806
|
+
const raw = JSON.parse(readFileSync(path, "utf8"));
|
|
26807
|
+
current = LoreConfig.parse(raw);
|
|
26808
|
+
return current;
|
|
26809
|
+
}
|
|
26782
26810
|
}
|
|
26783
26811
|
current = LoreConfig.parse({});
|
|
26784
26812
|
return current;
|
|
@@ -26818,6 +26846,14 @@ function vendorRegistration() {
|
|
|
26818
26846
|
|
|
26819
26847
|
// src/embedding.ts
|
|
26820
26848
|
var EMBED_TIMEOUT_MS = 1e4;
|
|
26849
|
+
var LOCAL_MAX_CHARS = 4096 * 4;
|
|
26850
|
+
function safeLocalTruncate(text4) {
|
|
26851
|
+
if (text4.length <= LOCAL_MAX_CHARS) return text4;
|
|
26852
|
+
let end = LOCAL_MAX_CHARS;
|
|
26853
|
+
const code2 = text4.charCodeAt(end - 1);
|
|
26854
|
+
if (code2 >= 55296 && code2 <= 56319) end--;
|
|
26855
|
+
return text4.slice(0, end);
|
|
26856
|
+
}
|
|
26821
26857
|
var VOYAGE_API_URL = "https://api.voyageai.com/v1/embeddings";
|
|
26822
26858
|
var VoyageProvider = class {
|
|
26823
26859
|
maxBatchSize = 128;
|
|
@@ -27000,8 +27036,9 @@ var LocalProvider = class {
|
|
|
27000
27036
|
localProviderKnownBroken = true;
|
|
27001
27037
|
if (!localProviderErrorLogged) {
|
|
27002
27038
|
localProviderErrorLogged = true;
|
|
27003
|
-
|
|
27004
|
-
`local embedding provider failed to init: ${msg.error}. Set VOYAGE_API_KEY/OPENAI_API_KEY for automatic remote fallback
|
|
27039
|
+
error(
|
|
27040
|
+
`local embedding provider failed to init: ${msg.error}. Set VOYAGE_API_KEY/OPENAI_API_KEY for automatic remote fallback.`,
|
|
27041
|
+
new Error(`embedding worker init failed: ${msg.error}`)
|
|
27005
27042
|
);
|
|
27006
27043
|
}
|
|
27007
27044
|
for (const [, p2] of this.pendingRequests) {
|
|
@@ -27016,6 +27053,7 @@ var LocalProvider = class {
|
|
|
27016
27053
|
this.worker.on("error", (err) => {
|
|
27017
27054
|
this.workerInitError = err.message;
|
|
27018
27055
|
this.workerReady = false;
|
|
27056
|
+
error("embedding worker crashed:", err);
|
|
27019
27057
|
for (const [, p2] of this.pendingRequests) {
|
|
27020
27058
|
p2.reject(new LocalProviderUnavailableError(err));
|
|
27021
27059
|
}
|
|
@@ -27025,6 +27063,10 @@ var LocalProvider = class {
|
|
|
27025
27063
|
this.worker.on("exit", (code2) => {
|
|
27026
27064
|
if (code2 !== 0 && !this.workerInitError) {
|
|
27027
27065
|
this.workerInitError = `embedding worker exited with code ${code2}`;
|
|
27066
|
+
error(
|
|
27067
|
+
this.workerInitError,
|
|
27068
|
+
new Error(this.workerInitError)
|
|
27069
|
+
);
|
|
27028
27070
|
}
|
|
27029
27071
|
this.workerReady = false;
|
|
27030
27072
|
for (const [, p2] of this.pendingRequests) {
|
|
@@ -27055,8 +27097,9 @@ var LocalProvider = class {
|
|
|
27055
27097
|
}
|
|
27056
27098
|
async embed(texts, inputType) {
|
|
27057
27099
|
await this.ensureWorker();
|
|
27100
|
+
const truncated = texts.map(safeLocalTruncate);
|
|
27058
27101
|
const prefix = inputType === "document" ? "search_document: " : "search_query: ";
|
|
27059
|
-
const prefixed =
|
|
27102
|
+
const prefixed = truncated.map((t2) => prefix + t2);
|
|
27060
27103
|
const id = this.nextRequestId++;
|
|
27061
27104
|
const priority = inputType === "query" && texts.length === 1 ? "high" : "normal";
|
|
27062
27105
|
return new Promise((resolve, reject) => {
|
|
@@ -27284,27 +27327,30 @@ function vectorSearchAllDistillations(queryEmbedding, projectId2, limit = 20) {
|
|
|
27284
27327
|
return scored.slice(0, limit);
|
|
27285
27328
|
}
|
|
27286
27329
|
function embedKnowledgeEntry(id, title, content3) {
|
|
27330
|
+
if (!isAvailable()) return;
|
|
27287
27331
|
const text4 = `${title}
|
|
27288
27332
|
${content3}`;
|
|
27289
27333
|
embed([text4], "document").then(([vec]) => {
|
|
27290
27334
|
db().query("UPDATE knowledge SET embedding = ? WHERE id = ?").run(toBlob(vec), id);
|
|
27291
27335
|
}).catch((err) => {
|
|
27292
|
-
|
|
27336
|
+
error("embedding failed for knowledge entry", id, ":", err);
|
|
27293
27337
|
});
|
|
27294
27338
|
}
|
|
27295
27339
|
function embedDistillation(id, observations) {
|
|
27340
|
+
if (!isAvailable()) return;
|
|
27296
27341
|
embed([observations], "document").then(([vec]) => {
|
|
27297
27342
|
db().query("UPDATE distillations SET embedding = ? WHERE id = ?").run(toBlob(vec), id);
|
|
27298
27343
|
}).catch((err) => {
|
|
27299
|
-
|
|
27344
|
+
error("embedding failed for distillation", id, ":", err);
|
|
27300
27345
|
});
|
|
27301
27346
|
}
|
|
27302
27347
|
function embedTemporalMessage(id, content3) {
|
|
27348
|
+
if (!isAvailable()) return;
|
|
27303
27349
|
if (content3.length < 50) return;
|
|
27304
27350
|
embed([content3], "document").then(([vec]) => {
|
|
27305
27351
|
db().query("UPDATE temporal_messages SET embedding = ? WHERE id = ?").run(toBlob(vec), id);
|
|
27306
27352
|
}).catch((err) => {
|
|
27307
|
-
|
|
27353
|
+
error("embedding failed for temporal message", id, ":", err);
|
|
27308
27354
|
});
|
|
27309
27355
|
}
|
|
27310
27356
|
function vectorSearchTemporal(queryEmbedding, projectId2, limit = 10, sessionId) {
|
|
@@ -27424,6 +27470,7 @@ ${r.content}` }));
|
|
|
27424
27470
|
}
|
|
27425
27471
|
} catch (err) {
|
|
27426
27472
|
error(`embedding backfill batch failed (${batch.length} items):`, err);
|
|
27473
|
+
if (err instanceof LocalProviderUnavailableError) break;
|
|
27427
27474
|
}
|
|
27428
27475
|
}
|
|
27429
27476
|
if (embedded > 0) {
|
|
@@ -27457,6 +27504,7 @@ async function backfillDistillationEmbeddings() {
|
|
|
27457
27504
|
}
|
|
27458
27505
|
} catch (err) {
|
|
27459
27506
|
error(`distillation embedding backfill batch failed (${batch.length} items):`, err);
|
|
27507
|
+
if (err instanceof LocalProviderUnavailableError) break;
|
|
27460
27508
|
}
|
|
27461
27509
|
if (embedded >= nextProgressAt) {
|
|
27462
27510
|
info(`embedding distillations: ${embedded}/${rows.length}\u2026`);
|
|
@@ -27546,14 +27594,14 @@ function store(input) {
|
|
|
27546
27594
|
embedTemporalMessage(input.info.id, content3);
|
|
27547
27595
|
}
|
|
27548
27596
|
}
|
|
27549
|
-
function undistilled(
|
|
27550
|
-
const pid = ensureProject(
|
|
27597
|
+
function undistilled(projectPath2, sessionID) {
|
|
27598
|
+
const pid = ensureProject(projectPath2);
|
|
27551
27599
|
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
27600
|
const params = sessionID ? [pid, sessionID] : [pid];
|
|
27553
27601
|
return db().query(query).all(...params);
|
|
27554
27602
|
}
|
|
27555
|
-
function bySession(
|
|
27556
|
-
const pid = ensureProject(
|
|
27603
|
+
function bySession(projectPath2, sessionID) {
|
|
27604
|
+
const pid = ensureProject(projectPath2);
|
|
27557
27605
|
return db().query(
|
|
27558
27606
|
"SELECT * FROM temporal_messages WHERE project_id = ? AND session_id = ? ORDER BY created_at ASC"
|
|
27559
27607
|
).all(pid, sessionID);
|
|
@@ -27629,26 +27677,26 @@ function temporalCnorm(timestamps, now = Date.now()) {
|
|
|
27629
27677
|
const maxVariance = (n - 1) / (n * n);
|
|
27630
27678
|
return maxVariance === 0 ? 0 : variance / maxVariance;
|
|
27631
27679
|
}
|
|
27632
|
-
function count(
|
|
27633
|
-
const pid = ensureProject(
|
|
27680
|
+
function count(projectPath2, sessionID) {
|
|
27681
|
+
const pid = ensureProject(projectPath2);
|
|
27634
27682
|
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
27683
|
const params = sessionID ? [pid, sessionID] : [pid];
|
|
27636
27684
|
return db().query(query).get(...params).count;
|
|
27637
27685
|
}
|
|
27638
|
-
function hasMessages(
|
|
27639
|
-
const pid = ensureProject(
|
|
27686
|
+
function hasMessages(projectPath2, sessionID) {
|
|
27687
|
+
const pid = ensureProject(projectPath2);
|
|
27640
27688
|
return !!db().query(
|
|
27641
27689
|
"SELECT 1 FROM temporal_messages WHERE project_id = ? AND session_id = ? LIMIT 1"
|
|
27642
27690
|
).get(pid, sessionID);
|
|
27643
27691
|
}
|
|
27644
|
-
function undistilledCount(
|
|
27645
|
-
const pid = ensureProject(
|
|
27692
|
+
function undistilledCount(projectPath2, sessionID) {
|
|
27693
|
+
const pid = ensureProject(projectPath2);
|
|
27646
27694
|
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
27695
|
const params = sessionID ? [pid, sessionID] : [pid];
|
|
27648
27696
|
return db().query(query).get(...params).count;
|
|
27649
27697
|
}
|
|
27650
|
-
function undistilledTokens(
|
|
27651
|
-
const pid = ensureProject(
|
|
27698
|
+
function undistilledTokens(projectPath2, sessionID) {
|
|
27699
|
+
const pid = ensureProject(projectPath2);
|
|
27652
27700
|
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
27701
|
const params = sessionID ? [pid, sessionID] : [pid];
|
|
27654
27702
|
return db().query(query).get(...params).total;
|
|
@@ -28169,14 +28217,16 @@ function listMarkdownFiles(dir) {
|
|
|
28169
28217
|
function contentHash(content3) {
|
|
28170
28218
|
return sha256(content3);
|
|
28171
28219
|
}
|
|
28172
|
-
function hasLatDir(
|
|
28173
|
-
|
|
28220
|
+
function hasLatDir(projectPath2) {
|
|
28221
|
+
if (isHostedMode()) return false;
|
|
28222
|
+
const latDir = join6(projectPath2, "lat.md");
|
|
28174
28223
|
return existsSync3(latDir) && statSync2(latDir).isDirectory();
|
|
28175
28224
|
}
|
|
28176
|
-
function refresh(
|
|
28177
|
-
|
|
28225
|
+
function refresh(projectPath2) {
|
|
28226
|
+
if (isHostedMode()) return 0;
|
|
28227
|
+
const latDir = join6(projectPath2, "lat.md");
|
|
28178
28228
|
if (!existsSync3(latDir) || !statSync2(latDir).isDirectory()) return 0;
|
|
28179
|
-
const pid = ensureProject(
|
|
28229
|
+
const pid = ensureProject(projectPath2);
|
|
28180
28230
|
const files = listMarkdownFiles(latDir);
|
|
28181
28231
|
let upserted = 0;
|
|
28182
28232
|
const seenFiles = /* @__PURE__ */ new Set();
|
|
@@ -28191,7 +28241,7 @@ function refresh(projectPath) {
|
|
|
28191
28241
|
} catch {
|
|
28192
28242
|
continue;
|
|
28193
28243
|
}
|
|
28194
|
-
const fileRel = relative(
|
|
28244
|
+
const fileRel = relative(projectPath2, filePath);
|
|
28195
28245
|
seenFiles.add(fileRel);
|
|
28196
28246
|
const hash2 = contentHash(content3);
|
|
28197
28247
|
const existing = db().query("SELECT content_hash FROM lat_sections WHERE project_id = ? AND file = ? LIMIT 1").get(pid, fileRel.replace(/\.md$/, ""));
|
|
@@ -28199,7 +28249,7 @@ function refresh(projectPath) {
|
|
|
28199
28249
|
continue;
|
|
28200
28250
|
}
|
|
28201
28251
|
db().query("DELETE FROM lat_sections WHERE project_id = ? AND file = ?").run(pid, fileRel.replace(/\.md$/, ""));
|
|
28202
|
-
const sections = parseSections(filePath, content3,
|
|
28252
|
+
const sections = parseSections(filePath, content3, projectPath2);
|
|
28203
28253
|
const now = Date.now();
|
|
28204
28254
|
for (const section of sections) {
|
|
28205
28255
|
upsertStmt.run(
|
|
@@ -28249,9 +28299,9 @@ function searchScored2(input) {
|
|
|
28249
28299
|
return [];
|
|
28250
28300
|
}
|
|
28251
28301
|
}
|
|
28252
|
-
function scoreForSession(
|
|
28253
|
-
if (!hasLatDir(
|
|
28254
|
-
const pid = ensureProject(
|
|
28302
|
+
function scoreForSession(projectPath2, sessionContext, maxTokens) {
|
|
28303
|
+
if (!hasLatDir(projectPath2)) return [];
|
|
28304
|
+
const pid = ensureProject(projectPath2);
|
|
28255
28305
|
const terms = extractTopTerms(sessionContext);
|
|
28256
28306
|
if (!terms.length) return [];
|
|
28257
28307
|
const q = terms.map((t2) => `${t2}*`).join(" OR ");
|
|
@@ -28283,8 +28333,8 @@ function scoreForSession(projectPath, sessionContext, maxTokens) {
|
|
|
28283
28333
|
}
|
|
28284
28334
|
return packed;
|
|
28285
28335
|
}
|
|
28286
|
-
function count2(
|
|
28287
|
-
const pid = ensureProject(
|
|
28336
|
+
function count2(projectPath2) {
|
|
28337
|
+
const pid = ensureProject(projectPath2);
|
|
28288
28338
|
const row = db().query("SELECT COUNT(*) as cnt FROM lat_sections WHERE project_id = ?").get(pid);
|
|
28289
28339
|
return row.cnt;
|
|
28290
28340
|
}
|
|
@@ -28411,8 +28461,8 @@ function findFuzzyDuplicate(input) {
|
|
|
28411
28461
|
}
|
|
28412
28462
|
return null;
|
|
28413
28463
|
}
|
|
28414
|
-
function forProject(
|
|
28415
|
-
const pid = ensureProject(
|
|
28464
|
+
function forProject(projectPath2, includeCross = true) {
|
|
28465
|
+
const pid = ensureProject(projectPath2);
|
|
28416
28466
|
if (includeCross) {
|
|
28417
28467
|
return db().query(
|
|
28418
28468
|
`SELECT ${KNOWLEDGE_COLS} FROM knowledge
|
|
@@ -28460,8 +28510,8 @@ function scoreEntriesFTS(sessionContext) {
|
|
|
28460
28510
|
return /* @__PURE__ */ new Map();
|
|
28461
28511
|
}
|
|
28462
28512
|
}
|
|
28463
|
-
async function forSession(
|
|
28464
|
-
const pid = ensureProject(
|
|
28513
|
+
async function forSession(projectPath2, sessionID, maxTokens, options) {
|
|
28514
|
+
const pid = ensureProject(projectPath2);
|
|
28465
28515
|
const categoryFilter = options?.categories;
|
|
28466
28516
|
const excludeFilter = options?.excludeCategories;
|
|
28467
28517
|
let categoryClause = "";
|
|
@@ -28565,9 +28615,9 @@ async function forSession(projectPath, sessionID, maxTokens, options) {
|
|
|
28565
28615
|
result.push(entry);
|
|
28566
28616
|
used += cost;
|
|
28567
28617
|
}
|
|
28568
|
-
if (hasLatDir(
|
|
28618
|
+
if (hasLatDir(projectPath2) && used < maxTokens) {
|
|
28569
28619
|
const latSections = scoreForSession(
|
|
28570
|
-
|
|
28620
|
+
projectPath2,
|
|
28571
28621
|
sessionContext,
|
|
28572
28622
|
maxTokens - used
|
|
28573
28623
|
);
|
|
@@ -28790,8 +28840,8 @@ function cleanDeadRefs() {
|
|
|
28790
28840
|
}
|
|
28791
28841
|
return cleaned;
|
|
28792
28842
|
}
|
|
28793
|
-
function check2(
|
|
28794
|
-
const entries = forProject(
|
|
28843
|
+
function check2(projectPath2) {
|
|
28844
|
+
const entries = forProject(projectPath2, false);
|
|
28795
28845
|
const issues = [];
|
|
28796
28846
|
for (const entry of entries) {
|
|
28797
28847
|
if (entry.content.length > 1200) {
|
|
@@ -28946,10 +28996,10 @@ function _dedup(entries, dryRun, embeddingThreshold = EMBEDDING_DEDUP_THRESHOLD)
|
|
|
28946
28996
|
const entryTitles = new Map(entries.map((e) => [e.id, e.title]));
|
|
28947
28997
|
return { clusters: result, totalRemoved, pairSimilarities, entryTitles };
|
|
28948
28998
|
}
|
|
28949
|
-
async function deduplicate(
|
|
28950
|
-
const pid = ensureProject(
|
|
28999
|
+
async function deduplicate(projectPath2, opts) {
|
|
29000
|
+
const pid = ensureProject(projectPath2);
|
|
28951
29001
|
const threshold = loadCalibratedThreshold(pid) ?? EMBEDDING_DEDUP_THRESHOLD;
|
|
28952
|
-
const entries = forProject(
|
|
29002
|
+
const entries = forProject(projectPath2, false);
|
|
28953
29003
|
return _dedup(entries, opts?.dryRun ?? true, threshold);
|
|
28954
29004
|
}
|
|
28955
29005
|
async function deduplicateGlobal(opts) {
|
|
@@ -29174,8 +29224,8 @@ function setCache(fp, entry) {
|
|
|
29174
29224
|
"INSERT INTO kv_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = ?"
|
|
29175
29225
|
).run(key, value, value);
|
|
29176
29226
|
}
|
|
29177
|
-
function clearLoreFileCache(
|
|
29178
|
-
db().query("DELETE FROM kv_meta WHERE key = ?").run(CACHE_PREFIX + join7(
|
|
29227
|
+
function clearLoreFileCache(projectPath2) {
|
|
29228
|
+
db().query("DELETE FROM kv_meta WHERE key = ?").run(CACHE_PREFIX + join7(projectPath2, LORE_FILE));
|
|
29179
29229
|
}
|
|
29180
29230
|
function splitFile(fileContent) {
|
|
29181
29231
|
const spans = [];
|
|
@@ -29251,8 +29301,8 @@ function hashSection(section) {
|
|
|
29251
29301
|
}
|
|
29252
29302
|
return (h3 >>> 0).toString(16).padStart(8, "0");
|
|
29253
29303
|
}
|
|
29254
|
-
function buildSection(
|
|
29255
|
-
const entries = forProject(
|
|
29304
|
+
function buildSection(projectPath2) {
|
|
29305
|
+
const entries = forProject(projectPath2, false);
|
|
29256
29306
|
if (!entries.length) {
|
|
29257
29307
|
return "\n";
|
|
29258
29308
|
}
|
|
@@ -29284,6 +29334,7 @@ function buildSection(projectPath) {
|
|
|
29284
29334
|
return out.join("\n");
|
|
29285
29335
|
}
|
|
29286
29336
|
function exportToFile(input) {
|
|
29337
|
+
if (isHostedMode()) return;
|
|
29287
29338
|
exportLoreFile(input.projectPath);
|
|
29288
29339
|
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
29340
|
const newSection = LORE_SECTION_START + pointerBody + LORE_SECTION_END + "\n";
|
|
@@ -29301,6 +29352,7 @@ function exportToFile(input) {
|
|
|
29301
29352
|
writeFileSync(input.filePath, result, "utf8");
|
|
29302
29353
|
}
|
|
29303
29354
|
function shouldImport(input) {
|
|
29355
|
+
if (isHostedMode()) return false;
|
|
29304
29356
|
if (!existsSync4(input.filePath)) return false;
|
|
29305
29357
|
const fileContent = readFileSync3(input.filePath, "utf8");
|
|
29306
29358
|
const { section } = splitFile(fileContent);
|
|
@@ -29310,7 +29362,7 @@ function shouldImport(input) {
|
|
|
29310
29362
|
const expected = buildSection(input.projectPath);
|
|
29311
29363
|
return hashSection(section) !== hashSection(expected);
|
|
29312
29364
|
}
|
|
29313
|
-
function _importEntries(entries,
|
|
29365
|
+
function _importEntries(entries, projectPath2) {
|
|
29314
29366
|
const seenIds = /* @__PURE__ */ new Set();
|
|
29315
29367
|
for (const entry of entries) {
|
|
29316
29368
|
if (entry.id !== null) {
|
|
@@ -29322,7 +29374,7 @@ function _importEntries(entries, projectPath) {
|
|
|
29322
29374
|
update(entry.id, { content: entry.content });
|
|
29323
29375
|
}
|
|
29324
29376
|
} else {
|
|
29325
|
-
const pid = ensureProject(
|
|
29377
|
+
const pid = ensureProject(projectPath2);
|
|
29326
29378
|
const fuzzyMatch = findFuzzyDuplicate({ title: entry.title, projectId: pid });
|
|
29327
29379
|
if (fuzzyMatch) {
|
|
29328
29380
|
if (fuzzyMatch.title !== entry.title || get(fuzzyMatch.id)?.content !== entry.content) {
|
|
@@ -29330,7 +29382,7 @@ function _importEntries(entries, projectPath) {
|
|
|
29330
29382
|
}
|
|
29331
29383
|
} else {
|
|
29332
29384
|
create({
|
|
29333
|
-
projectPath,
|
|
29385
|
+
projectPath: projectPath2,
|
|
29334
29386
|
category: entry.category,
|
|
29335
29387
|
title: entry.title,
|
|
29336
29388
|
content: entry.content,
|
|
@@ -29341,13 +29393,13 @@ function _importEntries(entries, projectPath) {
|
|
|
29341
29393
|
}
|
|
29342
29394
|
}
|
|
29343
29395
|
} else {
|
|
29344
|
-
const existing = forProject(
|
|
29396
|
+
const existing = forProject(projectPath2, false);
|
|
29345
29397
|
const titleMatch = existing.find(
|
|
29346
29398
|
(e) => e.title.toLowerCase() === entry.title.toLowerCase()
|
|
29347
29399
|
);
|
|
29348
29400
|
if (!titleMatch) {
|
|
29349
29401
|
create({
|
|
29350
|
-
projectPath,
|
|
29402
|
+
projectPath: projectPath2,
|
|
29351
29403
|
category: entry.category,
|
|
29352
29404
|
title: entry.title,
|
|
29353
29405
|
content: entry.content,
|
|
@@ -29359,6 +29411,7 @@ function _importEntries(entries, projectPath) {
|
|
|
29359
29411
|
}
|
|
29360
29412
|
}
|
|
29361
29413
|
function importFromFile(input) {
|
|
29414
|
+
if (isHostedMode()) return;
|
|
29362
29415
|
if (!existsSync4(input.filePath)) return;
|
|
29363
29416
|
const fileContent = readFileSync3(input.filePath, "utf8");
|
|
29364
29417
|
const { section } = splitFile(fileContent);
|
|
@@ -29367,14 +29420,16 @@ function importFromFile(input) {
|
|
|
29367
29420
|
if (!fileEntries.length) return;
|
|
29368
29421
|
_importEntries(fileEntries, input.projectPath);
|
|
29369
29422
|
}
|
|
29370
|
-
function loreFileExists(
|
|
29371
|
-
|
|
29423
|
+
function loreFileExists(projectPath2) {
|
|
29424
|
+
if (isHostedMode()) return false;
|
|
29425
|
+
return existsSync4(join7(projectPath2, LORE_FILE));
|
|
29372
29426
|
}
|
|
29373
|
-
function exportLoreFile(
|
|
29374
|
-
|
|
29427
|
+
function exportLoreFile(projectPath2) {
|
|
29428
|
+
if (isHostedMode()) return;
|
|
29429
|
+
const sectionBody = buildSection(projectPath2);
|
|
29375
29430
|
const content3 = LORE_FILE_HEADER + "\n" + sectionBody;
|
|
29376
29431
|
const contentHash2 = hashSection(content3);
|
|
29377
|
-
const fp = join7(
|
|
29432
|
+
const fp = join7(projectPath2, LORE_FILE);
|
|
29378
29433
|
const cached2 = getCache(fp);
|
|
29379
29434
|
if (cached2 && cached2.hash === contentHash2) {
|
|
29380
29435
|
return;
|
|
@@ -29383,8 +29438,9 @@ function exportLoreFile(projectPath) {
|
|
|
29383
29438
|
const { mtimeMs } = statSync3(fp);
|
|
29384
29439
|
setCache(fp, { mtimeMs, hash: contentHash2 });
|
|
29385
29440
|
}
|
|
29386
|
-
function shouldImportLoreFile(
|
|
29387
|
-
|
|
29441
|
+
function shouldImportLoreFile(projectPath2) {
|
|
29442
|
+
if (isHostedMode()) return false;
|
|
29443
|
+
const fp = join7(projectPath2, LORE_FILE);
|
|
29388
29444
|
if (!existsSync4(fp)) return false;
|
|
29389
29445
|
const { mtimeMs } = statSync3(fp);
|
|
29390
29446
|
const cached2 = getCache(fp);
|
|
@@ -29393,7 +29449,7 @@ function shouldImportLoreFile(projectPath) {
|
|
|
29393
29449
|
}
|
|
29394
29450
|
const fileContent = readFileSync3(fp, "utf8");
|
|
29395
29451
|
const fileHash = hashSection(fileContent);
|
|
29396
|
-
const expected = LORE_FILE_HEADER + "\n" + buildSection(
|
|
29452
|
+
const expected = LORE_FILE_HEADER + "\n" + buildSection(projectPath2);
|
|
29397
29453
|
const expectedHash = hashSection(expected);
|
|
29398
29454
|
if (fileHash === expectedHash) {
|
|
29399
29455
|
setCache(fp, { mtimeMs, hash: fileHash });
|
|
@@ -29401,13 +29457,14 @@ function shouldImportLoreFile(projectPath) {
|
|
|
29401
29457
|
}
|
|
29402
29458
|
return true;
|
|
29403
29459
|
}
|
|
29404
|
-
function importLoreFile(
|
|
29405
|
-
|
|
29460
|
+
function importLoreFile(projectPath2) {
|
|
29461
|
+
if (isHostedMode()) return;
|
|
29462
|
+
const fp = join7(projectPath2, LORE_FILE);
|
|
29406
29463
|
if (!existsSync4(fp)) return;
|
|
29407
29464
|
const fileContent = readFileSync3(fp, "utf8");
|
|
29408
29465
|
const fileEntries = parseEntriesFromSection(fileContent);
|
|
29409
29466
|
if (!fileEntries.length) return;
|
|
29410
|
-
_importEntries(fileEntries,
|
|
29467
|
+
_importEntries(fileEntries, projectPath2);
|
|
29411
29468
|
try {
|
|
29412
29469
|
const { mtimeMs } = statSync3(fp);
|
|
29413
29470
|
setCache(fp, { mtimeMs, hash: hashSection(fileContent) });
|
|
@@ -29426,8 +29483,8 @@ function listProjects() {
|
|
|
29426
29483
|
FROM projects p ORDER BY p.created_at DESC`
|
|
29427
29484
|
).all();
|
|
29428
29485
|
}
|
|
29429
|
-
function listSessions(
|
|
29430
|
-
const pid = ensureProject(
|
|
29486
|
+
function listSessions(projectPath2, limit = 50) {
|
|
29487
|
+
const pid = ensureProject(projectPath2);
|
|
29431
29488
|
return db().query(
|
|
29432
29489
|
`SELECT
|
|
29433
29490
|
session_id,
|
|
@@ -29446,8 +29503,8 @@ function listSessions(projectPath, limit = 50) {
|
|
|
29446
29503
|
LIMIT ?`
|
|
29447
29504
|
).all(pid, limit);
|
|
29448
29505
|
}
|
|
29449
|
-
function listDistillations(
|
|
29450
|
-
const pid = ensureProject(
|
|
29506
|
+
function listDistillations(projectPath2, opts) {
|
|
29507
|
+
const pid = ensureProject(projectPath2);
|
|
29451
29508
|
const limit = opts?.limit ?? 50;
|
|
29452
29509
|
if (opts?.sessionId) {
|
|
29453
29510
|
return db().query(
|
|
@@ -29496,8 +29553,8 @@ function globalStats() {
|
|
|
29496
29553
|
}
|
|
29497
29554
|
return { ...row, db_size_bytes };
|
|
29498
29555
|
}
|
|
29499
|
-
function countForProject(
|
|
29500
|
-
const pid = projectId(
|
|
29556
|
+
function countForProject(projectPath2) {
|
|
29557
|
+
const pid = projectId(projectPath2);
|
|
29501
29558
|
if (!pid)
|
|
29502
29559
|
return { knowledge: 0, messages: 0, distillations: 0, sessions: 0 };
|
|
29503
29560
|
const row = db().query(
|
|
@@ -29509,8 +29566,8 @@ function countForProject(projectPath) {
|
|
|
29509
29566
|
).get(pid, pid, pid, pid);
|
|
29510
29567
|
return row;
|
|
29511
29568
|
}
|
|
29512
|
-
function clearProject(
|
|
29513
|
-
const pid = ensureProject(
|
|
29569
|
+
function clearProject(projectPath2) {
|
|
29570
|
+
const pid = ensureProject(projectPath2);
|
|
29514
29571
|
const database = db();
|
|
29515
29572
|
const counts = {
|
|
29516
29573
|
knowledge: database.query(
|
|
@@ -29541,9 +29598,9 @@ function clearProject(projectPath) {
|
|
|
29541
29598
|
database.exec("ROLLBACK");
|
|
29542
29599
|
throw e;
|
|
29543
29600
|
}
|
|
29544
|
-
if (existsSync5(
|
|
29601
|
+
if (existsSync5(projectPath2)) {
|
|
29545
29602
|
try {
|
|
29546
|
-
exportLoreFile(
|
|
29603
|
+
exportLoreFile(projectPath2);
|
|
29547
29604
|
} catch {
|
|
29548
29605
|
}
|
|
29549
29606
|
}
|
|
@@ -29606,30 +29663,30 @@ function renameProject(projectId2, newName) {
|
|
|
29606
29663
|
const result = db().query("UPDATE projects SET name = ? WHERE id = ?").run(newName.trim(), projectId2);
|
|
29607
29664
|
return result.changes > 0;
|
|
29608
29665
|
}
|
|
29609
|
-
function clearKnowledge(
|
|
29610
|
-
const pid = ensureProject(
|
|
29666
|
+
function clearKnowledge(projectPath2) {
|
|
29667
|
+
const pid = ensureProject(projectPath2);
|
|
29611
29668
|
const count3 = db().query(
|
|
29612
29669
|
"SELECT COUNT(*) as c FROM knowledge WHERE project_id = ?"
|
|
29613
29670
|
).get(pid).c;
|
|
29614
29671
|
db().query("DELETE FROM knowledge WHERE project_id = ?").run(pid);
|
|
29615
|
-
if (existsSync5(
|
|
29672
|
+
if (existsSync5(projectPath2)) {
|
|
29616
29673
|
try {
|
|
29617
|
-
exportLoreFile(
|
|
29674
|
+
exportLoreFile(projectPath2);
|
|
29618
29675
|
} catch {
|
|
29619
29676
|
}
|
|
29620
29677
|
}
|
|
29621
29678
|
return count3;
|
|
29622
29679
|
}
|
|
29623
|
-
function clearTemporal(
|
|
29624
|
-
const pid = ensureProject(
|
|
29680
|
+
function clearTemporal(projectPath2) {
|
|
29681
|
+
const pid = ensureProject(projectPath2);
|
|
29625
29682
|
const count3 = db().query(
|
|
29626
29683
|
"SELECT COUNT(*) as c FROM temporal_messages WHERE project_id = ?"
|
|
29627
29684
|
).get(pid).c;
|
|
29628
29685
|
db().query("DELETE FROM temporal_messages WHERE project_id = ?").run(pid);
|
|
29629
29686
|
return count3;
|
|
29630
29687
|
}
|
|
29631
|
-
function clearDistillations(
|
|
29632
|
-
const pid = ensureProject(
|
|
29688
|
+
function clearDistillations(projectPath2) {
|
|
29689
|
+
const pid = ensureProject(projectPath2);
|
|
29633
29690
|
const count3 = db().query(
|
|
29634
29691
|
"SELECT COUNT(*) as c FROM distillations WHERE project_id = ?"
|
|
29635
29692
|
).get(pid).c;
|
|
@@ -29648,8 +29705,8 @@ function deleteDistillation(id) {
|
|
|
29648
29705
|
db().query("DELETE FROM distillations WHERE id = ?").run(id);
|
|
29649
29706
|
return true;
|
|
29650
29707
|
}
|
|
29651
|
-
function deleteSession(
|
|
29652
|
-
const pid = ensureProject(
|
|
29708
|
+
function deleteSession(projectPath2, sessionId) {
|
|
29709
|
+
const pid = ensureProject(projectPath2);
|
|
29653
29710
|
const database = db();
|
|
29654
29711
|
const msgCount = database.query(
|
|
29655
29712
|
"SELECT COUNT(*) as c FROM temporal_messages WHERE project_id = ? AND session_id = ?"
|
|
@@ -29893,9 +29950,22 @@ function setMaxContextTokens(tokens) {
|
|
|
29893
29950
|
function getMaxContextTokens() {
|
|
29894
29951
|
return maxContextTokensCeiling;
|
|
29895
29952
|
}
|
|
29896
|
-
function updateBustRate(cacheWrite, cacheRead, sessionID) {
|
|
29953
|
+
function updateBustRate(cacheWrite, cacheRead, sessionID, lastLayer) {
|
|
29897
29954
|
if (!sessionID) return;
|
|
29898
29955
|
const state = getSessionState(sessionID);
|
|
29956
|
+
if (lastLayer === 4) {
|
|
29957
|
+
state.consecutiveLayer4++;
|
|
29958
|
+
if (state.consecutiveLayer4 >= 5 && state.dynamicContextCap > 0 && maxContextTokensCeiling > 0) {
|
|
29959
|
+
state.dynamicContextCap = Math.min(
|
|
29960
|
+
maxContextTokensCeiling,
|
|
29961
|
+
Math.floor(state.dynamicContextCap * 1.1)
|
|
29962
|
+
);
|
|
29963
|
+
}
|
|
29964
|
+
return;
|
|
29965
|
+
}
|
|
29966
|
+
if (lastLayer !== void 0) {
|
|
29967
|
+
state.consecutiveLayer4 = 0;
|
|
29968
|
+
}
|
|
29899
29969
|
const total = cacheWrite + cacheRead;
|
|
29900
29970
|
if (total === 0) return;
|
|
29901
29971
|
const bustRatio = cacheWrite / total;
|
|
@@ -29950,6 +30020,7 @@ function makeSessionState() {
|
|
|
29950
30020
|
cameOutOfIdle: false,
|
|
29951
30021
|
postIdleCompact: false,
|
|
29952
30022
|
consecutiveHighLayer: 0,
|
|
30023
|
+
consecutiveLayer4: 0,
|
|
29953
30024
|
bustRateEMA: -1,
|
|
29954
30025
|
interBustIntervalEMA: -1,
|
|
29955
30026
|
lastBustAt: 0,
|
|
@@ -30052,6 +30123,11 @@ function getLastTransformedCount(sessionID) {
|
|
|
30052
30123
|
function getLastTransformEstimate(sessionID) {
|
|
30053
30124
|
return sessionStates.get(sessionID)?.lastTransformEstimate ?? 0;
|
|
30054
30125
|
}
|
|
30126
|
+
function getLastLayer(sessionID) {
|
|
30127
|
+
if (sessionID) return sessionStates.get(sessionID)?.lastLayer ?? 0;
|
|
30128
|
+
const first = sessionStates.values().next().value;
|
|
30129
|
+
return first?.lastLayer ?? 0;
|
|
30130
|
+
}
|
|
30055
30131
|
function setForceMinLayer(layer, sessionID) {
|
|
30056
30132
|
if (sessionID) {
|
|
30057
30133
|
getSessionState(sessionID).forceMinLayer = layer;
|
|
@@ -30072,7 +30148,10 @@ function inspectSessionState(sessionID) {
|
|
|
30072
30148
|
cameOutOfIdle: state.cameOutOfIdle,
|
|
30073
30149
|
postIdleCompact: state.postIdleCompact,
|
|
30074
30150
|
lastTurnAt: state.lastTurnAt,
|
|
30075
|
-
distillationSnapshot: state.distillationSnapshot
|
|
30151
|
+
distillationSnapshot: state.distillationSnapshot,
|
|
30152
|
+
bustRateEMA: state.bustRateEMA,
|
|
30153
|
+
dynamicContextCap: state.dynamicContextCap,
|
|
30154
|
+
consecutiveLayer4: state.consecutiveLayer4
|
|
30076
30155
|
};
|
|
30077
30156
|
}
|
|
30078
30157
|
function setLastTurnAtForTest(sessionID, ms) {
|
|
@@ -30091,13 +30170,13 @@ function saveGradientState(sessionID) {
|
|
|
30091
30170
|
lastBustAt: state.lastBustAt
|
|
30092
30171
|
});
|
|
30093
30172
|
}
|
|
30094
|
-
function loadDistillations(
|
|
30095
|
-
const pid = ensureProject(
|
|
30173
|
+
function loadDistillations(projectPath2, sessionID) {
|
|
30174
|
+
const pid = ensureProject(projectPath2);
|
|
30096
30175
|
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
30176
|
const params = sessionID ? [pid, sessionID] : [pid];
|
|
30098
30177
|
return db().query(query).all(...params);
|
|
30099
30178
|
}
|
|
30100
|
-
function loadDistillationsCached(
|
|
30179
|
+
function loadDistillationsCached(projectPath2, sessionID, messages, sessState) {
|
|
30101
30180
|
let lastUserMsgId = null;
|
|
30102
30181
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
30103
30182
|
if (messages[i].info.role === "user") {
|
|
@@ -30109,7 +30188,7 @@ function loadDistillationsCached(projectPath, sessionID, messages, sessState) {
|
|
|
30109
30188
|
if (snapshot && snapshot.lastUserMsgId === lastUserMsgId) {
|
|
30110
30189
|
return snapshot.rows;
|
|
30111
30190
|
}
|
|
30112
|
-
const rows = loadDistillations(
|
|
30191
|
+
const rows = loadDistillations(projectPath2, sessionID);
|
|
30113
30192
|
sessState.distillationSnapshot = { rows, lastUserMsgId };
|
|
30114
30193
|
info(
|
|
30115
30194
|
`distillation refresh: ${rows.length} rows (user msg ${lastUserMsgId?.substring(0, 16) ?? "none"})`
|
|
@@ -31093,18 +31172,18 @@ function parseDistillationResult(text4) {
|
|
|
31093
31172
|
if (!observations) return null;
|
|
31094
31173
|
return { observations };
|
|
31095
31174
|
}
|
|
31096
|
-
function latestObservations(
|
|
31097
|
-
const pid = ensureProject(
|
|
31175
|
+
function latestObservations(projectPath2, sessionID) {
|
|
31176
|
+
const pid = ensureProject(projectPath2);
|
|
31098
31177
|
const row = db().query(
|
|
31099
31178
|
"SELECT observations FROM distillations WHERE project_id = ? AND session_id = ? ORDER BY created_at DESC LIMIT 1"
|
|
31100
31179
|
).get(pid, sessionID);
|
|
31101
31180
|
return row?.observations || void 0;
|
|
31102
31181
|
}
|
|
31103
|
-
function latestMetaObservations(
|
|
31104
|
-
return latestMeta(
|
|
31182
|
+
function latestMetaObservations(projectPath2, sessionID) {
|
|
31183
|
+
return latestMeta(projectPath2, sessionID)?.observations;
|
|
31105
31184
|
}
|
|
31106
|
-
function latestMeta(
|
|
31107
|
-
const pid = ensureProject(
|
|
31185
|
+
function latestMeta(projectPath2, sessionID) {
|
|
31186
|
+
const pid = ensureProject(projectPath2);
|
|
31108
31187
|
const row = db().query(
|
|
31109
31188
|
`SELECT observations, generation FROM distillations
|
|
31110
31189
|
WHERE project_id = ? AND session_id = ? AND generation > 0
|
|
@@ -31122,8 +31201,8 @@ function parseSourceIds(raw) {
|
|
|
31122
31201
|
return [];
|
|
31123
31202
|
}
|
|
31124
31203
|
}
|
|
31125
|
-
function loadForSession(
|
|
31126
|
-
const pid = ensureProject(
|
|
31204
|
+
function loadForSession(projectPath2, sessionID, includeArchived = false) {
|
|
31205
|
+
const pid = ensureProject(projectPath2);
|
|
31127
31206
|
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
31207
|
const rows = db().query(sql).all(pid, sessionID);
|
|
31129
31208
|
return rows.map((r) => ({
|
|
@@ -31158,14 +31237,14 @@ function storeDistillation(input) {
|
|
|
31158
31237
|
);
|
|
31159
31238
|
return id;
|
|
31160
31239
|
}
|
|
31161
|
-
function gen0Count(
|
|
31162
|
-
const pid = ensureProject(
|
|
31240
|
+
function gen0Count(projectPath2, sessionID) {
|
|
31241
|
+
const pid = ensureProject(projectPath2);
|
|
31163
31242
|
return db().query(
|
|
31164
31243
|
"SELECT COUNT(*) as count FROM distillations WHERE project_id = ? AND session_id = ? AND generation = 0 AND archived = 0"
|
|
31165
31244
|
).get(pid, sessionID).count;
|
|
31166
31245
|
}
|
|
31167
|
-
function loadGen0(
|
|
31168
|
-
const pid = ensureProject(
|
|
31246
|
+
function loadGen0(projectPath2, sessionID) {
|
|
31247
|
+
const pid = ensureProject(projectPath2);
|
|
31169
31248
|
const rows = db().query(
|
|
31170
31249
|
"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
31250
|
).all(pid, sessionID);
|
|
@@ -31181,8 +31260,8 @@ function archiveDistillations(ids) {
|
|
|
31181
31260
|
`UPDATE distillations SET archived = 1 WHERE id IN (${placeholders})`
|
|
31182
31261
|
).run(...ids);
|
|
31183
31262
|
}
|
|
31184
|
-
function resetOrphans(
|
|
31185
|
-
const pid = ensureProject(
|
|
31263
|
+
function resetOrphans(projectPath2, sessionID) {
|
|
31264
|
+
const pid = ensureProject(projectPath2);
|
|
31186
31265
|
const rows = db().query(
|
|
31187
31266
|
"SELECT source_ids FROM distillations WHERE project_id = ? AND session_id = ?"
|
|
31188
31267
|
).all(pid, sessionID);
|
|
@@ -31814,11 +31893,11 @@ function clearProviders() {
|
|
|
31814
31893
|
}
|
|
31815
31894
|
|
|
31816
31895
|
// src/import/detect.ts
|
|
31817
|
-
function detectAll(
|
|
31896
|
+
function detectAll(projectPath2) {
|
|
31818
31897
|
const results = [];
|
|
31819
31898
|
for (const provider of getProviders()) {
|
|
31820
31899
|
try {
|
|
31821
|
-
const sessions = provider.detect(
|
|
31900
|
+
const sessions = provider.detect(projectPath2);
|
|
31822
31901
|
if (sessions.length > 0) {
|
|
31823
31902
|
results.push({
|
|
31824
31903
|
agentName: provider.name,
|
|
@@ -31907,8 +31986,8 @@ async function extractKnowledge(input) {
|
|
|
31907
31986
|
}
|
|
31908
31987
|
|
|
31909
31988
|
// src/import/history.ts
|
|
31910
|
-
function isImported(
|
|
31911
|
-
const projectId2 = ensureProject(
|
|
31989
|
+
function isImported(projectPath2, agentName, sourceId, sourceHash) {
|
|
31990
|
+
const projectId2 = ensureProject(projectPath2);
|
|
31912
31991
|
const row = db().query(
|
|
31913
31992
|
`SELECT * FROM import_history
|
|
31914
31993
|
WHERE project_id = ? AND agent_name = ? AND source_id = ?`
|
|
@@ -31917,8 +31996,8 @@ function isImported(projectPath, agentName, sourceId, sourceHash) {
|
|
|
31917
31996
|
if (row.source_hash !== sourceHash) return null;
|
|
31918
31997
|
return row;
|
|
31919
31998
|
}
|
|
31920
|
-
function recordImport(
|
|
31921
|
-
const projectId2 = ensureProject(
|
|
31999
|
+
function recordImport(projectPath2, agentName, sourceId, sourceHash, stats) {
|
|
32000
|
+
const projectId2 = ensureProject(projectPath2);
|
|
31922
32001
|
db().query(
|
|
31923
32002
|
`INSERT OR REPLACE INTO import_history
|
|
31924
32003
|
(id, project_id, agent_name, source_id, source_hash, entries_created, entries_updated, imported_at)
|
|
@@ -31934,8 +32013,8 @@ function recordImport(projectPath, agentName, sourceId, sourceHash, stats) {
|
|
|
31934
32013
|
Date.now()
|
|
31935
32014
|
);
|
|
31936
32015
|
}
|
|
31937
|
-
function listImports(
|
|
31938
|
-
const projectId2 = ensureProject(
|
|
32016
|
+
function listImports(projectPath2) {
|
|
32017
|
+
const projectId2 = ensureProject(projectPath2);
|
|
31939
32018
|
return db().query(
|
|
31940
32019
|
`SELECT * FROM import_history
|
|
31941
32020
|
WHERE project_id = ? AND source_id != '__declined__'
|
|
@@ -31953,8 +32032,8 @@ import { homedir as homedir2 } from "os";
|
|
|
31953
32032
|
var CLAUDE_DIR = join8(homedir2(), ".claude", "projects");
|
|
31954
32033
|
var MAX_TOOL_OUTPUT_CHARS = 500;
|
|
31955
32034
|
var DEFAULT_MAX_TOKENS = 12288;
|
|
31956
|
-
function manglePath(
|
|
31957
|
-
return
|
|
32035
|
+
function manglePath(projectPath2) {
|
|
32036
|
+
return projectPath2.replace(/\//g, "-");
|
|
31958
32037
|
}
|
|
31959
32038
|
function estimateTokens4(text4) {
|
|
31960
32039
|
return Math.ceil(text4.length / 3);
|
|
@@ -32068,8 +32147,8 @@ function getSessionMetadata(filePath) {
|
|
|
32068
32147
|
var claudeCodeProvider = {
|
|
32069
32148
|
name: "claude-code",
|
|
32070
32149
|
displayName: "Claude Code",
|
|
32071
|
-
detect(
|
|
32072
|
-
const mangled = manglePath(
|
|
32150
|
+
detect(projectPath2) {
|
|
32151
|
+
const mangled = manglePath(projectPath2);
|
|
32073
32152
|
const dir = join8(CLAUDE_DIR, mangled);
|
|
32074
32153
|
let entries;
|
|
32075
32154
|
try {
|
|
@@ -32267,7 +32346,7 @@ function getSessionMeta(filePath) {
|
|
|
32267
32346
|
var codexProvider = {
|
|
32268
32347
|
name: "codex",
|
|
32269
32348
|
displayName: "Codex",
|
|
32270
|
-
detect(
|
|
32349
|
+
detect(projectPath2) {
|
|
32271
32350
|
const sessions = [];
|
|
32272
32351
|
const allFiles = [
|
|
32273
32352
|
...findJsonlFiles(SESSIONS_DIR),
|
|
@@ -32276,7 +32355,7 @@ var codexProvider = {
|
|
|
32276
32355
|
for (const filePath of allFiles) {
|
|
32277
32356
|
const meta3 = getSessionMeta(filePath);
|
|
32278
32357
|
if (!meta3) continue;
|
|
32279
|
-
if (meta3.cwd !==
|
|
32358
|
+
if (meta3.cwd !== projectPath2) continue;
|
|
32280
32359
|
if (meta3.messageCount < 3) continue;
|
|
32281
32360
|
const ts = new Date(meta3.timestamp).getTime();
|
|
32282
32361
|
const estimatedTokens = Math.ceil(meta3.fileSize / 5);
|
|
@@ -32408,14 +32487,14 @@ function partsToConversationText(parts) {
|
|
|
32408
32487
|
var opencodeProvider = {
|
|
32409
32488
|
name: "opencode",
|
|
32410
32489
|
displayName: "OpenCode",
|
|
32411
|
-
detect(
|
|
32490
|
+
detect(projectPath2) {
|
|
32412
32491
|
const database = openDB();
|
|
32413
32492
|
if (!database) return [];
|
|
32414
32493
|
try {
|
|
32415
32494
|
if (!tableExists(database, "project") || !tableExists(database, "session") || !tableExists(database, "message")) {
|
|
32416
32495
|
return [];
|
|
32417
32496
|
}
|
|
32418
|
-
const project = database.query("SELECT id FROM project WHERE worktree = ?").get(
|
|
32497
|
+
const project = database.query("SELECT id FROM project WHERE worktree = ?").get(projectPath2);
|
|
32419
32498
|
if (!project) return [];
|
|
32420
32499
|
const sessions = database.query(
|
|
32421
32500
|
`SELECT s.id, s.title, s.time_created, s.time_updated,
|
|
@@ -32580,7 +32659,7 @@ function findGlobalStorageDirs() {
|
|
|
32580
32659
|
}
|
|
32581
32660
|
return dirs;
|
|
32582
32661
|
}
|
|
32583
|
-
function loadTaskHistory(storageDir,
|
|
32662
|
+
function loadTaskHistory(storageDir, projectPath2) {
|
|
32584
32663
|
const paths = [
|
|
32585
32664
|
join11(storageDir, "state", "taskHistory.json"),
|
|
32586
32665
|
join11(storageDir, "taskHistory.json")
|
|
@@ -32592,7 +32671,7 @@ function loadTaskHistory(storageDir, projectPath) {
|
|
|
32592
32671
|
const items = JSON.parse(raw);
|
|
32593
32672
|
if (!Array.isArray(items)) continue;
|
|
32594
32673
|
return items.filter(
|
|
32595
|
-
(item) => item.cwdOnTaskInitialization ===
|
|
32674
|
+
(item) => item.cwdOnTaskInitialization === projectPath2
|
|
32596
32675
|
);
|
|
32597
32676
|
} catch {
|
|
32598
32677
|
continue;
|
|
@@ -32645,11 +32724,11 @@ function messageToText(msg) {
|
|
|
32645
32724
|
var clineProvider = {
|
|
32646
32725
|
name: "cline",
|
|
32647
32726
|
displayName: "Cline",
|
|
32648
|
-
detect(
|
|
32727
|
+
detect(projectPath2) {
|
|
32649
32728
|
const sessions = [];
|
|
32650
32729
|
const storageDirs = findGlobalStorageDirs();
|
|
32651
32730
|
for (const storageDir of storageDirs) {
|
|
32652
|
-
const tasks = loadTaskHistory(storageDir,
|
|
32731
|
+
const tasks = loadTaskHistory(storageDir, projectPath2);
|
|
32653
32732
|
for (const task of tasks) {
|
|
32654
32733
|
const taskDir = join11(storageDir, "tasks", task.id);
|
|
32655
32734
|
if (!existsSync8(taskDir)) continue;
|
|
@@ -32797,11 +32876,11 @@ function historyItemToText(item) {
|
|
|
32797
32876
|
var continueProvider = {
|
|
32798
32877
|
name: "continue",
|
|
32799
32878
|
displayName: "Continue",
|
|
32800
|
-
detect(
|
|
32879
|
+
detect(projectPath2) {
|
|
32801
32880
|
const sessions = [];
|
|
32802
32881
|
const index2 = loadSessionIndex();
|
|
32803
32882
|
for (const meta3 of index2) {
|
|
32804
|
-
if (meta3.workspaceDirectory !==
|
|
32883
|
+
if (meta3.workspaceDirectory !== projectPath2) continue;
|
|
32805
32884
|
const session = loadSession(meta3.sessionId);
|
|
32806
32885
|
if (!session || !session.history || session.history.length < 3) continue;
|
|
32807
32886
|
const ts = new Date(meta3.dateCreated).getTime();
|
|
@@ -32833,7 +32912,7 @@ var continueProvider = {
|
|
|
32833
32912
|
if (existingIds.has(sessionId)) continue;
|
|
32834
32913
|
const session = loadSession(sessionId);
|
|
32835
32914
|
if (!session) continue;
|
|
32836
|
-
if (session.workspaceDirectory !==
|
|
32915
|
+
if (session.workspaceDirectory !== projectPath2) continue;
|
|
32837
32916
|
if (!session.history || session.history.length < 3) continue;
|
|
32838
32917
|
const dateStr = session.title ? truncate5(session.title, 60) : sessionId.slice(0, 8);
|
|
32839
32918
|
sessions.push({
|
|
@@ -32982,8 +33061,8 @@ function getSessionMeta2(filePath) {
|
|
|
32982
33061
|
var piProvider = {
|
|
32983
33062
|
name: "pi",
|
|
32984
33063
|
displayName: "Pi",
|
|
32985
|
-
detect(
|
|
32986
|
-
const encoded = encodeCwd(
|
|
33064
|
+
detect(projectPath2) {
|
|
33065
|
+
const encoded = encodeCwd(projectPath2);
|
|
32987
33066
|
const dir = join13(PI_DIR, encoded);
|
|
32988
33067
|
let entries;
|
|
32989
33068
|
try {
|
|
@@ -33121,8 +33200,8 @@ function parseAiderHistory(content3) {
|
|
|
33121
33200
|
var aiderProvider = {
|
|
33122
33201
|
name: "aider",
|
|
33123
33202
|
displayName: "Aider",
|
|
33124
|
-
detect(
|
|
33125
|
-
const filePath = join14(
|
|
33203
|
+
detect(projectPath2) {
|
|
33204
|
+
const filePath = join14(projectPath2, HISTORY_FILE);
|
|
33126
33205
|
if (!existsSync11(filePath)) return [];
|
|
33127
33206
|
let stat;
|
|
33128
33207
|
try {
|
|
@@ -33151,7 +33230,7 @@ var aiderProvider = {
|
|
|
33151
33230
|
}
|
|
33152
33231
|
];
|
|
33153
33232
|
},
|
|
33154
|
-
readChunks(
|
|
33233
|
+
readChunks(projectPath2, sessionIds, maxTokens = DEFAULT_MAX_TOKENS7) {
|
|
33155
33234
|
const chunks = [];
|
|
33156
33235
|
for (const filePath of sessionIds) {
|
|
33157
33236
|
let content3;
|
|
@@ -33446,7 +33525,7 @@ async function searchRecall(input) {
|
|
|
33446
33525
|
const {
|
|
33447
33526
|
query,
|
|
33448
33527
|
scope = "all",
|
|
33449
|
-
projectPath,
|
|
33528
|
+
projectPath: projectPath2,
|
|
33450
33529
|
sessionID,
|
|
33451
33530
|
knowledgeEnabled = true,
|
|
33452
33531
|
llm,
|
|
@@ -33473,7 +33552,7 @@ async function searchRecall(input) {
|
|
|
33473
33552
|
if (knowledgeEnabled && scope !== "session") {
|
|
33474
33553
|
try {
|
|
33475
33554
|
knowledgeResults.push(
|
|
33476
|
-
...searchScored3({ query: q, projectPath, limit })
|
|
33555
|
+
...searchScored3({ query: q, projectPath: projectPath2, limit })
|
|
33477
33556
|
);
|
|
33478
33557
|
} catch (err) {
|
|
33479
33558
|
error("recall: knowledge search failed:", err);
|
|
@@ -33484,7 +33563,7 @@ async function searchRecall(input) {
|
|
|
33484
33563
|
try {
|
|
33485
33564
|
distillationResults.push(
|
|
33486
33565
|
...searchDistillationsScored({
|
|
33487
|
-
projectPath,
|
|
33566
|
+
projectPath: projectPath2,
|
|
33488
33567
|
query: q,
|
|
33489
33568
|
sessionID: scope === "session" ? sessionID : void 0,
|
|
33490
33569
|
limit
|
|
@@ -33499,7 +33578,7 @@ async function searchRecall(input) {
|
|
|
33499
33578
|
try {
|
|
33500
33579
|
temporalResults.push(
|
|
33501
33580
|
...searchScored({
|
|
33502
|
-
projectPath,
|
|
33581
|
+
projectPath: projectPath2,
|
|
33503
33582
|
query: q,
|
|
33504
33583
|
sessionID: scope === "session" ? sessionID : void 0,
|
|
33505
33584
|
limit
|
|
@@ -33593,7 +33672,7 @@ async function searchRecall(input) {
|
|
|
33593
33672
|
}
|
|
33594
33673
|
}
|
|
33595
33674
|
if (scope !== "knowledge") {
|
|
33596
|
-
const pid = ensureProject(
|
|
33675
|
+
const pid = ensureProject(projectPath2);
|
|
33597
33676
|
const temporalVectorHits = vectorSearchTemporal(
|
|
33598
33677
|
queryVec,
|
|
33599
33678
|
pid,
|
|
@@ -33621,11 +33700,11 @@ async function searchRecall(input) {
|
|
|
33621
33700
|
info("recall: vector search failed:", err);
|
|
33622
33701
|
}
|
|
33623
33702
|
}
|
|
33624
|
-
if (scope !== "session" && hasLatDir(
|
|
33703
|
+
if (scope !== "session" && hasLatDir(projectPath2)) {
|
|
33625
33704
|
try {
|
|
33626
33705
|
const latResults = searchScored2({
|
|
33627
33706
|
query,
|
|
33628
|
-
projectPath,
|
|
33707
|
+
projectPath: projectPath2,
|
|
33629
33708
|
limit
|
|
33630
33709
|
});
|
|
33631
33710
|
if (latResults.length) {
|
|
@@ -33645,7 +33724,7 @@ async function searchRecall(input) {
|
|
|
33645
33724
|
try {
|
|
33646
33725
|
const crossProjectResults = searchScoredOtherProjects({
|
|
33647
33726
|
query,
|
|
33648
|
-
excludeProjectPath:
|
|
33727
|
+
excludeProjectPath: projectPath2,
|
|
33649
33728
|
limit
|
|
33650
33729
|
});
|
|
33651
33730
|
if (crossProjectResults.length) {
|
|
@@ -33851,6 +33930,7 @@ export {
|
|
|
33851
33930
|
distillationUser,
|
|
33852
33931
|
embedding_exports as embedding,
|
|
33853
33932
|
embedding_vendor_exports as embeddingVendor,
|
|
33933
|
+
enableHostedMode,
|
|
33854
33934
|
ensureProject,
|
|
33855
33935
|
exactTermMatchRank,
|
|
33856
33936
|
expandQuery,
|
|
@@ -33866,6 +33946,7 @@ export {
|
|
|
33866
33946
|
getInstanceId,
|
|
33867
33947
|
getKV,
|
|
33868
33948
|
getLastImportAt,
|
|
33949
|
+
getLastLayer,
|
|
33869
33950
|
getLastTransformEstimate,
|
|
33870
33951
|
getLastTransformedCount,
|
|
33871
33952
|
getLastTurnAt,
|
|
@@ -33880,6 +33961,7 @@ export {
|
|
|
33880
33961
|
inspectSessionState,
|
|
33881
33962
|
instruction_detect_exports as instructionDetect,
|
|
33882
33963
|
isFirstRun,
|
|
33964
|
+
isHostedMode,
|
|
33883
33965
|
isReasoningPart,
|
|
33884
33966
|
isTextPart,
|
|
33885
33967
|
isToolPart,
|
|
@@ -33905,10 +33987,12 @@ export {
|
|
|
33905
33987
|
pattern_extract_exports as patternExtract,
|
|
33906
33988
|
projectId,
|
|
33907
33989
|
projectName,
|
|
33990
|
+
projectPath,
|
|
33908
33991
|
recallById,
|
|
33909
33992
|
reciprocalRankFusion,
|
|
33910
33993
|
recursiveUser,
|
|
33911
33994
|
renderMarkdown,
|
|
33995
|
+
resolveProjectByRemoteOrPath,
|
|
33912
33996
|
root2 as root,
|
|
33913
33997
|
runRecall,
|
|
33914
33998
|
sanitizeSurrogates,
|