fix: remove deterministic embedding backend (#146)

* fix: remove deterministic embedding backend

* test: update slow tests for disabled embeddings
This commit is contained in:
Andrey Avtomonov 2026-05-19 16:40:01 +02:00 committed by GitHub
parent e80f755a6c
commit 06aeb56f39
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 148 additions and 222 deletions

View file

@ -676,8 +676,7 @@ describe('runKtxDoctor', () => {
' adapters:',
' - live-database',
' embeddings:',
' backend: deterministic',
' model: deterministic',
' backend: none',
' dimensions: 8',
'',
].join('\n'),
@ -694,8 +693,8 @@ describe('runKtxDoctor', () => {
).resolves.toBe(0);
expect(testIo.stdout()).toContain('Embeddings');
expect(testIo.stdout()).toContain('deterministic');
expect(testIo.stdout()).toContain('semantic search degraded');
expect(testIo.stdout()).toContain('none');
expect(testIo.stdout()).toContain('semantic search will be skipped');
delete process.env.ANTHROPIC_API_KEY;
});

View file

@ -62,7 +62,6 @@ export function deepReadinessGaps(config: KtxProjectConfig): string[] {
if (
!embeddings ||
embeddings.backend === 'none' ||
embeddings.backend === 'deterministic' ||
!embeddings.model ||
embeddings.dimensions <= 0
) {

View file

@ -133,7 +133,7 @@ export async function writeMetabaseConfig(projectDir: string): Promise<void> {
' adapters:',
' - metabase',
' embeddings:',
' backend: deterministic',
' backend: none',
'',
].join('\n'),
'utf-8',
@ -502,7 +502,7 @@ export async function runPublicMetabaseSyncModeCase(tempDir: string, input: Sync
' adapters:',
' - metabase',
' embeddings:',
' backend: deterministic',
' backend: none',
'',
].join('\n'),
'utf-8',

View file

@ -777,7 +777,7 @@ describe('runKtxIngest', () => {
' adapters:',
' - metabase',
' embeddings:',
' backend: deterministic',
' backend: none',
'',
].join('\n'),
'utf-8',
@ -1845,7 +1845,7 @@ describe('runKtxIngest', () => {
' adapters:',
' - looker',
' embeddings:',
' backend: deterministic',
' backend: none',
'',
].join('\n'),
'utf-8',

View file

@ -324,7 +324,7 @@ describe('setup embeddings step', () => {
expect(result.status).toBe('failed');
const config = parseKtxProjectConfig(await readFile(join(tempDir, 'ktx.yaml'), 'utf-8'));
expect(await readFile(join(tempDir, 'ktx.yaml'), 'utf-8')).not.toContain('completed_steps:');
expect(config.ingest.embeddings.backend).toBe('deterministic');
expect(config.ingest.embeddings.backend).toBe('none');
expect(io.stderr()).toContain('Local embedding health check failed: 401 invalid api key [redacted]');
expect(io.stderr()).toContain('Prepare the runtime with: ktx dev runtime start --feature local-embeddings');
expect(io.stderr()).not.toContain('skip for now');
@ -436,7 +436,7 @@ describe('setup embeddings step', () => {
expect(result.status).toBe('skipped');
const config = parseKtxProjectConfig(await readFile(join(tempDir, 'ktx.yaml'), 'utf-8'));
expect(await readFile(join(tempDir, 'ktx.yaml'), 'utf-8')).not.toContain('completed_steps:');
expect(config.ingest.embeddings.backend).toBe('deterministic');
expect(config.ingest.embeddings.backend).toBe('none');
});
it('returns back without writing config when the local health check fails and Back is selected', async () => {
@ -460,7 +460,7 @@ describe('setup embeddings step', () => {
expect(result.status).toBe('back');
const config = parseKtxProjectConfig(await readFile(join(tempDir, 'ktx.yaml'), 'utf-8'));
expect(config.ingest.embeddings.backend).toBe('deterministic');
expect(config.ingest.embeddings.backend).toBe('none');
});
it('preserves already completed embeddings setup when no embedding args request changes', async () => {

View file

@ -94,7 +94,6 @@ async function hasCompletedEmbeddings(projectDir: string, config: KtxProjectConf
return (
(await readKtxSetupState(projectDir)).completed_steps.includes('embeddings') &&
config.ingest.embeddings.backend !== 'none' &&
config.ingest.embeddings.backend !== 'deterministic' &&
typeof config.ingest.embeddings.model === 'string' &&
config.ingest.embeddings.model.length > 0 &&
config.ingest.embeddings.dimensions > 0

View file

@ -1166,8 +1166,7 @@ describe('setup Anthropic model step', () => {
' default: claude-sonnet-4-6',
'ingest:',
' embeddings:',
' backend: deterministic',
' model: deterministic',
' backend: none',
' dimensions: 8',
].join('\n'),
'utf-8',
@ -1209,8 +1208,7 @@ describe('setup Anthropic model step', () => {
` default: ${fixture.model}`,
'ingest:',
' embeddings:',
' backend: deterministic',
' model: deterministic',
' backend: none',
' dimensions: 8',
].join('\n'),
'utf-8',

View file

@ -108,7 +108,7 @@ describe('setup status', () => {
});
});
it('reports deterministic default embeddings as not setup-ready', async () => {
it('reports disabled default embeddings as not setup-ready', async () => {
await mkdir(tempDir, { recursive: true });
await writeFile(
join(tempDir, 'ktx.yaml'),
@ -122,8 +122,7 @@ describe('setup status', () => {
' default: claude-sonnet-4-6',
'ingest:',
' embeddings:',
' backend: deterministic',
' model: deterministic',
' backend: none',
' dimensions: 8',
'connections: {}',
].join('\n'),
@ -133,7 +132,7 @@ describe('setup status', () => {
await expect(readKtxSetupStatus(tempDir)).resolves.toMatchObject({
project: { path: tempDir, ready: true },
llm: { backend: 'anthropic', ready: true, model: 'claude-sonnet-4-6' },
embeddings: { backend: 'deterministic', ready: false, model: 'deterministic', dimensions: 8 },
embeddings: { backend: 'none', ready: false, dimensions: 8 },
});
});
@ -373,8 +372,7 @@ describe('setup status', () => {
' default: claude-sonnet-4-6',
'ingest:',
' embeddings:',
' backend: deterministic',
' model: deterministic',
' backend: none',
' dimensions: 8',
'',
].join('\n'),

View file

@ -238,7 +238,6 @@ function embeddingsReady(status: KtxSetupStatus['embeddings']): boolean {
return (
status.backend !== undefined &&
status.backend !== 'none' &&
status.backend !== 'deterministic' &&
typeof status.model === 'string' &&
status.model.length > 0 &&
typeof status.dimensions === 'number' &&

View file

@ -123,7 +123,8 @@ describe('runKtxSl', () => {
yaml: [
'name: orders',
'table: public.orders',
'description: Paid order facts',
'descriptions:',
' user: Paid order facts',
'grain: [order_id]',
'columns:',
' - name: order_id',

View file

@ -93,7 +93,7 @@ async function writeSqliteScanConfig(projectDir: string, dbPath: string, enrich
' enrichment:',
' mode: deterministic',
' embeddings:',
' backend: deterministic',
' backend: none',
' dimensions: 6',
]
: []),
@ -166,7 +166,7 @@ describe('standalone built ktx CLI smoke', () => {
});
it('runs status setup checks through the built binary', async () => {
const result = await runBuiltCli(['status', '--verbose', '--no-input']);
const result = await runBuiltCli(['status', '--verbose', '--no-input'], { cwd: tempDir });
expect(result.stdout).toMatch(/KTX status/);
if (result.stdout.includes('No project here yet.')) {

View file

@ -242,15 +242,6 @@ function buildEmbeddingsStatus(config: KtxProjectEmbeddingConfig, env: NodeJS.Pr
detail: 'disabled — semantic search will be skipped',
};
}
if (backend === 'deterministic') {
return {
backend,
model,
dimensions,
status: 'warn',
detail: 'deterministic — semantic search degraded (lexical/dictionary lanes still work)',
};
}
if (backend === 'openai') {
const ref = config.openai?.api_key;
const resolved = resolveRef(ref, env);
@ -645,7 +636,7 @@ function buildVerdict(
const reasons: string[] = [];
if (llm.status === 'warn') reasons.push('LLM credentials missing');
if (embeddings.status === 'warn') {
if (embeddings.backend === 'deterministic' || embeddings.backend === 'none') {
if (embeddings.backend === 'none') {
reasons.push('semantic search disabled');
} else {
reasons.push('embedding credentials missing');