2025-08-26 12:32:21 -07:00
|
|
|
/**
|
2025-12-17 17:42:37 -08:00
|
|
|
* Embedding functions for converting data to vectors
|
|
|
|
|
*
|
2026-01-06 12:52:34 -08:00
|
|
|
* Uses Candle WASM for universal compatibility.
|
|
|
|
|
* No transformers.js or ONNX Runtime dependency - clean, production-grade implementation.
|
2025-08-26 12:32:21 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { EmbeddingFunction, EmbeddingModel, Vector } from '../coreTypes.js'
|
2025-12-17 17:42:37 -08:00
|
|
|
import { embeddingManager } from '../embeddings/EmbeddingManager.js'
|
2025-08-26 12:32:21 -07:00
|
|
|
|
|
|
|
|
/**
|
2025-12-17 17:42:37 -08:00
|
|
|
* TransformerEmbedding options (kept for backward compatibility)
|
2025-08-26 12:32:21 -07:00
|
|
|
*/
|
|
|
|
|
export interface TransformerEmbeddingOptions {
|
2025-12-17 17:42:37 -08:00
|
|
|
/** Model name - only all-MiniLM-L6-v2 is supported */
|
2025-08-26 12:32:21 -07:00
|
|
|
model?: string
|
|
|
|
|
/** Whether to enable verbose logging */
|
|
|
|
|
verbose?: boolean
|
2025-12-17 17:42:37 -08:00
|
|
|
/** Custom cache directory - ignored (model is bundled) */
|
2025-08-26 12:32:21 -07:00
|
|
|
cacheDir?: string
|
2025-12-17 17:42:37 -08:00
|
|
|
/** Force local files only - ignored (model is bundled) */
|
2025-08-26 12:32:21 -07:00
|
|
|
localFilesOnly?: boolean
|
2025-12-17 17:42:37 -08:00
|
|
|
/** Model precision - always q8 */
|
2025-08-29 13:22:13 -07:00
|
|
|
precision?: 'fp32' | 'q8'
|
2025-12-17 17:42:37 -08:00
|
|
|
/** Device - always WASM */
|
2025-08-26 12:32:21 -07:00
|
|
|
device?: 'auto' | 'cpu' | 'webgpu' | 'cuda' | 'gpu'
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-17 17:42:37 -08:00
|
|
|
/**
|
2026-01-06 12:52:34 -08:00
|
|
|
* TransformerEmbedding - Sentence embeddings using Candle WASM
|
2025-12-17 17:42:37 -08:00
|
|
|
*
|
|
|
|
|
* This class delegates all work to EmbeddingManager which uses
|
2026-01-06 12:52:34 -08:00
|
|
|
* the Candle WASM engine. Kept for backward compatibility.
|
2025-12-17 17:42:37 -08:00
|
|
|
*/
|
2025-08-26 12:32:21 -07:00
|
|
|
export class TransformerEmbedding implements EmbeddingModel {
|
|
|
|
|
private initialized = false
|
2025-12-17 17:42:37 -08:00
|
|
|
private verbose: boolean
|
2025-08-26 12:32:21 -07:00
|
|
|
|
|
|
|
|
constructor(options: TransformerEmbeddingOptions = {}) {
|
|
|
|
|
this.verbose = options.verbose !== undefined ? options.verbose : true
|
|
|
|
|
|
2025-12-17 17:42:37 -08:00
|
|
|
if (this.verbose) {
|
2026-01-06 12:52:34 -08:00
|
|
|
console.log('[TransformerEmbedding] Using Candle WASM backend (delegating to EmbeddingManager)')
|
2025-09-02 10:00:52 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-26 12:32:21 -07:00
|
|
|
/**
|
|
|
|
|
* Initialize the embedding model
|
|
|
|
|
*/
|
|
|
|
|
public async init(): Promise<void> {
|
|
|
|
|
if (this.initialized) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-17 17:42:37 -08:00
|
|
|
try {
|
|
|
|
|
await embeddingManager.init()
|
2025-09-02 10:00:52 -07:00
|
|
|
this.initialized = true
|
2025-08-26 12:32:21 -07:00
|
|
|
|
|
|
|
|
if (this.verbose) {
|
2025-12-17 17:42:37 -08:00
|
|
|
console.log('[TransformerEmbedding] Initialized via EmbeddingManager (WASM)')
|
2025-08-26 12:32:21 -07:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
2025-12-17 17:42:37 -08:00
|
|
|
console.error('[TransformerEmbedding] Failed to initialize:', error)
|
|
|
|
|
throw new Error(`TransformerEmbedding initialization failed: ${error}`)
|
2025-08-26 12:32:21 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Generate embeddings for text data
|
|
|
|
|
*/
|
|
|
|
|
public async embed(data: string | string[]): Promise<Vector> {
|
|
|
|
|
if (!this.initialized) {
|
|
|
|
|
await this.init()
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-17 17:42:37 -08:00
|
|
|
// Delegate to EmbeddingManager
|
|
|
|
|
return embeddingManager.embed(data)
|
2025-08-26 12:32:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-12-17 17:42:37 -08:00
|
|
|
* Get the embedding function
|
2025-08-26 12:32:21 -07:00
|
|
|
*/
|
2025-12-17 17:42:37 -08:00
|
|
|
getEmbeddingFunction(): EmbeddingFunction {
|
|
|
|
|
return async (data: string | string[] | Record<string, unknown>): Promise<Vector> => {
|
|
|
|
|
return this.embed(data as string | string[])
|
2025-08-26 12:32:21 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-12-17 17:42:37 -08:00
|
|
|
* Check if initialized
|
2025-08-26 12:32:21 -07:00
|
|
|
*/
|
2025-12-17 17:42:37 -08:00
|
|
|
isInitialized(): boolean {
|
|
|
|
|
return this.initialized
|
2025-08-26 12:32:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-12-17 17:42:37 -08:00
|
|
|
* Dispose resources (no-op for WASM engine)
|
2025-08-26 12:32:21 -07:00
|
|
|
*/
|
2025-12-17 17:42:37 -08:00
|
|
|
async dispose(): Promise<void> {
|
|
|
|
|
this.initialized = false
|
2025-08-26 12:32:21 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-17 17:42:37 -08:00
|
|
|
/**
|
|
|
|
|
* Create a simple embedding function using the default TransformerEmbedding
|
|
|
|
|
* This is the recommended way to create an embedding function for Brainy
|
|
|
|
|
*/
|
|
|
|
|
export function createEmbeddingFunction(options: TransformerEmbeddingOptions = {}): EmbeddingFunction {
|
|
|
|
|
return embeddingManager.getEmbeddingFunction()
|
|
|
|
|
}
|
2025-08-26 12:32:21 -07:00
|
|
|
|
|
|
|
|
/**
|
2025-12-17 17:42:37 -08:00
|
|
|
* Create a TransformerEmbedding instance (backward compatibility)
|
2025-08-26 12:32:21 -07:00
|
|
|
*/
|
2025-12-17 17:42:37 -08:00
|
|
|
export function createTransformerEmbedding(options: TransformerEmbeddingOptions = {}): TransformerEmbedding {
|
2025-08-26 12:32:21 -07:00
|
|
|
return new TransformerEmbedding(options)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-12-17 17:42:37 -08:00
|
|
|
* Convenience function to detect best device (always returns 'wasm')
|
2025-08-26 12:32:21 -07:00
|
|
|
*/
|
2025-12-17 17:42:37 -08:00
|
|
|
export async function detectBestDevice(): Promise<'cpu' | 'webgpu' | 'cuda' | 'wasm'> {
|
2026-06-11 14:51:00 -07:00
|
|
|
return 'wasm'
|
2025-08-26 12:32:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-12-17 17:42:37 -08:00
|
|
|
* Resolve device string (always returns 'wasm')
|
2025-08-26 12:32:21 -07:00
|
|
|
*/
|
2025-12-17 17:42:37 -08:00
|
|
|
export async function resolveDevice(_device: string = 'auto'): Promise<string> {
|
|
|
|
|
return 'wasm'
|
|
|
|
|
}
|
2025-10-17 12:29:27 -07:00
|
|
|
|
|
|
|
|
|
2025-12-17 17:42:37 -08:00
|
|
|
/**
|
|
|
|
|
* Default embedding function (backward compatibility)
|
|
|
|
|
*/
|
|
|
|
|
export const defaultEmbeddingFunction: EmbeddingFunction = embeddingManager.getEmbeddingFunction()
|
2025-08-26 12:32:21 -07:00
|
|
|
|
|
|
|
|
/**
|
2025-12-17 17:42:37 -08:00
|
|
|
* UniversalSentenceEncoder alias (backward compatibility)
|
2025-08-26 12:32:21 -07:00
|
|
|
*/
|
2025-12-17 17:42:37 -08:00
|
|
|
export const UniversalSentenceEncoder = TransformerEmbedding
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Batch embed function (backward compatibility)
|
|
|
|
|
*/
|
|
|
|
|
export async function batchEmbed(texts: string[]): Promise<Vector[]> {
|
|
|
|
|
const results: Vector[] = []
|
|
|
|
|
for (const text of texts) {
|
|
|
|
|
results.push(await embeddingManager.embed(text))
|
2025-08-26 12:32:21 -07:00
|
|
|
}
|
2025-12-17 17:42:37 -08:00
|
|
|
return results
|
2025-08-26 12:32:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-12-17 17:42:37 -08:00
|
|
|
* Embedding functions registry (backward compatibility)
|
2025-08-26 12:32:21 -07:00
|
|
|
*/
|
|
|
|
|
export const embeddingFunctions = {
|
2025-12-17 17:42:37 -08:00
|
|
|
transformer: createEmbeddingFunction,
|
|
|
|
|
default: createEmbeddingFunction,
|
|
|
|
|
}
|