vecbox 0.2.1 → 0.2.3

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/README.md CHANGED
@@ -1,67 +1,78 @@
1
- # vecbox v0.1.0
1
+ # Vecbox
2
2
 
3
3
  ![vecbox](./src/images/vecbox.png)
4
- [![npm version](https://img.shields.io/npm/v/vecbox.svg)](https://www.npmjs.com/package/vecbox)
4
+ [![npm version](https://img.shields.io/npm/v/vecbox.svg)](https://www.npmjs.org/package/vecbox)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
6
6
 
7
- ## Why vecbox?
8
-
9
- **One API, multiple providers.** Switch between OpenAI, Gemini, or run locally with Llama.cpp without changing code.
7
+ **One API, multiple providers.** Switch between OpenAI, Gemini, Mistral, or run locally with Llama.cpp using native N-API performance.
10
8
  ```typescript
11
- // Works with any provider
9
+ import { autoEmbed } from 'vecbox';
10
+
11
+ // Works with any provider - auto-detects the best available
12
12
  const result = await autoEmbed({ text: 'Hello, world!' });
13
13
  console.log(result.embedding); // [0.1, 0.2, ...]
14
+ console.log(result.provider); // 'llamacpp' | 'openai' | 'gemini' | 'mistral'
14
15
  ```
15
16
 
17
+ ## Why Vecbox?
18
+
19
+ **Universal API** - Write once, run anywhere. Switch providers without changing code.
20
+
21
+ **Local-First** - Runs on your machine with Llama.cpp. No API costs, no data leaving your server, full privacy.
22
+
23
+ **Production Ready** - Cloud APIs (OpenAI, Gemini, Mistral) available when you need scale or specific models.
24
+
25
+ **Native Speed** - C++ bindings via N-API make local embeddings 10x faster than HTTP-based solutions.
26
+
16
27
  ## Installation
17
28
  ```bash
18
- npm install vecbox
19
- pnpm add vecbox
29
+ npm install vecbox
30
+ # or
31
+ pnpm add vecbox
20
32
  ```
21
33
 
22
- **Zero setup required!** Everything is included - no need to download Llama.cpp or compile anything.
34
+ The native module compiles automatically during installation. No manual build steps required.
23
35
 
24
36
  ## Quick Start
25
37
 
26
- ### Auto-detect (Recommended)
38
+ ### Auto Mode (Recommended)
39
+
40
+ Let Vecbox choose the best available provider:
27
41
  ```typescript
28
42
  import { autoEmbed } from 'vecbox';
29
43
 
30
- // Just works - automatically picks the best available provider
31
- const result = await autoEmbed({ text: 'Your text' });
32
- console.log(result.embedding); // [0.1, 0.2, ...]
33
- console.log(result.provider); // 'llamacpp' | 'openai' | 'gemini' | 'mistral'
44
+ const result = await autoEmbed({ text: 'Your text here' });
45
+ console.log(result.embedding); // [0.1, 0.2, ...]
46
+ console.log(result.provider); // Shows which provider was used
34
47
  ```
35
48
 
49
+ Priority order: Llama.cpp (local) → OpenAI → Gemini → Mistral
50
+
36
51
  ### Specific Provider
37
52
  ```typescript
38
53
  import { embed } from 'vecbox';
39
54
 
55
+ // OpenAI
40
56
  const result = await embed(
41
57
  { provider: 'openai', apiKey: process.env.OPENAI_API_KEY },
42
58
  { text: 'Your text' }
43
59
  );
44
60
  ```
45
61
 
46
- ### File Input
62
+ ### From Files
47
63
  ```typescript
48
- import { embed } from 'vecbox';
49
-
50
- // Embed text from files
51
64
  const result = await embed(
52
- { provider: 'gemini', apiKey: process.env.GEMINI_API_KEY },
65
+ { provider: 'gemini', apiKey: process.env.GOOGLE_GENERATIVE_AI_API_KEY },
53
66
  { filePath: './document.txt' }
54
67
  );
55
68
  ```
56
69
 
57
70
  ### Batch Processing
58
71
  ```typescript
59
- import { embed } from 'vecbox';
60
-
61
72
  const inputs = [
62
- { text: 'First text' },
63
- { text: 'Second text' },
64
- { text: 'Third text' }
73
+ { text: 'First document' },
74
+ { text: 'Second document' },
75
+ { text: 'Third document' }
65
76
  ];
66
77
 
67
78
  const result = await embed(
@@ -74,25 +85,60 @@ console.log(result.embeddings.length); // 3
74
85
 
75
86
  ## Providers
76
87
 
77
- <details>
78
- <summary><b>OpenAI</b></summary>
88
+ ### Llama.cpp (Local - Free & Private)
89
+
90
+ **Advantages:**
91
+ - ✅ Zero API costs
92
+ - ✅ Full privacy (data never leaves your machine)
93
+ - ✅ Works offline
94
+ - ✅ Native C++ performance via N-API
95
+
96
+ **Setup:**
97
+ ```bash
98
+ # 1. Download a GGUF embedding model
99
+ wget https://huggingface.co/nomic-ai/nomic-embed-text-v1.5-GGUF/resolve/main/nomic-embed-text-v1.5.Q4_K_M.gguf
100
+
101
+ # 2. Place in your project
102
+ mkdir models
103
+ mv nomic-embed-text-v1.5.Q4_K_M.gguf models/
104
+ ```
105
+
106
+ **Usage:**
107
+ ```typescript
108
+ // Auto-detect (uses local model automatically)
109
+ const result = await autoEmbed({ text: 'Your text' });
110
+
111
+ // Explicit path
112
+ const result = await embed(
113
+ { provider: 'llamacpp', model: './models/nomic-embed-text-v1.5.Q4_K_M.gguf' },
114
+ { text: 'Your text' }
115
+ );
116
+ ```
117
+
118
+ **Recommended Models:**
119
+ - `nomic-embed-text-v1.5.Q4_K_M.gguf` (81MB) - Best overall
120
+ - `bge-base-en-v1.5.Q4_K_M.gguf` (133MB) - Higher quality
121
+ - `bge-small-en-v1.5.Q4_0.gguf` (33MB) - Fastest, smaller
122
+
123
+ ### OpenAI
79
124
  ```typescript
80
125
  await embed(
81
126
  {
82
127
  provider: 'openai',
83
- model: 'text-embedding-3-small', // or text-embedding-3-large
128
+ model: 'text-embedding-3-small', // or 'text-embedding-3-large'
84
129
  apiKey: process.env.OPENAI_API_KEY
85
130
  },
86
131
  { text: 'Your text' }
87
132
  );
88
133
  ```
89
134
 
90
- **Setup:** Get API key at [platform.openai.com](https://platform.openai.com)
135
+ **Setup:** Get API key at [platform.openai.com/api-keys](https://platform.openai.com/api-keys)
91
136
 
92
- </details>
137
+ **Models:**
138
+ - `text-embedding-3-small` - Fast, cost-effective
139
+ - `text-embedding-3-large` - Highest quality
93
140
 
94
- <details>
95
- <summary><b>Google Gemini</b></summary>
141
+ ### Google Gemini
96
142
  ```typescript
97
143
  await embed(
98
144
  {
@@ -104,36 +150,9 @@ await embed(
104
150
  );
105
151
  ```
106
152
 
107
- **Setup:** Get API key at [aistudio.google.com](https://aistudio.google.com)
108
-
109
- </details>
110
-
111
- <details>
112
- <summary><b>Llama.cpp (Local)</b></summary>
113
- ```typescript
114
- await embed(
115
- { provider: 'llamacpp', model: 'nomic-embed-text-v1.5.Q4_K_M.gguf' },
116
- { text: 'Your text' }
117
- );
118
- ```
119
-
120
- **Setup:**
121
- ```bash
122
- # 1. Install
123
- git clone https://github.com/ggerganov/llama.cpp
124
- cd llama.cpp && make llama-server
125
-
126
- # 2. Download model
127
- wget https://huggingface.co/nomic-ai/nomic-embed-text-v1.5-GGUF/resolve/main/nomic-embed-text-v1.5.Q4_K_M.gguf
128
-
129
- # 3. Run server
130
- ./llama-server -m nomic-embed-text-v1.5.Q4_K_M.gguf --embedding --port 8080
131
- ```
132
-
133
- </details>
153
+ **Setup:** Get API key at [aistudio.google.com/apikey](https://aistudio.google.com/apikey)
134
154
 
135
- <details>
136
- <summary><b>Mistral</b></summary>
155
+ ### Mistral AI
137
156
  ```typescript
138
157
  await embed(
139
158
  {
@@ -145,287 +164,254 @@ await embed(
145
164
  );
146
165
  ```
147
166
 
148
- **Setup:** Get API key at [mistral.ai](https://mistral.ai)
167
+ **Setup:** Get API key at [console.mistral.ai](https://console.mistral.ai)
149
168
 
150
- </details>
169
+ ## Environment Variables
151
170
 
152
- ## 🚀 Features
171
+ Create a `.env` file in your project root:
172
+ ```bash
173
+ # Optional - only needed for cloud providers
174
+ OPENAI_API_KEY=sk-...
175
+ GOOGLE_GENERATIVE_AI_API_KEY=...
176
+ MISTRAL_API_KEY=...
177
+ ```
153
178
 
154
- - **🎯 One API, Multiple Providers** - Switch between OpenAI, Gemini, Mistral, or local Llama.cpp
155
- - **🤖 Auto-Detection** - Automatically picks the best available provider
156
- - **⚡ Native Performance** - Llama.cpp integration with N-API (10x faster than HTTP)
157
- - **🔄 Smart Fallbacks** - Never fails, always has a backup provider
158
- - **📁 File Support** - Embed text from files directly
159
- - **📦 Batch Processing** - Process multiple texts efficiently
160
- - **🛡️ Type Safe** - Full TypeScript support
161
- - **🌍 Zero Dependencies** - No external downloads or setup required
179
+ Vecbox works without any API keys when using Llama.cpp locally.
162
180
 
163
- ## 🏆 Why Vecbox?
181
+ ## API Reference
164
182
 
165
- **vs Other Libraries:**
166
- - ✅ **Native Llama.cpp** - Others use HTTP, we use direct C++ integration
167
- - ✅ **Auto-Detection** - Others require manual provider selection
168
- - ✅ **Zero Setup** - Others need external downloads and configuration
169
- - ✅ **Multiple Providers** - Others are limited to one provider
170
- - ✅ **Smart Fallbacks** - Others fail when a provider is unavailable
183
+ ### `autoEmbed(input: Input): Promise<Result>`
171
184
 
172
- **Performance:**
173
- - **Llama.cpp Native**: ~50ms per embedding
174
- - **Cloud Providers**: ~100-300ms per embedding
175
- - **HTTP Llama.cpp**: ~500ms+ per embedding
185
+ Automatically selects the best available provider.
176
186
 
177
- ## Common Use Cases
187
+ **Input:**
188
+ ```typescript
189
+ { text: string } | { filePath: string }
190
+ ```
178
191
 
179
- ### Semantic Search
192
+ **Returns:**
180
193
  ```typescript
181
- // Helper function for cosine similarity
182
- function cosineSimilarity(vecA: number[], vecB: number[]): number {
183
- const dotProduct = vecA.reduce((sum, val, i) => sum + val * vecB[i], 0);
184
- const magnitudeA = Math.sqrt(vecA.reduce((sum, val) => sum + val * val, 0));
185
- const magnitudeB = Math.sqrt(vecB.reduce((sum, val) => sum + val * val, 0));
186
- return dotProduct / (magnitudeA * magnitudeB);
194
+ {
195
+ embedding: number[]; // The embedding vector
196
+ dimensions: number; // Vector dimensions
197
+ provider: string; // Which provider was used
198
+ model: string; // Model name
199
+ usage?: {
200
+ promptTokens?: number;
201
+ totalTokens?: number;
202
+ }
187
203
  }
204
+ ```
188
205
 
189
- const query = await autoEmbed({ text: 'machine learning' });
190
- const docs = await Promise.all(
191
- documents.map(doc => autoEmbed({ text: doc }))
192
- );
206
+ ### `embed(config: Config, input: Input | Input[]): Promise<Result>`
193
207
 
194
- // Find most similar
195
- const scores = docs.map(doc =>
196
- cosineSimilarity(query.embedding, doc.embedding)
197
- );
198
- const mostSimilar = scores.indexOf(Math.max(...scores));
199
- console.log(`Best match: ${documents[mostSimilar]}`);
200
- ```
208
+ Use a specific provider.
201
209
 
202
- ### Text Similarity
210
+ **Config:**
203
211
  ```typescript
204
- function cosineSimilarity(vecA: number[], vecB: number[]): number {
205
- const dotProduct = vecA.reduce((sum, val, i) => sum + val * vecB[i], 0);
206
- const magnitudeA = Math.sqrt(vecA.reduce((sum, val) => sum + val * val, 0));
207
- const magnitudeB = Math.sqrt(vecB.reduce((sum, val) => sum + val * val, 0));
208
- return dotProduct / (magnitudeA * magnitudeB);
212
+ {
213
+ provider: 'llamacpp' | 'openai' | 'gemini' | 'mistral';
214
+ model?: string; // Provider-specific model
215
+ apiKey?: string; // Required for cloud providers
216
+ baseUrl?: string; // Custom API endpoint
217
+ timeout?: number; // Request timeout in ms
218
+ maxRetries?: number; // Retry attempts
209
219
  }
220
+ ```
210
221
 
211
- const [emb1, emb2] = await Promise.all([
212
- autoEmbed({ text: 'cat sleeping' }),
213
- autoEmbed({ text: 'cat napping' })
214
- ]);
215
-
216
- const similarity = cosineSimilarity(emb1.embedding, emb2.embedding);
217
- console.log(`Similarity: ${similarity.toFixed(3)}`); // → 0.95 (very similar)
222
+ **Input:**
223
+ ```typescript
224
+ { text: string } | { filePath: string } | Array<{text: string} | {filePath: string}>
218
225
  ```
219
226
 
220
- ### Batch Processing
227
+ **Returns:** Same as `autoEmbed`, but `embeddings: number[][]` for batch inputs.
228
+
229
+ ## Examples
230
+
231
+ ### Semantic Search
221
232
  ```typescript
222
- const results = await embed(
223
- { provider: 'openai', apiKey: 'key' },
224
- [
225
- { text: 'Text 1' },
226
- { text: 'Text 2' },
227
- { filePath: './doc.txt' }
228
- ]
233
+ import { autoEmbed } from 'vecbox';
234
+
235
+ function cosineSimilarity(a: number[], b: number[]): number {
236
+ const dotProduct = a.reduce((sum, val, i) => sum + val * b[i], 0);
237
+ const magA = Math.sqrt(a.reduce((sum, val) => sum + val * val, 0));
238
+ const magB = Math.sqrt(b.reduce((sum, val) => sum + val * val, 0));
239
+ return dotProduct / (magA * magB);
240
+ }
241
+
242
+ // Embed query and documents
243
+ const query = await autoEmbed({ text: 'machine learning tutorials' });
244
+ const docs = await Promise.all([
245
+ autoEmbed({ text: 'Introduction to neural networks' }),
246
+ autoEmbed({ text: 'Python web scraping guide' }),
247
+ autoEmbed({ text: 'Deep learning fundamentals' })
248
+ ]);
249
+
250
+ // Calculate similarity scores
251
+ const similarities = docs.map(doc =>
252
+ cosineSimilarity(query.embedding, doc.embedding)
229
253
  );
230
- // → { embeddings: [[...], [...], [...]], dimensions: 1536 }
231
254
 
232
- console.log(`Processed ${results.embeddings.length} texts`);
233
- console.log(`Dimensions: ${results.dimensions}`);
255
+ // Find best match
256
+ const bestIdx = similarities.indexOf(Math.max(...similarities));
257
+ console.log(`Best match: Document ${bestIdx + 1} (score: ${similarities[bestIdx].toFixed(3)})`);
234
258
  ```
235
259
 
236
- ### File Processing
260
+ ### Batch File Processing
237
261
  ```typescript
262
+ import { embed } from 'vecbox';
238
263
  import { readdir } from 'fs/promises';
239
264
  import { join } from 'path';
240
265
 
241
- async function embedAllFiles(dirPath: string) {
266
+ async function embedDirectory(dirPath: string) {
242
267
  const files = await readdir(dirPath);
243
- const textFiles = files.filter(file => file.endsWith('.txt'));
244
-
245
- const inputs = textFiles.map(file => ({
246
- filePath: join(dirPath, file)
247
- }));
268
+ const textFiles = files.filter(f => f.endsWith('.txt'));
248
269
 
249
- const results = await embed(
270
+ // Process all files in one batch
271
+ const result = await embed(
250
272
  { provider: 'llamacpp' },
251
- inputs
273
+ textFiles.map(file => ({ filePath: join(dirPath, file) }))
252
274
  );
253
275
 
254
- return textFiles.map((file, index) => ({
255
- file,
256
- embedding: results.embeddings[index]
276
+ return textFiles.map((file, i) => ({
277
+ filename: file,
278
+ embedding: result.embeddings[i]
257
279
  }));
258
280
  }
259
281
 
260
- const embeddings = await embedAllFiles('./documents');
261
- console.log(`Processed ${embeddings.length} files`);
282
+ const results = await embedDirectory('./documents');
283
+ console.log(`Embedded ${results.length} files`);
262
284
  ```
263
285
 
264
- ## API
265
-
266
- ### `autoEmbed(input)`
267
-
268
- Auto-detects best provider in priority order:
269
- 1. **Llama.cpp** (Local & Free)
270
- 2. **OpenAI** (if API key available)
271
- 3. **Gemini** (if API key available)
272
- 4. **Mistral** (if API key available)
273
-
286
+ ### Document Clustering
274
287
  ```typescript
275
- await autoEmbed({ text: string } | { filePath: string })
276
- ```
288
+ import { autoEmbed } from 'vecbox';
277
289
 
278
- ### `embed(config, input)`
290
+ const documents = [
291
+ 'The cat sat on the mat',
292
+ 'Dogs are loyal pets',
293
+ 'Python is a programming language',
294
+ 'JavaScript runs in browsers',
295
+ 'Birds can fly high'
296
+ ];
279
297
 
280
- Explicit provider selection.
281
- ```typescript
282
- await embed(
283
- { provider, model?, apiKey?, baseUrl?, timeout?, maxRetries? },
284
- { text: string } | { filePath: string } | Array
285
- )
286
- ```
298
+ // Get embeddings
299
+ const embeddings = await Promise.all(
300
+ documents.map(doc => autoEmbed({ text: doc }))
301
+ );
287
302
 
288
- **Returns:**
289
- ```typescript
290
- {
291
- embedding: number[],
292
- dimensions: number,
293
- provider: string,
294
- model: string,
295
- usage?: {
296
- promptTokens?: number;
297
- totalTokens?: number;
298
- }
303
+ // Simple clustering by similarity threshold
304
+ function findClusters(embeddings: number[][], threshold = 0.7) {
305
+ const clusters: number[][] = [];
306
+ const assigned = new Set<number>();
307
+
308
+ embeddings.forEach((emb, i) => {
309
+ if (assigned.has(i)) return;
310
+
311
+ const cluster = [i];
312
+ assigned.add(i);
313
+
314
+ embeddings.forEach((other, j) => {
315
+ if (i !== j && !assigned.has(j)) {
316
+ const sim = cosineSimilarity(emb, other);
317
+ if (sim > threshold) {
318
+ cluster.push(j);
319
+ assigned.add(j);
320
+ }
321
+ }
322
+ });
323
+
324
+ clusters.push(cluster);
325
+ });
326
+
327
+ return clusters;
299
328
  }
300
- ```
301
-
302
- ### `getSupportedProviders()`
303
-
304
- Returns available providers.
305
- ```typescript
306
- import { getSupportedProviders } from 'embedbox';
307
329
 
308
- const providers = getSupportedProviders();
309
- // → ['openai', 'gemini', 'mistral', 'llamacpp']
330
+ const clusters = findClusters(embeddings.map(e => e.embedding));
331
+ console.log('Clusters:', clusters);
332
+ // Output: [[0, 1, 4], [2, 3]] - animals vs programming
310
333
  ```
311
334
 
312
- ### `createProvider(config)`
335
+ ## Troubleshooting
313
336
 
314
- Create provider instance for advanced usage.
315
- ```typescript
316
- import { createProvider } from 'embedbox';
337
+ ### Native Module Issues
317
338
 
318
- const provider = createProvider({
319
- provider: 'openai',
320
- model: 'text-embedding-3-small',
321
- apiKey: 'your-key'
322
- });
339
+ **Error: `Cannot find module './build/Release/vecbox.node'`**
323
340
 
324
- const isReady = await provider.isReady();
325
- if (isReady) {
326
- const result = await provider.embed({ text: 'Hello' });
327
- }
341
+ The native module failed to compile. Rebuild it:
342
+ ```bash
343
+ npm run build:native
344
+ # or
345
+ node-gyp rebuild
328
346
  ```
329
347
 
330
- ## Environment Variables
348
+ **Error: `binding.createModel is not a function`**
349
+
350
+ Your native module is outdated. Clean and rebuild:
331
351
  ```bash
332
- # .env file
333
- OPENAI_API_KEY=sk-...
334
- GOOGLE_GENERATIVE_AI_API_KEY=...
335
- ANTHROPIC_API_KEY=sk-ant-...
336
- MISTRAL_API_KEY=...
352
+ rm -rf build/
353
+ npm install
337
354
  ```
338
355
 
339
- ## Error Handling
356
+ ### Model Loading Issues
340
357
 
341
- ```typescript
342
- import { autoEmbed } from 'embedbox';
343
-
344
- try {
345
- const result = await autoEmbed({ text: 'Hello' });
346
- console.log(result.embedding);
347
- } catch (error) {
348
- if (error.message.includes('API key')) {
349
- console.error('Please set up your API keys in .env');
350
- } else if (error.message.includes('not ready')) {
351
- console.error('Provider is not available');
352
- } else if (error.message.includes('network')) {
353
- console.error('Network connection failed');
354
- } else {
355
- console.error('Embedding failed:', error.message);
356
- }
357
- }
358
- ```
358
+ **Error: `Model file not found`**
359
359
 
360
- ## TypeScript Support
360
+ Check that the model path is correct:
361
+ ```bash
362
+ ls -la models/ # Verify model exists
363
+ pwd # Check current directory
364
+ ```
361
365
 
362
- Full TypeScript support with type definitions:
366
+ Use absolute paths if relative paths fail:
363
367
  ```typescript
364
- import {
365
- autoEmbed,
366
- embed,
367
- getSupportedProviders,
368
- createProvider,
369
- type EmbedConfig,
370
- type EmbedInput,
371
- type EmbedResult
372
- } from 'embedbox';
373
-
374
- // Full type safety
375
- const config: EmbedConfig = {
376
- provider: 'openai',
377
- model: 'text-embedding-3-small'
378
- };
379
-
380
- const input: EmbedInput = {
381
- text: 'Your text here'
382
- };
383
-
384
- const result: EmbedResult = await embed(config, input);
368
+ const path = require('path');
369
+ const modelPath = path.join(__dirname, 'models', 'model.gguf');
385
370
  ```
386
371
 
387
- ## 📚 Documentation
372
+ ### Performance
388
373
 
389
- - **[API Reference](./API.md)** - Complete API documentation
390
- - **[Contributing Guide](./CONTRIBUTING.md)** - How to contribute to Vecbox
391
- - **[Troubleshooting](./TROUBLESHOOTING.md)** - Common issues and solutions
392
- - **[Examples](./examples/)** - Code examples and tutorials
374
+ **Embeddings are slow:**
375
+ - Use smaller quantized models (Q4_K_M is recommended)
376
+ - Process texts in batches instead of one-by-one
377
+ - Verify native module is loaded (check `result.provider === 'llamacpp'`)
393
378
 
394
- ## 🤝 Contributing
379
+ **High memory usage:**
380
+ - Models stay loaded in memory for performance
381
+ - Use smaller models (bge-small instead of bge-large)
382
+ - Process files in chunks for very large datasets
395
383
 
396
- We welcome contributions! See our [Contributing Guide](./CONTRIBUTING.md) for:
397
- - Adding new providers
398
- - Improving performance
399
- - Bug fixes and features
400
- - Documentation improvements
384
+ ## Features
401
385
 
402
- ## 🐛 Troubleshooting
386
+ - **🎯 Provider Agnostic** - One API for all embedding providers
387
+ - **🤖 Smart Auto-Detection** - Automatically uses the best available option
388
+ - **⚡ Native Performance** - C++ via N-API for maximum speed
389
+ - **🔄 Automatic Fallbacks** - Seamlessly switches providers if one fails
390
+ - **📁 File Support** - Read and embed text files directly
391
+ - **📦 Batch Processing** - Efficient multi-document embedding
392
+ - **🛡️ TypeScript First** - Full type safety and IDE autocomplete
393
+ - **🌍 Zero Setup** - Native module compiles automatically on install
394
+ - **🔒 Privacy-First** - Local processing keeps your data private
403
395
 
404
- Having issues? Check our [Troubleshooting Guide](./TROUBLESHOOTING.md) for:
405
- - Installation problems
406
- - Runtime errors
407
- - Performance issues
408
- - Common solutions
409
-
410
- ## 📄 License
396
+ ## License
411
397
 
412
398
  MIT License - see [LICENSE](LICENSE) file for details.
413
399
 
414
- ## 🙏 Acknowledgments
400
+ ## Credits
401
+
402
+ Built on top of excellent open-source projects:
415
403
 
416
- - [Llama.cpp](https://github.com/ggml-org/llama.cpp) - Core embedding engine
417
- - [OpenAI](https://openai.com/) - Embedding API
418
- - [Google Gemini](https://ai.google.dev/) - Embedding API
419
- - [Mistral AI](https://mistral.ai/) - Embedding API
404
+ - [llama.cpp](https://github.com/ggml-org/llama.cpp) - High-performance LLM inference
405
+ - [OpenAI](https://openai.com/) - text-embedding-3 models
406
+ - [Google Gemini](https://ai.google.dev/) - gemini-embedding models
407
+ - [Mistral AI](https://mistral.ai/) - mistral-embed model
420
408
 
421
- ## 📞 Support
409
+ ## Contributing
422
410
 
423
- - **GitHub Issues**: [Report bugs](https://github.com/box-safe/vecbox/issues)
424
- - **GitHub Discussions**: [Ask questions](https://github.com/box-safe/vecbox/discussions)
425
- - **Documentation**: [API Reference](./API.md)
411
+ Issues and pull requests welcome at [github.com/box-safe/vecbox](https://github.com/box-safe/vecbox)
426
412
 
427
413
  ---
428
414
 
429
- **⭐ Star us on GitHub!** [github.com/box-safe/vecbox](https://github.com/box-safe/vecbox)
415
+ **⭐ If Vecbox saves you time, star us on GitHub!**
430
416
 
431
- **Made with ❤️ by the Vecbox Team**
417
+ **Made with ❤️ for developers who value simplicity and performance**