Add EmbeddingProvider interface with OpenAI-compatible, local (optional @xenova/transformers via dynamic import), and Noop (FTS5-only fallback) implementations. EmbeddingService batches requests and persists Float32Array blobs to snippet_embeddings. GET/PUT /api/v1/settings/embedding endpoints read and write embedding config from the settings table. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
48 lines
1.1 KiB
TypeScript
48 lines
1.1 KiB
TypeScript
/**
|
|
* EmbeddingProvider interface and NoopEmbeddingProvider.
|
|
*
|
|
* The Noop provider returns null embeddings and enables FTS5-only mode
|
|
* when no embedding backend is configured.
|
|
*/
|
|
|
|
export interface EmbeddingVector {
|
|
values: Float32Array;
|
|
dimensions: number;
|
|
model: string;
|
|
}
|
|
|
|
export interface EmbeddingProvider {
|
|
readonly name: string;
|
|
readonly dimensions: number;
|
|
readonly model: string;
|
|
|
|
embed(texts: string[]): Promise<EmbeddingVector[]>;
|
|
isAvailable(): Promise<boolean>;
|
|
}
|
|
|
|
export class EmbeddingError extends Error {
|
|
constructor(message: string) {
|
|
super(message);
|
|
this.name = 'EmbeddingError';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* NoopEmbeddingProvider — always returns empty results.
|
|
* Used as the default when no provider is configured; the system
|
|
* falls back gracefully to FTS5-only search.
|
|
*/
|
|
export class NoopEmbeddingProvider implements EmbeddingProvider {
|
|
readonly name = 'noop';
|
|
readonly dimensions = 0;
|
|
readonly model = 'none';
|
|
|
|
async embed(_texts: string[]): Promise<EmbeddingVector[]> {
|
|
return [];
|
|
}
|
|
|
|
async isAvailable(): Promise<boolean> {
|
|
return false;
|
|
}
|
|
}
|