@loom-node/knowledge 0.1.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/LICENSE +21 -0
- package/dist/chunkers/fixed-size.d.ts +12 -0
- package/dist/chunkers/fixed-size.d.ts.map +1 -0
- package/dist/chunkers/fixed-size.js +27 -0
- package/dist/chunkers/fixed-size.js.map +1 -0
- package/dist/chunkers/recursive.d.ts +13 -0
- package/dist/chunkers/recursive.d.ts.map +1 -0
- package/dist/chunkers/recursive.js +46 -0
- package/dist/chunkers/recursive.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge-base.d.ts +31 -0
- package/dist/knowledge-base.d.ts.map +1 -0
- package/dist/knowledge-base.js +93 -0
- package/dist/knowledge-base.js.map +1 -0
- package/dist/knowledge-provider.d.ts +9 -0
- package/dist/knowledge-provider.d.ts.map +1 -0
- package/dist/knowledge-provider.js +27 -0
- package/dist/knowledge-provider.js.map +1 -0
- package/dist/retrievers/graph-retriever.d.ts +12 -0
- package/dist/retrievers/graph-retriever.d.ts.map +1 -0
- package/dist/retrievers/graph-retriever.js +31 -0
- package/dist/retrievers/graph-retriever.js.map +1 -0
- package/dist/retrievers/hybrid-retriever.d.ts +13 -0
- package/dist/retrievers/hybrid-retriever.d.ts.map +1 -0
- package/dist/retrievers/hybrid-retriever.js +26 -0
- package/dist/retrievers/hybrid-retriever.js.map +1 -0
- package/dist/retrievers/keyword-retriever.d.ts +8 -0
- package/dist/retrievers/keyword-retriever.d.ts.map +1 -0
- package/dist/retrievers/keyword-retriever.js +24 -0
- package/dist/retrievers/keyword-retriever.js.map +1 -0
- package/dist/retrievers/vector-retriever.d.ts +12 -0
- package/dist/retrievers/vector-retriever.d.ts.map +1 -0
- package/dist/retrievers/vector-retriever.js +21 -0
- package/dist/retrievers/vector-retriever.js.map +1 -0
- package/dist/stores/in-memory-vector-store.d.ts +9 -0
- package/dist/stores/in-memory-vector-store.d.ts.map +1 -0
- package/dist/stores/in-memory-vector-store.js +39 -0
- package/dist/stores/in-memory-vector-store.js.map +1 -0
- package/package.json +27 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Loom Node Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Document, Chunk, Chunker } from '@loom-node/core';
|
|
2
|
+
export interface FixedSizeChunkerConfig {
|
|
3
|
+
chunkSize: number;
|
|
4
|
+
overlap?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare class FixedSizeChunker implements Chunker {
|
|
7
|
+
private readonly size;
|
|
8
|
+
private readonly overlap;
|
|
9
|
+
constructor(config: FixedSizeChunkerConfig);
|
|
10
|
+
chunk(doc: Document): Chunk[];
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=fixed-size.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixed-size.d.ts","sourceRoot":"","sources":["../../src/chunkers/fixed-size.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,gBAAiB,YAAW,OAAO;IAC9C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,MAAM,EAAE,sBAAsB;IAK1C,KAAK,CAAC,GAAG,EAAE,QAAQ,GAAG,KAAK,EAAE;CAmB9B"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export class FixedSizeChunker {
|
|
2
|
+
size;
|
|
3
|
+
overlap;
|
|
4
|
+
constructor(config) {
|
|
5
|
+
this.size = config.chunkSize;
|
|
6
|
+
this.overlap = config.overlap ?? 0;
|
|
7
|
+
}
|
|
8
|
+
chunk(doc) {
|
|
9
|
+
const chunks = [];
|
|
10
|
+
const step = this.size - this.overlap;
|
|
11
|
+
let index = 0;
|
|
12
|
+
for (let start = 0; start < doc.content.length; start += step) {
|
|
13
|
+
const content = doc.content.slice(start, start + this.size);
|
|
14
|
+
chunks.push({
|
|
15
|
+
id: `${doc.id}_chunk_${index}`,
|
|
16
|
+
documentId: doc.id,
|
|
17
|
+
content,
|
|
18
|
+
index,
|
|
19
|
+
tokens: Math.ceil(content.length / 4),
|
|
20
|
+
metadata: doc.metadata,
|
|
21
|
+
});
|
|
22
|
+
index++;
|
|
23
|
+
}
|
|
24
|
+
return chunks;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=fixed-size.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixed-size.js","sourceRoot":"","sources":["../../src/chunkers/fixed-size.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,gBAAgB;IACV,IAAI,CAAS;IACb,OAAO,CAAS;IAEjC,YAAY,MAA8B;QACxC,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,GAAa;QACjB,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;QACtC,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,IAAI,IAAI,EAAE,CAAC;YAC9D,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5D,MAAM,CAAC,IAAI,CAAC;gBACV,EAAE,EAAE,GAAG,GAAG,CAAC,EAAE,UAAU,KAAK,EAAE;gBAC9B,UAAU,EAAE,GAAG,CAAC,EAAE;gBAClB,OAAO;gBACP,KAAK;gBACL,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;gBACrC,QAAQ,EAAE,GAAG,CAAC,QAAQ;aACvB,CAAC,CAAC;YACH,KAAK,EAAE,CAAC;QACV,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Document, Chunk, Chunker } from '@loom-node/core';
|
|
2
|
+
export interface RecursiveChunkerConfig {
|
|
3
|
+
maxChunkSize: number;
|
|
4
|
+
separators?: string[];
|
|
5
|
+
}
|
|
6
|
+
export declare class RecursiveChunker implements Chunker {
|
|
7
|
+
private readonly maxSize;
|
|
8
|
+
private readonly separators;
|
|
9
|
+
constructor(config: RecursiveChunkerConfig);
|
|
10
|
+
chunk(doc: Document): Chunk[];
|
|
11
|
+
private split;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=recursive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recursive.d.ts","sourceRoot":"","sources":["../../src/chunkers/recursive.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAID,qBAAa,gBAAiB,YAAW,OAAO;IAC9C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAW;gBAE1B,MAAM,EAAE,sBAAsB;IAK1C,KAAK,CAAC,GAAG,EAAE,QAAQ,GAAG,KAAK,EAAE;IAY7B,OAAO,CAAC,KAAK;CAuBd"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const DEFAULT_SEPARATORS = ['\n\n', '\n', '. ', ' '];
|
|
2
|
+
export class RecursiveChunker {
|
|
3
|
+
maxSize;
|
|
4
|
+
separators;
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.maxSize = config.maxChunkSize;
|
|
7
|
+
this.separators = config.separators ?? DEFAULT_SEPARATORS;
|
|
8
|
+
}
|
|
9
|
+
chunk(doc) {
|
|
10
|
+
const pieces = this.split(doc.content, 0);
|
|
11
|
+
return pieces.map((content, index) => ({
|
|
12
|
+
id: `${doc.id}_chunk_${index}`,
|
|
13
|
+
documentId: doc.id,
|
|
14
|
+
content,
|
|
15
|
+
index,
|
|
16
|
+
tokens: Math.ceil(content.length / 4),
|
|
17
|
+
metadata: doc.metadata,
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
split(text, sepIdx) {
|
|
21
|
+
if (text.length <= this.maxSize)
|
|
22
|
+
return [text];
|
|
23
|
+
const sep = this.separators[sepIdx];
|
|
24
|
+
if (!sep)
|
|
25
|
+
return [text.slice(0, this.maxSize)];
|
|
26
|
+
const parts = text.split(sep);
|
|
27
|
+
const results = [];
|
|
28
|
+
let current = '';
|
|
29
|
+
for (const part of parts) {
|
|
30
|
+
const candidate = current ? current + sep + part : part;
|
|
31
|
+
if (candidate.length > this.maxSize && current) {
|
|
32
|
+
results.push(current);
|
|
33
|
+
current = part.length > this.maxSize
|
|
34
|
+
? this.split(part, sepIdx + 1)[0]
|
|
35
|
+
: part;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
current = candidate;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (current)
|
|
42
|
+
results.push(current);
|
|
43
|
+
return results;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=recursive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recursive.js","sourceRoot":"","sources":["../../src/chunkers/recursive.ts"],"names":[],"mappings":"AAOA,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;AAErD,MAAM,OAAO,gBAAgB;IACV,OAAO,CAAS;IAChB,UAAU,CAAW;IAEtC,YAAY,MAA8B;QACxC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,YAAY,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,kBAAkB,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,GAAa;QACjB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC1C,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YACrC,EAAE,EAAE,GAAG,GAAG,CAAC,EAAE,UAAU,KAAK,EAAE;YAC9B,UAAU,EAAE,GAAG,CAAC,EAAE;YAClB,OAAO;YACP,KAAK;YACL,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YACrC,QAAQ,EAAE,GAAG,CAAC,QAAQ;SACvB,CAAC,CAAC,CAAC;IACN,CAAC;IAEO,KAAK,CAAC,IAAY,EAAE,MAAc;QACxC,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG;YAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAE/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,IAAI,OAAO,GAAG,EAAE,CAAC;QAEjB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;YACxD,IAAI,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,EAAE,CAAC;gBAC/C,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACtB,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO;oBAClC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;oBACjC,CAAC,CAAC,IAAI,CAAC;YACX,CAAC;iBAAM,CAAC;gBACN,OAAO,GAAG,SAAS,CAAC;YACtB,CAAC;QACH,CAAC;QACD,IAAI,OAAO;YAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { FixedSizeChunker } from './chunkers/fixed-size.js';
|
|
2
|
+
export type { FixedSizeChunkerConfig } from './chunkers/fixed-size.js';
|
|
3
|
+
export { RecursiveChunker } from './chunkers/recursive.js';
|
|
4
|
+
export type { RecursiveChunkerConfig } from './chunkers/recursive.js';
|
|
5
|
+
export { KeywordRetriever } from './retrievers/keyword-retriever.js';
|
|
6
|
+
export { VectorRetriever } from './retrievers/vector-retriever.js';
|
|
7
|
+
export type { VectorRetrieverConfig } from './retrievers/vector-retriever.js';
|
|
8
|
+
export { GraphRetriever } from './retrievers/graph-retriever.js';
|
|
9
|
+
export type { GraphRetrieverConfig } from './retrievers/graph-retriever.js';
|
|
10
|
+
export { HybridRetriever } from './retrievers/hybrid-retriever.js';
|
|
11
|
+
export type { HybridRetrieverConfig } from './retrievers/hybrid-retriever.js';
|
|
12
|
+
export { KnowledgeBase } from './knowledge-base.js';
|
|
13
|
+
export type { KnowledgeBaseConfig } from './knowledge-base.js';
|
|
14
|
+
export { KnowledgeProvider } from './knowledge-provider.js';
|
|
15
|
+
export { InMemoryVectorStore } from './stores/in-memory-vector-store.js';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,YAAY,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,YAAY,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,YAAY,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,YAAY,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { FixedSizeChunker } from './chunkers/fixed-size.js';
|
|
2
|
+
export { RecursiveChunker } from './chunkers/recursive.js';
|
|
3
|
+
export { KeywordRetriever } from './retrievers/keyword-retriever.js';
|
|
4
|
+
export { VectorRetriever } from './retrievers/vector-retriever.js';
|
|
5
|
+
export { GraphRetriever } from './retrievers/graph-retriever.js';
|
|
6
|
+
export { HybridRetriever } from './retrievers/hybrid-retriever.js';
|
|
7
|
+
export { KnowledgeBase } from './knowledge-base.js';
|
|
8
|
+
export { KnowledgeProvider } from './knowledge-provider.js';
|
|
9
|
+
export { InMemoryVectorStore } from './stores/in-memory-vector-store.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Document, Chunker, KnowledgeBase as IKnowledgeBase, RetrieverOptions, RetrievalResult, EmbeddingProvider, VectorStore, GraphStore, EntityExtractor } from '@loom-node/core';
|
|
2
|
+
export interface KnowledgeBaseConfig {
|
|
3
|
+
chunker: Chunker;
|
|
4
|
+
embedder?: EmbeddingProvider;
|
|
5
|
+
vectorStore?: VectorStore;
|
|
6
|
+
graphStore?: GraphStore;
|
|
7
|
+
entityExtractor?: EntityExtractor;
|
|
8
|
+
weights?: {
|
|
9
|
+
keyword?: number;
|
|
10
|
+
vector?: number;
|
|
11
|
+
graph?: number;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export declare class KnowledgeBase implements IKnowledgeBase {
|
|
15
|
+
private readonly chunker;
|
|
16
|
+
private readonly keywordRetriever;
|
|
17
|
+
private readonly vectorRetriever?;
|
|
18
|
+
private readonly graphRetriever?;
|
|
19
|
+
private readonly hybridRetriever;
|
|
20
|
+
private readonly embedder?;
|
|
21
|
+
private readonly vectorStore?;
|
|
22
|
+
private readonly graphStore?;
|
|
23
|
+
private readonly entityExtractor?;
|
|
24
|
+
private readonly docs;
|
|
25
|
+
constructor(config: KnowledgeBaseConfig);
|
|
26
|
+
ingest(docs: Document[]): Promise<void>;
|
|
27
|
+
private ingestOne;
|
|
28
|
+
query(query: string, opts?: RetrieverOptions): Promise<RetrievalResult[]>;
|
|
29
|
+
delete(documentIds: string[]): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=knowledge-base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-base.d.ts","sourceRoot":"","sources":["../src/knowledge-base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EAER,OAAO,EACP,aAAa,IAAI,cAAc,EAC/B,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAMzB,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACjE;AAED,qBAAa,aAAc,YAAW,cAAc;IAClD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA0B;IAC3D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAiB;IACjD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAoB;IAC9C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA8B;gBAEvC,MAAM,EAAE,mBAAmB;IA4BjC,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAM/B,SAAS;IAwCjB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAIzE,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAanD"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { KeywordRetriever } from './retrievers/keyword-retriever.js';
|
|
2
|
+
import { VectorRetriever } from './retrievers/vector-retriever.js';
|
|
3
|
+
import { GraphRetriever } from './retrievers/graph-retriever.js';
|
|
4
|
+
import { HybridRetriever } from './retrievers/hybrid-retriever.js';
|
|
5
|
+
export class KnowledgeBase {
|
|
6
|
+
chunker;
|
|
7
|
+
keywordRetriever = new KeywordRetriever();
|
|
8
|
+
vectorRetriever;
|
|
9
|
+
graphRetriever;
|
|
10
|
+
hybridRetriever;
|
|
11
|
+
embedder;
|
|
12
|
+
vectorStore;
|
|
13
|
+
graphStore;
|
|
14
|
+
entityExtractor;
|
|
15
|
+
docs = new Map();
|
|
16
|
+
constructor(config) {
|
|
17
|
+
this.chunker = config.chunker;
|
|
18
|
+
this.embedder = config.embedder;
|
|
19
|
+
this.vectorStore = config.vectorStore;
|
|
20
|
+
this.graphStore = config.graphStore;
|
|
21
|
+
this.entityExtractor = config.entityExtractor;
|
|
22
|
+
const w = config.weights ?? {};
|
|
23
|
+
const retrievers = [
|
|
24
|
+
{ retriever: this.keywordRetriever, weight: w.keyword ?? 0.3 },
|
|
25
|
+
];
|
|
26
|
+
if (config.embedder && config.vectorStore) {
|
|
27
|
+
this.vectorRetriever = new VectorRetriever({
|
|
28
|
+
embedder: config.embedder,
|
|
29
|
+
store: config.vectorStore,
|
|
30
|
+
});
|
|
31
|
+
retrievers.push({ retriever: this.vectorRetriever, weight: w.vector ?? 0.5 });
|
|
32
|
+
}
|
|
33
|
+
if (config.graphStore) {
|
|
34
|
+
this.graphRetriever = new GraphRetriever({ store: config.graphStore });
|
|
35
|
+
retrievers.push({ retriever: this.graphRetriever, weight: w.graph ?? 0.2 });
|
|
36
|
+
}
|
|
37
|
+
this.hybridRetriever = new HybridRetriever({ retrievers });
|
|
38
|
+
}
|
|
39
|
+
async ingest(docs) {
|
|
40
|
+
for (const doc of docs) {
|
|
41
|
+
await this.ingestOne(doc);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async ingestOne(doc) {
|
|
45
|
+
const chunks = this.chunker.chunk(doc);
|
|
46
|
+
this.docs.set(doc.id, chunks);
|
|
47
|
+
this.keywordRetriever.addChunks(chunks);
|
|
48
|
+
if (this.embedder && this.vectorStore) {
|
|
49
|
+
const texts = chunks.map(c => c.content);
|
|
50
|
+
const vectors = await this.embedder.embedBatch(texts);
|
|
51
|
+
await this.vectorStore.upsert(chunks.map((c, i) => ({
|
|
52
|
+
id: c.id,
|
|
53
|
+
vector: vectors[i],
|
|
54
|
+
content: c.content,
|
|
55
|
+
metadata: { chunk: JSON.stringify(c), documentId: doc.id },
|
|
56
|
+
})));
|
|
57
|
+
}
|
|
58
|
+
if (this.entityExtractor && this.graphStore) {
|
|
59
|
+
const { entities, relations } = await this.entityExtractor.extract(doc.content);
|
|
60
|
+
await this.graphStore.addNodes(entities.map((e, i) => ({
|
|
61
|
+
id: `${doc.id}_entity_${i}`,
|
|
62
|
+
type: e.type,
|
|
63
|
+
name: e.name,
|
|
64
|
+
properties: { ...e.properties, documentId: doc.id },
|
|
65
|
+
})));
|
|
66
|
+
await this.graphStore.addEdges(relations.map((r, i) => ({
|
|
67
|
+
id: `${doc.id}_rel_${i}`,
|
|
68
|
+
source: r.source,
|
|
69
|
+
target: r.target,
|
|
70
|
+
relation: r.relation,
|
|
71
|
+
properties: { documentId: doc.id },
|
|
72
|
+
})));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async query(query, opts) {
|
|
76
|
+
return this.hybridRetriever.retrieve(query, opts);
|
|
77
|
+
}
|
|
78
|
+
async delete(documentIds) {
|
|
79
|
+
for (const id of documentIds) {
|
|
80
|
+
this.docs.delete(id);
|
|
81
|
+
this.keywordRetriever.removeByDocument(id);
|
|
82
|
+
if (this.vectorStore) {
|
|
83
|
+
const chunks = this.docs.get(id);
|
|
84
|
+
if (chunks)
|
|
85
|
+
await this.vectorStore.delete(chunks.map(c => c.id));
|
|
86
|
+
}
|
|
87
|
+
if (this.graphStore) {
|
|
88
|
+
await this.graphStore.deleteByDocument(id);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=knowledge-base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-base.js","sourceRoot":"","sources":["../src/knowledge-base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ContextProvider, ContextFragment } from '@loom-node/core';
|
|
2
|
+
import type { KnowledgeBase } from './knowledge-base.js';
|
|
3
|
+
export declare class KnowledgeProvider implements ContextProvider {
|
|
4
|
+
private kb;
|
|
5
|
+
readonly source: "knowledge";
|
|
6
|
+
constructor(kb: KnowledgeBase);
|
|
7
|
+
provide(query: string, budget: number): Promise<ContextFragment[]>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=knowledge-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-provider.d.ts","sourceRoot":"","sources":["../src/knowledge-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAoB,MAAM,iBAAiB,CAAC;AAC1F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,qBAAa,iBAAkB,YAAW,eAAe;IAG3C,OAAO,CAAC,EAAE;IAFtB,QAAQ,CAAC,MAAM,EAAG,WAAW,CAAU;gBAEnB,EAAE,EAAE,aAAa;IAE/B,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CAmBzE"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export class KnowledgeProvider {
|
|
2
|
+
kb;
|
|
3
|
+
source = 'knowledge';
|
|
4
|
+
constructor(kb) {
|
|
5
|
+
this.kb = kb;
|
|
6
|
+
}
|
|
7
|
+
async provide(query, budget) {
|
|
8
|
+
const results = await this.kb.query(query, { limit: 10 });
|
|
9
|
+
const fragments = [];
|
|
10
|
+
let used = 0;
|
|
11
|
+
for (const r of results) {
|
|
12
|
+
const tokens = r.chunk.tokens ?? Math.ceil(r.chunk.content.length / 4);
|
|
13
|
+
if (used + tokens > budget)
|
|
14
|
+
break;
|
|
15
|
+
fragments.push({
|
|
16
|
+
source: 'knowledge',
|
|
17
|
+
content: r.chunk.content,
|
|
18
|
+
tokens,
|
|
19
|
+
relevance: r.score,
|
|
20
|
+
metadata: { chunkId: r.chunk.id, documentId: r.chunk.documentId },
|
|
21
|
+
});
|
|
22
|
+
used += tokens;
|
|
23
|
+
}
|
|
24
|
+
return fragments;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=knowledge-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-provider.js","sourceRoot":"","sources":["../src/knowledge-provider.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,iBAAiB;IAGR;IAFX,MAAM,GAAG,WAAoB,CAAC;IAEvC,YAAoB,EAAiB;QAAjB,OAAE,GAAF,EAAE,CAAe;IAAG,CAAC;IAEzC,KAAK,CAAC,OAAO,CAAC,KAAa,EAAE,MAAc;QACzC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAA6B,CAAC,CAAC;QACrF,MAAM,SAAS,GAAsB,EAAE,CAAC;QACxC,IAAI,IAAI,GAAG,CAAC,CAAC;QAEb,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACvE,IAAI,IAAI,GAAG,MAAM,GAAG,MAAM;gBAAE,MAAM;YAClC,SAAS,CAAC,IAAI,CAAC;gBACb,MAAM,EAAE,WAAW;gBACnB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO;gBACxB,MAAM;gBACN,SAAS,EAAE,CAAC,CAAC,KAAK;gBAClB,QAAQ,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,EAAE;aAClE,CAAC,CAAC;YACH,IAAI,IAAI,MAAM,CAAC;QACjB,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Retriever, RetrieverOptions, RetrievalResult, GraphStore } from '@loom-node/core';
|
|
2
|
+
export interface GraphRetrieverConfig {
|
|
3
|
+
store: GraphStore;
|
|
4
|
+
depth?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare class GraphRetriever implements Retriever {
|
|
7
|
+
private readonly store;
|
|
8
|
+
private readonly depth;
|
|
9
|
+
constructor(config: GraphRetrieverConfig);
|
|
10
|
+
retrieve(query: string, opts?: RetrieverOptions): Promise<RetrievalResult[]>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=graph-retriever.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-retriever.d.ts","sourceRoot":"","sources":["../../src/retrievers/graph-retriever.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,SAAS,EACT,gBAAgB,EAChB,eAAe,EACf,UAAU,EACX,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,cAAe,YAAW,SAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,MAAM,EAAE,oBAAoB;IAKlC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CAwBnF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export class GraphRetriever {
|
|
2
|
+
store;
|
|
3
|
+
depth;
|
|
4
|
+
constructor(config) {
|
|
5
|
+
this.store = config.store;
|
|
6
|
+
this.depth = config.depth ?? 2;
|
|
7
|
+
}
|
|
8
|
+
async retrieve(query, opts) {
|
|
9
|
+
const limit = opts?.limit ?? 5;
|
|
10
|
+
const nodes = await this.store.search(query, limit);
|
|
11
|
+
const results = [];
|
|
12
|
+
for (const node of nodes) {
|
|
13
|
+
const { nodes: neighbors } = await this.store.getNeighbors(node.id, this.depth);
|
|
14
|
+
const context = [node, ...neighbors]
|
|
15
|
+
.map(n => `${n.type}:${n.name}`)
|
|
16
|
+
.join(' -> ');
|
|
17
|
+
results.push({
|
|
18
|
+
chunk: {
|
|
19
|
+
id: `graph_${node.id}`,
|
|
20
|
+
documentId: node.properties['documentId'] ?? '',
|
|
21
|
+
content: context,
|
|
22
|
+
index: 0,
|
|
23
|
+
metadata: { graphNode: node.id, type: node.type },
|
|
24
|
+
},
|
|
25
|
+
score: 1 / (results.length + 1),
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return results.slice(0, limit);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=graph-retriever.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-retriever.js","sourceRoot":"","sources":["../../src/retrievers/graph-retriever.ts"],"names":[],"mappings":"AAaA,MAAM,OAAO,cAAc;IACR,KAAK,CAAa;IAClB,KAAK,CAAS;IAE/B,YAAY,MAA4B;QACtC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,KAAa,EAAE,IAAuB;QACnD,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAEpD,MAAM,OAAO,GAAsB,EAAE,CAAC;QACtC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YAChF,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,GAAG,SAAS,CAAC;iBACjC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;iBAC/B,IAAI,CAAC,MAAM,CAAC,CAAC;YAEhB,OAAO,CAAC,IAAI,CAAC;gBACX,KAAK,EAAE;oBACL,EAAE,EAAE,SAAS,IAAI,CAAC,EAAE,EAAE;oBACtB,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAW,IAAI,EAAE;oBACzD,OAAO,EAAE,OAAO;oBAChB,KAAK,EAAE,CAAC;oBACR,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;iBAClC;gBACjB,KAAK,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;aAChC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Retriever, RetrieverOptions, RetrievalResult } from '@loom-node/core';
|
|
2
|
+
export interface HybridRetrieverConfig {
|
|
3
|
+
retrievers: {
|
|
4
|
+
retriever: Retriever;
|
|
5
|
+
weight: number;
|
|
6
|
+
}[];
|
|
7
|
+
}
|
|
8
|
+
export declare class HybridRetriever implements Retriever {
|
|
9
|
+
private readonly retrievers;
|
|
10
|
+
constructor(config: HybridRetrieverConfig);
|
|
11
|
+
retrieve(query: string, opts?: RetrieverOptions): Promise<RetrievalResult[]>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=hybrid-retriever.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hybrid-retriever.d.ts","sourceRoot":"","sources":["../../src/retrievers/hybrid-retriever.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEpF,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE;QAAE,SAAS,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACxD;AAED,qBAAa,eAAgB,YAAW,SAAS;IAC/C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6C;gBAE5D,MAAM,EAAE,qBAAqB;IAInC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CAuBnF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export class HybridRetriever {
|
|
2
|
+
retrievers;
|
|
3
|
+
constructor(config) {
|
|
4
|
+
this.retrievers = config.retrievers;
|
|
5
|
+
}
|
|
6
|
+
async retrieve(query, opts) {
|
|
7
|
+
const limit = opts?.limit ?? 5;
|
|
8
|
+
const allResults = await Promise.all(this.retrievers.map(async ({ retriever, weight }) => {
|
|
9
|
+
const results = await retriever.retrieve(query, { ...opts, limit: limit * 2 });
|
|
10
|
+
return results.map(r => ({ ...r, score: r.score * weight }));
|
|
11
|
+
}));
|
|
12
|
+
const merged = new Map();
|
|
13
|
+
for (const results of allResults) {
|
|
14
|
+
for (const r of results) {
|
|
15
|
+
const existing = merged.get(r.chunk.id);
|
|
16
|
+
if (!existing || r.score > existing.score) {
|
|
17
|
+
merged.set(r.chunk.id, r);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return [...merged.values()]
|
|
22
|
+
.sort((a, b) => b.score - a.score)
|
|
23
|
+
.slice(0, limit);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=hybrid-retriever.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hybrid-retriever.js","sourceRoot":"","sources":["../../src/retrievers/hybrid-retriever.ts"],"names":[],"mappings":"AAMA,MAAM,OAAO,eAAe;IACT,UAAU,CAA6C;IAExE,YAAY,MAA6B;QACvC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,KAAa,EAAE,IAAuB;QACnD,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,CAAC,CAAC;QAC/B,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAClC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE;YAClD,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC;YAC/E,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAC,CACH,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,GAAG,EAA2B,CAAC;QAClD,KAAK,MAAM,OAAO,IAAI,UAAU,EAAE,CAAC;YACjC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACxC,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;oBAC1C,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;gBAC5B,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;aACxB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;aACjC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACrB,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Chunk, Retriever, RetrieverOptions, RetrievalResult } from '@loom-node/core';
|
|
2
|
+
export declare class KeywordRetriever implements Retriever {
|
|
3
|
+
private chunks;
|
|
4
|
+
addChunks(chunks: Chunk[]): void;
|
|
5
|
+
removeByDocument(documentId: string): void;
|
|
6
|
+
retrieve(query: string, opts?: RetrieverOptions): Promise<RetrievalResult[]>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=keyword-retriever.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyword-retriever.d.ts","sourceRoot":"","sources":["../../src/retrievers/keyword-retriever.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAE3F,qBAAa,gBAAiB,YAAW,SAAS;IAChD,OAAO,CAAC,MAAM,CAAe;IAE7B,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI;IAIhC,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIpC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CAgBnF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export class KeywordRetriever {
|
|
2
|
+
chunks = [];
|
|
3
|
+
addChunks(chunks) {
|
|
4
|
+
this.chunks.push(...chunks);
|
|
5
|
+
}
|
|
6
|
+
removeByDocument(documentId) {
|
|
7
|
+
this.chunks = this.chunks.filter(c => c.documentId !== documentId);
|
|
8
|
+
}
|
|
9
|
+
async retrieve(query, opts) {
|
|
10
|
+
const limit = opts?.limit ?? 5;
|
|
11
|
+
const minScore = opts?.minScore ?? 0;
|
|
12
|
+
const terms = query.toLowerCase().split(/\s+/).filter(Boolean);
|
|
13
|
+
const scored = this.chunks.map(chunk => {
|
|
14
|
+
const lower = chunk.content.toLowerCase();
|
|
15
|
+
const hits = terms.filter(t => lower.includes(t)).length;
|
|
16
|
+
return { chunk, score: terms.length > 0 ? hits / terms.length : 0 };
|
|
17
|
+
});
|
|
18
|
+
return scored
|
|
19
|
+
.filter(r => r.score > minScore)
|
|
20
|
+
.sort((a, b) => b.score - a.score)
|
|
21
|
+
.slice(0, limit);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=keyword-retriever.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyword-retriever.js","sourceRoot":"","sources":["../../src/retrievers/keyword-retriever.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,gBAAgB;IACnB,MAAM,GAAY,EAAE,CAAC;IAE7B,SAAS,CAAC,MAAe;QACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;IAC9B,CAAC;IAED,gBAAgB,CAAC,UAAkB;QACjC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,KAAa,EAAE,IAAuB;QACnD,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,CAAC,CAAC;QAC/B,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,IAAI,CAAC,CAAC;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAE/D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YACrC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACzD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM;aACV,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,QAAQ,CAAC;aAC/B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;aACjC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACrB,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Retriever, RetrieverOptions, RetrievalResult, EmbeddingProvider, VectorStore } from '@loom-node/core';
|
|
2
|
+
export interface VectorRetrieverConfig {
|
|
3
|
+
embedder: EmbeddingProvider;
|
|
4
|
+
store: VectorStore;
|
|
5
|
+
}
|
|
6
|
+
export declare class VectorRetriever implements Retriever {
|
|
7
|
+
private readonly embedder;
|
|
8
|
+
private readonly store;
|
|
9
|
+
constructor(config: VectorRetrieverConfig);
|
|
10
|
+
retrieve(query: string, opts?: RetrieverOptions): Promise<RetrievalResult[]>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=vector-retriever.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vector-retriever.d.ts","sourceRoot":"","sources":["../../src/retrievers/vector-retriever.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,SAAS,EACT,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,WAAW,EACZ,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,qBAAa,eAAgB,YAAW,SAAS;IAC/C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;gBAExB,MAAM,EAAE,qBAAqB;IAKnC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CAanF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export class VectorRetriever {
|
|
2
|
+
embedder;
|
|
3
|
+
store;
|
|
4
|
+
constructor(config) {
|
|
5
|
+
this.embedder = config.embedder;
|
|
6
|
+
this.store = config.store;
|
|
7
|
+
}
|
|
8
|
+
async retrieve(query, opts) {
|
|
9
|
+
const limit = opts?.limit ?? 5;
|
|
10
|
+
const minScore = opts?.minScore ?? 0;
|
|
11
|
+
const vector = await this.embedder.embed(query);
|
|
12
|
+
const results = await this.store.search(vector, limit, opts?.filter);
|
|
13
|
+
return results
|
|
14
|
+
.filter(r => r.score >= minScore)
|
|
15
|
+
.map(r => ({
|
|
16
|
+
chunk: JSON.parse(r.metadata['chunk']),
|
|
17
|
+
score: r.score,
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=vector-retriever.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vector-retriever.js","sourceRoot":"","sources":["../../src/retrievers/vector-retriever.ts"],"names":[],"mappings":"AAcA,MAAM,OAAO,eAAe;IACT,QAAQ,CAAoB;IAC5B,KAAK,CAAc;IAEpC,YAAY,MAA6B;QACvC,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QAChC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,KAAa,EAAE,IAAuB;QACnD,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,CAAC,CAAC;QAC/B,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,IAAI,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAErE,OAAO,OAAO;aACX,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC;aAChC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACT,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAW,CAAU;YACzD,KAAK,EAAE,CAAC,CAAC,KAAK;SACf,CAAC,CAAC,CAAC;IACR,CAAC;CACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { VectorStore, VectorEntry, VectorSearchResult } from '@loom-node/core';
|
|
2
|
+
export declare class InMemoryVectorStore implements VectorStore {
|
|
3
|
+
private entries;
|
|
4
|
+
upsert(entries: VectorEntry[]): Promise<void>;
|
|
5
|
+
search(vector: number[], limit: number, filter?: Record<string, unknown>): Promise<VectorSearchResult[]>;
|
|
6
|
+
delete(ids: string[]): Promise<void>;
|
|
7
|
+
private matchFilter;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=in-memory-vector-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-vector-store.d.ts","sourceRoot":"","sources":["../../src/stores/in-memory-vector-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAEpF,qBAAa,mBAAoB,YAAW,WAAW;IACrD,OAAO,CAAC,OAAO,CAAkC;IAE3C,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7C,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAcxG,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,OAAO,CAAC,WAAW;CAGpB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export class InMemoryVectorStore {
|
|
2
|
+
entries = new Map();
|
|
3
|
+
async upsert(entries) {
|
|
4
|
+
for (const e of entries)
|
|
5
|
+
this.entries.set(e.id, e);
|
|
6
|
+
}
|
|
7
|
+
async search(vector, limit, filter) {
|
|
8
|
+
const results = [];
|
|
9
|
+
for (const entry of this.entries.values()) {
|
|
10
|
+
if (filter && !this.matchFilter(entry.metadata, filter))
|
|
11
|
+
continue;
|
|
12
|
+
results.push({
|
|
13
|
+
id: entry.id,
|
|
14
|
+
score: cosine(vector, entry.vector),
|
|
15
|
+
content: entry.content,
|
|
16
|
+
metadata: entry.metadata,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
return results.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
20
|
+
}
|
|
21
|
+
async delete(ids) {
|
|
22
|
+
for (const id of ids)
|
|
23
|
+
this.entries.delete(id);
|
|
24
|
+
}
|
|
25
|
+
matchFilter(metadata, filter) {
|
|
26
|
+
return Object.entries(filter).every(([k, v]) => metadata[k] === v);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function cosine(a, b) {
|
|
30
|
+
let dot = 0, na = 0, nb = 0;
|
|
31
|
+
for (let i = 0; i < a.length; i++) {
|
|
32
|
+
dot += a[i] * b[i];
|
|
33
|
+
na += a[i] * a[i];
|
|
34
|
+
nb += b[i] * b[i];
|
|
35
|
+
}
|
|
36
|
+
const denom = Math.sqrt(na) * Math.sqrt(nb);
|
|
37
|
+
return denom === 0 ? 0 : dot / denom;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=in-memory-vector-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-vector-store.js","sourceRoot":"","sources":["../../src/stores/in-memory-vector-store.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,mBAAmB;IACtB,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;IAEjD,KAAK,CAAC,MAAM,CAAC,OAAsB;QACjC,KAAK,MAAM,CAAC,IAAI,OAAO;YAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAgB,EAAE,KAAa,EAAE,MAAgC;QAC5E,MAAM,OAAO,GAAyB,EAAE,CAAC;QACzC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1C,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAAE,SAAS;YAClE,OAAO,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;gBACnC,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;aACzB,CAAC,CAAC;QACL,CAAC;QACD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAa;QACxB,KAAK,MAAM,EAAE,IAAI,GAAG;YAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAChD,CAAC;IAEO,WAAW,CAAC,QAAiC,EAAE,MAA+B;QACpF,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACrE,CAAC;CACF;AAED,SAAS,MAAM,CAAC,CAAW,EAAE,CAAW;IACtC,IAAI,GAAG,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACnB,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClB,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5C,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC;AACvC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@loom-node/knowledge",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@loom-node/core": "0.1.0"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc -b",
|
|
25
|
+
"clean": "rm -rf dist .tsbuildinfo"
|
|
26
|
+
}
|
|
27
|
+
}
|