@dzhechkov/harness-core 0.3.47 → 0.3.50
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/book-kb.d.ts +1 -0
- package/dist/book-kb.d.ts.map +1 -1
- package/dist/book-kb.js +5 -1
- package/dist/book-kb.js.map +1 -1
- package/dist/brain.d.ts +114 -0
- package/dist/brain.d.ts.map +1 -0
- package/dist/brain.js +403 -0
- package/dist/brain.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/book-kb.ts +6 -2
- package/src/brain.ts +472 -0
- package/src/index.ts +13 -0
package/dist/book-kb.d.ts
CHANGED
package/dist/book-kb.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"book-kb.d.ts","sourceRoot":"","sources":["../src/book-kb.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,2DAA2D;AAC3D,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC7C;AAED,qDAAqD;AACrD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAaD,iGAAiG;AACjG,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEtD;AAyBD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,SAAS,MAAM,EAAE,EACtB,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAsChE;AAED,wFAAwF;AACxF,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,
|
|
1
|
+
{"version":3,"file":"book-kb.d.ts","sourceRoot":"","sources":["../src/book-kb.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,2DAA2D;AAC3D,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC7C;AAED,qDAAqD;AACrD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAaD,iGAAiG;AACjG,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEtD;AAyBD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,SAAS,MAAM,EAAE,EACtB,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAsChE;AAED,wFAAwF;AACxF,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,GAAG,KAAK,CAAA;CAAO,GACnF,OAAO,CAAC;IAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAwChD"}
|
package/dist/book-kb.js
CHANGED
|
@@ -108,7 +108,11 @@ export async function queryBookKnowledge(projectRoot, query, opts = {}) {
|
|
|
108
108
|
const terms = query.split(/\s+/).map((t) => t.replace(/[^\p{L}\p{N}]+/gu, '')).filter(Boolean);
|
|
109
109
|
if (terms.length === 0)
|
|
110
110
|
return { hits: [] };
|
|
111
|
-
|
|
111
|
+
// Default `all` (AND) — precise search for `dz recall --books`. `any` (OR) — recall-friendly for
|
|
112
|
+
// grounding, where a natural-language prompt carries some terms not in the KB (a verb, filler):
|
|
113
|
+
// AND-ing them all would return 0, so OR lets the matching terms surface KUs, FTS5-rank-ordered.
|
|
114
|
+
const joiner = opts.match === 'any' ? ' OR ' : ' AND ';
|
|
115
|
+
const match = terms.map((t) => `"${t}"*`).join(joiner);
|
|
112
116
|
const rows = (opts.book !== undefined
|
|
113
117
|
? db.prepare('SELECT book, ku_id, type, name, problem, content, chapter, pages FROM book_knowledge WHERE book_knowledge MATCH ? AND book = ? ORDER BY rank LIMIT ?').all(match, opts.book, limit)
|
|
114
118
|
: db.prepare('SELECT book, ku_id, type, name, problem, content, chapter, pages FROM book_knowledge WHERE book_knowledge MATCH ? ORDER BY rank LIMIT ?').all(match, limit));
|
package/dist/book-kb.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"book-kb.js","sourceRoot":"","sources":["../src/book-kb.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"book-kb.js","sourceRoot":"","sources":["../src/book-kb.ts"],"names":[],"mappings":"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"}
|
package/dist/brain.d.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge Brain (ADR-001 `features/book-brain`, Phase P0) — the durable, cross-project home that
|
|
3
|
+
* accretes digitized-book Knowledge Units from many projects into ONE shared, queryable brain.
|
|
4
|
+
*
|
|
5
|
+
* **Reuse-first by design (P0's whole point):** this module does NOT reimplement storage. It
|
|
6
|
+
* repoints the already-shipped primitives at a global brain home:
|
|
7
|
+
* - lexical mirror + idempotent upsert → {@link putBookKnowledge} (`dbPath` = brain books.sqlite)
|
|
8
|
+
* - lexical cross-source query → {@link queryBookKnowledge} (`dbPath` = brain books.sqlite)
|
|
9
|
+
* - vector re-embed + index → {@link indexPatternsToAgentdb} (`dbPath` = brain agentdb.db)
|
|
10
|
+
*
|
|
11
|
+
* All functions are pure/best-effort: they never throw uncontrolled and return honest `error`
|
|
12
|
+
* strings when a store is absent or a dependency cannot be resolved. `addedTs` is passed IN by the
|
|
13
|
+
* caller — core stays clock-free and deterministic-friendly.
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import { type BookKUHit } from './book-kb.js';
|
|
18
|
+
/** The durable, cross-project brain home. `DZ_BRAIN_HOME` overrides `~/.dz/brain`. */
|
|
19
|
+
export declare function brainHome(): string;
|
|
20
|
+
/** Lexical (FTS5) store for the whole brain — all sources, source-tagged. */
|
|
21
|
+
export declare function brainBooksPath(home: string): string;
|
|
22
|
+
/** Vector (ReasoningBank schema + HNSW) store for the whole brain — all sources, source-tagged. */
|
|
23
|
+
export declare function brainAgentdbPath(home: string): string;
|
|
24
|
+
/** Registry manifest — every ingested source with metadata. */
|
|
25
|
+
export declare function brainRegistryPath(home: string): string;
|
|
26
|
+
/** One registered source in the brain (a book, repo, or paper). */
|
|
27
|
+
export interface BrainSource {
|
|
28
|
+
readonly slug: string;
|
|
29
|
+
readonly kind: 'book' | 'repo' | 'paper';
|
|
30
|
+
readonly kuCount: number;
|
|
31
|
+
readonly corpusVersion?: string;
|
|
32
|
+
readonly lang?: string;
|
|
33
|
+
readonly isbn?: string;
|
|
34
|
+
readonly addedTs: string;
|
|
35
|
+
}
|
|
36
|
+
/** The brain registry — the durable list of everything ingested. */
|
|
37
|
+
export interface BrainRegistry {
|
|
38
|
+
readonly version: 1;
|
|
39
|
+
readonly sources: Record<string, BrainSource>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Read the registry from `brain.json`. Returns the empty default if the file is absent or corrupt
|
|
43
|
+
* — never throws (a corrupt/half-written registry must not brick the brain).
|
|
44
|
+
*/
|
|
45
|
+
export declare function readRegistry(home: string): BrainRegistry;
|
|
46
|
+
/** Write the registry to `brain.json`, creating the brain home if absent. Best-effort. */
|
|
47
|
+
export declare function writeRegistry(home: string, reg: BrainRegistry): void;
|
|
48
|
+
/** List every registered source. `home` defaults to {@link brainHome}. */
|
|
49
|
+
export declare function listBrain(home?: string): BrainSource[];
|
|
50
|
+
/**
|
|
51
|
+
* Promote a PROJECT's digitized book KB into the durable cross-project brain (ADR-001 P0
|
|
52
|
+
* `book-brain-register`). Reads the project's lexical `books.sqlite`, groups KUs by book, and for
|
|
53
|
+
* each book mirrors them into the brain's lexical store ({@link putBookKnowledge}) and re-embeds
|
|
54
|
+
* them into the brain's vector store ({@link indexPatternsToAgentdb}), then refreshes the registry.
|
|
55
|
+
*
|
|
56
|
+
* **Non-clobbering:** promoting the same book twice does not duplicate — the lexical upsert keys on
|
|
57
|
+
* `(book, ku_id, corpus_version)` and the vector rows are pre-deleted before re-index.
|
|
58
|
+
*/
|
|
59
|
+
export declare function promoteProjectToBrain(opts: {
|
|
60
|
+
projectRoot: string;
|
|
61
|
+
depsRoot?: string;
|
|
62
|
+
brainHome?: string;
|
|
63
|
+
source?: string;
|
|
64
|
+
addedTs: string;
|
|
65
|
+
}): Promise<{
|
|
66
|
+
sources: string[];
|
|
67
|
+
kus: number;
|
|
68
|
+
error?: string;
|
|
69
|
+
}>;
|
|
70
|
+
/**
|
|
71
|
+
* Cross-source lexical recall over the whole brain — a thin, brain-home-scoped wrapper over
|
|
72
|
+
* {@link queryBookKnowledge}. `source` narrows to one source; default is cross-source. Never throws.
|
|
73
|
+
*/
|
|
74
|
+
export declare function queryBrain(opts: {
|
|
75
|
+
query: string;
|
|
76
|
+
brainHome?: string;
|
|
77
|
+
depsRoot?: string;
|
|
78
|
+
source?: string;
|
|
79
|
+
limit?: number;
|
|
80
|
+
match?: 'all' | 'any';
|
|
81
|
+
}): Promise<{
|
|
82
|
+
hits: BookKUHit[];
|
|
83
|
+
error?: string;
|
|
84
|
+
}>;
|
|
85
|
+
/**
|
|
86
|
+
* The grounding-enforcement hook entrypoint (ADR-001 §7, P1). Given a user prompt, deterministically
|
|
87
|
+
* builds a GROUNDING DIRECTIVE block from the brain's top lexical hits — the mechanical half of
|
|
88
|
+
* ruvnet-brain's "answer from source, not drift" (the agent honoring it is the soft, agent-enforced
|
|
89
|
+
* half, §7.2). Best-effort and **silent by design**: grounding must never inject noise or block a
|
|
90
|
+
* prompt, so any generic prompt, empty brain, store error, or thrown exception yields
|
|
91
|
+
* `{ emitted:false, block:'', hitCount:0 }` rather than an error to the user.
|
|
92
|
+
*
|
|
93
|
+
* **Relevance gate (P1):** `≥ 1 content term AND ≥ 1 lexical hit` under OR/any-term matching. The
|
|
94
|
+
* query uses `match:'any'` (OR), not AND: a natural-language prompt carries terms not in the KB
|
|
95
|
+
* (a verb like "проектирую", filler), and AND-ing them all returns 0 even when the topical terms
|
|
96
|
+
* (репликация, кворум) match — the too-strict gate that made real prompts silent. OR lets the
|
|
97
|
+
* matching terms surface KUs, FTS5-rank-ordered; the stopword filter still keeps "how are you"
|
|
98
|
+
* silent (no content terms). A numeric `--min-score` threshold (§7.1/§7.3) is deferred to **P3**:
|
|
99
|
+
* FTS5's `rank` isn't exposed and a meaningful score needs the vector (cosine) path the sync hook
|
|
100
|
+
* doesn't run. Until then, "≥1 content-term OR-hit clears the gate" is the honest P1 rule.
|
|
101
|
+
*/
|
|
102
|
+
export declare function groundPrompt(opts: {
|
|
103
|
+
prompt: string;
|
|
104
|
+
brainHome?: string;
|
|
105
|
+
depsRoot?: string;
|
|
106
|
+
k?: number;
|
|
107
|
+
source?: string;
|
|
108
|
+
}): Promise<{
|
|
109
|
+
emitted: boolean;
|
|
110
|
+
block: string;
|
|
111
|
+
hitCount: number;
|
|
112
|
+
error?: string;
|
|
113
|
+
}>;
|
|
114
|
+
//# sourceMappingURL=brain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brain.d.ts","sourceRoot":"","sources":["../src/brain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,OAAO,EAAiE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAK7G,sFAAsF;AACtF,wBAAgB,SAAS,IAAI,MAAM,CAGlC;AAED,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,mGAAmG;AACnG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAID,mEAAmE;AACnE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,oEAAoE;AACpE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CAC/C;AAMD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAgBxD;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,GAAG,IAAI,CAGpE;AAED,0EAA0E;AAC1E,wBAAgB,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE,CAEtD;AAwHD;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAuF9D;AAID;;;GAGG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;CACvB,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAQjD;AAmDD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAkDjF"}
|
package/dist/brain.js
ADDED
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge Brain (ADR-001 `features/book-brain`, Phase P0) — the durable, cross-project home that
|
|
3
|
+
* accretes digitized-book Knowledge Units from many projects into ONE shared, queryable brain.
|
|
4
|
+
*
|
|
5
|
+
* **Reuse-first by design (P0's whole point):** this module does NOT reimplement storage. It
|
|
6
|
+
* repoints the already-shipped primitives at a global brain home:
|
|
7
|
+
* - lexical mirror + idempotent upsert → {@link putBookKnowledge} (`dbPath` = brain books.sqlite)
|
|
8
|
+
* - lexical cross-source query → {@link queryBookKnowledge} (`dbPath` = brain books.sqlite)
|
|
9
|
+
* - vector re-embed + index → {@link indexPatternsToAgentdb} (`dbPath` = brain agentdb.db)
|
|
10
|
+
*
|
|
11
|
+
* All functions are pure/best-effort: they never throw uncontrolled and return honest `error`
|
|
12
|
+
* strings when a store is absent or a dependency cannot be resolved. `addedTs` is passed IN by the
|
|
13
|
+
* caller — core stays clock-free and deterministic-friendly.
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
import { homedir } from 'node:os';
|
|
19
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
20
|
+
import { pathToFileURL } from 'node:url';
|
|
21
|
+
import { createRequire } from 'node:module';
|
|
22
|
+
import { putBookKnowledge, queryBookKnowledge, bookKbPath } from './book-kb.js';
|
|
23
|
+
import { indexPatternsToAgentdb } from './agentdb-index.js';
|
|
24
|
+
// ─────────────────────────────────────── Home & paths ───────────────────────────────────────
|
|
25
|
+
/** The durable, cross-project brain home. `DZ_BRAIN_HOME` overrides `~/.dz/brain`. */
|
|
26
|
+
export function brainHome() {
|
|
27
|
+
const env = process.env['DZ_BRAIN_HOME'];
|
|
28
|
+
return env !== undefined && env !== '' ? env : join(homedir(), '.dz', 'brain');
|
|
29
|
+
}
|
|
30
|
+
/** Lexical (FTS5) store for the whole brain — all sources, source-tagged. */
|
|
31
|
+
export function brainBooksPath(home) {
|
|
32
|
+
return join(home, 'books.sqlite');
|
|
33
|
+
}
|
|
34
|
+
/** Vector (ReasoningBank schema + HNSW) store for the whole brain — all sources, source-tagged. */
|
|
35
|
+
export function brainAgentdbPath(home) {
|
|
36
|
+
return join(home, 'agentdb.db');
|
|
37
|
+
}
|
|
38
|
+
/** Registry manifest — every ingested source with metadata. */
|
|
39
|
+
export function brainRegistryPath(home) {
|
|
40
|
+
return join(home, 'brain.json');
|
|
41
|
+
}
|
|
42
|
+
function defaultRegistry() {
|
|
43
|
+
return { version: 1, sources: {} };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Read the registry from `brain.json`. Returns the empty default if the file is absent or corrupt
|
|
47
|
+
* — never throws (a corrupt/half-written registry must not brick the brain).
|
|
48
|
+
*/
|
|
49
|
+
export function readRegistry(home) {
|
|
50
|
+
const path = brainRegistryPath(home);
|
|
51
|
+
if (!existsSync(path))
|
|
52
|
+
return defaultRegistry();
|
|
53
|
+
try {
|
|
54
|
+
const parsed = JSON.parse(readFileSync(path, 'utf8'));
|
|
55
|
+
if (parsed !== null && typeof parsed === 'object' &&
|
|
56
|
+
typeof parsed.sources === 'object' &&
|
|
57
|
+
parsed.sources !== null) {
|
|
58
|
+
return { version: 1, sources: parsed.sources };
|
|
59
|
+
}
|
|
60
|
+
return defaultRegistry();
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return defaultRegistry();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Write the registry to `brain.json`, creating the brain home if absent. Best-effort. */
|
|
67
|
+
export function writeRegistry(home, reg) {
|
|
68
|
+
mkdirSync(home, { recursive: true });
|
|
69
|
+
writeFileSync(brainRegistryPath(home), `${JSON.stringify(reg, null, 2)}\n`);
|
|
70
|
+
}
|
|
71
|
+
/** List every registered source. `home` defaults to {@link brainHome}. */
|
|
72
|
+
export function listBrain(home) {
|
|
73
|
+
return Object.values(readRegistry(home ?? brainHome()).sources);
|
|
74
|
+
}
|
|
75
|
+
/** Resolve the project's `better-sqlite3` from `depsRoot` (matches the reused primitives). */
|
|
76
|
+
function resolveSqlite(depsRoot) {
|
|
77
|
+
try {
|
|
78
|
+
const req = createRequire(join(depsRoot, 'package.json'));
|
|
79
|
+
return { url: pathToFileURL(req.resolve('better-sqlite3')).href };
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return { error: 'better-sqlite3 not installed (run: dz setup --memory agentdb)' };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/** Read the project's lexical book KB (all rows, or one `source`). Best-effort; honest errors. */
|
|
86
|
+
async function readProjectRows(depsRoot, projectDbPath, source) {
|
|
87
|
+
const sqlite = resolveSqlite(depsRoot);
|
|
88
|
+
if ('error' in sqlite)
|
|
89
|
+
return { error: sqlite.error };
|
|
90
|
+
try {
|
|
91
|
+
const { default: Database } = (await import(sqlite.url));
|
|
92
|
+
const db = new Database(projectDbPath, { readonly: true });
|
|
93
|
+
try {
|
|
94
|
+
const cols = 'book, ku_id, corpus_version, type, name, problem, content, chapter, pages, metadata';
|
|
95
|
+
const rows = (source !== undefined
|
|
96
|
+
? db.prepare(`SELECT ${cols} FROM book_knowledge WHERE book = ?`).all(source)
|
|
97
|
+
: db.prepare(`SELECT ${cols} FROM book_knowledge`).all());
|
|
98
|
+
return { rows };
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
db.close();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
return { error: `read project book KB failed: ${err instanceof Error ? err.message : String(err)}` };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* The vector primitive is insert-only, so before re-indexing a book we delete its existing brain
|
|
110
|
+
* vector rows — mirroring the reindex approach. Best-effort: a missing store/table is a no-op.
|
|
111
|
+
* `foreign_keys = ON` makes the embeddings cascade with the pattern rows.
|
|
112
|
+
*/
|
|
113
|
+
async function deleteBrainVectors(depsRoot, agentdbPath, book) {
|
|
114
|
+
if (!existsSync(agentdbPath))
|
|
115
|
+
return; // nothing indexed yet
|
|
116
|
+
const sqlite = resolveSqlite(depsRoot);
|
|
117
|
+
if ('error' in sqlite)
|
|
118
|
+
return;
|
|
119
|
+
try {
|
|
120
|
+
const { default: Database } = (await import(sqlite.url));
|
|
121
|
+
const db = new Database(agentdbPath);
|
|
122
|
+
try {
|
|
123
|
+
db.pragma('busy_timeout = 5000');
|
|
124
|
+
db.pragma('foreign_keys = ON');
|
|
125
|
+
db.prepare("DELETE FROM reasoning_patterns WHERE task_type = 'book-knowledge' AND tags LIKE ?").run(`%"${book}"%`);
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
db.close();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
/* best-effort: table may not exist yet, or store is cold */
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// ──────────────────────────────────────── Promote ───────────────────────────────────────────
|
|
136
|
+
function jsonObj(s) {
|
|
137
|
+
if (s === null)
|
|
138
|
+
return {};
|
|
139
|
+
try {
|
|
140
|
+
const v = JSON.parse(s);
|
|
141
|
+
return v !== null && typeof v === 'object' ? v : {};
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return {};
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function jsonPages(s) {
|
|
148
|
+
if (s === null)
|
|
149
|
+
return undefined;
|
|
150
|
+
try {
|
|
151
|
+
const v = JSON.parse(s);
|
|
152
|
+
return Array.isArray(v) ? v : undefined;
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/** Map a KU's declared `worth` to an honest vector score. Unknown/absent → 0.5 (no fabrication). */
|
|
159
|
+
function worthScore(meta) {
|
|
160
|
+
switch (meta['worth']) {
|
|
161
|
+
case 'high':
|
|
162
|
+
return 0.9;
|
|
163
|
+
case 'medium':
|
|
164
|
+
return 0.6;
|
|
165
|
+
case 'low':
|
|
166
|
+
return 0.3;
|
|
167
|
+
default:
|
|
168
|
+
return 0.5;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Promote a PROJECT's digitized book KB into the durable cross-project brain (ADR-001 P0
|
|
173
|
+
* `book-brain-register`). Reads the project's lexical `books.sqlite`, groups KUs by book, and for
|
|
174
|
+
* each book mirrors them into the brain's lexical store ({@link putBookKnowledge}) and re-embeds
|
|
175
|
+
* them into the brain's vector store ({@link indexPatternsToAgentdb}), then refreshes the registry.
|
|
176
|
+
*
|
|
177
|
+
* **Non-clobbering:** promoting the same book twice does not duplicate — the lexical upsert keys on
|
|
178
|
+
* `(book, ku_id, corpus_version)` and the vector rows are pre-deleted before re-index.
|
|
179
|
+
*/
|
|
180
|
+
export async function promoteProjectToBrain(opts) {
|
|
181
|
+
const home = opts.brainHome ?? brainHome();
|
|
182
|
+
const depsRoot = opts.depsRoot ?? opts.projectRoot;
|
|
183
|
+
const projectDbPath = bookKbPath(opts.projectRoot);
|
|
184
|
+
if (!existsSync(projectDbPath))
|
|
185
|
+
return { sources: [], kus: 0, error: 'no project book KB' };
|
|
186
|
+
const read = await readProjectRows(depsRoot, projectDbPath, opts.source);
|
|
187
|
+
if ('error' in read)
|
|
188
|
+
return { sources: [], kus: 0, error: read.error };
|
|
189
|
+
if (read.rows.length === 0)
|
|
190
|
+
return { sources: [], kus: 0 };
|
|
191
|
+
// Group rows by book (each book is one promote unit + one registry entry).
|
|
192
|
+
const byBook = new Map();
|
|
193
|
+
for (const r of read.rows) {
|
|
194
|
+
const bucket = byBook.get(r.book);
|
|
195
|
+
if (bucket)
|
|
196
|
+
bucket.push(r);
|
|
197
|
+
else
|
|
198
|
+
byBook.set(r.book, [r]);
|
|
199
|
+
}
|
|
200
|
+
const reg = readRegistry(home);
|
|
201
|
+
const sources = { ...reg.sources };
|
|
202
|
+
const promoted = [];
|
|
203
|
+
let totalKus = 0;
|
|
204
|
+
let firstError;
|
|
205
|
+
for (const [book, rows] of byBook) {
|
|
206
|
+
// 1. Lexical mirror — reuse the idempotent upsert, pointed at the brain store.
|
|
207
|
+
const kus = rows.map((r) => {
|
|
208
|
+
const pages = jsonPages(r.pages);
|
|
209
|
+
const meta = jsonObj(r.metadata);
|
|
210
|
+
return {
|
|
211
|
+
book: r.book,
|
|
212
|
+
kuId: r.ku_id,
|
|
213
|
+
corpusVersion: r.corpus_version,
|
|
214
|
+
type: r.type,
|
|
215
|
+
name: r.name,
|
|
216
|
+
problem: r.problem,
|
|
217
|
+
content: r.content,
|
|
218
|
+
...(r.chapter !== null ? { chapter: r.chapter } : {}),
|
|
219
|
+
...(pages !== undefined ? { pages } : {}),
|
|
220
|
+
...(Object.keys(meta).length > 0 ? { metadata: meta } : {}),
|
|
221
|
+
};
|
|
222
|
+
});
|
|
223
|
+
const lex = await putBookKnowledge(depsRoot, kus, { dbPath: brainBooksPath(home) });
|
|
224
|
+
if (lex.error !== undefined && firstError === undefined)
|
|
225
|
+
firstError = lex.error;
|
|
226
|
+
// 2. Vector re-embed — pre-delete this book's stale vectors (insert-only primitive), then index.
|
|
227
|
+
await deleteBrainVectors(depsRoot, brainAgentdbPath(home), book);
|
|
228
|
+
const vecRows = rows.map((r) => {
|
|
229
|
+
const meta = jsonObj(r.metadata);
|
|
230
|
+
return {
|
|
231
|
+
taskType: 'book-knowledge',
|
|
232
|
+
text: `${r.name}: ${r.problem}`,
|
|
233
|
+
score: worthScore(meta),
|
|
234
|
+
tags: ['book', r.book, r.type],
|
|
235
|
+
metadata: {
|
|
236
|
+
chapter: r.chapter,
|
|
237
|
+
pages: jsonPages(r.pages) ?? null,
|
|
238
|
+
ku_id: r.ku_id,
|
|
239
|
+
corpus_version: r.corpus_version,
|
|
240
|
+
},
|
|
241
|
+
};
|
|
242
|
+
});
|
|
243
|
+
const vec = await indexPatternsToAgentdb(depsRoot, vecRows, { dbPath: brainAgentdbPath(home) });
|
|
244
|
+
if (vec.error !== undefined && firstError === undefined)
|
|
245
|
+
firstError = vec.error;
|
|
246
|
+
// 3. Registry entry for this book — corpus_version/lang/isbn from the first row's metadata.
|
|
247
|
+
const meta0 = jsonObj(rows[0].metadata);
|
|
248
|
+
const corpusVersion = rows[0].corpus_version;
|
|
249
|
+
const lang = typeof meta0['lang'] === 'string' ? meta0['lang'] : undefined;
|
|
250
|
+
const isbn = typeof meta0['isbn'] === 'string' ? meta0['isbn'] : undefined;
|
|
251
|
+
sources[book] = {
|
|
252
|
+
slug: book,
|
|
253
|
+
kind: 'book',
|
|
254
|
+
kuCount: rows.length,
|
|
255
|
+
addedTs: opts.addedTs,
|
|
256
|
+
...(corpusVersion !== undefined && corpusVersion !== '' ? { corpusVersion } : {}),
|
|
257
|
+
...(lang !== undefined ? { lang } : {}),
|
|
258
|
+
...(isbn !== undefined ? { isbn } : {}),
|
|
259
|
+
};
|
|
260
|
+
promoted.push(book);
|
|
261
|
+
totalKus += rows.length;
|
|
262
|
+
}
|
|
263
|
+
writeRegistry(home, { version: 1, sources });
|
|
264
|
+
return firstError !== undefined
|
|
265
|
+
? { sources: promoted, kus: totalKus, error: firstError }
|
|
266
|
+
: { sources: promoted, kus: totalKus };
|
|
267
|
+
}
|
|
268
|
+
// ───────────────────────────────────────── Query ────────────────────────────────────────────
|
|
269
|
+
/**
|
|
270
|
+
* Cross-source lexical recall over the whole brain — a thin, brain-home-scoped wrapper over
|
|
271
|
+
* {@link queryBookKnowledge}. `source` narrows to one source; default is cross-source. Never throws.
|
|
272
|
+
*/
|
|
273
|
+
export async function queryBrain(opts) {
|
|
274
|
+
const home = opts.brainHome ?? brainHome();
|
|
275
|
+
const depsRoot = opts.depsRoot ?? process.cwd();
|
|
276
|
+
const qopts = { dbPath: brainBooksPath(home) };
|
|
277
|
+
if (opts.source !== undefined)
|
|
278
|
+
qopts.book = opts.source;
|
|
279
|
+
if (opts.limit !== undefined)
|
|
280
|
+
qopts.limit = opts.limit;
|
|
281
|
+
if (opts.match !== undefined)
|
|
282
|
+
qopts.match = opts.match;
|
|
283
|
+
return queryBookKnowledge(depsRoot, opts.query, qopts);
|
|
284
|
+
}
|
|
285
|
+
// ──────────────────────────────────────── Grounding ─────────────────────────────────────────
|
|
286
|
+
/**
|
|
287
|
+
* A small bilingual (RU+EN) stopword list. Deliberately tiny — the goal is only to strip the most
|
|
288
|
+
* common glue words so the residual tokens are CONTENT terms worth grounding on, not to do real NLP.
|
|
289
|
+
*/
|
|
290
|
+
const STOPWORDS = new Set([
|
|
291
|
+
// EN
|
|
292
|
+
'the', 'and', 'for', 'are', 'but', 'not', 'you', 'all', 'any', 'can', 'her', 'was', 'one',
|
|
293
|
+
'our', 'out', 'has', 'had', 'his', 'how', 'its', 'who', 'get', 'got', 'use', 'via', 'per',
|
|
294
|
+
'with', 'this', 'that', 'from', 'into', 'over', 'your', 'they', 'them', 'then', 'than', 'have',
|
|
295
|
+
'will', 'what', 'when', 'why', 'where', 'which', 'about', 'would', 'should', 'could', 'does',
|
|
296
|
+
'did', 'yes', 'no', 'or', 'a', 'an', 'of', 'to', 'in', 'on', 'is', 'it', 'be', 'as', 'at', 'by',
|
|
297
|
+
// RU
|
|
298
|
+
'и', 'в', 'на', 'как', 'для', 'что', 'это', 'или', 'но', 'же', 'то', 'по', 'из', 'за', 'от',
|
|
299
|
+
'до', 'со', 'об', 'при', 'без', 'над', 'под', 'про', 'так', 'уже', 'еще', 'ещё', 'вот', 'бы',
|
|
300
|
+
'ли', 'не', 'ни', 'да', 'нет', 'мне', 'мой', 'моя', 'вы', 'ты', 'он', 'она', 'они', 'оно',
|
|
301
|
+
'кто', 'где', 'чем', 'чей', 'быть', 'если', 'чтобы', 'этот', 'эта', 'эти', 'все', 'всё', 'меня',
|
|
302
|
+
]);
|
|
303
|
+
/**
|
|
304
|
+
* Extract meaningful CONTENT TERMS from a prompt: lowercase, keep `\p{L}\p{N}` tokens of length ≥ 3,
|
|
305
|
+
* and drop the small RU+EN stopword list. Deterministic; deduped preserving first-seen order.
|
|
306
|
+
*/
|
|
307
|
+
function contentTerms(prompt) {
|
|
308
|
+
const seen = new Set();
|
|
309
|
+
const out = [];
|
|
310
|
+
// Split on anything that is not a Unicode letter or number (handles RU + EN + punctuation).
|
|
311
|
+
for (const raw of prompt.toLowerCase().split(/[^\p{L}\p{N}]+/u)) {
|
|
312
|
+
if (raw.length < 3)
|
|
313
|
+
continue;
|
|
314
|
+
if (STOPWORDS.has(raw))
|
|
315
|
+
continue;
|
|
316
|
+
if (seen.has(raw))
|
|
317
|
+
continue;
|
|
318
|
+
seen.add(raw);
|
|
319
|
+
out.push(raw);
|
|
320
|
+
}
|
|
321
|
+
return out;
|
|
322
|
+
}
|
|
323
|
+
/** Clamp a snippet to a max length, collapsing whitespace, with an ellipsis when truncated. */
|
|
324
|
+
function snippet(s, max = 160) {
|
|
325
|
+
const flat = s.replace(/\s+/g, ' ').trim();
|
|
326
|
+
return flat.length <= max ? flat : `${flat.slice(0, max - 1).trimEnd()}…`;
|
|
327
|
+
}
|
|
328
|
+
/** The directive line prepended to every grounding block (§7.1). */
|
|
329
|
+
const GROUNDING_DIRECTIVE = 'Ground your answer in the KNOWLEDGE BRAIN below; prefer these ingested sources over ' +
|
|
330
|
+
'training-data recall; cite [Kn] source+page per claim; if the brain is silent on a point, say so.';
|
|
331
|
+
/**
|
|
332
|
+
* The grounding-enforcement hook entrypoint (ADR-001 §7, P1). Given a user prompt, deterministically
|
|
333
|
+
* builds a GROUNDING DIRECTIVE block from the brain's top lexical hits — the mechanical half of
|
|
334
|
+
* ruvnet-brain's "answer from source, not drift" (the agent honoring it is the soft, agent-enforced
|
|
335
|
+
* half, §7.2). Best-effort and **silent by design**: grounding must never inject noise or block a
|
|
336
|
+
* prompt, so any generic prompt, empty brain, store error, or thrown exception yields
|
|
337
|
+
* `{ emitted:false, block:'', hitCount:0 }` rather than an error to the user.
|
|
338
|
+
*
|
|
339
|
+
* **Relevance gate (P1):** `≥ 1 content term AND ≥ 1 lexical hit` under OR/any-term matching. The
|
|
340
|
+
* query uses `match:'any'` (OR), not AND: a natural-language prompt carries terms not in the KB
|
|
341
|
+
* (a verb like "проектирую", filler), and AND-ing them all returns 0 even when the topical terms
|
|
342
|
+
* (репликация, кворум) match — the too-strict gate that made real prompts silent. OR lets the
|
|
343
|
+
* matching terms surface KUs, FTS5-rank-ordered; the stopword filter still keeps "how are you"
|
|
344
|
+
* silent (no content terms). A numeric `--min-score` threshold (§7.1/§7.3) is deferred to **P3**:
|
|
345
|
+
* FTS5's `rank` isn't exposed and a meaningful score needs the vector (cosine) path the sync hook
|
|
346
|
+
* doesn't run. Until then, "≥1 content-term OR-hit clears the gate" is the honest P1 rule.
|
|
347
|
+
*/
|
|
348
|
+
export async function groundPrompt(opts) {
|
|
349
|
+
const silent = { emitted: false, block: '', hitCount: 0 };
|
|
350
|
+
try {
|
|
351
|
+
// Gate 1: at least one CONTENT term (all-stopword prompts like "how are you" → silent).
|
|
352
|
+
const terms = contentTerms(opts.prompt ?? '');
|
|
353
|
+
if (terms.length < 1)
|
|
354
|
+
return silent;
|
|
355
|
+
// Best-effort OR/any-term lexical recall over the whole brain. Never throws. `match:'any'` so a
|
|
356
|
+
// matching topical term surfaces KUs even when other prompt terms (a verb, filler) miss — the
|
|
357
|
+
// fix for real-prompt silence (AND required every term to co-occur). Rank ordering + top-K keep
|
|
358
|
+
// it precise; the stopword filter keeps generic prompts silent.
|
|
359
|
+
const query = {
|
|
360
|
+
query: terms.join(' '),
|
|
361
|
+
limit: opts.k ?? 5,
|
|
362
|
+
match: 'any',
|
|
363
|
+
};
|
|
364
|
+
if (opts.brainHome !== undefined)
|
|
365
|
+
query.brainHome = opts.brainHome;
|
|
366
|
+
if (opts.depsRoot !== undefined)
|
|
367
|
+
query.depsRoot = opts.depsRoot;
|
|
368
|
+
if (opts.source !== undefined)
|
|
369
|
+
query.source = opts.source;
|
|
370
|
+
const res = await queryBrain(query);
|
|
371
|
+
// Gate 2: any lexical hit? On error or zero hits, stay silent (no noise, no block).
|
|
372
|
+
if (res.error !== undefined)
|
|
373
|
+
return silent;
|
|
374
|
+
if (res.hits.length === 0)
|
|
375
|
+
return silent;
|
|
376
|
+
// Gate 3 — COVERAGE (the OR balance): OR recall alone over-fires when a single common term
|
|
377
|
+
// ("today", "data") incidentally matches a KU. Require the retrieved hits to actually cover the
|
|
378
|
+
// prompt's intent: for a single-content-term prompt ("кворум") one hit suffices; for a
|
|
379
|
+
// multi-term prompt, ≥2 DISTINCT content terms must prefix-appear in the hit set — so an
|
|
380
|
+
// off-topic prompt whose only matching word is incidental ("weather today" → only "today"
|
|
381
|
+
// matches) stays silent, while a real one ("репликацию single multi leader" → 4 covered) grounds.
|
|
382
|
+
if (terms.length >= 2) {
|
|
383
|
+
const hay = res.hits.map((h) => `${h.name} ${h.problem} ${h.content}`.toLowerCase()).join(' ');
|
|
384
|
+
const covered = terms.filter((t) => hay.includes(t.toLowerCase())).length;
|
|
385
|
+
if (covered < 2)
|
|
386
|
+
return silent;
|
|
387
|
+
}
|
|
388
|
+
// Build the GROUNDING DIRECTIVE block (§7.1): directive line + numbered citations.
|
|
389
|
+
const lines = [GROUNDING_DIRECTIVE, ''];
|
|
390
|
+
res.hits.forEach((h, i) => {
|
|
391
|
+
const ch = h.chapter !== undefined && h.chapter !== '' ? ` гл.${h.chapter}` : '';
|
|
392
|
+
const pg = h.pages !== undefined && h.pages.length > 0 ? ` с.${h.pages.join('–')}` : '';
|
|
393
|
+
const body = snippet(h.problem !== '' ? h.problem : h.content);
|
|
394
|
+
lines.push(`[K${i + 1}] ${h.book}${ch}${pg} — ${h.name}: ${body}`);
|
|
395
|
+
});
|
|
396
|
+
return { emitted: true, block: lines.join('\n'), hitCount: res.hits.length };
|
|
397
|
+
}
|
|
398
|
+
catch {
|
|
399
|
+
// Grounding is advisory — a bug here must never surface to the user or block the prompt.
|
|
400
|
+
return silent;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
//# sourceMappingURL=brain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brain.js","sourceRoot":"","sources":["../src/brain.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -26,6 +26,8 @@ export { runSetup, generateHooksConfig, generateAgentdbWriter, writerVersionOf,
|
|
|
26
26
|
export { indexPatternsToAgentdb, resolveAgentdbPath } from './agentdb-index.js';
|
|
27
27
|
export { putBookKnowledge, queryBookKnowledge, bookKbPath } from './book-kb.js';
|
|
28
28
|
export type { BookKU, BookKUHit } from './book-kb.js';
|
|
29
|
+
export { brainHome, brainBooksPath, brainAgentdbPath, brainRegistryPath, readRegistry, writeRegistry, listBrain, promoteProjectToBrain, queryBrain, groundPrompt, } from './brain.js';
|
|
30
|
+
export type { BrainRegistry, BrainSource } from './brain.js';
|
|
29
31
|
export type { AgentdbRow, AgentdbIndexResult } from './agentdb-index.js';
|
|
30
32
|
export { generatePlugin } from './plugin.js';
|
|
31
33
|
export type { PluginManifest } from './plugin.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -22,6 +22,7 @@ export { loadPatterns, loadSessions, computePatternBoost, readLearningConfig, BO
|
|
|
22
22
|
export { runSetup, generateHooksConfig, generateAgentdbWriter, writerVersionOf, AGENTDB_WRITER_VERSION } from './setup.js';
|
|
23
23
|
export { indexPatternsToAgentdb, resolveAgentdbPath } from './agentdb-index.js';
|
|
24
24
|
export { putBookKnowledge, queryBookKnowledge, bookKbPath } from './book-kb.js';
|
|
25
|
+
export { brainHome, brainBooksPath, brainAgentdbPath, brainRegistryPath, readRegistry, writeRegistry, listBrain, promoteProjectToBrain, queryBrain, groundPrompt, } from './brain.js';
|
|
25
26
|
export { generatePlugin } from './plugin.js';
|
|
26
27
|
export { discoverPackages, publishPackages, bumpPatch, compareVersions, findUnpackagedSkills, orderByDependencies, syncReadmeVersion } from './publish.js';
|
|
27
28
|
export { fetchAllDownloads } from './downloads.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,mFAAmF;AACnF,MAAM,CAAC,MAAM,oBAAoB,GAC9B,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAyB,CAAC,OAAO,CAAC;AAErF,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAElH,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC1H,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,qBAAqB,EAAE,eAAe,EAAE,eAAe,EAAE,mBAAmB,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEhP,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAC3H,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,mFAAmF;AACnF,MAAM,CAAC,MAAM,oBAAoB,GAC9B,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAyB,CAAC,OAAO,CAAC;AAErF,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAElH,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC1H,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,SAAS,EAAE,aAAa,EAAE,qBAAqB,EAAE,eAAe,EAAE,eAAe,EAAE,mBAAmB,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEhP,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAC3H,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEhF,OAAO,EACL,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,SAAS,EACT,qBAAqB,EACrB,UAAU,EACV,YAAY,GACb,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAK7C,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,SAAS,EAAE,eAAe,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC3J,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EACL,YAAY,EACZ,UAAU,EACV,cAAc,EACd,SAAS,EACT,cAAc,EACd,cAAc,EACd,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAS3B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,mBAAmB,EACnB,cAAc,EACd,QAAQ,GACT,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dzhechkov/harness-core",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.50",
|
|
4
4
|
"description": "Shared harness logic - skill loading, additive apply, and the init/sync/verify/doctor operations.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"@dzhechkov/adapter-opencode": "^0.2.0",
|
|
32
32
|
"yaml": "^2.0.0",
|
|
33
33
|
"@dzhechkov/adapter-copilot": "0.1.1",
|
|
34
|
-
"@dzhechkov/
|
|
35
|
-
"@dzhechkov/
|
|
34
|
+
"@dzhechkov/memory": "0.2.7",
|
|
35
|
+
"@dzhechkov/core": "0.2.4"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": "^25.6.0",
|
package/src/book-kb.ts
CHANGED
|
@@ -135,7 +135,7 @@ export async function putBookKnowledge(
|
|
|
135
135
|
export async function queryBookKnowledge(
|
|
136
136
|
projectRoot: string,
|
|
137
137
|
query: string,
|
|
138
|
-
opts: { limit?: number; book?: string; dbPath?: string } = {},
|
|
138
|
+
opts: { limit?: number; book?: string; dbPath?: string; match?: 'all' | 'any' } = {},
|
|
139
139
|
): Promise<{ hits: BookKUHit[]; error?: string }> {
|
|
140
140
|
const path = opts.dbPath ?? bookKbPath(projectRoot);
|
|
141
141
|
if (!existsSync(path)) return { hits: [] };
|
|
@@ -155,7 +155,11 @@ export async function queryBookKnowledge(
|
|
|
155
155
|
// no MATCH (return no hits) rather than an FTS5 error.
|
|
156
156
|
const terms = query.split(/\s+/).map((t) => t.replace(/[^\p{L}\p{N}]+/gu, '')).filter(Boolean);
|
|
157
157
|
if (terms.length === 0) return { hits: [] };
|
|
158
|
-
|
|
158
|
+
// Default `all` (AND) — precise search for `dz recall --books`. `any` (OR) — recall-friendly for
|
|
159
|
+
// grounding, where a natural-language prompt carries some terms not in the KB (a verb, filler):
|
|
160
|
+
// AND-ing them all would return 0, so OR lets the matching terms surface KUs, FTS5-rank-ordered.
|
|
161
|
+
const joiner = opts.match === 'any' ? ' OR ' : ' AND ';
|
|
162
|
+
const match = terms.map((t) => `"${t}"*`).join(joiner);
|
|
159
163
|
const rows = (opts.book !== undefined
|
|
160
164
|
? db.prepare('SELECT book, ku_id, type, name, problem, content, chapter, pages FROM book_knowledge WHERE book_knowledge MATCH ? AND book = ? ORDER BY rank LIMIT ?').all(match, opts.book, limit)
|
|
161
165
|
: db.prepare('SELECT book, ku_id, type, name, problem, content, chapter, pages FROM book_knowledge WHERE book_knowledge MATCH ? ORDER BY rank LIMIT ?').all(match, limit)
|
package/src/brain.ts
ADDED
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge Brain (ADR-001 `features/book-brain`, Phase P0) — the durable, cross-project home that
|
|
3
|
+
* accretes digitized-book Knowledge Units from many projects into ONE shared, queryable brain.
|
|
4
|
+
*
|
|
5
|
+
* **Reuse-first by design (P0's whole point):** this module does NOT reimplement storage. It
|
|
6
|
+
* repoints the already-shipped primitives at a global brain home:
|
|
7
|
+
* - lexical mirror + idempotent upsert → {@link putBookKnowledge} (`dbPath` = brain books.sqlite)
|
|
8
|
+
* - lexical cross-source query → {@link queryBookKnowledge} (`dbPath` = brain books.sqlite)
|
|
9
|
+
* - vector re-embed + index → {@link indexPatternsToAgentdb} (`dbPath` = brain agentdb.db)
|
|
10
|
+
*
|
|
11
|
+
* All functions are pure/best-effort: they never throw uncontrolled and return honest `error`
|
|
12
|
+
* strings when a store is absent or a dependency cannot be resolved. `addedTs` is passed IN by the
|
|
13
|
+
* caller — core stays clock-free and deterministic-friendly.
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { join } from 'node:path';
|
|
19
|
+
import { homedir } from 'node:os';
|
|
20
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
21
|
+
import { pathToFileURL } from 'node:url';
|
|
22
|
+
import { createRequire } from 'node:module';
|
|
23
|
+
import { putBookKnowledge, queryBookKnowledge, bookKbPath, type BookKU, type BookKUHit } from './book-kb.js';
|
|
24
|
+
import { indexPatternsToAgentdb, type AgentdbRow } from './agentdb-index.js';
|
|
25
|
+
|
|
26
|
+
// ─────────────────────────────────────── Home & paths ───────────────────────────────────────
|
|
27
|
+
|
|
28
|
+
/** The durable, cross-project brain home. `DZ_BRAIN_HOME` overrides `~/.dz/brain`. */
|
|
29
|
+
export function brainHome(): string {
|
|
30
|
+
const env = process.env['DZ_BRAIN_HOME'];
|
|
31
|
+
return env !== undefined && env !== '' ? env : join(homedir(), '.dz', 'brain');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Lexical (FTS5) store for the whole brain — all sources, source-tagged. */
|
|
35
|
+
export function brainBooksPath(home: string): string {
|
|
36
|
+
return join(home, 'books.sqlite');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Vector (ReasoningBank schema + HNSW) store for the whole brain — all sources, source-tagged. */
|
|
40
|
+
export function brainAgentdbPath(home: string): string {
|
|
41
|
+
return join(home, 'agentdb.db');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Registry manifest — every ingested source with metadata. */
|
|
45
|
+
export function brainRegistryPath(home: string): string {
|
|
46
|
+
return join(home, 'brain.json');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// ──────────────────────────────────────── Registry ──────────────────────────────────────────
|
|
50
|
+
|
|
51
|
+
/** One registered source in the brain (a book, repo, or paper). */
|
|
52
|
+
export interface BrainSource {
|
|
53
|
+
readonly slug: string;
|
|
54
|
+
readonly kind: 'book' | 'repo' | 'paper';
|
|
55
|
+
readonly kuCount: number;
|
|
56
|
+
readonly corpusVersion?: string;
|
|
57
|
+
readonly lang?: string;
|
|
58
|
+
readonly isbn?: string;
|
|
59
|
+
readonly addedTs: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** The brain registry — the durable list of everything ingested. */
|
|
63
|
+
export interface BrainRegistry {
|
|
64
|
+
readonly version: 1;
|
|
65
|
+
readonly sources: Record<string, BrainSource>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function defaultRegistry(): BrainRegistry {
|
|
69
|
+
return { version: 1, sources: {} };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Read the registry from `brain.json`. Returns the empty default if the file is absent or corrupt
|
|
74
|
+
* — never throws (a corrupt/half-written registry must not brick the brain).
|
|
75
|
+
*/
|
|
76
|
+
export function readRegistry(home: string): BrainRegistry {
|
|
77
|
+
const path = brainRegistryPath(home);
|
|
78
|
+
if (!existsSync(path)) return defaultRegistry();
|
|
79
|
+
try {
|
|
80
|
+
const parsed = JSON.parse(readFileSync(path, 'utf8')) as unknown;
|
|
81
|
+
if (
|
|
82
|
+
parsed !== null && typeof parsed === 'object' &&
|
|
83
|
+
typeof (parsed as { sources?: unknown }).sources === 'object' &&
|
|
84
|
+
(parsed as { sources?: unknown }).sources !== null
|
|
85
|
+
) {
|
|
86
|
+
return { version: 1, sources: (parsed as BrainRegistry).sources };
|
|
87
|
+
}
|
|
88
|
+
return defaultRegistry();
|
|
89
|
+
} catch {
|
|
90
|
+
return defaultRegistry();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Write the registry to `brain.json`, creating the brain home if absent. Best-effort. */
|
|
95
|
+
export function writeRegistry(home: string, reg: BrainRegistry): void {
|
|
96
|
+
mkdirSync(home, { recursive: true });
|
|
97
|
+
writeFileSync(brainRegistryPath(home), `${JSON.stringify(reg, null, 2)}\n`);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** List every registered source. `home` defaults to {@link brainHome}. */
|
|
101
|
+
export function listBrain(home?: string): BrainSource[] {
|
|
102
|
+
return Object.values(readRegistry(home ?? brainHome()).sources);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// ─────────────────────────────────── Native SQLite helpers ──────────────────────────────────
|
|
106
|
+
|
|
107
|
+
interface NativeDb {
|
|
108
|
+
pragma: (s: string) => void;
|
|
109
|
+
prepare: (q: string) => { run: (...a: unknown[]) => unknown; all: (...a: unknown[]) => unknown[] };
|
|
110
|
+
close: () => void;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Resolve the project's `better-sqlite3` from `depsRoot` (matches the reused primitives). */
|
|
114
|
+
function resolveSqlite(depsRoot: string): { url: string } | { error: string } {
|
|
115
|
+
try {
|
|
116
|
+
const req = createRequire(join(depsRoot, 'package.json'));
|
|
117
|
+
return { url: pathToFileURL(req.resolve('better-sqlite3')).href };
|
|
118
|
+
} catch {
|
|
119
|
+
return { error: 'better-sqlite3 not installed (run: dz setup --memory agentdb)' };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
interface ProjRow {
|
|
124
|
+
book: string;
|
|
125
|
+
ku_id: string;
|
|
126
|
+
corpus_version: string;
|
|
127
|
+
type: string;
|
|
128
|
+
name: string;
|
|
129
|
+
problem: string;
|
|
130
|
+
content: string;
|
|
131
|
+
chapter: string | null;
|
|
132
|
+
pages: string | null;
|
|
133
|
+
metadata: string | null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** Read the project's lexical book KB (all rows, or one `source`). Best-effort; honest errors. */
|
|
137
|
+
async function readProjectRows(
|
|
138
|
+
depsRoot: string,
|
|
139
|
+
projectDbPath: string,
|
|
140
|
+
source: string | undefined,
|
|
141
|
+
): Promise<{ rows: ProjRow[] } | { error: string }> {
|
|
142
|
+
const sqlite = resolveSqlite(depsRoot);
|
|
143
|
+
if ('error' in sqlite) return { error: sqlite.error };
|
|
144
|
+
try {
|
|
145
|
+
const { default: Database } = (await import(sqlite.url)) as { default: new (p: string, o?: object) => NativeDb };
|
|
146
|
+
const db = new Database(projectDbPath, { readonly: true });
|
|
147
|
+
try {
|
|
148
|
+
const cols = 'book, ku_id, corpus_version, type, name, problem, content, chapter, pages, metadata';
|
|
149
|
+
const rows = (source !== undefined
|
|
150
|
+
? db.prepare(`SELECT ${cols} FROM book_knowledge WHERE book = ?`).all(source)
|
|
151
|
+
: db.prepare(`SELECT ${cols} FROM book_knowledge`).all()) as ProjRow[];
|
|
152
|
+
return { rows };
|
|
153
|
+
} finally {
|
|
154
|
+
db.close();
|
|
155
|
+
}
|
|
156
|
+
} catch (err) {
|
|
157
|
+
return { error: `read project book KB failed: ${err instanceof Error ? err.message : String(err)}` };
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* The vector primitive is insert-only, so before re-indexing a book we delete its existing brain
|
|
163
|
+
* vector rows — mirroring the reindex approach. Best-effort: a missing store/table is a no-op.
|
|
164
|
+
* `foreign_keys = ON` makes the embeddings cascade with the pattern rows.
|
|
165
|
+
*/
|
|
166
|
+
async function deleteBrainVectors(depsRoot: string, agentdbPath: string, book: string): Promise<void> {
|
|
167
|
+
if (!existsSync(agentdbPath)) return; // nothing indexed yet
|
|
168
|
+
const sqlite = resolveSqlite(depsRoot);
|
|
169
|
+
if ('error' in sqlite) return;
|
|
170
|
+
try {
|
|
171
|
+
const { default: Database } = (await import(sqlite.url)) as { default: new (p: string) => NativeDb };
|
|
172
|
+
const db = new Database(agentdbPath);
|
|
173
|
+
try {
|
|
174
|
+
db.pragma('busy_timeout = 5000');
|
|
175
|
+
db.pragma('foreign_keys = ON');
|
|
176
|
+
db.prepare(
|
|
177
|
+
"DELETE FROM reasoning_patterns WHERE task_type = 'book-knowledge' AND tags LIKE ?",
|
|
178
|
+
).run(`%"${book}"%`);
|
|
179
|
+
} finally {
|
|
180
|
+
db.close();
|
|
181
|
+
}
|
|
182
|
+
} catch {
|
|
183
|
+
/* best-effort: table may not exist yet, or store is cold */
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// ──────────────────────────────────────── Promote ───────────────────────────────────────────
|
|
188
|
+
|
|
189
|
+
function jsonObj(s: string | null): Record<string, unknown> {
|
|
190
|
+
if (s === null) return {};
|
|
191
|
+
try {
|
|
192
|
+
const v = JSON.parse(s) as unknown;
|
|
193
|
+
return v !== null && typeof v === 'object' ? (v as Record<string, unknown>) : {};
|
|
194
|
+
} catch {
|
|
195
|
+
return {};
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function jsonPages(s: string | null): number[] | undefined {
|
|
200
|
+
if (s === null) return undefined;
|
|
201
|
+
try {
|
|
202
|
+
const v = JSON.parse(s) as unknown;
|
|
203
|
+
return Array.isArray(v) ? (v as number[]) : undefined;
|
|
204
|
+
} catch {
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/** Map a KU's declared `worth` to an honest vector score. Unknown/absent → 0.5 (no fabrication). */
|
|
210
|
+
function worthScore(meta: Record<string, unknown>): number {
|
|
211
|
+
switch (meta['worth']) {
|
|
212
|
+
case 'high':
|
|
213
|
+
return 0.9;
|
|
214
|
+
case 'medium':
|
|
215
|
+
return 0.6;
|
|
216
|
+
case 'low':
|
|
217
|
+
return 0.3;
|
|
218
|
+
default:
|
|
219
|
+
return 0.5;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Promote a PROJECT's digitized book KB into the durable cross-project brain (ADR-001 P0
|
|
225
|
+
* `book-brain-register`). Reads the project's lexical `books.sqlite`, groups KUs by book, and for
|
|
226
|
+
* each book mirrors them into the brain's lexical store ({@link putBookKnowledge}) and re-embeds
|
|
227
|
+
* them into the brain's vector store ({@link indexPatternsToAgentdb}), then refreshes the registry.
|
|
228
|
+
*
|
|
229
|
+
* **Non-clobbering:** promoting the same book twice does not duplicate — the lexical upsert keys on
|
|
230
|
+
* `(book, ku_id, corpus_version)` and the vector rows are pre-deleted before re-index.
|
|
231
|
+
*/
|
|
232
|
+
export async function promoteProjectToBrain(opts: {
|
|
233
|
+
projectRoot: string;
|
|
234
|
+
depsRoot?: string;
|
|
235
|
+
brainHome?: string;
|
|
236
|
+
source?: string;
|
|
237
|
+
addedTs: string;
|
|
238
|
+
}): Promise<{ sources: string[]; kus: number; error?: string }> {
|
|
239
|
+
const home = opts.brainHome ?? brainHome();
|
|
240
|
+
const depsRoot = opts.depsRoot ?? opts.projectRoot;
|
|
241
|
+
const projectDbPath = bookKbPath(opts.projectRoot);
|
|
242
|
+
if (!existsSync(projectDbPath)) return { sources: [], kus: 0, error: 'no project book KB' };
|
|
243
|
+
|
|
244
|
+
const read = await readProjectRows(depsRoot, projectDbPath, opts.source);
|
|
245
|
+
if ('error' in read) return { sources: [], kus: 0, error: read.error };
|
|
246
|
+
if (read.rows.length === 0) return { sources: [], kus: 0 };
|
|
247
|
+
|
|
248
|
+
// Group rows by book (each book is one promote unit + one registry entry).
|
|
249
|
+
const byBook = new Map<string, ProjRow[]>();
|
|
250
|
+
for (const r of read.rows) {
|
|
251
|
+
const bucket = byBook.get(r.book);
|
|
252
|
+
if (bucket) bucket.push(r);
|
|
253
|
+
else byBook.set(r.book, [r]);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const reg = readRegistry(home);
|
|
257
|
+
const sources: Record<string, BrainSource> = { ...reg.sources };
|
|
258
|
+
const promoted: string[] = [];
|
|
259
|
+
let totalKus = 0;
|
|
260
|
+
let firstError: string | undefined;
|
|
261
|
+
|
|
262
|
+
for (const [book, rows] of byBook) {
|
|
263
|
+
// 1. Lexical mirror — reuse the idempotent upsert, pointed at the brain store.
|
|
264
|
+
const kus: BookKU[] = rows.map((r) => {
|
|
265
|
+
const pages = jsonPages(r.pages);
|
|
266
|
+
const meta = jsonObj(r.metadata);
|
|
267
|
+
return {
|
|
268
|
+
book: r.book,
|
|
269
|
+
kuId: r.ku_id,
|
|
270
|
+
corpusVersion: r.corpus_version,
|
|
271
|
+
type: r.type,
|
|
272
|
+
name: r.name,
|
|
273
|
+
problem: r.problem,
|
|
274
|
+
content: r.content,
|
|
275
|
+
...(r.chapter !== null ? { chapter: r.chapter } : {}),
|
|
276
|
+
...(pages !== undefined ? { pages } : {}),
|
|
277
|
+
...(Object.keys(meta).length > 0 ? { metadata: meta } : {}),
|
|
278
|
+
};
|
|
279
|
+
});
|
|
280
|
+
const lex = await putBookKnowledge(depsRoot, kus, { dbPath: brainBooksPath(home) });
|
|
281
|
+
if (lex.error !== undefined && firstError === undefined) firstError = lex.error;
|
|
282
|
+
|
|
283
|
+
// 2. Vector re-embed — pre-delete this book's stale vectors (insert-only primitive), then index.
|
|
284
|
+
await deleteBrainVectors(depsRoot, brainAgentdbPath(home), book);
|
|
285
|
+
const vecRows: AgentdbRow[] = rows.map((r) => {
|
|
286
|
+
const meta = jsonObj(r.metadata);
|
|
287
|
+
return {
|
|
288
|
+
taskType: 'book-knowledge',
|
|
289
|
+
text: `${r.name}: ${r.problem}`,
|
|
290
|
+
score: worthScore(meta),
|
|
291
|
+
tags: ['book', r.book, r.type],
|
|
292
|
+
metadata: {
|
|
293
|
+
chapter: r.chapter,
|
|
294
|
+
pages: jsonPages(r.pages) ?? null,
|
|
295
|
+
ku_id: r.ku_id,
|
|
296
|
+
corpus_version: r.corpus_version,
|
|
297
|
+
},
|
|
298
|
+
};
|
|
299
|
+
});
|
|
300
|
+
const vec = await indexPatternsToAgentdb(depsRoot, vecRows, { dbPath: brainAgentdbPath(home) });
|
|
301
|
+
if (vec.error !== undefined && firstError === undefined) firstError = vec.error;
|
|
302
|
+
|
|
303
|
+
// 3. Registry entry for this book — corpus_version/lang/isbn from the first row's metadata.
|
|
304
|
+
const meta0 = jsonObj(rows[0]!.metadata);
|
|
305
|
+
const corpusVersion = rows[0]!.corpus_version;
|
|
306
|
+
const lang = typeof meta0['lang'] === 'string' ? (meta0['lang'] as string) : undefined;
|
|
307
|
+
const isbn = typeof meta0['isbn'] === 'string' ? (meta0['isbn'] as string) : undefined;
|
|
308
|
+
sources[book] = {
|
|
309
|
+
slug: book,
|
|
310
|
+
kind: 'book',
|
|
311
|
+
kuCount: rows.length,
|
|
312
|
+
addedTs: opts.addedTs,
|
|
313
|
+
...(corpusVersion !== undefined && corpusVersion !== '' ? { corpusVersion } : {}),
|
|
314
|
+
...(lang !== undefined ? { lang } : {}),
|
|
315
|
+
...(isbn !== undefined ? { isbn } : {}),
|
|
316
|
+
};
|
|
317
|
+
promoted.push(book);
|
|
318
|
+
totalKus += rows.length;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
writeRegistry(home, { version: 1, sources });
|
|
322
|
+
return firstError !== undefined
|
|
323
|
+
? { sources: promoted, kus: totalKus, error: firstError }
|
|
324
|
+
: { sources: promoted, kus: totalKus };
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// ───────────────────────────────────────── Query ────────────────────────────────────────────
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Cross-source lexical recall over the whole brain — a thin, brain-home-scoped wrapper over
|
|
331
|
+
* {@link queryBookKnowledge}. `source` narrows to one source; default is cross-source. Never throws.
|
|
332
|
+
*/
|
|
333
|
+
export async function queryBrain(opts: {
|
|
334
|
+
query: string;
|
|
335
|
+
brainHome?: string;
|
|
336
|
+
depsRoot?: string;
|
|
337
|
+
source?: string;
|
|
338
|
+
limit?: number;
|
|
339
|
+
match?: 'all' | 'any';
|
|
340
|
+
}): Promise<{ hits: BookKUHit[]; error?: string }> {
|
|
341
|
+
const home = opts.brainHome ?? brainHome();
|
|
342
|
+
const depsRoot = opts.depsRoot ?? process.cwd();
|
|
343
|
+
const qopts: { dbPath: string; book?: string; limit?: number; match?: 'all' | 'any' } = { dbPath: brainBooksPath(home) };
|
|
344
|
+
if (opts.source !== undefined) qopts.book = opts.source;
|
|
345
|
+
if (opts.limit !== undefined) qopts.limit = opts.limit;
|
|
346
|
+
if (opts.match !== undefined) qopts.match = opts.match;
|
|
347
|
+
return queryBookKnowledge(depsRoot, opts.query, qopts);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// ──────────────────────────────────────── Grounding ─────────────────────────────────────────
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* A small bilingual (RU+EN) stopword list. Deliberately tiny — the goal is only to strip the most
|
|
354
|
+
* common glue words so the residual tokens are CONTENT terms worth grounding on, not to do real NLP.
|
|
355
|
+
*/
|
|
356
|
+
const STOPWORDS = new Set<string>([
|
|
357
|
+
// EN
|
|
358
|
+
'the', 'and', 'for', 'are', 'but', 'not', 'you', 'all', 'any', 'can', 'her', 'was', 'one',
|
|
359
|
+
'our', 'out', 'has', 'had', 'his', 'how', 'its', 'who', 'get', 'got', 'use', 'via', 'per',
|
|
360
|
+
'with', 'this', 'that', 'from', 'into', 'over', 'your', 'they', 'them', 'then', 'than', 'have',
|
|
361
|
+
'will', 'what', 'when', 'why', 'where', 'which', 'about', 'would', 'should', 'could', 'does',
|
|
362
|
+
'did', 'yes', 'no', 'or', 'a', 'an', 'of', 'to', 'in', 'on', 'is', 'it', 'be', 'as', 'at', 'by',
|
|
363
|
+
// RU
|
|
364
|
+
'и', 'в', 'на', 'как', 'для', 'что', 'это', 'или', 'но', 'же', 'то', 'по', 'из', 'за', 'от',
|
|
365
|
+
'до', 'со', 'об', 'при', 'без', 'над', 'под', 'про', 'так', 'уже', 'еще', 'ещё', 'вот', 'бы',
|
|
366
|
+
'ли', 'не', 'ни', 'да', 'нет', 'мне', 'мой', 'моя', 'вы', 'ты', 'он', 'она', 'они', 'оно',
|
|
367
|
+
'кто', 'где', 'чем', 'чей', 'быть', 'если', 'чтобы', 'этот', 'эта', 'эти', 'все', 'всё', 'меня',
|
|
368
|
+
]);
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Extract meaningful CONTENT TERMS from a prompt: lowercase, keep `\p{L}\p{N}` tokens of length ≥ 3,
|
|
372
|
+
* and drop the small RU+EN stopword list. Deterministic; deduped preserving first-seen order.
|
|
373
|
+
*/
|
|
374
|
+
function contentTerms(prompt: string): string[] {
|
|
375
|
+
const seen = new Set<string>();
|
|
376
|
+
const out: string[] = [];
|
|
377
|
+
// Split on anything that is not a Unicode letter or number (handles RU + EN + punctuation).
|
|
378
|
+
for (const raw of prompt.toLowerCase().split(/[^\p{L}\p{N}]+/u)) {
|
|
379
|
+
if (raw.length < 3) continue;
|
|
380
|
+
if (STOPWORDS.has(raw)) continue;
|
|
381
|
+
if (seen.has(raw)) continue;
|
|
382
|
+
seen.add(raw);
|
|
383
|
+
out.push(raw);
|
|
384
|
+
}
|
|
385
|
+
return out;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/** Clamp a snippet to a max length, collapsing whitespace, with an ellipsis when truncated. */
|
|
389
|
+
function snippet(s: string, max = 160): string {
|
|
390
|
+
const flat = s.replace(/\s+/g, ' ').trim();
|
|
391
|
+
return flat.length <= max ? flat : `${flat.slice(0, max - 1).trimEnd()}…`;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/** The directive line prepended to every grounding block (§7.1). */
|
|
395
|
+
const GROUNDING_DIRECTIVE =
|
|
396
|
+
'Ground your answer in the KNOWLEDGE BRAIN below; prefer these ingested sources over ' +
|
|
397
|
+
'training-data recall; cite [Kn] source+page per claim; if the brain is silent on a point, say so.';
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* The grounding-enforcement hook entrypoint (ADR-001 §7, P1). Given a user prompt, deterministically
|
|
401
|
+
* builds a GROUNDING DIRECTIVE block from the brain's top lexical hits — the mechanical half of
|
|
402
|
+
* ruvnet-brain's "answer from source, not drift" (the agent honoring it is the soft, agent-enforced
|
|
403
|
+
* half, §7.2). Best-effort and **silent by design**: grounding must never inject noise or block a
|
|
404
|
+
* prompt, so any generic prompt, empty brain, store error, or thrown exception yields
|
|
405
|
+
* `{ emitted:false, block:'', hitCount:0 }` rather than an error to the user.
|
|
406
|
+
*
|
|
407
|
+
* **Relevance gate (P1):** `≥ 1 content term AND ≥ 1 lexical hit` under OR/any-term matching. The
|
|
408
|
+
* query uses `match:'any'` (OR), not AND: a natural-language prompt carries terms not in the KB
|
|
409
|
+
* (a verb like "проектирую", filler), and AND-ing them all returns 0 even when the topical terms
|
|
410
|
+
* (репликация, кворум) match — the too-strict gate that made real prompts silent. OR lets the
|
|
411
|
+
* matching terms surface KUs, FTS5-rank-ordered; the stopword filter still keeps "how are you"
|
|
412
|
+
* silent (no content terms). A numeric `--min-score` threshold (§7.1/§7.3) is deferred to **P3**:
|
|
413
|
+
* FTS5's `rank` isn't exposed and a meaningful score needs the vector (cosine) path the sync hook
|
|
414
|
+
* doesn't run. Until then, "≥1 content-term OR-hit clears the gate" is the honest P1 rule.
|
|
415
|
+
*/
|
|
416
|
+
export async function groundPrompt(opts: {
|
|
417
|
+
prompt: string;
|
|
418
|
+
brainHome?: string;
|
|
419
|
+
depsRoot?: string;
|
|
420
|
+
k?: number;
|
|
421
|
+
source?: string;
|
|
422
|
+
}): Promise<{ emitted: boolean; block: string; hitCount: number; error?: string }> {
|
|
423
|
+
const silent = { emitted: false, block: '', hitCount: 0 } as const;
|
|
424
|
+
try {
|
|
425
|
+
// Gate 1: at least one CONTENT term (all-stopword prompts like "how are you" → silent).
|
|
426
|
+
const terms = contentTerms(opts.prompt ?? '');
|
|
427
|
+
if (terms.length < 1) return silent;
|
|
428
|
+
|
|
429
|
+
// Best-effort OR/any-term lexical recall over the whole brain. Never throws. `match:'any'` so a
|
|
430
|
+
// matching topical term surfaces KUs even when other prompt terms (a verb, filler) miss — the
|
|
431
|
+
// fix for real-prompt silence (AND required every term to co-occur). Rank ordering + top-K keep
|
|
432
|
+
// it precise; the stopword filter keeps generic prompts silent.
|
|
433
|
+
const query: { query: string; brainHome?: string; depsRoot?: string; source?: string; limit: number; match: 'any' } = {
|
|
434
|
+
query: terms.join(' '),
|
|
435
|
+
limit: opts.k ?? 5,
|
|
436
|
+
match: 'any',
|
|
437
|
+
};
|
|
438
|
+
if (opts.brainHome !== undefined) query.brainHome = opts.brainHome;
|
|
439
|
+
if (opts.depsRoot !== undefined) query.depsRoot = opts.depsRoot;
|
|
440
|
+
if (opts.source !== undefined) query.source = opts.source;
|
|
441
|
+
const res = await queryBrain(query);
|
|
442
|
+
|
|
443
|
+
// Gate 2: any lexical hit? On error or zero hits, stay silent (no noise, no block).
|
|
444
|
+
if (res.error !== undefined) return silent;
|
|
445
|
+
if (res.hits.length === 0) return silent;
|
|
446
|
+
|
|
447
|
+
// Gate 3 — COVERAGE (the OR balance): OR recall alone over-fires when a single common term
|
|
448
|
+
// ("today", "data") incidentally matches a KU. Require the retrieved hits to actually cover the
|
|
449
|
+
// prompt's intent: for a single-content-term prompt ("кворум") one hit suffices; for a
|
|
450
|
+
// multi-term prompt, ≥2 DISTINCT content terms must prefix-appear in the hit set — so an
|
|
451
|
+
// off-topic prompt whose only matching word is incidental ("weather today" → only "today"
|
|
452
|
+
// matches) stays silent, while a real one ("репликацию single multi leader" → 4 covered) grounds.
|
|
453
|
+
if (terms.length >= 2) {
|
|
454
|
+
const hay = res.hits.map((h) => `${h.name} ${h.problem} ${h.content}`.toLowerCase()).join(' ');
|
|
455
|
+
const covered = terms.filter((t) => hay.includes(t.toLowerCase())).length;
|
|
456
|
+
if (covered < 2) return silent;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// Build the GROUNDING DIRECTIVE block (§7.1): directive line + numbered citations.
|
|
460
|
+
const lines: string[] = [GROUNDING_DIRECTIVE, ''];
|
|
461
|
+
res.hits.forEach((h, i) => {
|
|
462
|
+
const ch = h.chapter !== undefined && h.chapter !== '' ? ` гл.${h.chapter}` : '';
|
|
463
|
+
const pg = h.pages !== undefined && h.pages.length > 0 ? ` с.${h.pages.join('–')}` : '';
|
|
464
|
+
const body = snippet(h.problem !== '' ? h.problem : h.content);
|
|
465
|
+
lines.push(`[K${i + 1}] ${h.book}${ch}${pg} — ${h.name}: ${body}`);
|
|
466
|
+
});
|
|
467
|
+
return { emitted: true, block: lines.join('\n'), hitCount: res.hits.length };
|
|
468
|
+
} catch {
|
|
469
|
+
// Grounding is advisory — a bug here must never surface to the user or block the prompt.
|
|
470
|
+
return silent;
|
|
471
|
+
}
|
|
472
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -31,6 +31,19 @@ export { runSetup, generateHooksConfig, generateAgentdbWriter, writerVersionOf,
|
|
|
31
31
|
export { indexPatternsToAgentdb, resolveAgentdbPath } from './agentdb-index.js';
|
|
32
32
|
export { putBookKnowledge, queryBookKnowledge, bookKbPath } from './book-kb.js';
|
|
33
33
|
export type { BookKU, BookKUHit } from './book-kb.js';
|
|
34
|
+
export {
|
|
35
|
+
brainHome,
|
|
36
|
+
brainBooksPath,
|
|
37
|
+
brainAgentdbPath,
|
|
38
|
+
brainRegistryPath,
|
|
39
|
+
readRegistry,
|
|
40
|
+
writeRegistry,
|
|
41
|
+
listBrain,
|
|
42
|
+
promoteProjectToBrain,
|
|
43
|
+
queryBrain,
|
|
44
|
+
groundPrompt,
|
|
45
|
+
} from './brain.js';
|
|
46
|
+
export type { BrainRegistry, BrainSource } from './brain.js';
|
|
34
47
|
export type { AgentdbRow, AgentdbIndexResult } from './agentdb-index.js';
|
|
35
48
|
export { generatePlugin } from './plugin.js';
|
|
36
49
|
export type { PluginManifest } from './plugin.js';
|