fix: remove deterministic embedding backend

This commit is contained in:
Andrey Avtomonov 2026-05-19 16:09:05 +02:00
parent b4c77c0563
commit 6ee15018ad
26 changed files with 144 additions and 218 deletions

View file

@ -3,19 +3,16 @@ import { createKtxEmbeddingProvider } from './embedding-provider.js';
import type { KtxEmbeddingConfig } from './types.js';
describe('createKtxEmbeddingProvider', () => {
it('creates deterministic embeddings with stable dimensions', async () => {
const provider = createKtxEmbeddingProvider({
backend: 'deterministic',
model: 'sha256',
dimensions: 6,
batchSize: 4,
});
it('rejects deterministic embeddings', () => {
const config = JSON.parse(
JSON.stringify({
backend: 'deterministic',
model: 'sha256',
dimensions: 6,
}),
) as KtxEmbeddingConfig;
await expect(provider.embed('Revenue policy')).resolves.toHaveLength(6);
await expect(provider.embed('Revenue policy')).resolves.toEqual(await provider.embed('Revenue policy'));
await expect(provider.embed('Revenue policy')).resolves.not.toEqual(await provider.embed('Approval policy'));
await expect(provider.embedMany(['a', 'b'])).resolves.toHaveLength(2);
expect(provider.maxBatchSize).toBe(4);
expect(() => createKtxEmbeddingProvider(config)).toThrow('Unsupported KTX embedding backend: deterministic');
});
it('rejects gateway embeddings', () => {

View file

@ -1,4 +1,3 @@
import { createHash } from 'node:crypto';
import { spawn } from 'node:child_process';
import { join } from 'node:path';
import OpenAI from 'openai';
@ -33,14 +32,6 @@ export interface KtxEmbeddingProviderDeps {
const DEFAULT_BATCH_SIZE = 100;
function deterministicVector(text: string, dimensions: number): number[] {
const digest = createHash('sha256').update(text).digest();
return Array.from({ length: dimensions }, (_, index) => {
const byte = digest[index % digest.length];
return Number(((byte / 255) * 2 - 1).toFixed(6));
});
}
function assertNonEmptyText(text: string): void {
if (!text.trim()) {
throw new Error('Embedding text must be non-empty');
@ -184,24 +175,6 @@ function runSentenceTransformersProcessJson(options: {
};
}
class DeterministicEmbeddingProvider implements KtxEmbeddingProvider {
readonly maxBatchSize: number;
constructor(readonly dimensions: number, batchSize = DEFAULT_BATCH_SIZE) {
this.maxBatchSize = batchSize;
}
async embed(text: string): Promise<number[]> {
assertNonEmptyText(text);
return deterministicVector(text, this.dimensions);
}
async embedMany(texts: string[]): Promise<number[][]> {
assertBatchSize(texts, this.maxBatchSize);
return texts.map((text) => deterministicVector(text, this.dimensions));
}
}
class OpenAIEmbeddingProvider implements KtxEmbeddingProvider {
readonly dimensions: number;
readonly maxBatchSize: number;
@ -367,8 +340,6 @@ export function createKtxEmbeddingProvider(
deps: KtxEmbeddingProviderDeps = {},
): KtxEmbeddingProvider {
switch (config.backend) {
case 'deterministic':
return new DeterministicEmbeddingProvider(config.dimensions, config.batchSize);
case 'openai':
return new OpenAIEmbeddingProvider(config, deps);
case 'sentence-transformers':

View file

@ -62,7 +62,7 @@ export interface KtxLlmProvider {
activeBackend(): KtxLlmBackend;
}
export type KtxEmbeddingBackend = 'openai' | 'deterministic' | 'sentence-transformers';
export type KtxEmbeddingBackend = 'openai' | 'sentence-transformers';
export interface KtxEmbeddingTokenUsageEvent {
backend: KtxEmbeddingBackend;