@fluxsoft/fluxvector
v0.5.0
Published
Official TypeScript SDK for FluxVector — 7-signal HyperSearch with TopK fusion, ColBERT, and anti-hallucination confidence
Maintainers
Readme
@fluxsoft/fluxvector
Semantic search in 4 lines. No OpenAI key. No embedding pipelines. Just text in, results out.
npm install @fluxsoft/fluxvectorimport { FluxVector } from '@fluxsoft/fluxvector';
const fv = new FluxVector({ apiKey: 'fv_live_...' });
await fv.collections.create({ name: 'docs' });
await fv.vectors.upsert('docs', [{ id: '1', text: 'Your text here' }]);
const results = await fv.search('docs', 'find similar content');That's it. FluxVector embeds your text server-side with multilingual models (e5-large, BGE-M3). No OpenAI API key, no embedding code, no vector math.
vs Pinecone: Pinecone requires you to generate embeddings yourself (usually via OpenAI at $0.13/1M tokens), then send raw vectors. FluxVector does it all in one call.
Why FluxVector
- Built-in embeddings — send text, get search results. No external embedding API needed.
- Hybrid search — vector + BM25 keyword scoring combined, zero config.
- Self-hostable — one Docker image, your server, your data never leaves.
- Zero runtime dependencies — native
fetch, works in Node 18+, Deno, Bun, edge runtimes. - TypeScript-first — full types for every request and response.
Install
npm install @fluxsoft/fluxvector # or pnpm add / yarn addQuick Start
import { FluxVector } from '@fluxsoft/fluxvector';
const fv = new FluxVector({ apiKey: 'fv_live_abc123' });
// Create a collection (embeddings handled automatically)
await fv.collections.create({ name: 'products' });
// Just send text — FluxVector embeds it for you
await fv.vectors.upsert('products', [
{ id: 'p1', text: 'Red shoes', metadata: { price: 89 } },
{ id: 'p2', text: 'Blue sneakers', metadata: { price: 120 } },
]);
// Semantic search — returns results ranked by meaning, not keywords
const results = await fv.search('products', 'comfortable shoes', {
topK: 5,
filter: { price: { $lt: 100 } },
});
for (const r of results) {
console.log(`${r.id}: ${r.score.toFixed(2)} — ${r.text}`);
}Configuration
const fv = new FluxVector({
apiKey: 'fv_live_abc123', // Required
baseUrl: 'https://fluxvector.dev', // Default, configurable for self-hosted
maxRetries: 3, // Default: 3 (retries on 429 and 5xx)
timeout: 30000, // Default: 30s
});API Reference
Collections
// Create
const col = await fv.collections.create({
name: 'products',
dimension: 1024, // Optional, default: auto
metric: 'cosine', // 'cosine' | 'euclidean' | 'dotproduct'
description: 'Product catalog',
});
// List (cursor pagination)
const { data, has_more, next_cursor } = await fv.collections.list({ limit: 10 });
// Get
const col = await fv.collections.get('products');
// Delete
await fv.collections.delete('products');Vectors
// Upsert (auto-chunks at 1000 vectors)
await fv.vectors.upsert('products', [
{ id: 'p1', text: 'Red shoes', metadata: { price: 89, category: 'footwear' } },
{ id: 'p2', values: [0.1, 0.2, ...], metadata: { price: 120 } },
]);
// Query
const { results, usage, took_ms } = await fv.vectors.query({
collection: 'products',
text: 'comfortable shoes',
top_k: 10,
filter: { category: { $eq: 'footwear' } },
include_metadata: true,
include_text: true,
});
// Fetch by IDs
const { vectors } = await fv.vectors.fetch('products', ['p1', 'p2']);
// Delete by IDs
await fv.vectors.delete('products', { ids: ['p1', 'p2'] });
// Delete by filter
await fv.vectors.delete('products', { filter: { category: { $eq: 'old' } } });Search
The top-level fv.search() is the simplest way to do semantic search:
// Returns QueryResult[] directly
const results = await fv.search('products', 'comfortable shoes', {
topK: 5,
filter: { price: { $lt: 100 } },
mode: 'hybrid',
});
// Each result: { id, score, text?, metadata? }Embeddings
// Single text
const { embedding, dimension, model } = await fv.embeddings.create('hello world');
// Batch
const { embeddings, dimension, model } = await fv.embeddings.createBatch([
'hello world',
'goodbye world',
]);API Keys
// Create
const key = await fv.apiKeys.create({ name: 'Production', env: 'live' });
console.log(key.key); // fv_live_xxx — shown only once
// List
const { data } = await fv.apiKeys.list();
// Update
await fv.apiKeys.update('key_123', { name: 'Renamed' });
// Delete
await fv.apiKeys.delete('key_123');Usage
// Current period
const usage = await fv.usage.get();
// { plan, period_start, requests, embeddings, vectors_stored, collections }
// History
const { data } = await fv.usage.history({ days: 30 });
// [{ date, requests, embeddings, vectors }]Filter Operators
Filters use MongoDB-style operators on metadata fields:
| Operator | Description |
|----------|-------------|
| $eq | Equal to |
| $ne | Not equal to |
| $gt | Greater than |
| $gte | Greater than or equal |
| $lt | Less than |
| $lte | Less than or equal |
| $in | In array |
| $nin | Not in array |
// Examples
{ price: { $lt: 100 } }
{ category: { $in: ['shoes', 'boots'] } }
{ status: { $ne: 'archived' } }Error Handling
All errors extend FluxVectorError with status, code, and optional requestId:
import { FluxVector, AuthenticationError, NotFoundError, RateLimitError } from '@fluxsoft/fluxvector';
try {
await fv.collections.get('missing');
} catch (err) {
if (err instanceof NotFoundError) {
console.log('Collection does not exist');
} else if (err instanceof AuthenticationError) {
console.log('Check your API key');
} else if (err instanceof RateLimitError) {
console.log(`Retry after ${err.retryAfter}s`);
}
}| Error Class | Status | When |
|-------------|--------|------|
| AuthenticationError | 401 | Invalid or missing API key |
| NotFoundError | 404 | Resource not found |
| ValidationError | 422 | Invalid request body |
| RateLimitError | 429 | Too many requests |
| ServerError | 5xx | Server-side error |
| FluxVectorError | any | Base class for all errors |
Retry Behavior
The SDK automatically retries on 429 (rate limit) and 5xx (server errors):
- Default: 3 retries with exponential backoff (500ms, 1s, 2s + jitter)
- Respects
Retry-Afterheaders on 429 responses - Non-retryable errors (400, 401, 404, 422) fail immediately
- Set
maxRetries: 0to disable retries
License
MIT
