@loreai/core 0.0.1 → 0.10.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/LICENSE +21 -0
- package/README.md +26 -5
- package/dist/bun/agents-file.d.ts +59 -0
- package/dist/bun/agents-file.d.ts.map +1 -0
- package/dist/bun/config.d.ts +58 -0
- package/dist/bun/config.d.ts.map +1 -0
- package/dist/bun/curator.d.ts +35 -0
- package/dist/bun/curator.d.ts.map +1 -0
- package/dist/bun/db/driver.bun.d.ts +5 -0
- package/dist/bun/db/driver.bun.d.ts.map +1 -0
- package/dist/bun/db/driver.node.d.ts +15 -0
- package/dist/bun/db/driver.node.d.ts.map +1 -0
- package/dist/bun/db.d.ts +22 -0
- package/dist/bun/db.d.ts.map +1 -0
- package/dist/bun/distillation.d.ts +32 -0
- package/dist/bun/distillation.d.ts.map +1 -0
- package/dist/bun/embedding.d.ts +90 -0
- package/dist/bun/embedding.d.ts.map +1 -0
- package/dist/bun/gradient.d.ts +73 -0
- package/dist/bun/gradient.d.ts.map +1 -0
- package/dist/bun/index.d.ts +19 -0
- package/dist/bun/index.d.ts.map +1 -0
- package/dist/bun/index.js +28236 -0
- package/dist/bun/index.js.map +7 -0
- package/dist/bun/lat-reader.d.ts +69 -0
- package/dist/bun/lat-reader.d.ts.map +1 -0
- package/dist/bun/log.d.ts +17 -0
- package/dist/bun/log.d.ts.map +1 -0
- package/dist/bun/ltm.d.ts +138 -0
- package/dist/bun/ltm.d.ts.map +1 -0
- package/dist/bun/markdown.d.ts +37 -0
- package/dist/bun/markdown.d.ts.map +1 -0
- package/dist/bun/prompt.d.ts +47 -0
- package/dist/bun/prompt.d.ts.map +1 -0
- package/dist/bun/recall.d.ts +41 -0
- package/dist/bun/recall.d.ts.map +1 -0
- package/dist/bun/search.d.ts +113 -0
- package/dist/bun/search.d.ts.map +1 -0
- package/dist/bun/temporal.d.ts +66 -0
- package/dist/bun/temporal.d.ts.map +1 -0
- package/dist/bun/types.d.ts +180 -0
- package/dist/bun/types.d.ts.map +1 -0
- package/dist/bun/worker.d.ts +6 -0
- package/dist/bun/worker.d.ts.map +1 -0
- package/dist/node/agents-file.d.ts +59 -0
- package/dist/node/agents-file.d.ts.map +1 -0
- package/dist/node/config.d.ts +58 -0
- package/dist/node/config.d.ts.map +1 -0
- package/dist/node/curator.d.ts +35 -0
- package/dist/node/curator.d.ts.map +1 -0
- package/dist/node/db/driver.bun.d.ts +5 -0
- package/dist/node/db/driver.bun.d.ts.map +1 -0
- package/dist/node/db/driver.node.d.ts +15 -0
- package/dist/node/db/driver.node.d.ts.map +1 -0
- package/dist/node/db.d.ts +22 -0
- package/dist/node/db.d.ts.map +1 -0
- package/dist/node/distillation.d.ts +32 -0
- package/dist/node/distillation.d.ts.map +1 -0
- package/dist/node/embedding.d.ts +90 -0
- package/dist/node/embedding.d.ts.map +1 -0
- package/dist/node/gradient.d.ts +73 -0
- package/dist/node/gradient.d.ts.map +1 -0
- package/dist/node/index.d.ts +19 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +28253 -0
- package/dist/node/index.js.map +7 -0
- package/dist/node/lat-reader.d.ts +69 -0
- package/dist/node/lat-reader.d.ts.map +1 -0
- package/dist/node/log.d.ts +17 -0
- package/dist/node/log.d.ts.map +1 -0
- package/dist/node/ltm.d.ts +138 -0
- package/dist/node/ltm.d.ts.map +1 -0
- package/dist/node/markdown.d.ts +37 -0
- package/dist/node/markdown.d.ts.map +1 -0
- package/dist/node/prompt.d.ts +47 -0
- package/dist/node/prompt.d.ts.map +1 -0
- package/dist/node/recall.d.ts +41 -0
- package/dist/node/recall.d.ts.map +1 -0
- package/dist/node/search.d.ts +113 -0
- package/dist/node/search.d.ts.map +1 -0
- package/dist/node/temporal.d.ts +66 -0
- package/dist/node/temporal.d.ts.map +1 -0
- package/dist/node/types.d.ts +180 -0
- package/dist/node/types.d.ts.map +1 -0
- package/dist/node/worker.d.ts +6 -0
- package/dist/node/worker.d.ts.map +1 -0
- package/dist/types/agents-file.d.ts +59 -0
- package/dist/types/agents-file.d.ts.map +1 -0
- package/dist/types/config.d.ts +58 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/curator.d.ts +35 -0
- package/dist/types/curator.d.ts.map +1 -0
- package/dist/types/db/driver.bun.d.ts +5 -0
- package/dist/types/db/driver.bun.d.ts.map +1 -0
- package/dist/types/db/driver.node.d.ts +15 -0
- package/dist/types/db/driver.node.d.ts.map +1 -0
- package/dist/types/db.d.ts +22 -0
- package/dist/types/db.d.ts.map +1 -0
- package/dist/types/distillation.d.ts +32 -0
- package/dist/types/distillation.d.ts.map +1 -0
- package/dist/types/embedding.d.ts +90 -0
- package/dist/types/embedding.d.ts.map +1 -0
- package/dist/types/gradient.d.ts +73 -0
- package/dist/types/gradient.d.ts.map +1 -0
- package/dist/types/index.d.ts +19 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/lat-reader.d.ts +69 -0
- package/dist/types/lat-reader.d.ts.map +1 -0
- package/dist/types/log.d.ts +17 -0
- package/dist/types/log.d.ts.map +1 -0
- package/dist/types/ltm.d.ts +138 -0
- package/dist/types/ltm.d.ts.map +1 -0
- package/dist/types/markdown.d.ts +37 -0
- package/dist/types/markdown.d.ts.map +1 -0
- package/dist/types/prompt.d.ts +47 -0
- package/dist/types/prompt.d.ts.map +1 -0
- package/dist/types/recall.d.ts +41 -0
- package/dist/types/recall.d.ts.map +1 -0
- package/dist/types/search.d.ts +113 -0
- package/dist/types/search.d.ts.map +1 -0
- package/dist/types/temporal.d.ts +66 -0
- package/dist/types/temporal.d.ts.map +1 -0
- package/dist/types/types.d.ts +180 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/worker.d.ts +6 -0
- package/dist/types/worker.d.ts.map +1 -0
- package/package.json +48 -5
- package/src/agents-file.ts +406 -0
- package/src/config.ts +132 -0
- package/src/curator.ts +220 -0
- package/src/db/driver.bun.ts +18 -0
- package/src/db/driver.node.ts +54 -0
- package/src/db.ts +433 -0
- package/src/distillation.ts +433 -0
- package/src/embedding.ts +528 -0
- package/src/gradient.ts +1387 -0
- package/src/index.ts +109 -0
- package/src/lat-reader.ts +374 -0
- package/src/log.ts +27 -0
- package/src/ltm.ts +861 -0
- package/src/markdown.ts +129 -0
- package/src/prompt.ts +454 -0
- package/src/recall.ts +446 -0
- package/src/search.ts +330 -0
- package/src/temporal.ts +379 -0
- package/src/types.ts +199 -0
- package/src/worker.ts +26 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAC7B,OAAO,KAAK,YAAY,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC;AACrC,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,SAAS,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAE7B,OAAO,EACL,SAAS,EACT,uBAAuB,EACvB,yBAAyB,EACzB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,kBAAkB,GACxB,MAAM,UAAU,CAAC;AAElB,YAAY,EACV,WAAW,EACX,eAAe,EACf,oBAAoB,EACpB,QAAQ,EACR,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,EACpB,SAAS,GACV,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAElE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EACL,EAAE,EACF,aAAa,EACb,UAAU,EACV,SAAS,EACT,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,GACN,MAAM,MAAM,CAAC;AACd,OAAO,EACL,SAAS,EACT,cAAc,EACd,uBAAuB,EACvB,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,WAAW,EACX,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,EACL,QAAQ,EACR,UAAU,EACV,WAAW,EACX,oBAAoB,EACpB,WAAW,EACX,eAAe,GAChB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,SAAS,EACT,MAAM,EACN,CAAC,EACD,CAAC,EACD,EAAE,EACF,GAAG,EACH,IAAI,EACJ,CAAC,EACD,IAAI,EACJ,MAAM,EACN,SAAS,EACT,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lat.md reader — indexes lat.md/ directory sections for recall integration.
|
|
3
|
+
*
|
|
4
|
+
* When a project has a `lat.md/` directory (from the lat.md knowledge graph tool),
|
|
5
|
+
* this module parses the markdown files, extracts hierarchical sections, and stores
|
|
6
|
+
* them in SQLite with FTS5 indexing. Sections are included in recall results via
|
|
7
|
+
* RRF fusion and in LTM system-prompt injection via session-context scoring.
|
|
8
|
+
*
|
|
9
|
+
* Change detection uses SHA-256 content hashes per file — unchanged files are skipped.
|
|
10
|
+
*/
|
|
11
|
+
export type LatSection = {
|
|
12
|
+
id: string;
|
|
13
|
+
project_id: string;
|
|
14
|
+
file: string;
|
|
15
|
+
heading: string;
|
|
16
|
+
depth: number;
|
|
17
|
+
content: string;
|
|
18
|
+
content_hash: string;
|
|
19
|
+
first_paragraph: string | null;
|
|
20
|
+
updated_at: number;
|
|
21
|
+
};
|
|
22
|
+
export type ScoredLatSection = LatSection & {
|
|
23
|
+
rank: number;
|
|
24
|
+
};
|
|
25
|
+
type ParsedSection = {
|
|
26
|
+
id: string;
|
|
27
|
+
file: string;
|
|
28
|
+
heading: string;
|
|
29
|
+
depth: number;
|
|
30
|
+
content: string;
|
|
31
|
+
first_paragraph: string | null;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Parse a single markdown file into sections.
|
|
35
|
+
* Each heading creates a section; content is everything between headings.
|
|
36
|
+
* Section IDs use the lat.md convention: `file#Heading#SubHeading`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function parseSections(filePath: string, content: string, projectRoot: string): ParsedSection[];
|
|
39
|
+
/** Check if a project has a lat.md/ directory. */
|
|
40
|
+
export declare function hasLatDir(projectPath: string): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Refresh the lat_sections cache for a project.
|
|
43
|
+
* Scans lat.md/ directory, parses markdown files, and upserts sections.
|
|
44
|
+
* Skips files whose content hash hasn't changed since last scan.
|
|
45
|
+
* Removes sections from files that no longer exist.
|
|
46
|
+
*
|
|
47
|
+
* @returns Number of sections updated/inserted
|
|
48
|
+
*/
|
|
49
|
+
export declare function refresh(projectPath: string): number;
|
|
50
|
+
/**
|
|
51
|
+
* Search lat sections by FTS5 with BM25 scoring.
|
|
52
|
+
* Uses AND-then-OR fallback (same pattern as knowledge search).
|
|
53
|
+
*/
|
|
54
|
+
export declare function searchScored(input: {
|
|
55
|
+
query: string;
|
|
56
|
+
projectPath: string;
|
|
57
|
+
limit?: number;
|
|
58
|
+
}): ScoredLatSection[];
|
|
59
|
+
/**
|
|
60
|
+
* Score lat sections against session context for LTM injection.
|
|
61
|
+
* Uses OR-based FTS5 BM25 (same approach as ltm.ts scoreEntriesFTS).
|
|
62
|
+
*
|
|
63
|
+
* @returns Scored entries sorted by score descending, capped at maxTokens budget
|
|
64
|
+
*/
|
|
65
|
+
export declare function scoreForSession(projectPath: string, sessionContext: string, maxTokens: number): LatSection[];
|
|
66
|
+
/** Count lat sections for a project. */
|
|
67
|
+
export declare function count(projectPath: string): number;
|
|
68
|
+
export {};
|
|
69
|
+
//# sourceMappingURL=lat-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lat-reader.d.ts","sourceRoot":"","sources":["../../src/lat-reader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAkBH,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAI7D,KAAK,aAAa,GAAG;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,CAAC;AAyBF;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,aAAa,EAAE,CAqErG;AA8BD,kDAAkD;AAClD,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAGtD;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA+EnD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,gBAAgB,EAAE,CA2BrB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,GAChB,UAAU,EAAE,CA2Cd;AAED,wCAAwC;AACxC,wBAAgB,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAMjD"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight logger that suppresses informational messages by default.
|
|
3
|
+
*
|
|
4
|
+
* In TUI mode, all stderr output renders as red "error" text — confusing
|
|
5
|
+
* for routine status messages like "incremental distillation" or "pruned
|
|
6
|
+
* temporal messages". Only actual errors should be visible by default.
|
|
7
|
+
*
|
|
8
|
+
* Set LORE_DEBUG=1 to see informational messages (useful when debugging
|
|
9
|
+
* the plugin itself).
|
|
10
|
+
*/
|
|
11
|
+
/** Log an informational status message. Suppressed unless LORE_DEBUG=1. */
|
|
12
|
+
export declare function info(...args: unknown[]): void;
|
|
13
|
+
/** Log a warning. Suppressed unless LORE_DEBUG=1. */
|
|
14
|
+
export declare function warn(...args: unknown[]): void;
|
|
15
|
+
/** Log an error. Always visible — these indicate real failures. */
|
|
16
|
+
export declare function error(...args: unknown[]): void;
|
|
17
|
+
//# sourceMappingURL=log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,2EAA2E;AAC3E,wBAAgB,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAE7C;AAED,qDAAqD;AACrD,wBAAgB,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAE7C;AAED,mEAAmE;AACnE,wBAAgB,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAE9C"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
export type KnowledgeEntry = {
|
|
2
|
+
id: string;
|
|
3
|
+
project_id: string | null;
|
|
4
|
+
category: string;
|
|
5
|
+
title: string;
|
|
6
|
+
content: string;
|
|
7
|
+
source_session: string | null;
|
|
8
|
+
cross_project: number;
|
|
9
|
+
confidence: number;
|
|
10
|
+
created_at: number;
|
|
11
|
+
updated_at: number;
|
|
12
|
+
metadata: string | null;
|
|
13
|
+
};
|
|
14
|
+
export declare function create(input: {
|
|
15
|
+
projectPath?: string;
|
|
16
|
+
category: string;
|
|
17
|
+
title: string;
|
|
18
|
+
content: string;
|
|
19
|
+
session?: string;
|
|
20
|
+
scope: "project" | "global";
|
|
21
|
+
crossProject?: boolean;
|
|
22
|
+
/** Explicit ID to use — for cross-machine import via agents-file. Defaults to a new UUIDv7. */
|
|
23
|
+
id?: string;
|
|
24
|
+
}): string;
|
|
25
|
+
export declare function update(id: string, input: {
|
|
26
|
+
content?: string;
|
|
27
|
+
confidence?: number;
|
|
28
|
+
}): void;
|
|
29
|
+
export declare function remove(id: string): void;
|
|
30
|
+
export declare function forProject(projectPath: string, includeCross?: boolean): KnowledgeEntry[];
|
|
31
|
+
/**
|
|
32
|
+
* Build a relevance-ranked, budget-capped list of knowledge entries for injection
|
|
33
|
+
* into the system prompt of a live session.
|
|
34
|
+
*
|
|
35
|
+
* Strategy:
|
|
36
|
+
* 1. Both project-specific and cross-project entries are scored for relevance
|
|
37
|
+
* against recent session context (last distillation + recent raw messages).
|
|
38
|
+
* 2. Project entries get a safety net: the top PROJECT_SAFETY_NET entries by
|
|
39
|
+
* confidence are always included even if they have zero relevance score.
|
|
40
|
+
* This ensures the most important project knowledge is never lost to
|
|
41
|
+
* coarse term-overlap scoring.
|
|
42
|
+
* 3. All scored entries are merged into a single pool and greedily packed
|
|
43
|
+
* into the token budget by score descending.
|
|
44
|
+
* 4. If there's no session context yet (first turn), fall back to top entries
|
|
45
|
+
* by confidence only (capped at NO_CONTEXT_FALLBACK_CAP per pool).
|
|
46
|
+
*
|
|
47
|
+
* @param projectPath Current project path
|
|
48
|
+
* @param sessionID Current session ID (for context extraction)
|
|
49
|
+
* @param maxTokens Hard token budget for the entire formatted block
|
|
50
|
+
*/
|
|
51
|
+
export declare function forSession(projectPath: string, sessionID: string | undefined, maxTokens: number): KnowledgeEntry[];
|
|
52
|
+
export declare function all(): KnowledgeEntry[];
|
|
53
|
+
export declare function search(input: {
|
|
54
|
+
query: string;
|
|
55
|
+
projectPath?: string;
|
|
56
|
+
limit?: number;
|
|
57
|
+
}): KnowledgeEntry[];
|
|
58
|
+
export type ScoredKnowledgeEntry = KnowledgeEntry & {
|
|
59
|
+
rank: number;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Search with BM25 scores included. Returns results with raw FTS5 rank values
|
|
63
|
+
* for use in cross-source score fusion (RRF).
|
|
64
|
+
*/
|
|
65
|
+
export declare function searchScored(input: {
|
|
66
|
+
query: string;
|
|
67
|
+
projectPath?: string;
|
|
68
|
+
limit?: number;
|
|
69
|
+
}): ScoredKnowledgeEntry[];
|
|
70
|
+
/**
|
|
71
|
+
* Search knowledge entries from OTHER projects — entries that are project-specific
|
|
72
|
+
* (cross_project=0) and belong to a different project_id than the given one.
|
|
73
|
+
* Used by the recall tool in "all" scope to surface relevant knowledge from
|
|
74
|
+
* the user's other projects ("tunnel" discovery across projects).
|
|
75
|
+
*/
|
|
76
|
+
export declare function searchScoredOtherProjects(input: {
|
|
77
|
+
query: string;
|
|
78
|
+
excludeProjectPath: string;
|
|
79
|
+
limit?: number;
|
|
80
|
+
}): ScoredKnowledgeEntry[];
|
|
81
|
+
export declare function get(id: string): KnowledgeEntry | null;
|
|
82
|
+
/**
|
|
83
|
+
* Prune knowledge entries whose content exceeds maxLength characters.
|
|
84
|
+
* These are typically corrupted entries from AGENTS.md roundtrip escaping bugs
|
|
85
|
+
* or curator hallucinations with full code dumps.
|
|
86
|
+
*
|
|
87
|
+
* Rather than hard-deleting, sets confidence to 0 so they're excluded from
|
|
88
|
+
* queries (confidence > 0.2) but can be inspected for debugging.
|
|
89
|
+
*
|
|
90
|
+
* @returns Number of entries pruned
|
|
91
|
+
*/
|
|
92
|
+
export declare function pruneOversized(maxLength: number): number;
|
|
93
|
+
/**
|
|
94
|
+
* Resolve a wiki-link reference to a knowledge entry ID.
|
|
95
|
+
* - UUID format → direct O(1) lookup
|
|
96
|
+
* - Title text → FTS5 best-match search
|
|
97
|
+
* Returns null if the reference can't be resolved.
|
|
98
|
+
*/
|
|
99
|
+
export declare function resolveRef(ref: string): string | null;
|
|
100
|
+
/**
|
|
101
|
+
* Extract [[...]] wiki-link references from entry content.
|
|
102
|
+
* Returns the raw ref strings (UUIDs or titles).
|
|
103
|
+
*/
|
|
104
|
+
export declare function extractRefs(content: string): string[];
|
|
105
|
+
/**
|
|
106
|
+
* Populate the knowledge_refs join table for an entry by resolving its [[...]] links.
|
|
107
|
+
* Clears existing outgoing refs for this entry first.
|
|
108
|
+
*/
|
|
109
|
+
export declare function syncRefs(entryId: string): number;
|
|
110
|
+
/**
|
|
111
|
+
* Cascade-replace an entry ID in all knowledge content and the refs table.
|
|
112
|
+
* Used when an entry ID changes (future-proofing — current consolidation
|
|
113
|
+
* uses update-in-place so IDs don't change, but the mechanism exists).
|
|
114
|
+
*/
|
|
115
|
+
export declare function cascadeRefReplace(oldId: string, newId: string): number;
|
|
116
|
+
/**
|
|
117
|
+
* Clean dead references — remove [[uuid]] patterns pointing to deleted entries.
|
|
118
|
+
* Strips dead refs from content and purges orphan knowledge_refs rows.
|
|
119
|
+
*
|
|
120
|
+
* @returns Number of entries whose content was cleaned
|
|
121
|
+
*/
|
|
122
|
+
export declare function cleanDeadRefs(): number;
|
|
123
|
+
export type IntegrityIssue = {
|
|
124
|
+
entryId: string;
|
|
125
|
+
type: "duplicate" | "stale-path" | "oversized" | "empty";
|
|
126
|
+
description: string;
|
|
127
|
+
suggestion?: string;
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Check knowledge entries for integrity issues.
|
|
131
|
+
* Returns a list of issues found — does NOT auto-fix.
|
|
132
|
+
*
|
|
133
|
+
* Checks:
|
|
134
|
+
* 1. Duplicate detection — FTS5 title similarity between entries
|
|
135
|
+
* 2. Content quality — empty content, oversized entries
|
|
136
|
+
*/
|
|
137
|
+
export declare function check(projectPath: string): IntegrityIssue[];
|
|
138
|
+
//# sourceMappingURL=ltm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ltm.d.ts","sourceRoot":"","sources":["../../src/ltm.ts"],"names":[],"mappings":"AAaA,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AAWF,wBAAgB,MAAM,CAAC,KAAK,EAAE;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC5B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,+FAA+F;IAC/F,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,GAAG,MAAM,CAyET;AAED,wBAAgB,MAAM,CACpB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,QA0BjD;AAED,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,QAEhC;AAED,wBAAgB,UAAU,CACxB,WAAW,EAAE,MAAM,EACnB,YAAY,UAAO,GAClB,cAAc,EAAE,CAoBlB;AAqED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,UAAU,CACxB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,GAChB,cAAc,EAAE,CA2IlB;AAED,wBAAgB,GAAG,IAAI,cAAc,EAAE,CAMtC;AAgCD,wBAAgB,MAAM,CAAC,KAAK,EAAE;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,cAAc,EAAE,CA4CnB;AAED,MAAM,MAAM,oBAAoB,GAAG,cAAc,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErE;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,oBAAoB,EAAE,CAsCzB;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,oBAAoB,EAAE,CAkCzB;AAED,wBAAgB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAIrD;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAQxD;AASD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQrD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAQrD;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAwBhD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAqBtE;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAsCtC;AAMD,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,WAAW,GAAG,YAAY,GAAG,WAAW,GAAG,OAAO,CAAC;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,EAAE,CA8E3D"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Root, Heading, List, ListItem, Paragraph, Text, Strong, BlockContent, PhrasingContent } from "mdast";
|
|
2
|
+
export declare function serialize(tree: Root): string;
|
|
3
|
+
/**
|
|
4
|
+
* Replace unpaired Unicode surrogates with U+FFFD (replacement character).
|
|
5
|
+
*
|
|
6
|
+
* Unpaired surrogates (a high surrogate U+D800-U+DBFF without a following low
|
|
7
|
+
* surrogate U+DC00-U+DFFF, or a lone low surrogate) are technically invalid in
|
|
8
|
+
* UTF-8/JSON. They can appear in tool outputs (binary file contents, command
|
|
9
|
+
* output) and survive through SQLite storage into recall results. When the
|
|
10
|
+
* resulting string is serialized to JSON for the LLM API, the API rejects it
|
|
11
|
+
* with "no low surrogate in string".
|
|
12
|
+
*/
|
|
13
|
+
export declare function sanitizeSurrogates(value: string): string;
|
|
14
|
+
export declare function inline(value: string): string;
|
|
15
|
+
export declare function normalize(md: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Unescape a markdown-serialized inline string back to plain text.
|
|
18
|
+
*
|
|
19
|
+
* remark's serializer escapes special characters with backslashes
|
|
20
|
+
* (e.g. `<` → `\<`, `*` → `\*`, `\` → `\\`). When we read content
|
|
21
|
+
* back from an AGENTS.md file we must unescape it so it round-trips
|
|
22
|
+
* cleanly — otherwise each export/import cycle doubles the escapes.
|
|
23
|
+
*
|
|
24
|
+
* Uses remark's own parser to extract the text value, which handles
|
|
25
|
+
* all escape sequences correctly.
|
|
26
|
+
*/
|
|
27
|
+
export declare function unescapeMarkdown(md: string): string;
|
|
28
|
+
export declare function h(depth: 1 | 2 | 3 | 4 | 5 | 6, value: string): Heading;
|
|
29
|
+
export declare function p(value: string): Paragraph;
|
|
30
|
+
export declare function ul(items: ListItem[]): List;
|
|
31
|
+
export declare function li(...children: BlockContent[]): ListItem;
|
|
32
|
+
export declare function lip(value: string): ListItem;
|
|
33
|
+
export declare function liph(...children: PhrasingContent[]): ListItem;
|
|
34
|
+
export declare function t(value: string): Text;
|
|
35
|
+
export declare function strong(value: string): Strong;
|
|
36
|
+
export declare function root(...children: Root["children"]): Root;
|
|
37
|
+
//# sourceMappingURL=markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/markdown.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,MAAM,EACN,YAAY,EACZ,eAAe,EAChB,MAAM,OAAO,CAAC;AASf,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE5C;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMxD;AAOD,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE5C;AAOD,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAgBnD;AAID,wBAAgB,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED,wBAAgB,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAE1C;AAED,wBAAgB,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAE1C;AAED,wBAAgB,EAAE,CAAC,GAAG,QAAQ,EAAE,YAAY,EAAE,GAAG,QAAQ,CAExD;AAGD,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAE3C;AAGD,wBAAgB,IAAI,CAAC,GAAG,QAAQ,EAAE,eAAe,EAAE,GAAG,QAAQ,CAE7D;AAED,wBAAgB,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAErC;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,wBAAgB,IAAI,CAAC,GAAG,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAExD"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export declare const DISTILLATION_SYSTEM = "You are a memory observer. Your observations will be the ONLY information an AI assistant has about past interactions. Produce a dense, dated event log \u2014 not a summary.\n\nCRITICAL: DISTINGUISH USER ASSERTIONS FROM QUESTIONS\n\nWhen the user TELLS you something about themselves, mark it as an assertion (\uD83D\uDD34):\n- \"I have two kids\" \u2192 \uD83D\uDD34 (14:30) User stated has two kids\n- \"I work at Acme Corp\" \u2192 \uD83D\uDD34 (14:31) User stated works at Acme Corp\n\nWhen the user ASKS about something, mark it as a question (\uD83D\uDFE1):\n- \"Can you help me with X?\" \u2192 \uD83D\uDFE1 (15:00) User asked for help with X\n\nUser assertions are AUTHORITATIVE \u2014 the user is the source of truth about their own life.\n\nTEMPORAL ANCHORING \u2014 CRITICAL FOR TEMPORAL REASONING:\n\nEach observation has up to two timestamps:\n1. BEGINNING: The time the statement was made \u2014 ALWAYS include this as (HH:MM)\n2. END: The referenced date, if the content refers to a different time \u2014 add as \"(meaning DATE)\" or \"(estimated DATE)\"\n\nONLY add \"(meaning DATE)\" when you can derive an actual date:\n- \"last week\", \"yesterday\", \"next month\" \u2192 compute and add the date\n- \"recently\", \"a while ago\", \"soon\" \u2192 too vague, omit the end date\n\nALWAYS put the date annotation at the END of the observation line.\n\nGOOD: (09:15) User will visit parents this weekend. (meaning Jun 17-18, 2025)\nGOOD: (09:15) User's friend had a birthday party last month. (estimated May 2025)\nGOOD: (09:15) User prefers hiking in the mountains.\nBAD: (09:15) User prefers hiking. (meaning Jun 15, 2025) \u2190 no time reference, don't add date\n\nIf an observation contains MULTIPLE events, split into SEPARATE lines, each with its own date.\n\nSTATE CHANGES \u2014 make supersession explicit:\n- \"User will use X (replacing Y)\" \u2014 not just \"User will use X\"\n- \"User moved to Berlin (no longer in London)\"\n\nDETAILS TO ALWAYS PRESERVE:\n- Names, handles, usernames (@username, \"Dr. Smith\")\n- Numbers, counts, quantities (4 items, 3 sessions, $120)\n- Measurements, percentages (5kg, 20% improvement, 85% accuracy)\n- Sequences and orderings (steps 1-5, lucky numbers: 7 14 23)\n- Prices, dates, times, durations\n- Locations and distinguishing attributes\n- User's specific role (presenter, volunteer, organizer \u2014 not just \"attended\")\n- Exact phrasing when unusual (\"movement session\" for exercise)\n\nEXACT NUMBERS \u2014 NEVER APPROXIMATE:\n\nWhen the conversation states a specific count, record that EXACT number \u2014 do not round, estimate, or substitute a count you see later. If the same quantity appears with different values at different times, record each with its timestamp.\n\nBAD: All existing entries bulk-updated to cross_project=1 (50 entries) \u2190 wrong: mixed up with a later count\nGOOD: 43 knowledge entries bulk-updated to cross_project=1 via SQL UPDATE \u2190 exact number from the operation\n\nBAD: ~130 test failures\nGOOD: 131 test failures (1902 pass, 131 fail, 1 error across 100 files) \u2190 preserve exact counts\n\nBUG FIXES AND CODE CHANGES \u2014 HIGH PRIORITY:\n\nEvery bug fix, code change, or technical decision is important regardless of where it appears in the conversation. Early-session fixes are just as valuable as later ones.\n\nFor each fix, record:\n- The specific bug/problem (what went wrong)\n- The root cause (why it went wrong)\n- The fix applied (what changed, with file paths and line numbers)\n- The outcome (tests pass, deployed, etc.)\n\nBAD: \uD83D\uDFE1 Fixed an FTS5 search bug\nGOOD: \uD83D\uDFE1 FTS5 was doing exact term matching instead of prefix matching in ltm.ts. Fix: added ftsQuery() function that appends * to each search term for prefix matching. Committed as [hash].\n\nASSISTANT-GENERATED CONTENT \u2014 THIS IS CRITICAL:\n\nWhen the assistant produces lists, recommendations, explanations, recipes, schedules, creative content, or any structured output \u2014 record EVERY ITEM with its distinguishing details. The user WILL ask about specific items later.\n\nBAD: \uD83D\uDFE1 Assistant recommended 5 dessert spots in Orlando.\nGOOD: \uD83D\uDFE1 Assistant recommended dessert spots: Sugar Factory (Icon Park, giant milkshakes), Wondermade (Sanford, gourmet marshmallows), Gideon's Bakehouse (Disney Springs, cookies), Farris & Foster's (unique flavors), Kilwins (handmade fudge)\n\nBAD: \uD83D\uDFE1 Assistant listed work-from-home jobs for seniors.\nGOOD: \uD83D\uDFE1 Assistant listed 10 WFH jobs for seniors: 1. Virtual assistant, 2. Online tutor, 3. Freelance writer, 4. Social media manager, 5. Customer service rep, 6. Bookkeeper, 7. Transcriptionist, 8. Web designer, 9. Data entry, 10. Consultant\n\nBAD: \uD83D\uDFE1 Assistant explained refining processes.\nGOOD: \uD83D\uDFE1 Assistant explained Lake Charles refinery processes: atmospheric distillation, fluid catalytic cracking (FCC), alkylation, hydrotreating\n\nRules for assistant content:\n- Record EACH item in a list with at least one distinguishing attribute\n- For numbered lists, preserve the EXACT ordering (1st, 2nd, 3rd...)\n- For recipes: preserve specific quantities, ratios, temperatures, times\n- For recommendations: preserve names, locations, prices, key features\n- For creative content (songs, stories, poems): preserve titles, key phrases, character names, structural details\n- For technical explanations: preserve specific values, percentages, formulas, tool/library names\n- Ordered lists must keep their numbering \u2014 users ask \"what was the 7th item?\"\n- Use \uD83D\uDFE1 priority but NEVER skip assistant-generated details to save space\n\nENUMERATABLE ENTITIES \u2014 always flag for cross-session aggregation:\nWhen the user mentions attending events, buying things, meeting people, completing tasks \u2014 mark with entity type so these can be aggregated across sessions:\n\uD83D\uDD34 [event-attended] User attended Rachel+Mike's wedding (vineyard in Napa, Aug 12, 2023)\n\uD83D\uDD34 [item-purchased] User bought Sony WH-1000XM5 headphones ($280, replaced old Bose)\nThis makes it possible to answer \"how many weddings did I attend?\" by aggregating across sessions.\n\nPRIORITY LEVELS:\n- \uD83D\uDD34 High: user assertions, stated facts, preferences, goals, enumeratable entities\n- \uD83D\uDFE1 Medium: questions asked, context, assistant-generated content with full detail\n- \uD83D\uDFE2 Low: minor conversational context, greetings, acknowledgments\n\nOUTPUT FORMAT \u2014 output ONLY observations, no preamble:\n\n<observations>\nDate: Jan 15, 2026\n* \uD83D\uDD34 (09:15) User stated has two kids: Emma (12) and Jake (9)\n* \uD83D\uDD34 (09:16) User's anniversary is March 15\n* \uD83D\uDFE1 (09:20) User asked how to optimize database queries\n* \uD83D\uDD34 [event-attended] (10:00) User attended company holiday party as a presenter (gave talk on microservices)\n* \uD83D\uDD34 (11:30) User will visit parents this weekend. (meaning Jan 17-18, 2026)\n* \uD83D\uDFE1 (14:00) Agent debugging auth issue \u2014 found missing null check in auth.ts:45, applied fix, tests pass\n* \uD83D\uDFE1 (14:30) Assistant recommended 5 hotels: 1. Grand Plaza (near station, $180), 2. Seaside Inn (pet-friendly, $120), 3. Mountain Lodge (pool, free breakfast, $95), 4. Harbor View (historic, walkable, $150), 5. Zen Garden (quietest, spa, $200)\n* \uD83D\uDD34 (15:00) User switched from Python to TypeScript for the project (no longer using Python)\n</observations>";
|
|
2
|
+
export declare function distillationUser(input: {
|
|
3
|
+
priorObservations?: string;
|
|
4
|
+
date: string;
|
|
5
|
+
messages: string;
|
|
6
|
+
}): string;
|
|
7
|
+
export declare const RECURSIVE_SYSTEM = "You are a memory reflector. You are given a set of observations from multiple conversation segments. Your job is to consolidate them into a structured working context that will become the agent's entire memory going forward.\n\nIMPORTANT: Your reflections ARE the entirety of the assistant's memory. Any information you omit is permanently forgotten. Do not leave out anything important.\n\nSTRUCTURE your output into these sections \u2014 each section supports a different type of downstream query:\n\n### Current State\nWhat is in progress right now? Active branches, open files, current task, blockers.\nThis section answers: \"What was I working on?\"\n\n### Key Decisions\nWhat was decided and why? Include the alternatives considered and rationale.\nThis section answers: \"Why did we choose approach X?\" and \"What alternatives were rejected?\"\n\n### Technical Changes\nBugs found, root causes, fixes applied, files modified, tests added/fixed.\nPreserve exact file paths, line numbers, error messages, and commit references.\nThis section answers: \"What bugs were fixed?\" and \"What files were changed?\"\n\n### Session Timeline\nCondensed chronological events with timestamps. Older events compressed more aggressively; recent events retain detail. This section answers: \"When did X happen?\" and \"What was the sequence of events?\"\n\nCONSOLIDATION RULES:\n- Preserve ALL dates and timestamps \u2014 temporal context is critical\n- Combine related items (e.g., \"agent called view tool 5 times on file x\" \u2192 single line)\n- Merge duplicate facts, keeping the most specific version\n- Drop observations superseded by later info (if value changed, keep only final value)\n- When consolidating, USER ASSERTIONS take precedence over questions about the same topic\n- Preserve all enumeratable entities [entity-type] \u2014 these are needed for aggregation questions\n- For enumeratable entities spanning multiple segments, create an explicit aggregation:\n \uD83D\uDD34 [event-attended] User attended 3 weddings total: Rachel+Mike (vineyard, Aug 2023), Emily+Sarah (garden, Sep 2023), Jen+Tom (Oct 8, 2023)\n\nEXACT NUMBERS: When two segments report different numbers for what seems like the same thing, keep the number from the earlier/original observation \u2014 it's likely the correct one from the actual event. Later references may be from memory or approximation.\n\nEARLY-SESSION CONTENT: Bug fixes, code changes, and decisions from the start of a session are just as important as later work. Never drop them just because the segment is short or old. If the first segment contains a specific bug fix with file paths and root cause, it MUST survive into the reflection.\n\nOutput ONLY an <observations> block with the consolidated observations.";
|
|
8
|
+
export declare function recursiveUser(distillations: Array<{
|
|
9
|
+
observations: string;
|
|
10
|
+
}>): string;
|
|
11
|
+
export declare const CURATOR_SYSTEM = "You are a long-term memory curator. Your job is to extract durable knowledge from a conversation that should persist across sessions.\n\nFocus ONLY on knowledge that helps a coding agent work effectively on THIS codebase:\n- Architectural decisions and their rationale (why something was built a certain way)\n- Non-obvious implementation patterns and conventions specific to the project\n- Recurring gotchas, constraints, or traps in the codebase\n- Environment/tooling setup details that affect development\n- Important relationships between components that aren't obvious from reading the code\n- User preferences and working style specific to how they use this project\n\nDo NOT extract:\n- Task-specific details (file currently being edited, current bug being fixed)\n- Temporary state (current branch, in-progress work)\n- Information that will change frequently\n- Ecosystem descriptions, product announcements, or marketing content\n- Business strategy, roadmap, or organizational information\n- Information that's readily available in public documentation or READMEs\n- Knowledge about unrelated projects or repositories unless explicitly cross-project\n- Restatements of what the code obviously does (e.g. \"the auth module handles authentication\")\n\nBREVITY IS CRITICAL \u2014 each entry must be concise:\n- content MUST be under 150 words (~600 characters). Capture ONE specific actionable\n insight in 2-3 sentences. Prefer terse technical language.\n- Each \"gotcha\": one specific trap + its fix in 1-2 sentences\n- Each \"architecture\": one design decision and its key constraint\n- Focus on the actionable insight, not the full story behind it\n- If a pattern requires more detail, split into multiple focused entries (each under 150 words)\n- Omit code examples unless a single short snippet is essential\n- Never include full file contents, large diffs, or complete command outputs\n\nPREFER UPDATES OVER CREATES:\n- Before creating a new entry, always check if an existing entry covers the same system\n or component. Update the existing entry rather than creating a new one.\n- When updating, REPLACE the full content with a concise rewrite \u2014 do not append to\n the existing content or repeat what was already there.\n- If multiple existing entries cover the same system from different angles (e.g. different\n bugs in the same module), consolidate them: update one with merged insights, delete the\n rest. Fewer, denser entries are better than many scattered ones.\n\nCROSS-REFERENCES between entries:\n- When an entry relates to another entry, reference it with [[entry-uuid]] using the entry's ID\n from the existing entries list. This creates navigable links between entries.\n- Only reference entries you can see in the existing entries list \u2014 don't guess IDs.\n- Example: \"Uses the gradient system [[019c904b-791e-772a-ab2b-93ac892a960c]] for context management.\"\n\ncrossProject flag:\n- Default is true \u2014 most useful knowledge is worth sharing across projects\n- Set crossProject to false for things that are meaningless outside this specific repo (e.g. a config path, a project-local naming convention that conflicts with your usual style)\n\nProduce a JSON array of operations:\n[\n {\n \"op\": \"create\",\n \"category\": \"decision\" | \"pattern\" | \"preference\" | \"architecture\" | \"gotcha\",\n \"title\": \"Short descriptive title\",\n \"content\": \"Concise knowledge entry \u2014 under 150 words\",\n \"scope\": \"project\" | \"global\",\n \"crossProject\": true\n },\n {\n \"op\": \"update\",\n \"id\": \"existing-entry-id\",\n \"content\": \"Updated content \u2014 under 150 words\",\n \"confidence\": 0.0-1.0\n },\n {\n \"op\": \"delete\",\n \"id\": \"existing-entry-id\",\n \"reason\": \"Why this is no longer relevant\"\n }\n]\n\nIf nothing warrants extraction, return an empty array: []\n\nOutput ONLY valid JSON. No markdown fences, no explanation, no preamble.";
|
|
12
|
+
export declare function curatorUser(input: {
|
|
13
|
+
messages: string;
|
|
14
|
+
existing: Array<{
|
|
15
|
+
id: string;
|
|
16
|
+
category: string;
|
|
17
|
+
title: string;
|
|
18
|
+
content: string;
|
|
19
|
+
}>;
|
|
20
|
+
}): string;
|
|
21
|
+
/**
|
|
22
|
+
* System prompt for the consolidation pass.
|
|
23
|
+
* Unlike the normal curator (which extracts from conversation), consolidation
|
|
24
|
+
* reviews the FULL entry corpus and aggressively merges/trims/deletes to reduce
|
|
25
|
+
* entry count while preserving the most actionable knowledge.
|
|
26
|
+
*/
|
|
27
|
+
export declare const CONSOLIDATION_SYSTEM = "You are a long-term memory curator performing a consolidation pass. The knowledge base has grown too large and needs to be trimmed.\n\nYour goal: reduce the entry count to the target maximum while preserving the most valuable knowledge.\n\nCONSOLIDATION RULES:\n1. MERGE related entries \u2014 if multiple entries describe the same system, module, or concept\n from different angles (e.g. several bug fixes in the same component), merge them into\n ONE concise entry. Use an \"update\" op for the surviving entry and \"delete\" ops for the rest.\n2. TRIM verbose entries \u2014 any entry over 150 words must be trimmed to its essential insight.\n Use an \"update\" op with the rewritten content.\n3. DELETE low-value entries:\n - Stale entries about bugs that have been fixed and no longer need gotcha warnings\n - Entries whose knowledge is fully subsumed by another entry\n - Entries about one-off incidents with no recurring applicability\n - General advice available in any documentation\n4. PRESERVE:\n - Entries describing non-obvious design decisions specific to this codebase\n - Entries about recurring traps that a developer would hit again\n - Entries that capture a hard-won gotcha with a concrete fix\n\nOUTPUT: A JSON array of \"update\" and \"delete\" ops only. No \"create\" ops \u2014 you are not\nextracting new knowledge, only consolidating existing knowledge.\n\n- \"update\": Replace content with a concise rewrite (under 150 words). Use to merge survivors or trim verbose entries.\n- \"delete\": Remove entries that are merged, stale, or low-value.\n\nOutput ONLY valid JSON. No markdown fences, no explanation, no preamble.";
|
|
28
|
+
export declare function consolidationUser(input: {
|
|
29
|
+
entries: Array<{
|
|
30
|
+
id: string;
|
|
31
|
+
category: string;
|
|
32
|
+
title: string;
|
|
33
|
+
content: string;
|
|
34
|
+
}>;
|
|
35
|
+
targetMax: number;
|
|
36
|
+
}): string;
|
|
37
|
+
export declare function formatDistillations(distillations: Array<{
|
|
38
|
+
observations: string;
|
|
39
|
+
generation: number;
|
|
40
|
+
}>): string;
|
|
41
|
+
export declare function formatKnowledge(entries: Array<{
|
|
42
|
+
category: string;
|
|
43
|
+
title: string;
|
|
44
|
+
content: string;
|
|
45
|
+
}>, maxTokens?: number): string;
|
|
46
|
+
export declare const QUERY_EXPANSION_SYSTEM = "You are a search query expander for a code knowledge base. Given a search query, generate 2\u20133 alternative queries that would help find relevant results. Focus on:\n- Synonyms and related technical terms\n- Different phrasings of the same concept\n- Broader or narrower scopes\n\nReturn ONLY a JSON array of strings. No explanation, no markdown.\n\nExample:\nInput: \"SQLite FTS5 ranking\"\nOutput: [\"full text search scoring SQLite\", \"BM25 relevance ranking database\", \"FTS5 match order by rank\"]";
|
|
47
|
+
//# sourceMappingURL=prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/prompt.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,mBAAmB,s1OAmHhB,CAAC;AAEjB,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IACtC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,CAaT;AAUD,eAAO,MAAM,gBAAgB,qtFAoC2C,CAAC;AAEzE,wBAAgB,aAAa,CAC3B,aAAa,EAAE,KAAK,CAAC;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,GAC7C,MAAM,CAOR;AAED,eAAO,MAAM,cAAc,i5HA0E8C,CAAC;AAE1E,wBAAgB,WAAW,CAAC,KAAK,EAAE;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,KAAK,CAAC;QACd,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;CACJ,GAAG,MAAM,CAoBT;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,uoDA0BwC,CAAC;AAE1E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,OAAO,EAAE,KAAK,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,MAAM,CAUT;AAID,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,KAAK,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC,GACD,MAAM,CAsBR;AAOD,wBAAgB,eAAe,CAC7B,OAAO,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,EACpE,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAwCR;AAMD,eAAO,MAAM,sBAAsB,ggBASwE,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { LoreConfig } from "./config";
|
|
2
|
+
import type { LLMClient } from "./types";
|
|
3
|
+
type Distillation = {
|
|
4
|
+
id: string;
|
|
5
|
+
observations: string;
|
|
6
|
+
generation: number;
|
|
7
|
+
created_at: number;
|
|
8
|
+
session_id: string;
|
|
9
|
+
};
|
|
10
|
+
export type ScoredDistillation = Distillation & {
|
|
11
|
+
rank: number;
|
|
12
|
+
};
|
|
13
|
+
export type RecallScope = "all" | "session" | "project" | "knowledge";
|
|
14
|
+
export type RecallInput = {
|
|
15
|
+
query: string;
|
|
16
|
+
/** Narrow the search surface. Defaults to `"all"`. */
|
|
17
|
+
scope?: RecallScope;
|
|
18
|
+
/** Project root — used by all scoring paths. */
|
|
19
|
+
projectPath: string;
|
|
20
|
+
/** Current session ID — required when `scope === "session"`. */
|
|
21
|
+
sessionID?: string;
|
|
22
|
+
/** Whether to include long-term knowledge results. Default `true`. */
|
|
23
|
+
knowledgeEnabled?: boolean;
|
|
24
|
+
/** Optional LLM client for query expansion (if `config.search.queryExpansion`). */
|
|
25
|
+
llm?: LLMClient;
|
|
26
|
+
/** Search config — provides recallLimit, queryExpansion, ftsWeights, etc. */
|
|
27
|
+
searchConfig?: LoreConfig["search"];
|
|
28
|
+
};
|
|
29
|
+
/** Result of a full recall run — markdown-formatted string for the LLM. */
|
|
30
|
+
export type RecallResult = string;
|
|
31
|
+
/** Full recall run: search every relevant source, fuse with RRF, format as markdown. */
|
|
32
|
+
export declare function runRecall(input: RecallInput): Promise<RecallResult>;
|
|
33
|
+
/** Standard tool description reused verbatim by each host adapter. */
|
|
34
|
+
export declare const RECALL_TOOL_DESCRIPTION = "Search your persistent memory for this project. Your visible context is a trimmed window \u2014 older messages, decisions, and details may not be visible to you even within the current session. Use this tool whenever you need information that isn't in your current context: file paths, past decisions, user preferences, prior approaches, or anything from earlier in this conversation or previous sessions. Always prefer recall over assuming you don't have the information. Searches long-term knowledge, distilled history, and raw message archives.";
|
|
35
|
+
/** Standard parameter descriptions reused by each host adapter. */
|
|
36
|
+
export declare const RECALL_PARAM_DESCRIPTIONS: {
|
|
37
|
+
query: string;
|
|
38
|
+
scope: string;
|
|
39
|
+
};
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=recall.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recall.d.ts","sourceRoot":"","sources":["../../src/recall.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAczC,KAAK,YAAY,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjE,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;AAEtE,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,mFAAmF;IACnF,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;CACrC,CAAC;AAEF,2EAA2E;AAC3E,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AA+JlC,wFAAwF;AACxF,wBAAsB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAqNzE;AAED,sEAAsE;AACtE,eAAO,MAAM,uBAAuB,wiBAC8f,CAAC;AAEniB,mEAAmE;AACnE,eAAO,MAAM,yBAAyB;;;CAIrC,CAAC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized FTS5 search utilities for Lore.
|
|
3
|
+
*
|
|
4
|
+
* Provides query building, stopword filtering, and (Phase 2+) score fusion.
|
|
5
|
+
* All FTS5 search callers (ltm, temporal, reflect) import from here.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Curated stopword set for FTS5 queries. These are common English words that
|
|
9
|
+
* match broadly and dilute search precision when used with OR semantics.
|
|
10
|
+
*
|
|
11
|
+
* CRITICAL: OR without stopword filtering is catastrophic — "the OR for OR and"
|
|
12
|
+
* matches every document in the corpus. Stopwords MUST be filtered before
|
|
13
|
+
* building OR queries.
|
|
14
|
+
*
|
|
15
|
+
* This list is intentionally conservative: only includes words that are
|
|
16
|
+
* genuinely content-free. Domain terms like "handle", "state", "type" are
|
|
17
|
+
* NOT stopwords — they carry meaning in code/technical contexts.
|
|
18
|
+
*/
|
|
19
|
+
export declare const STOPWORDS: ReadonlySet<string>;
|
|
20
|
+
/**
|
|
21
|
+
* The sentinel value returned when a query contains no meaningful terms after
|
|
22
|
+
* filtering. Callers should check for this and return a "query too vague"
|
|
23
|
+
* message instead of executing an FTS5 MATCH against it.
|
|
24
|
+
*/
|
|
25
|
+
export declare const EMPTY_QUERY = "\"\"";
|
|
26
|
+
/**
|
|
27
|
+
* Filter raw query text into meaningful FTS5 tokens.
|
|
28
|
+
*
|
|
29
|
+
* Filtering (in order):
|
|
30
|
+
* 1. Strip non-word chars (punctuation, operators — prevents FTS5 injection)
|
|
31
|
+
* 2. Remove single-character tokens (contraction artifacts like "s", "t")
|
|
32
|
+
* 3. Remove stopwords
|
|
33
|
+
*
|
|
34
|
+
* If ALL words are filtered, returns an empty array. The caller decides
|
|
35
|
+
* what to do (typically returns a "query too vague" message).
|
|
36
|
+
*
|
|
37
|
+
* No general length filter — short but meaningful tokens like "DB", "CI",
|
|
38
|
+
* "IO", "PR" are preserved. Only single chars are dropped.
|
|
39
|
+
*/
|
|
40
|
+
export declare function filterTerms(raw: string): string[];
|
|
41
|
+
/**
|
|
42
|
+
* Build an FTS5 MATCH expression using AND semantics (implicit AND via space).
|
|
43
|
+
*
|
|
44
|
+
* Returns `""` (match-nothing sentinel) when no meaningful terms remain after
|
|
45
|
+
* filtering. Callers should check `q === EMPTY_QUERY` and handle accordingly.
|
|
46
|
+
*/
|
|
47
|
+
export declare function ftsQuery(raw: string): string;
|
|
48
|
+
/**
|
|
49
|
+
* Build an FTS5 MATCH expression using OR semantics.
|
|
50
|
+
* Same filtering as ftsQuery(), but joins terms with OR.
|
|
51
|
+
* Used as fallback when AND returns zero results.
|
|
52
|
+
*/
|
|
53
|
+
export declare function ftsQueryOr(raw: string): string;
|
|
54
|
+
/**
|
|
55
|
+
* Extract the top meaningful terms from text, sorted by frequency.
|
|
56
|
+
*
|
|
57
|
+
* Same filtering as ftsQuery: drops single chars + stopwords.
|
|
58
|
+
* No general length threshold — preserves short meaningful tokens like "DB", "CI".
|
|
59
|
+
*
|
|
60
|
+
* Used by forSession() to build session context queries for FTS5 scoring.
|
|
61
|
+
*
|
|
62
|
+
* @param text Raw text to extract terms from
|
|
63
|
+
* @param limit Max number of terms to return (default 40)
|
|
64
|
+
*/
|
|
65
|
+
export declare function extractTopTerms(text: string, limit?: number): string[];
|
|
66
|
+
/**
|
|
67
|
+
* Normalize a raw FTS5 BM25 rank to a 0–1 range using min-max normalization.
|
|
68
|
+
*
|
|
69
|
+
* FTS5 rank/bm25() values are negative (more negative = better match).
|
|
70
|
+
* This converts them to 0–1 where 1 = best match in the result set.
|
|
71
|
+
*
|
|
72
|
+
* Used for display scores only — RRF fusion uses rank positions, not scores.
|
|
73
|
+
*/
|
|
74
|
+
export declare function normalizeRank(rank: number, minRank: number, maxRank: number): number;
|
|
75
|
+
/**
|
|
76
|
+
* Reciprocal Rank Fusion: merge multiple ranked lists into a single ranked list.
|
|
77
|
+
*
|
|
78
|
+
* RRF score = Σ(1 / (k + rank_i)) for each list where the item appears.
|
|
79
|
+
* k = 60 is standard (from Cormack et al., 2009; also used by QMD).
|
|
80
|
+
*
|
|
81
|
+
* RRF is rank-based, not score-based — raw score magnitude differences across
|
|
82
|
+
* different FTS5 tables don't matter. Only relative ordering within each list.
|
|
83
|
+
*
|
|
84
|
+
* @param lists Each list provides items (in ranked order) and a key function
|
|
85
|
+
* for deduplication. Items at the front of the array are rank 0.
|
|
86
|
+
* @param k Smoothing constant. Default 60.
|
|
87
|
+
* @returns Fused list sorted by RRF score descending. When items appear
|
|
88
|
+
* in multiple lists, the first occurrence's item is kept.
|
|
89
|
+
*/
|
|
90
|
+
export declare function reciprocalRankFusion<T>(lists: Array<{
|
|
91
|
+
items: T[];
|
|
92
|
+
key: (item: T) => string;
|
|
93
|
+
}>, k?: number): Array<{
|
|
94
|
+
item: T;
|
|
95
|
+
score: number;
|
|
96
|
+
}>;
|
|
97
|
+
import type { LLMClient } from "./types";
|
|
98
|
+
/**
|
|
99
|
+
* Expand a user query into multiple search variants using the configured LLM.
|
|
100
|
+
* Returns `[original, ...expanded]`. The original is always first.
|
|
101
|
+
*
|
|
102
|
+
* Uses a 3-second timeout — if the LLM is slow, returns only the original query.
|
|
103
|
+
* Errors are caught silently (logged) and the original query is returned.
|
|
104
|
+
*
|
|
105
|
+
* @param llm LLM client for prompt calls
|
|
106
|
+
* @param query The original user query
|
|
107
|
+
* @param model Optional model override
|
|
108
|
+
*/
|
|
109
|
+
export declare function expandQuery(llm: LLMClient, query: string, model?: {
|
|
110
|
+
providerID: string;
|
|
111
|
+
modelID: string;
|
|
112
|
+
}): Promise<string[]>;
|
|
113
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/search.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,SAAS,EAAE,WAAW,CAAC,MAAM,CAmGxC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,WAAW,SAAO,CAAC;AAEhC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CASjD;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI5C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI9C;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,MAAM,EAAE,CAelE;AAMD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,MAAM,CAMR;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,KAAK,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAAC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAA;CAAE,CAAC,EACtD,CAAC,SAAK,GACL,KAAK,CAAC;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAkBnC;AAQD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC9C,OAAO,CAAC,MAAM,EAAE,CAAC,CAqCnB"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { LoreMessage, LorePart } from "./types";
|
|
2
|
+
export declare function store(input: {
|
|
3
|
+
projectPath: string;
|
|
4
|
+
info: LoreMessage;
|
|
5
|
+
parts: LorePart[];
|
|
6
|
+
}): void;
|
|
7
|
+
export type TemporalMessage = {
|
|
8
|
+
id: string;
|
|
9
|
+
project_id: string;
|
|
10
|
+
session_id: string;
|
|
11
|
+
role: string;
|
|
12
|
+
content: string;
|
|
13
|
+
tokens: number;
|
|
14
|
+
distilled: number;
|
|
15
|
+
created_at: number;
|
|
16
|
+
metadata: string;
|
|
17
|
+
};
|
|
18
|
+
export declare function undistilled(projectPath: string, sessionID?: string): TemporalMessage[];
|
|
19
|
+
export declare function bySession(projectPath: string, sessionID: string): TemporalMessage[];
|
|
20
|
+
export declare function markDistilled(ids: string[]): void;
|
|
21
|
+
export declare function search(input: {
|
|
22
|
+
projectPath: string;
|
|
23
|
+
query: string;
|
|
24
|
+
sessionID?: string;
|
|
25
|
+
limit?: number;
|
|
26
|
+
}): TemporalMessage[];
|
|
27
|
+
export type ScoredTemporalMessage = TemporalMessage & {
|
|
28
|
+
rank: number;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Search with BM25 scores included. Returns results with raw FTS5 rank values
|
|
32
|
+
* for use in cross-source score fusion (RRF).
|
|
33
|
+
*/
|
|
34
|
+
export declare function searchScored(input: {
|
|
35
|
+
projectPath: string;
|
|
36
|
+
query: string;
|
|
37
|
+
sessionID?: string;
|
|
38
|
+
limit?: number;
|
|
39
|
+
}): ScoredTemporalMessage[];
|
|
40
|
+
export declare function count(projectPath: string, sessionID?: string): number;
|
|
41
|
+
export declare function undistilledCount(projectPath: string, sessionID?: string): number;
|
|
42
|
+
export type PruneResult = {
|
|
43
|
+
/** Rows deleted by the TTL pass (distilled=1 AND older than retention period). */
|
|
44
|
+
ttlDeleted: number;
|
|
45
|
+
/** Rows deleted by the size-cap pass (distilled=1, oldest-first, to get under maxStorage). */
|
|
46
|
+
capDeleted: number;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Prune temporal messages for a project using a two-pass Hybrid C strategy:
|
|
50
|
+
*
|
|
51
|
+
* Pass 1 — TTL: delete messages where distilled=1 AND created_at is older than
|
|
52
|
+
* retentionDays. This covers normal operation — both distillation and curation
|
|
53
|
+
* have had ample time to process anything that old.
|
|
54
|
+
*
|
|
55
|
+
* Pass 2 — Size cap: if total temporal storage for the project still exceeds
|
|
56
|
+
* maxStorageMB, delete the oldest distilled=1 messages (regardless of age)
|
|
57
|
+
* until under the cap.
|
|
58
|
+
*
|
|
59
|
+
* Invariant: undistilled messages (distilled=0) are NEVER deleted by either pass.
|
|
60
|
+
*/
|
|
61
|
+
export declare function prune(input: {
|
|
62
|
+
projectPath: string;
|
|
63
|
+
retentionDays: number;
|
|
64
|
+
maxStorageMB: number;
|
|
65
|
+
}): PruneResult;
|
|
66
|
+
//# sourceMappingURL=temporal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"temporal.d.ts","sourceRoot":"","sources":["../../src/temporal.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAsCrD,wBAAgB,KAAK,CAAC,KAAK,EAAE;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB,QAqCA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,WAAW,CACzB,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,eAAe,EAAE,CASnB;AAED,wBAAgB,SAAS,CACvB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,eAAe,EAAE,CAOnB;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,QAQ1C;AA2BD,wBAAgB,MAAM,CAAC,KAAK,EAAE;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,eAAe,EAAE,CA0CpB;AAED,MAAM,MAAM,qBAAqB,GAAG,eAAe,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvE;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,qBAAqB,EAAE,CAgC1B;AAED,wBAAgB,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAWrE;AAED,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAWR;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,kFAAkF;IAClF,UAAU,EAAE,MAAM,CAAC;IACnB,8FAA8F;IAC9F,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,WAAW,CA0Ed"}
|