knowy 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.
Files changed (3) hide show
  1. package/README.md +108 -0
  2. package/knowy.js +116 -0
  3. package/package.json +39 -0
package/README.md ADDED
@@ -0,0 +1,108 @@
1
+ # Knowy
2
+
3
+ A local-first, zero-config knowledge base engine with semantic vector search. Built on LanceDB and Hugging Face Transformers.
4
+
5
+ ## Features
6
+
7
+ - 🔍 **Semantic Search** - Find relevant content using natural language queries
8
+ - 💾 **Local-First** - All data stored locally using LanceDB (no cloud required)
9
+ - 🧠 **Built-in Embeddings** - Uses Qwen3-Embedding-0.6B-ONNX for high-quality vectors
10
+ - 📚 **Knowledge Base Organization** - Group data into named knowledge bases
11
+ - ❓ **Q&A Support** - Store question-answer pairs or free text documents
12
+ - 🚀 **Zero Configuration** - Works out of the box with sensible defaults
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install knowy
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ```javascript
23
+ import { knowy } from 'knowy';
24
+
25
+ // Initialize the engine
26
+ const kbs = await knowy('./my_database');
27
+
28
+ // Create or access a knowledge base
29
+ const docs = kbs('documentation');
30
+
31
+ // Add Q&A pairs
32
+ await docs.addQA('getting-started', 'How do I install?', 'Run npm install knowy');
33
+
34
+ // Or add free text
35
+ await docs.addText('api-reference', 'The API supports vector search with cosine similarity...');
36
+
37
+ // Search across your knowledge base
38
+ const results = await docs.search('how to install this package?', { limit: 5 });
39
+ console.log(results);
40
+ ```
41
+
42
+ ## API Reference
43
+
44
+ ### `knowy(dbPath)`
45
+
46
+ Initialize the Knowy engine.
47
+
48
+ - `dbPath` (string): Path to the LanceDB database directory (default: `\"./knowy_database\"`)
49
+
50
+ Returns a `kbs` function with attached methods.
51
+
52
+ ### `kbs(kbName)`
53
+
54
+ Get or create a knowledge base.
55
+
56
+ Returns a knowledge base object with methods:
57
+ - `addQA(topic, question, answer)` - Add a Q&A pair
58
+ - `addText(topic, text)` - Add free text content
59
+ - `search(query, options)` - Search within this KB
60
+ - `delete()` - Delete this knowledge base
61
+
62
+ ### `kbs.search(query, options)`
63
+
64
+ Search across all knowledge bases.
65
+
66
+ - `query` (string): Search query
67
+ - `options.kbs` (string|string[]): Filter by specific knowledge base(s)
68
+ - `options.limit` (number): Max results (default: 10)
69
+
70
+ Returns array of results with `kb`, `topic`, `type`, `content`, and `score` (0-1).
71
+
72
+ ### `kbs.list()`
73
+
74
+ List all knowledge bases.
75
+
76
+ ## Example: Multi-KB Setup
77
+
78
+ ```javascript
79
+ const kbs = await knowy();
80
+
81
+ // Separate KBs for different domains
82
+ const codeKB = kbs('code-snippets');
83
+ const docsKB = kbs('documentation');
84
+ const supportKB = kbs('support-tickets');
85
+
86
+ // Add content to each...
87
+ await codeKB.addText('auth', 'JWT authentication implementation...');
88
+ await docsKB.addQA('setup', 'Node version?', 'Requires Node 18+');
89
+ await supportKB.addQA('billing', 'How to cancel?', 'Go to settings > billing...');
90
+
91
+ // Search everything
92
+ const allResults = await kbs.search('authentication', { limit: 10 });
93
+
94
+ // Search specific KBs only
95
+ const codeOnly = await kbs.search('authentication', { kbs: 'code-snippets' });
96
+ ```
97
+
98
+ ## Search Scoring
99
+
100
+ Results include a `score` from 0 to 1, where 1 is a perfect match. The score is calculated using cosine similarity between the query embedding and stored vectors.
101
+
102
+ ## Requirements
103
+
104
+ - Node.js >= 18.0.0
105
+
106
+ ## License
107
+
108
+ MIT © littlejustnode
package/knowy.js ADDED
@@ -0,0 +1,116 @@
1
+ import { pipeline } from '@huggingface/transformers';
2
+ import * as lancedb from "@lancedb/lancedb";
3
+ import crypto from "crypto";
4
+
5
+ class KnowyEngine {
6
+ constructor(dbPath) {
7
+ this.dbPath = dbPath;
8
+ this.modelId = 'onnx-community/Qwen3-Embedding-0.6B-ONNX';
9
+ this.tableName = "all_knowledge_records";
10
+ this.extractor = null;
11
+ this.db = null;
12
+ this.table = null;
13
+ }
14
+
15
+ async init() {
16
+ this.extractor = await pipeline('feature-extraction', this.modelId, { dtype: 'fp32' });
17
+ this.db = await lancedb.connect(this.dbPath);
18
+ const tableNames = await this.db.tableNames();
19
+ if (tableNames.includes(this.tableName)) {
20
+ this.table = await this.db.openTable(this.tableName);
21
+ }
22
+ return this;
23
+ }
24
+
25
+ async _getEmbedding(text) {
26
+ const output = await this.extractor(text, { pooling: 'last_token', normalize: true });
27
+ return Array.from(output.data);
28
+ }
29
+
30
+ async _upsert(record) {
31
+ if (!this.table) {
32
+ this.table = await this.db.createTable(this.tableName, [record]);
33
+ } else {
34
+ await this.table.add([record]);
35
+ }
36
+ }
37
+
38
+ getKB(kbName) {
39
+ return {
40
+ name: kbName,
41
+ addQA: (topic, q, a) => this.addQA(kbName, topic, q, a),
42
+ addText: (topic, text) => this.addText(kbName, topic, text),
43
+ search: (query, options = {}) => this.search(query, { ...options, kbs: kbName }),
44
+ delete: () => this.deleteKB(kbName)
45
+ };
46
+ }
47
+
48
+ async addQA(kbName, topic, question, answer) {
49
+ const vector = await this._getEmbedding(question);
50
+ await this._upsert({
51
+ id: crypto.randomUUID(),
52
+ vector, kb_name: kbName, topic, type: 'qa',
53
+ question, answer, text: "", created_at: new Date().toISOString()
54
+ });
55
+ }
56
+
57
+ async addText(kbName, topic, text) {
58
+ const vector = await this._getEmbedding(text);
59
+ await this._upsert({
60
+ id: crypto.randomUUID(),
61
+ vector, kb_name: kbName, topic, type: 'text',
62
+ question: "", answer: "", text, created_at: new Date().toISOString()
63
+ });
64
+ }
65
+
66
+ async search(query, options = {}) {
67
+ if (!this.table) return [];
68
+ const { kbs, limit = 10 } = options;
69
+ const queryVector = await this._getEmbedding(query);
70
+ let request = this.table.vectorSearch(queryVector);
71
+ request.metricType = "cosine";
72
+
73
+ if (kbs) {
74
+ const filter = Array.isArray(kbs)
75
+ ? `kb_name IN (${kbs.map(n => `"${n}"`).join(",")})`
76
+ : `kb_name = "${kbs}"`;
77
+ request = request.where(filter);
78
+ }
79
+
80
+ const results = await request.limit(limit).toArray();
81
+ return results.map(r => ({
82
+ kb: r.kb_name,
83
+ topic: r.topic,
84
+ type: r.type,
85
+ content: r.type === 'qa' ? { q: r.question, a: r.answer } : { text: r.text },
86
+ score: 1-(r._distance/2)
87
+ }));
88
+ }
89
+
90
+ async deleteKB(kbName) {
91
+ if (this.table) await this.table.delete(`kb_name = "${kbName}"`);
92
+ }
93
+
94
+ async listKBs() {
95
+ if (!this.table) return [];
96
+ const all = await this.table.query().select(["kb_name"]).toArray();
97
+ return [...new Set(all.map(i => i.kb_name))];
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Main export: initializes engine and returns the kbs function.
103
+ */
104
+ export const knowy = async (dbPath = "./knowy_database") => {
105
+ const engine = new KnowyEngine(dbPath);
106
+ await engine.init();
107
+
108
+ // The kbs function
109
+ const kbs = (kbName) => engine.getKB(kbName);
110
+
111
+ // Attached methods
112
+ kbs.search = (query, options) => engine.search(query, options);
113
+ kbs.list = () => engine.listKBs();
114
+
115
+ return kbs;
116
+ };
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "knowy",
3
+ "version": "1.0.0",
4
+ "description": "A local-first knowledge base engine with vector search using LanceDB and Hugging Face embeddings",
5
+ "main": "knowy.js",
6
+ "type": "module",
7
+ "scripts": {
8
+ "test": "echo \"Error: no test specified\" && exit 1"
9
+ },
10
+ "keywords": [
11
+ "knowledge-base",
12
+ "vector-search",
13
+ "embeddings",
14
+ "lancedb",
15
+ "huggingface",
16
+ "semantic-search",
17
+ "qa",
18
+ "ai",
19
+ "knowy",
20
+ "local-first"
21
+ ],
22
+ "author": "littlejustnode",
23
+ "license": "MIT",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/littlejustnode/knowy.git"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/littlejustnode/knowy/issues"
30
+ },
31
+ "homepage": "https://github.com/littlejustnode/knowy#readme",
32
+ "dependencies": {
33
+ "@huggingface/transformers": "^3.0.0",
34
+ "@lancedb/lancedb": "^0.15.0"
35
+ },
36
+ "engines": {
37
+ "node": ">=18.0.0"
38
+ }
39
+ }