mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-22 08:38:08 +02:00
127 lines
4.2 KiB
TypeScript
127 lines
4.2 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest';
|
|
import {
|
|
buildDefaultKtxProjectConfig,
|
|
type KtxProjectEmbeddingConfig,
|
|
type KtxProjectLlmConfig,
|
|
} from '../project/config.js';
|
|
import {
|
|
createLocalKtxEmbeddingProviderFromConfig,
|
|
createLocalKtxLlmProviderFromConfig,
|
|
resolveLocalKtxEmbeddingConfig,
|
|
resolveLocalKtxLlmConfig,
|
|
} from './local-config.js';
|
|
|
|
describe('local KTX LLM config', () => {
|
|
it('resolves env and file references into a KtxLlmConfig', () => {
|
|
const config: KtxProjectLlmConfig = {
|
|
provider: {
|
|
backend: 'gateway',
|
|
gateway: { api_key: 'env:AI_GATEWAY_API_KEY', base_url: 'https://gateway.example/v1' }, // pragma: allowlist secret
|
|
},
|
|
models: { default: 'env:KTX_MODEL', triage: 'anthropic/claude-haiku-4-5' },
|
|
promptCaching: { enabled: false },
|
|
};
|
|
|
|
expect(
|
|
resolveLocalKtxLlmConfig(config, {
|
|
AI_GATEWAY_API_KEY: 'gateway-key', // pragma: allowlist secret
|
|
KTX_MODEL: 'anthropic/claude-sonnet-4-6',
|
|
}),
|
|
).toEqual({
|
|
backend: 'gateway',
|
|
gateway: { apiKey: 'gateway-key', baseURL: 'https://gateway.example/v1' }, // pragma: allowlist secret
|
|
modelSlots: { default: 'anthropic/claude-sonnet-4-6', triage: 'anthropic/claude-haiku-4-5' },
|
|
promptCaching: { enabled: false },
|
|
});
|
|
});
|
|
|
|
it('returns null when the local LLM backend is disabled', () => {
|
|
expect(
|
|
createLocalKtxLlmProviderFromConfig({
|
|
provider: { backend: 'none' },
|
|
models: {},
|
|
}),
|
|
).toBeNull();
|
|
});
|
|
|
|
it('constructs providers through @ktx/llm', () => {
|
|
const createKtxLlmProvider = vi.fn(() => ({ getModel: vi.fn() }) as never);
|
|
const result = createLocalKtxLlmProviderFromConfig(
|
|
{
|
|
provider: {
|
|
backend: 'anthropic',
|
|
anthropic: { api_key: 'env:ANTHROPIC_API_KEY' }, // pragma: allowlist secret
|
|
},
|
|
models: { default: 'claude-sonnet-4-6' },
|
|
},
|
|
{ env: { ANTHROPIC_API_KEY: 'sk-ant-test' }, createKtxLlmProvider }, // pragma: allowlist secret
|
|
);
|
|
|
|
expect(result).not.toBeNull();
|
|
expect(createKtxLlmProvider).toHaveBeenCalledWith({
|
|
backend: 'anthropic',
|
|
anthropic: { apiKey: 'sk-ant-test' }, // pragma: allowlist secret
|
|
modelSlots: { default: 'claude-sonnet-4-6' },
|
|
promptCaching: undefined,
|
|
});
|
|
});
|
|
|
|
it('inherits enabled prompt caching from @ktx/llm when local config omits promptCaching', () => {
|
|
const provider = createLocalKtxLlmProviderFromConfig({
|
|
provider: {
|
|
backend: 'gateway',
|
|
gateway: { base_url: 'https://gateway.example/v1' },
|
|
},
|
|
models: { default: 'anthropic/claude-sonnet-4-6' },
|
|
});
|
|
|
|
expect(provider?.promptCachingConfig()).toMatchObject({
|
|
enabled: true,
|
|
systemTtl: '1h',
|
|
toolsTtl: '1h',
|
|
historyTtl: '5m',
|
|
vertexFallbackTo5m: false,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('local KTX embedding config', () => {
|
|
it('resolves sentence-transformers config', () => {
|
|
const config: KtxProjectEmbeddingConfig = {
|
|
backend: 'sentence-transformers',
|
|
model: 'all-MiniLM-L6-v2',
|
|
dimensions: 384,
|
|
sentenceTransformers: { base_url: 'http://localhost:18081', pathPrefix: '' },
|
|
batchSize: 16,
|
|
};
|
|
|
|
expect(resolveLocalKtxEmbeddingConfig(config, {})).toEqual({
|
|
backend: 'sentence-transformers',
|
|
model: 'all-MiniLM-L6-v2',
|
|
dimensions: 384,
|
|
sentenceTransformers: { baseURL: 'http://localhost:18081', pathPrefix: '' },
|
|
batchSize: 16,
|
|
});
|
|
});
|
|
|
|
it('constructs deterministic embeddings from the default project config', () => {
|
|
const createKtxEmbeddingProvider = vi.fn(() => ({}) as never);
|
|
const provider = createLocalKtxEmbeddingProviderFromConfig(
|
|
buildDefaultKtxProjectConfig('warehouse').ingest.embeddings,
|
|
{ createKtxEmbeddingProvider },
|
|
);
|
|
|
|
expect(provider).not.toBeNull();
|
|
expect(createKtxEmbeddingProvider).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
backend: 'deterministic',
|
|
model: 'deterministic',
|
|
dimensions: 8,
|
|
}),
|
|
);
|
|
});
|
|
|
|
it('returns null when embeddings are disabled', () => {
|
|
expect(createLocalKtxEmbeddingProviderFromConfig({ backend: 'none', dimensions: 8 })).toBeNull();
|
|
});
|
|
});
|