knowledge-mcp-server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/LICENSE +21 -0
- package/README.md +205 -0
- package/dist/analytics.d.ts +24 -0
- package/dist/analytics.js +102 -0
- package/dist/analytics.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +98 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +39 -0
- package/dist/config.js +80 -0
- package/dist/config.js.map +1 -0
- package/dist/embeddings.d.ts +26 -0
- package/dist/embeddings.js +534 -0
- package/dist/embeddings.js.map +1 -0
- package/dist/formatter.d.ts +51 -0
- package/dist/formatter.js +273 -0
- package/dist/formatter.js.map +1 -0
- package/dist/generate-embeddings.d.ts +8 -0
- package/dist/generate-embeddings.js +146 -0
- package/dist/generate-embeddings.js.map +1 -0
- package/dist/graph.d.ts +20 -0
- package/dist/graph.js +133 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +481 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +1 -0
- package/dist/init.js +65 -0
- package/dist/init.js.map +1 -0
- package/dist/loader.d.ts +26 -0
- package/dist/loader.js +151 -0
- package/dist/loader.js.map +1 -0
- package/dist/logger.d.ts +6 -0
- package/dist/logger.js +15 -0
- package/dist/logger.js.map +1 -0
- package/dist/query-classifier.d.ts +23 -0
- package/dist/query-classifier.js +111 -0
- package/dist/query-classifier.js.map +1 -0
- package/dist/reranker.d.ts +7 -0
- package/dist/reranker.js +38 -0
- package/dist/reranker.js.map +1 -0
- package/dist/search.d.ts +17 -0
- package/dist/search.js +299 -0
- package/dist/search.js.map +1 -0
- package/dist/validator.d.ts +23 -0
- package/dist/validator.js +97 -0
- package/dist/validator.js.map +1 -0
- package/dist/writer.d.ts +36 -0
- package/dist/writer.js +360 -0
- package/dist/writer.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
// Word budgets per relevance tier and detail level
|
|
2
|
+
const WORD_BUDGETS = {
|
|
3
|
+
summary: { ancestor: 40, "graph-expanded": 150, primary: 500 },
|
|
4
|
+
normal: { ancestor: 80, "graph-expanded": 300, primary: 1500 },
|
|
5
|
+
full: { ancestor: Infinity, "graph-expanded": Infinity, primary: Infinity },
|
|
6
|
+
};
|
|
7
|
+
function parseSections(content) {
|
|
8
|
+
const lines = content.split("\n");
|
|
9
|
+
const sections = [];
|
|
10
|
+
let currentHeading = "";
|
|
11
|
+
let currentLines = [];
|
|
12
|
+
for (const line of lines) {
|
|
13
|
+
if (/^#{1,6}\s+/.test(line)) {
|
|
14
|
+
// Flush previous section
|
|
15
|
+
const body = currentLines.join("\n").trim();
|
|
16
|
+
if (body || sections.length > 0) {
|
|
17
|
+
sections.push({
|
|
18
|
+
heading: currentHeading,
|
|
19
|
+
body,
|
|
20
|
+
wordCount: body.split(/\s+/).filter(Boolean).length,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
currentHeading = line;
|
|
24
|
+
currentLines = [];
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
currentLines.push(line);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Flush final section
|
|
31
|
+
const body = currentLines.join("\n").trim();
|
|
32
|
+
sections.push({
|
|
33
|
+
heading: currentHeading,
|
|
34
|
+
body,
|
|
35
|
+
wordCount: body.split(/\s+/).filter(Boolean).length,
|
|
36
|
+
});
|
|
37
|
+
return sections;
|
|
38
|
+
}
|
|
39
|
+
function truncateContent(content, wordBudget) {
|
|
40
|
+
if (!Number.isFinite(wordBudget))
|
|
41
|
+
return content;
|
|
42
|
+
const sections = parseSections(content);
|
|
43
|
+
// No headings found — fall back to paragraph-based truncation
|
|
44
|
+
const hasHeadings = sections.some((s) => s.heading !== "");
|
|
45
|
+
if (!hasHeadings) {
|
|
46
|
+
return truncateByParagraphs(content, wordBudget);
|
|
47
|
+
}
|
|
48
|
+
const kept = [];
|
|
49
|
+
let wordCount = 0;
|
|
50
|
+
for (const section of sections) {
|
|
51
|
+
const sectionWords = section.wordCount + (section.heading ? section.heading.split(/\s+/).length : 0);
|
|
52
|
+
if (wordCount + sectionWords > wordBudget && kept.length > 0) {
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
kept.push(section);
|
|
56
|
+
wordCount += sectionWords;
|
|
57
|
+
}
|
|
58
|
+
// Build output from kept sections
|
|
59
|
+
const parts = [];
|
|
60
|
+
for (const section of kept) {
|
|
61
|
+
if (section.heading)
|
|
62
|
+
parts.push(section.heading);
|
|
63
|
+
if (section.body)
|
|
64
|
+
parts.push(section.body);
|
|
65
|
+
}
|
|
66
|
+
// Summarize omitted sections
|
|
67
|
+
const omitted = sections.slice(kept.length);
|
|
68
|
+
if (omitted.length > 0) {
|
|
69
|
+
const omittedSummary = omitted
|
|
70
|
+
.filter((s) => s.heading)
|
|
71
|
+
.map((s) => `${s.heading.replace(/^#+\s+/, "")} (${s.wordCount} words)`)
|
|
72
|
+
.join(", ");
|
|
73
|
+
if (omittedSummary) {
|
|
74
|
+
parts.push(`\n[Sections omitted: ${omittedSummary}]`);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const remaining = omitted.reduce((sum, s) => sum + s.wordCount, 0);
|
|
78
|
+
if (remaining > 0)
|
|
79
|
+
parts.push(`\n[... ${remaining} more words]`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return parts.join("\n");
|
|
83
|
+
}
|
|
84
|
+
function truncateByParagraphs(content, wordBudget) {
|
|
85
|
+
const paragraphs = content.split(/\n\n/);
|
|
86
|
+
const kept = [];
|
|
87
|
+
let wordCount = 0;
|
|
88
|
+
for (const paragraph of paragraphs) {
|
|
89
|
+
const words = paragraph.split(/\s+/).filter(Boolean);
|
|
90
|
+
if (wordCount + words.length > wordBudget && kept.length > 0) {
|
|
91
|
+
const totalWords = content.split(/\s+/).filter(Boolean).length;
|
|
92
|
+
const remaining = totalWords - wordCount;
|
|
93
|
+
if (remaining > 0) {
|
|
94
|
+
kept.push(`[... ${remaining} more words]`);
|
|
95
|
+
}
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
kept.push(paragraph);
|
|
99
|
+
wordCount += words.length;
|
|
100
|
+
}
|
|
101
|
+
return kept.join("\n\n");
|
|
102
|
+
}
|
|
103
|
+
function escapeXml(text) {
|
|
104
|
+
return text
|
|
105
|
+
.replace(/&/g, "&")
|
|
106
|
+
.replace(/</g, "<")
|
|
107
|
+
.replace(/>/g, ">")
|
|
108
|
+
.replace(/"/g, """);
|
|
109
|
+
}
|
|
110
|
+
function formatSingleDoc(entry, detailLevel) {
|
|
111
|
+
const { doc, relevance, similarity, matchedOn, scoringMethod, expandedFrom } = entry;
|
|
112
|
+
const attrs = [`id="${escapeXml(doc.id)}"`, `type="${doc.type}"`, `relevance="${relevance}"`];
|
|
113
|
+
if (doc.status !== "active") {
|
|
114
|
+
attrs.push(`status="${doc.status}"`);
|
|
115
|
+
}
|
|
116
|
+
if (doc.supersededBy) {
|
|
117
|
+
attrs.push(`superseded_by="${escapeXml(doc.supersededBy)}"`);
|
|
118
|
+
}
|
|
119
|
+
if (similarity !== undefined) {
|
|
120
|
+
attrs.push(`similarity="${similarity.toFixed(2)}"`);
|
|
121
|
+
}
|
|
122
|
+
if (matchedOn) {
|
|
123
|
+
attrs.push(`matched_on="${escapeXml(matchedOn)}"`);
|
|
124
|
+
}
|
|
125
|
+
if (scoringMethod) {
|
|
126
|
+
attrs.push(`scoring_method="${escapeXml(scoringMethod)}"`);
|
|
127
|
+
}
|
|
128
|
+
if (expandedFrom) {
|
|
129
|
+
attrs.push(`expanded_from="${escapeXml(expandedFrom)}"`);
|
|
130
|
+
}
|
|
131
|
+
attrs.push(`path="${escapeXml(doc.filePath)}"`);
|
|
132
|
+
const parts = [` <document ${attrs.join(" ")}>`];
|
|
133
|
+
parts.push(` <title>${escapeXml(doc.title)}</title>`);
|
|
134
|
+
if (doc.tags.length > 0) {
|
|
135
|
+
parts.push(` <tags>${escapeXml(doc.tags.join(", "))}</tags>`);
|
|
136
|
+
}
|
|
137
|
+
if (doc.related.length > 0) {
|
|
138
|
+
parts.push(` <related>${escapeXml(doc.related.join(", "))}</related>`);
|
|
139
|
+
}
|
|
140
|
+
if (doc.type === "decision") {
|
|
141
|
+
const meta = [];
|
|
142
|
+
if (doc.decisionStatus)
|
|
143
|
+
meta.push(`status="${escapeXml(doc.decisionStatus)}"`);
|
|
144
|
+
if (doc.decisionDate)
|
|
145
|
+
meta.push(`date="${escapeXml(doc.decisionDate)}"`);
|
|
146
|
+
if (meta.length > 0) {
|
|
147
|
+
parts.push(` <decision_meta ${meta.join(" ")}>`);
|
|
148
|
+
if (doc.alternativesConsidered && doc.alternativesConsidered.length > 0) {
|
|
149
|
+
parts.push(` <alternatives>${escapeXml(doc.alternativesConsidered.join(", "))}</alternatives>`);
|
|
150
|
+
}
|
|
151
|
+
parts.push(` </decision_meta>`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const budget = WORD_BUDGETS[detailLevel][relevance];
|
|
155
|
+
const content = truncateContent(doc.contentBody, budget);
|
|
156
|
+
parts.push(` <content>\n${content}\n </content>`);
|
|
157
|
+
parts.push(` </document>`);
|
|
158
|
+
return parts.join("\n");
|
|
159
|
+
}
|
|
160
|
+
function formatFacets(facets) {
|
|
161
|
+
const parts = [` <facets>`];
|
|
162
|
+
for (const [name, count] of [...facets.domains].sort((a, b) => b[1] - a[1])) {
|
|
163
|
+
parts.push(` <domain name="${escapeXml(name)}" count="${count}"/>`);
|
|
164
|
+
}
|
|
165
|
+
for (const [name, count] of [...facets.types].sort((a, b) => b[1] - a[1])) {
|
|
166
|
+
parts.push(` <type name="${escapeXml(name)}" count="${count}"/>`);
|
|
167
|
+
}
|
|
168
|
+
for (const [name, count] of [...facets.phases].sort((a, b) => b[1] - a[1])) {
|
|
169
|
+
parts.push(` <phase name="${escapeXml(name)}" count="${count}"/>`);
|
|
170
|
+
}
|
|
171
|
+
parts.push(` </facets>`);
|
|
172
|
+
return parts.join("\n");
|
|
173
|
+
}
|
|
174
|
+
export function formatSearchResults(query, results, detailLevel = "normal", searchMethod, facets) {
|
|
175
|
+
const methodAttr = searchMethod ? ` search_method="${escapeXml(searchMethod)}"` : "";
|
|
176
|
+
const parts = [
|
|
177
|
+
`<knowledge_context query="${escapeXml(query)}" total_docs="${results.length}"${methodAttr}>`,
|
|
178
|
+
];
|
|
179
|
+
// Order: ancestors first, then primaries by similarity, then expanded
|
|
180
|
+
const ancestors = results.filter((r) => r.relevance === "ancestor");
|
|
181
|
+
const primaries = results.filter((r) => r.relevance === "primary");
|
|
182
|
+
const expanded = results.filter((r) => r.relevance === "graph-expanded");
|
|
183
|
+
for (const entry of [...ancestors, ...primaries, ...expanded]) {
|
|
184
|
+
parts.push(formatSingleDoc(entry, detailLevel));
|
|
185
|
+
}
|
|
186
|
+
if (facets) {
|
|
187
|
+
parts.push(formatFacets(facets));
|
|
188
|
+
}
|
|
189
|
+
parts.push(`</knowledge_context>`);
|
|
190
|
+
return parts.join("\n");
|
|
191
|
+
}
|
|
192
|
+
export function formatLookupResult(doc, ancestors, related, contentLevel = "full") {
|
|
193
|
+
const detailLevel = contentLevel === "summary" ? "normal" : "full";
|
|
194
|
+
const parts = [`<knowledge_context total_docs="${1 + ancestors.length + related.length}">`];
|
|
195
|
+
for (const a of ancestors) {
|
|
196
|
+
parts.push(formatSingleDoc({ doc: a, relevance: "ancestor" }, detailLevel));
|
|
197
|
+
}
|
|
198
|
+
parts.push(formatSingleDoc({ doc, relevance: "primary" }, detailLevel));
|
|
199
|
+
for (const r of related) {
|
|
200
|
+
parts.push(formatSingleDoc({ doc: r, relevance: "graph-expanded" }, detailLevel));
|
|
201
|
+
}
|
|
202
|
+
parts.push(`</knowledge_context>`);
|
|
203
|
+
return parts.join("\n");
|
|
204
|
+
}
|
|
205
|
+
export function formatGraphResult(nodes, edges, totalDocs, rootId) {
|
|
206
|
+
const parts = [];
|
|
207
|
+
parts.push(`<knowledge_graph root="${escapeXml(rootId)}" total_docs="${totalDocs}" nodes_shown="${nodes.length}">`);
|
|
208
|
+
for (const node of nodes) {
|
|
209
|
+
parts.push(` <node id="${escapeXml(node.id)}" type="${escapeXml(node.type)}" domain="${escapeXml(node.domain)}" word_count="${node.wordCount}" children_count="${node.childrenCount}">`);
|
|
210
|
+
parts.push(` <title>${escapeXml(node.title)}</title>`);
|
|
211
|
+
parts.push(` </node>`);
|
|
212
|
+
}
|
|
213
|
+
parts.push(` <edges>`);
|
|
214
|
+
for (const edge of edges) {
|
|
215
|
+
parts.push(` <edge source="${escapeXml(edge.source)}" target="${escapeXml(edge.target)}" type="${escapeXml(edge.type)}"/>`);
|
|
216
|
+
}
|
|
217
|
+
parts.push(` </edges>`);
|
|
218
|
+
parts.push(`</knowledge_graph>`);
|
|
219
|
+
return parts.join("\n");
|
|
220
|
+
}
|
|
221
|
+
export function formatWriteResult(result) {
|
|
222
|
+
const lines = [
|
|
223
|
+
`Document ${result.status}: "${result.id}"`,
|
|
224
|
+
` File: ${result.filePath}`,
|
|
225
|
+
` Parent: ${result.parentId ?? "(root)"}`,
|
|
226
|
+
``,
|
|
227
|
+
`BM25 search index updated — document is immediately searchable.`,
|
|
228
|
+
`Note: Embedding vectors update automatically when VOYAGE_API_KEY is set.`,
|
|
229
|
+
];
|
|
230
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
231
|
+
lines.push(``);
|
|
232
|
+
lines.push(`Warnings:`);
|
|
233
|
+
for (const w of result.warnings) {
|
|
234
|
+
lines.push(` - ${w}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return lines.join("\n");
|
|
238
|
+
}
|
|
239
|
+
export function formatDeleteResult(result) {
|
|
240
|
+
const lines = [`Document deleted: "${result.id}"`, ``, `BM25 search index updated.`];
|
|
241
|
+
if (result.warnings.length > 0) {
|
|
242
|
+
lines.push(``);
|
|
243
|
+
lines.push(`Warnings:`);
|
|
244
|
+
for (const w of result.warnings) {
|
|
245
|
+
lines.push(` - ${w}`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return lines.join("\n");
|
|
249
|
+
}
|
|
250
|
+
export function formatListResult(docs, totalDocs) {
|
|
251
|
+
const parts = [`<knowledge_list total="${docs.length}" of="${totalDocs}">`];
|
|
252
|
+
for (const doc of docs) {
|
|
253
|
+
const attrs = [
|
|
254
|
+
`id="${escapeXml(doc.id)}"`,
|
|
255
|
+
`type="${doc.type}"`,
|
|
256
|
+
`domain="${escapeXml(doc.domain)}"`,
|
|
257
|
+
`words="${doc.wordCount}"`,
|
|
258
|
+
];
|
|
259
|
+
if (doc.status !== "active")
|
|
260
|
+
attrs.push(`status="${doc.status}"`);
|
|
261
|
+
if (doc.lastUpdated)
|
|
262
|
+
attrs.push(`updated="${doc.lastUpdated}"`);
|
|
263
|
+
parts.push(` <doc ${attrs.join(" ")}>`);
|
|
264
|
+
parts.push(` <title>${escapeXml(doc.title)}</title>`);
|
|
265
|
+
if (doc.tags.length > 0) {
|
|
266
|
+
parts.push(` <tags>${escapeXml(doc.tags.join(", "))}</tags>`);
|
|
267
|
+
}
|
|
268
|
+
parts.push(` </doc>`);
|
|
269
|
+
}
|
|
270
|
+
parts.push(`</knowledge_list>`);
|
|
271
|
+
return parts.join("\n");
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatter.js","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"AAaA,mDAAmD;AACnD,MAAM,YAAY,GAAmE;IACnF,OAAO,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,gBAAgB,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE;IAC9D,MAAM,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,gBAAgB,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE;IAC9D,IAAI,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE;CAC5E,CAAC;AAQF,SAAS,aAAa,CAAC,OAAe;IACpC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,IAAI,cAAc,GAAG,EAAE,CAAC;IACxB,IAAI,YAAY,GAAa,EAAE,CAAC;IAEhC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,yBAAyB;YACzB,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,IAAI,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChC,QAAQ,CAAC,IAAI,CAAC;oBACZ,OAAO,EAAE,cAAc;oBACvB,IAAI;oBACJ,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM;iBACpD,CAAC,CAAC;YACL,CAAC;YACD,cAAc,GAAG,IAAI,CAAC;YACtB,YAAY,GAAG,EAAE,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,sBAAsB;IACtB,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5C,QAAQ,CAAC,IAAI,CAAC;QACZ,OAAO,EAAE,cAAc;QACvB,IAAI;QACJ,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM;KACpD,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,eAAe,CAAC,OAAe,EAAE,UAAkB;IAC1D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,OAAO,CAAC;IAEjD,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAExC,8DAA8D;IAC9D,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC;IAC3D,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,oBAAoB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,IAAI,GAAc,EAAE,CAAC;IAC3B,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,YAAY,GAChB,OAAO,CAAC,SAAS,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClF,IAAI,SAAS,GAAG,YAAY,GAAG,UAAU,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7D,MAAM;QACR,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnB,SAAS,IAAI,YAAY,CAAC;IAC5B,CAAC;IAED,kCAAkC;IAClC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,OAAO,IAAI,IAAI,EAAE,CAAC;QAC3B,IAAI,OAAO,CAAC,OAAO;YAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,OAAO,CAAC,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED,6BAA6B;IAC7B,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,cAAc,GAAG,OAAO;aAC3B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;aACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,CAAC;aACvE,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,IAAI,cAAc,EAAE,CAAC;YACnB,KAAK,CAAC,IAAI,CAAC,wBAAwB,cAAc,GAAG,CAAC,CAAC;QACxD,CAAC;aAAM,CAAC;YACN,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;YACnE,IAAI,SAAS,GAAG,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,UAAU,SAAS,cAAc,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAe,EAAE,UAAkB;IAC/D,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACrD,IAAI,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,UAAU,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7D,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;YAC/D,MAAM,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;YACzC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;gBAClB,IAAI,CAAC,IAAI,CAAC,QAAQ,SAAS,cAAc,CAAC,CAAC;YAC7C,CAAC;YACD,MAAM;QACR,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrB,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC3B,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,IAAI;SACR,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,eAAe,CAAC,KAAmB,EAAE,WAAwB;IACpE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC;IACrF,MAAM,KAAK,GAAG,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,GAAG,CAAC,IAAI,GAAG,EAAE,cAAc,SAAS,GAAG,CAAC,CAAC;IAC9F,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;IACvC,CAAC;IACD,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,kBAAkB,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,eAAe,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACtD,CAAC;IACD,IAAI,SAAS,EAAE,CAAC;QACd,KAAK,CAAC,IAAI,CAAC,eAAe,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC;IACD,IAAI,aAAa,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,mBAAmB,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,YAAY,EAAE,CAAC;QACjB,KAAK,CAAC,IAAI,CAAC,kBAAkB,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAC3D,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,SAAS,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAEhD,MAAM,KAAK,GAAG,CAAC,eAAe,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClD,KAAK,CAAC,IAAI,CAAC,cAAc,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAEzD,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,aAAa,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;IACnE,CAAC;IACD,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,gBAAgB,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC;IAC5E,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAa,EAAE,CAAC;QAC1B,IAAI,GAAG,CAAC,cAAc;YAAE,IAAI,CAAC,IAAI,CAAC,WAAW,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QAC/E,IAAI,GAAG,CAAC,YAAY;YAAE,IAAI,CAAC,IAAI,CAAC,SAAS,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QACzE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,sBAAsB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACpD,IAAI,GAAG,CAAC,sBAAsB,IAAI,GAAG,CAAC,sBAAsB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxE,KAAK,CAAC,IAAI,CACR,uBAAuB,SAAS,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,iBAAiB,CACzF,CAAC;YACJ,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACzD,KAAK,CAAC,IAAI,CAAC,kBAAkB,OAAO,kBAAkB,CAAC,CAAC;IACxD,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAE5B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAQD,SAAS,YAAY,CAAC,MAAmB;IACvC,MAAM,KAAK,GAAa,CAAC,YAAY,CAAC,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5E,KAAK,CAAC,IAAI,CAAC,qBAAqB,SAAS,CAAC,IAAI,CAAC,YAAY,KAAK,KAAK,CAAC,CAAC;IACzE,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,KAAK,CAAC,IAAI,CAAC,mBAAmB,SAAS,CAAC,IAAI,CAAC,YAAY,KAAK,KAAK,CAAC,CAAC;IACvE,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3E,KAAK,CAAC,IAAI,CAAC,oBAAoB,SAAS,CAAC,IAAI,CAAC,YAAY,KAAK,KAAK,CAAC,CAAC;IACxE,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC1B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,OAAuB,EACvB,cAA2B,QAAQ,EACnC,YAAqB,EACrB,MAAoB;IAEpB,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,mBAAmB,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACrF,MAAM,KAAK,GAAG;QACZ,6BAA6B,SAAS,CAAC,KAAK,CAAC,iBAAiB,OAAO,CAAC,MAAM,IAAI,UAAU,GAAG;KAC9F,CAAC;IAEF,sEAAsE;IACtE,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,UAAU,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;IACnE,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,gBAAgB,CAAC,CAAC;IAEzE,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,EAAE,GAAG,SAAS,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;QAC9D,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,GAAsB,EACtB,SAA8B,EAC9B,OAA4B,EAC5B,eAAmC,MAAM;IAEzC,MAAM,WAAW,GAAgB,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;IAChF,MAAM,KAAK,GAAG,CAAC,kCAAkC,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;IAE5F,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;IAExE,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;IACpF,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,KAOE,EACF,KAIE,EACF,SAAiB,EACjB,MAAc;IAEd,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CACR,0BAA0B,SAAS,CAAC,MAAM,CAAC,iBAAiB,SAAS,kBAAkB,KAAK,CAAC,MAAM,IAAI,CACxG,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CACR,eAAe,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,IAAI,CAAC,SAAS,qBAAqB,IAAI,CAAC,aAAa,IAAI,CAC9K,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,cAAc,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC1D,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACxB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CACR,qBAAqB,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CACnH,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAEzB,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACjC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAMjC;IACC,MAAM,KAAK,GAAG;QACZ,YAAY,MAAM,CAAC,MAAM,MAAM,MAAM,CAAC,EAAE,GAAG;QAC3C,WAAW,MAAM,CAAC,QAAQ,EAAE;QAC5B,aAAa,MAAM,CAAC,QAAQ,IAAI,QAAQ,EAAE;QAC1C,EAAE;QACF,iEAAiE;QACjE,0EAA0E;KAC3E,CAAC;IACF,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACxB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAA0C;IAC3E,MAAM,KAAK,GAAG,CAAC,sBAAsB,MAAM,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,4BAA4B,CAAC,CAAC;IACrF,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACxB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,IASE,EACF,SAAiB;IAEjB,MAAM,KAAK,GAAG,CAAC,0BAA0B,IAAI,CAAC,MAAM,SAAS,SAAS,IAAI,CAAC,CAAC;IAC5E,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG;YACZ,OAAO,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG;YAC3B,SAAS,GAAG,CAAC,IAAI,GAAG;YACpB,WAAW,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG;YACnC,UAAU,GAAG,CAAC,SAAS,GAAG;SAC3B,CAAC;QACF,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;QAClE,IAAI,GAAG,CAAC,WAAW;YAAE,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC;QAChE,KAAK,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC,cAAc,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACzD,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,aAAa,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;QACnE,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACzB,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAChC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate embeddings for all knowledge documents using Voyage AI.
|
|
3
|
+
* Writes to <knowledge-dir>/.embeddings.json
|
|
4
|
+
*
|
|
5
|
+
* Skips documents whose content hash hasn't changed since last run.
|
|
6
|
+
* Reads knowledge.config.yaml for embedding provider settings if present.
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateEmbeddings(knowledgeDir: string): Promise<void>;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate embeddings for all knowledge documents using Voyage AI.
|
|
3
|
+
* Writes to <knowledge-dir>/.embeddings.json
|
|
4
|
+
*
|
|
5
|
+
* Skips documents whose content hash hasn't changed since last run.
|
|
6
|
+
* Reads knowledge.config.yaml for embedding provider settings if present.
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { createHash } from "node:crypto";
|
|
11
|
+
import { parse as parseYaml } from "yaml";
|
|
12
|
+
import { collectMarkdownFiles } from "./loader.js";
|
|
13
|
+
function loadEmbeddingConfig(knowledgeDir) {
|
|
14
|
+
const configPath = join(knowledgeDir, "knowledge.config.yaml");
|
|
15
|
+
try {
|
|
16
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
17
|
+
const parsed = parseYaml(raw);
|
|
18
|
+
const embeddings = parsed?.embeddings;
|
|
19
|
+
return {
|
|
20
|
+
model: embeddings?.model || "voyage-3-lite",
|
|
21
|
+
apiKeyEnv: embeddings?.api_key_env || "VOYAGE_API_KEY",
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return { model: "voyage-3-lite", apiKeyEnv: "VOYAGE_API_KEY" };
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function parseFrontmatter(raw) {
|
|
29
|
+
const match = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
30
|
+
if (!match)
|
|
31
|
+
return { body: raw };
|
|
32
|
+
const fm = parseYaml(match[1]);
|
|
33
|
+
return {
|
|
34
|
+
id: fm.id,
|
|
35
|
+
title: fm.title,
|
|
36
|
+
domain: fm.domain,
|
|
37
|
+
subdomain: fm.subdomain,
|
|
38
|
+
tags: fm.tags,
|
|
39
|
+
body: match[2].trim(),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function buildEmbeddingInput(doc) {
|
|
43
|
+
const parts = [];
|
|
44
|
+
if (doc.title)
|
|
45
|
+
parts.push(doc.title);
|
|
46
|
+
const domainPart = [doc.domain, doc.subdomain].filter(Boolean).join("/");
|
|
47
|
+
if (domainPart)
|
|
48
|
+
parts.push(`Domain: ${domainPart}`);
|
|
49
|
+
if (doc.tags?.length)
|
|
50
|
+
parts.push(`Tags: ${doc.tags.join(", ")}`);
|
|
51
|
+
parts.push("");
|
|
52
|
+
parts.push(doc.body);
|
|
53
|
+
return parts.join("\n");
|
|
54
|
+
}
|
|
55
|
+
async function embedBatch(texts, model, apiKey) {
|
|
56
|
+
const response = await fetch("https://api.voyageai.com/v1/embeddings", {
|
|
57
|
+
method: "POST",
|
|
58
|
+
headers: {
|
|
59
|
+
"Content-Type": "application/json",
|
|
60
|
+
Authorization: `Bearer ${apiKey}`,
|
|
61
|
+
},
|
|
62
|
+
body: JSON.stringify({
|
|
63
|
+
model,
|
|
64
|
+
input: texts,
|
|
65
|
+
input_type: "document",
|
|
66
|
+
}),
|
|
67
|
+
});
|
|
68
|
+
if (!response.ok) {
|
|
69
|
+
const err = await response.text();
|
|
70
|
+
throw new Error(`Voyage AI API error (${response.status}): ${err}`);
|
|
71
|
+
}
|
|
72
|
+
const data = (await response.json());
|
|
73
|
+
console.log(` Batch embedded: ${texts.length} docs, ${data.usage.total_tokens} tokens`);
|
|
74
|
+
return data.data.map((d) => d.embedding);
|
|
75
|
+
}
|
|
76
|
+
export async function generateEmbeddings(knowledgeDir) {
|
|
77
|
+
if (!existsSync(knowledgeDir)) {
|
|
78
|
+
console.error(`Error: Knowledge directory not found: ${knowledgeDir}`);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
const embeddingConfig = loadEmbeddingConfig(knowledgeDir);
|
|
82
|
+
const embeddingsPath = join(knowledgeDir, ".embeddings.json");
|
|
83
|
+
const hashesPath = join(knowledgeDir, ".embeddings-hashes.json");
|
|
84
|
+
const apiKey = process.env[embeddingConfig.apiKeyEnv];
|
|
85
|
+
if (!apiKey) {
|
|
86
|
+
console.error(`Error: ${embeddingConfig.apiKeyEnv} environment variable is required`);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
console.log(`Knowledge dir: ${knowledgeDir}`);
|
|
90
|
+
console.log(`Embedding model: ${embeddingConfig.model}`);
|
|
91
|
+
// Load existing embeddings and hashes
|
|
92
|
+
let existingEmbeddings = {};
|
|
93
|
+
let existingHashes = {};
|
|
94
|
+
if (existsSync(embeddingsPath)) {
|
|
95
|
+
existingEmbeddings = JSON.parse(readFileSync(embeddingsPath, "utf-8"));
|
|
96
|
+
}
|
|
97
|
+
if (existsSync(hashesPath)) {
|
|
98
|
+
existingHashes = JSON.parse(readFileSync(hashesPath, "utf-8"));
|
|
99
|
+
}
|
|
100
|
+
// Collect all docs
|
|
101
|
+
const files = collectMarkdownFiles(knowledgeDir);
|
|
102
|
+
const docs = [];
|
|
103
|
+
for (const filePath of files) {
|
|
104
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
105
|
+
const parsed = parseFrontmatter(raw);
|
|
106
|
+
if (!parsed.id)
|
|
107
|
+
continue;
|
|
108
|
+
const text = buildEmbeddingInput(parsed);
|
|
109
|
+
const hash = createHash("sha256").update(text).digest("hex");
|
|
110
|
+
docs.push({ id: parsed.id, text, hash });
|
|
111
|
+
}
|
|
112
|
+
console.log(`Found ${docs.length} documents`);
|
|
113
|
+
// Find docs that need (re-)embedding
|
|
114
|
+
const toEmbed = docs.filter((d) => !existingHashes[d.id] || existingHashes[d.id] !== d.hash);
|
|
115
|
+
console.log(`${toEmbed.length} documents need embedding (${docs.length - toEmbed.length} cached)`);
|
|
116
|
+
if (toEmbed.length === 0) {
|
|
117
|
+
console.log("All embeddings up to date!");
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
// Embed in batches of 20
|
|
121
|
+
const BATCH_SIZE = 20;
|
|
122
|
+
const newEmbeddings = { ...existingEmbeddings };
|
|
123
|
+
const newHashes = { ...existingHashes };
|
|
124
|
+
for (let i = 0; i < toEmbed.length; i += BATCH_SIZE) {
|
|
125
|
+
const batch = toEmbed.slice(i, i + BATCH_SIZE);
|
|
126
|
+
console.log(`Embedding batch ${Math.floor(i / BATCH_SIZE) + 1}/${Math.ceil(toEmbed.length / BATCH_SIZE)}...`);
|
|
127
|
+
const vectors = await embedBatch(batch.map((d) => d.text), embeddingConfig.model, apiKey);
|
|
128
|
+
for (let j = 0; j < batch.length; j++) {
|
|
129
|
+
newEmbeddings[batch[j].id] = vectors[j];
|
|
130
|
+
newHashes[batch[j].id] = batch[j].hash;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Remove embeddings for deleted docs
|
|
134
|
+
const validIds = new Set(docs.map((d) => d.id));
|
|
135
|
+
for (const id of Object.keys(newEmbeddings)) {
|
|
136
|
+
if (!validIds.has(id)) {
|
|
137
|
+
delete newEmbeddings[id];
|
|
138
|
+
delete newHashes[id];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// Write output
|
|
142
|
+
writeFileSync(embeddingsPath, JSON.stringify(newEmbeddings));
|
|
143
|
+
writeFileSync(hashesPath, JSON.stringify(newHashes));
|
|
144
|
+
console.log(`\nDone! Wrote ${Object.keys(newEmbeddings).length} embeddings to ${embeddingsPath}`);
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=generate-embeddings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-embeddings.js","sourceRoot":"","sources":["../src/generate-embeddings.ts"],"names":[],"mappings":"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"}
|
package/dist/graph.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type KnowledgeDocument } from "./loader.js";
|
|
2
|
+
import { type EmbeddingsStore } from "./embeddings.js";
|
|
3
|
+
export interface TagTaxonomy {
|
|
4
|
+
knownTags: Set<string>;
|
|
5
|
+
aliases: Map<string, string>;
|
|
6
|
+
}
|
|
7
|
+
export interface KnowledgeGraph {
|
|
8
|
+
documents: Map<string, KnowledgeDocument>;
|
|
9
|
+
embeddings: EmbeddingsStore;
|
|
10
|
+
tagIndex: Map<string, Set<string>>;
|
|
11
|
+
domainIndex: Map<string, Set<string>>;
|
|
12
|
+
phaseIndex: Map<number, Set<string>>;
|
|
13
|
+
typeIndex: Map<string, Set<string>>;
|
|
14
|
+
backlinkIndex: Map<string, Set<string>>;
|
|
15
|
+
tagTaxonomy: TagTaxonomy | null;
|
|
16
|
+
}
|
|
17
|
+
export declare function loadTagTaxonomy(knowledgeDir: string): TagTaxonomy | null;
|
|
18
|
+
export declare function buildGraph(knowledgeDir: string, validDomains?: string[] | null): KnowledgeGraph;
|
|
19
|
+
export declare function getAncestors(graph: KnowledgeGraph, docId: string): KnowledgeDocument[];
|
|
20
|
+
export declare function getRelated(graph: KnowledgeGraph, docId: string): KnowledgeDocument[];
|
package/dist/graph.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { loadDocuments } from "./loader.js";
|
|
4
|
+
import { loadEmbeddings } from "./embeddings.js";
|
|
5
|
+
import { log } from "./logger.js";
|
|
6
|
+
function buildTagIndex(docs) {
|
|
7
|
+
const index = new Map();
|
|
8
|
+
for (const doc of docs.values()) {
|
|
9
|
+
for (const tag of doc.tags) {
|
|
10
|
+
const lower = tag.toLowerCase();
|
|
11
|
+
if (!index.has(lower))
|
|
12
|
+
index.set(lower, new Set());
|
|
13
|
+
index.get(lower).add(doc.id);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return index;
|
|
17
|
+
}
|
|
18
|
+
function buildDomainIndex(docs) {
|
|
19
|
+
const index = new Map();
|
|
20
|
+
for (const doc of docs.values()) {
|
|
21
|
+
const domain = doc.domain.toLowerCase();
|
|
22
|
+
if (!index.has(domain))
|
|
23
|
+
index.set(domain, new Set());
|
|
24
|
+
index.get(domain).add(doc.id);
|
|
25
|
+
}
|
|
26
|
+
return index;
|
|
27
|
+
}
|
|
28
|
+
function buildPhaseIndex(docs) {
|
|
29
|
+
const index = new Map();
|
|
30
|
+
for (const doc of docs.values()) {
|
|
31
|
+
for (const phase of doc.phase) {
|
|
32
|
+
if (!index.has(phase))
|
|
33
|
+
index.set(phase, new Set());
|
|
34
|
+
index.get(phase).add(doc.id);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return index;
|
|
38
|
+
}
|
|
39
|
+
function buildTypeIndex(docs) {
|
|
40
|
+
const index = new Map();
|
|
41
|
+
for (const doc of docs.values()) {
|
|
42
|
+
if (!index.has(doc.type))
|
|
43
|
+
index.set(doc.type, new Set());
|
|
44
|
+
index.get(doc.type).add(doc.id);
|
|
45
|
+
}
|
|
46
|
+
return index;
|
|
47
|
+
}
|
|
48
|
+
function buildBacklinkIndex(docs) {
|
|
49
|
+
const index = new Map();
|
|
50
|
+
for (const doc of docs.values()) {
|
|
51
|
+
for (const targetId of doc.related) {
|
|
52
|
+
if (!index.has(targetId))
|
|
53
|
+
index.set(targetId, new Set());
|
|
54
|
+
index.get(targetId).add(doc.id);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return index;
|
|
58
|
+
}
|
|
59
|
+
export function loadTagTaxonomy(knowledgeDir) {
|
|
60
|
+
const tagsPath = join(knowledgeDir, ".tags.json");
|
|
61
|
+
try {
|
|
62
|
+
const raw = readFileSync(tagsPath, "utf-8");
|
|
63
|
+
const parsed = JSON.parse(raw);
|
|
64
|
+
const knownTags = new Set();
|
|
65
|
+
if (parsed.categories) {
|
|
66
|
+
for (const tags of Object.values(parsed.categories)) {
|
|
67
|
+
for (const tag of tags) {
|
|
68
|
+
knownTags.add(tag);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const aliases = new Map();
|
|
73
|
+
if (parsed.aliases) {
|
|
74
|
+
for (const [alias, canonical] of Object.entries(parsed.aliases)) {
|
|
75
|
+
aliases.set(alias.toLowerCase(), canonical);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
log.info("tag-taxonomy-loaded", { tagCount: knownTags.size, aliasCount: aliases.size });
|
|
79
|
+
return { knownTags, aliases };
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
log.debug("tag-taxonomy-skipped", { reason: "No .tags.json found or failed to parse" });
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export function buildGraph(knowledgeDir, validDomains) {
|
|
87
|
+
const documents = loadDocuments(knowledgeDir, validDomains);
|
|
88
|
+
const embeddings = loadEmbeddings(knowledgeDir);
|
|
89
|
+
const tagIndex = buildTagIndex(documents);
|
|
90
|
+
const domainIndex = buildDomainIndex(documents);
|
|
91
|
+
const phaseIndex = buildPhaseIndex(documents);
|
|
92
|
+
const typeIndex = buildTypeIndex(documents);
|
|
93
|
+
const backlinkIndex = buildBacklinkIndex(documents);
|
|
94
|
+
const tagTaxonomy = loadTagTaxonomy(knowledgeDir);
|
|
95
|
+
return {
|
|
96
|
+
documents,
|
|
97
|
+
embeddings,
|
|
98
|
+
tagIndex,
|
|
99
|
+
domainIndex,
|
|
100
|
+
phaseIndex,
|
|
101
|
+
typeIndex,
|
|
102
|
+
backlinkIndex,
|
|
103
|
+
tagTaxonomy,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
export function getAncestors(graph, docId) {
|
|
107
|
+
const ancestors = [];
|
|
108
|
+
let currentId = graph.documents.get(docId)?.parentId ?? null;
|
|
109
|
+
while (currentId) {
|
|
110
|
+
const parent = graph.documents.get(currentId);
|
|
111
|
+
if (!parent)
|
|
112
|
+
break;
|
|
113
|
+
ancestors.unshift(parent);
|
|
114
|
+
currentId = parent.parentId;
|
|
115
|
+
}
|
|
116
|
+
return ancestors;
|
|
117
|
+
}
|
|
118
|
+
export function getRelated(graph, docId) {
|
|
119
|
+
const doc = graph.documents.get(docId);
|
|
120
|
+
if (!doc)
|
|
121
|
+
return [];
|
|
122
|
+
// Merge forward links + backlinks, deduplicate
|
|
123
|
+
const relatedIds = new Set(doc.related);
|
|
124
|
+
const backlinks = graph.backlinkIndex.get(docId);
|
|
125
|
+
if (backlinks) {
|
|
126
|
+
for (const id of backlinks)
|
|
127
|
+
relatedIds.add(id);
|
|
128
|
+
}
|
|
129
|
+
return [...relatedIds]
|
|
130
|
+
.map((id) => graph.documents.get(id))
|
|
131
|
+
.filter((d) => d !== undefined);
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { type TfIdfIndex } from "./search.js";
|
|
3
|
+
import type { KnowledgeGraph } from "./graph.js";
|
|
4
|
+
import { type KnowledgeConfig } from "./config.js";
|
|
5
|
+
export interface KnowledgeServerResult {
|
|
6
|
+
server: McpServer;
|
|
7
|
+
graph: KnowledgeGraph;
|
|
8
|
+
tfidfIndex: TfIdfIndex;
|
|
9
|
+
config: KnowledgeConfig | null;
|
|
10
|
+
}
|
|
11
|
+
export declare function createKnowledgeServer(knowledgeDir: string): KnowledgeServerResult;
|
|
12
|
+
export type { KnowledgeGraph } from "./graph.js";
|
|
13
|
+
export type { KnowledgeDocument } from "./loader.js";
|
|
14
|
+
export type { KnowledgeConfig } from "./config.js";
|