@kaelio/ktx 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/python/{kaelio_ktx-0.3.0-py3-none-any.whl → kaelio_ktx-0.4.1-py3-none-any.whl} +0 -0
- package/assets/python/manifest.json +4 -4
- package/dist/admin-reindex.js +9 -14
- package/dist/admin-reindex.test.js +4 -1
- package/dist/cli-project.d.ts +4 -10
- package/dist/cli-project.js +5 -49
- package/dist/cli-project.test.js +4 -131
- package/dist/commands/knowledge-commands.js +2 -0
- package/dist/commands/sl-commands.js +2 -0
- package/dist/embedding-resolution.d.ts +36 -0
- package/dist/embedding-resolution.js +63 -0
- package/dist/embedding-resolution.test.d.ts +1 -0
- package/dist/embedding-resolution.test.js +132 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.test.js +36 -33
- package/dist/ingest.js +12 -9
- package/dist/knowledge.d.ts +7 -2
- package/dist/knowledge.js +21 -7
- package/dist/knowledge.test.js +53 -9
- package/dist/managed-local-embeddings.d.ts +7 -6
- package/dist/managed-local-embeddings.js +19 -13
- package/dist/managed-local-embeddings.test.js +87 -18
- package/dist/mcp-server-factory.js +11 -0
- package/dist/public-ingest.js +2 -8
- package/dist/runtime-requirements.js +1 -2
- package/dist/runtime-requirements.test.js +1 -2
- package/dist/scan.js +8 -4
- package/dist/setup-embeddings.js +6 -2
- package/dist/setup-embeddings.test.js +2 -5
- package/dist/setup-runtime.test.js +1 -3
- package/dist/sl.d.ts +6 -4
- package/dist/sl.js +23 -9
- package/dist/sl.test.js +77 -6
- package/node_modules/@ktx/context/dist/ingest/local-bundle-runtime.d.ts +2 -0
- package/node_modules/@ktx/context/dist/ingest/local-bundle-runtime.js +2 -2
- package/node_modules/@ktx/context/dist/ingest/local-ingest.d.ts +1 -0
- package/node_modules/@ktx/context/dist/ingest/local-ingest.js +2 -0
- package/node_modules/@ktx/context/dist/llm/index.d.ts +1 -1
- package/node_modules/@ktx/context/dist/llm/index.js +1 -1
- package/node_modules/@ktx/context/dist/llm/local-config.d.ts +0 -1
- package/node_modules/@ktx/context/dist/llm/local-config.js +1 -2
- package/node_modules/@ktx/context/dist/llm/local-config.test.js +3 -3
- package/node_modules/@ktx/context/dist/mcp/local-project-ports.d.ts +2 -2
- package/node_modules/@ktx/context/dist/mcp/local-project-ports.js +2 -5
- package/node_modules/@ktx/context/dist/mcp/local-project-ports.test.js +14 -10
- package/node_modules/@ktx/context/dist/package-exports.test.js +0 -1
- package/node_modules/@ktx/context/dist/project/config.js +1 -1
- package/node_modules/@ktx/context/dist/scan/local-enrichment.test.js +4 -5
- package/node_modules/@ktx/context/dist/scan/local-scan.d.ts +3 -1
- package/node_modules/@ktx/context/dist/scan/local-scan.js +3 -2
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, it, vi } from 'vitest';
|
|
2
2
|
import { buildDefaultKtxProjectConfig, } from '../project/config.js';
|
|
3
|
-
import {
|
|
3
|
+
import { createLocalKtxEmbeddingProviderFromConfig, createLocalKtxLlmProviderFromConfig, resolveLocalKtxEmbeddingConfig, resolveLocalKtxLlmConfig, } from './local-config.js';
|
|
4
4
|
describe('local KTX LLM config', () => {
|
|
5
5
|
it('resolves env and file references into a KtxLlmConfig', () => {
|
|
6
6
|
const config = {
|
|
@@ -116,13 +116,13 @@ describe('local KTX embedding config', () => {
|
|
|
116
116
|
batchSize: 16,
|
|
117
117
|
});
|
|
118
118
|
});
|
|
119
|
-
it('returns null when sentence-transformers
|
|
119
|
+
it('returns null when sentence-transformers has no base_url (managed daemon delegation)', () => {
|
|
120
120
|
const config = {
|
|
121
121
|
backend: 'sentence-transformers',
|
|
122
122
|
model: 'all-MiniLM-L6-v2',
|
|
123
123
|
dimensions: 384,
|
|
124
124
|
sentenceTransformers: {
|
|
125
|
-
base_url:
|
|
125
|
+
base_url: '',
|
|
126
126
|
pathPrefix: '',
|
|
127
127
|
},
|
|
128
128
|
};
|
|
@@ -10,7 +10,7 @@ interface CreateLocalProjectMcpContextPortsOptions {
|
|
|
10
10
|
queryExecutor?: KtxSqlQueryExecutorPort;
|
|
11
11
|
sqlAnalysis?: SqlAnalysisPort;
|
|
12
12
|
localScan?: LocalScanMcpOptions;
|
|
13
|
-
embeddingService
|
|
13
|
+
embeddingService: KtxEmbeddingPort | null;
|
|
14
14
|
}
|
|
15
|
-
export declare function createLocalProjectMcpContextPorts(project: KtxLocalProject, options
|
|
15
|
+
export declare function createLocalProjectMcpContextPorts(project: KtxLocalProject, options: CreateLocalProjectMcpContextPortsOptions): KtxMcpContextPorts;
|
|
16
16
|
export {};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { localConnectionInfoFromConfig } from '../connections/index.js';
|
|
2
|
-
import { createLocalKtxEmbeddingProviderFromConfig, KtxIngestEmbeddingPortAdapter } from '../llm/index.js';
|
|
3
2
|
import { createKtxEntityDetailsService } from '../scan/index.js';
|
|
4
3
|
import { createKtxDiscoverDataService } from '../search/index.js';
|
|
5
4
|
import { compileLocalSlQuery, createKtxDictionarySearchService } from '../sl/index.js';
|
|
@@ -99,10 +98,8 @@ async function executeValidatedReadOnlySql(project, options, input, onProgress)
|
|
|
99
98
|
await cleanupConnector(connector);
|
|
100
99
|
}
|
|
101
100
|
}
|
|
102
|
-
export function createLocalProjectMcpContextPorts(project, options
|
|
103
|
-
const
|
|
104
|
-
const embeddingService = options.embeddingService ??
|
|
105
|
-
(configuredEmbeddingProvider ? new KtxIngestEmbeddingPortAdapter(configuredEmbeddingProvider) : null);
|
|
101
|
+
export function createLocalProjectMcpContextPorts(project, options) {
|
|
102
|
+
const embeddingService = options.embeddingService;
|
|
106
103
|
const ports = {
|
|
107
104
|
connections: {
|
|
108
105
|
async list() {
|
|
@@ -138,7 +138,7 @@ describe('createLocalProjectMcpContextPorts', () => {
|
|
|
138
138
|
driver: 'postgres',
|
|
139
139
|
url: 'env:DATABASE_URL',
|
|
140
140
|
};
|
|
141
|
-
const ports = createLocalProjectMcpContextPorts(project);
|
|
141
|
+
const ports = createLocalProjectMcpContextPorts(project, { embeddingService: null });
|
|
142
142
|
expect(Object.keys(ports).sort()).toEqual([
|
|
143
143
|
'connections',
|
|
144
144
|
'dictionarySearch',
|
|
@@ -178,6 +178,7 @@ describe('createLocalProjectMcpContextPorts', () => {
|
|
|
178
178
|
localScan: {
|
|
179
179
|
createConnector,
|
|
180
180
|
},
|
|
181
|
+
embeddingService: null,
|
|
181
182
|
});
|
|
182
183
|
expect(Object.keys(ports).sort()).toContain('sqlExecution');
|
|
183
184
|
await expect(ports.sqlExecution?.execute({
|
|
@@ -224,6 +225,7 @@ describe('createLocalProjectMcpContextPorts', () => {
|
|
|
224
225
|
localScan: {
|
|
225
226
|
createConnector,
|
|
226
227
|
},
|
|
228
|
+
embeddingService: null,
|
|
227
229
|
});
|
|
228
230
|
const result = await ports.sqlExecution?.execute({ connectionId: 'warehouse', sql: 'select id from public.orders', maxRows: 5 }, {
|
|
229
231
|
onProgress: (event) => {
|
|
@@ -262,6 +264,7 @@ describe('createLocalProjectMcpContextPorts', () => {
|
|
|
262
264
|
localScan: {
|
|
263
265
|
createConnector: vi.fn(async () => connector),
|
|
264
266
|
},
|
|
267
|
+
embeddingService: null,
|
|
265
268
|
});
|
|
266
269
|
await expect(ports.sqlExecution?.execute({
|
|
267
270
|
connectionId: 'warehouse',
|
|
@@ -277,7 +280,7 @@ describe('createLocalProjectMcpContextPorts', () => {
|
|
|
277
280
|
url: 'env:DATABASE_URL',
|
|
278
281
|
};
|
|
279
282
|
await seedScanReport(project.projectDir);
|
|
280
|
-
const ports = createLocalProjectMcpContextPorts(project);
|
|
283
|
+
const ports = createLocalProjectMcpContextPorts(project, { embeddingService: null });
|
|
281
284
|
await expect(ports.entityDetails?.read({
|
|
282
285
|
connectionId: 'warehouse',
|
|
283
286
|
entities: [{ table: 'public.orders', columns: ['id'] }],
|
|
@@ -299,7 +302,7 @@ describe('createLocalProjectMcpContextPorts', () => {
|
|
|
299
302
|
driver: 'postgres',
|
|
300
303
|
url: 'env:DATABASE_URL',
|
|
301
304
|
};
|
|
302
|
-
const ports = createLocalProjectMcpContextPorts(project);
|
|
305
|
+
const ports = createLocalProjectMcpContextPorts(project, { embeddingService: null });
|
|
303
306
|
await expect(ports.entityDetails?.read({
|
|
304
307
|
connectionId: 'warehouse',
|
|
305
308
|
entities: [{ table: 'public.orders' }],
|
|
@@ -337,7 +340,7 @@ describe('createLocalProjectMcpContextPorts', () => {
|
|
|
337
340
|
},
|
|
338
341
|
warnings: [],
|
|
339
342
|
}, null, 2)}\n`, 'ktx', 'ktx@example.com', 'Seed dictionary profile');
|
|
340
|
-
const ports = createLocalProjectMcpContextPorts(project);
|
|
343
|
+
const ports = createLocalProjectMcpContextPorts(project, { embeddingService: null });
|
|
341
344
|
await expect(ports.dictionarySearch?.search({ values: ['paid'] })).resolves.toMatchObject({
|
|
342
345
|
searched: [{ connectionId: 'warehouse', status: 'ready' }],
|
|
343
346
|
results: [
|
|
@@ -355,7 +358,7 @@ describe('createLocalProjectMcpContextPorts', () => {
|
|
|
355
358
|
driver: 'postgres',
|
|
356
359
|
url: 'env:DATABASE_URL',
|
|
357
360
|
};
|
|
358
|
-
const ports = createLocalProjectMcpContextPorts(project);
|
|
361
|
+
const ports = createLocalProjectMcpContextPorts(project, { embeddingService: null });
|
|
359
362
|
await expect(ports.dictionarySearch?.search({ values: ['paid'] })).resolves.toEqual({
|
|
360
363
|
searched: [
|
|
361
364
|
{
|
|
@@ -483,7 +486,7 @@ describe('createLocalProjectMcpContextPorts', () => {
|
|
|
483
486
|
enrichmentState: { resumedStages: [], completedStages: [], failedStages: [] },
|
|
484
487
|
createdAt: '2026-05-14T09:00:00.000Z',
|
|
485
488
|
}, null, 2), 'ktx', 'ktx@example.com', 'seed scan report');
|
|
486
|
-
const ports = createLocalProjectMcpContextPorts(project);
|
|
489
|
+
const ports = createLocalProjectMcpContextPorts(project, { embeddingService: null });
|
|
487
490
|
const results = await ports.discover?.search({ query: 'paid orders', connectionId: 'warehouse', limit: 10 });
|
|
488
491
|
expect(results).toEqual(expect.arrayContaining([
|
|
489
492
|
expect.objectContaining({ kind: 'wiki', id: 'orders-playbook' }),
|
|
@@ -507,7 +510,7 @@ describe('createLocalProjectMcpContextPorts', () => {
|
|
|
507
510
|
'Revenue is net of refunds.',
|
|
508
511
|
'',
|
|
509
512
|
].join('\n'), 'ktx', 'ktx@example.com', 'Seed wiki');
|
|
510
|
-
const ports = createLocalProjectMcpContextPorts(project);
|
|
513
|
+
const ports = createLocalProjectMcpContextPorts(project, { embeddingService: null });
|
|
511
514
|
await expect(ports.knowledge?.read({ userId: 'local-user', key: 'revenue' })).resolves.toMatchObject({
|
|
512
515
|
key: 'revenue',
|
|
513
516
|
scope: 'GLOBAL',
|
|
@@ -549,7 +552,7 @@ describe('createLocalProjectMcpContextPorts', () => {
|
|
|
549
552
|
'',
|
|
550
553
|
].join('\n'),
|
|
551
554
|
});
|
|
552
|
-
const ports = createLocalProjectMcpContextPorts(project);
|
|
555
|
+
const ports = createLocalProjectMcpContextPorts(project, { embeddingService: null });
|
|
553
556
|
await expect(ports.semanticLayer?.readSource({ connectionId: 'warehouse', sourceName: 'orders' })).resolves.toMatchObject({
|
|
554
557
|
sourceName: 'orders',
|
|
555
558
|
yaml: expect.stringContaining('name: orders'),
|
|
@@ -557,7 +560,7 @@ describe('createLocalProjectMcpContextPorts', () => {
|
|
|
557
560
|
});
|
|
558
561
|
it('rejects path traversal keys before touching the project directory', async () => {
|
|
559
562
|
const project = await initKtxProject({ projectDir: tempDir });
|
|
560
|
-
const ports = createLocalProjectMcpContextPorts(project);
|
|
563
|
+
const ports = createLocalProjectMcpContextPorts(project, { embeddingService: null });
|
|
561
564
|
await expect(ports.knowledge?.read({
|
|
562
565
|
userId: 'local-user',
|
|
563
566
|
key: '../outside',
|
|
@@ -603,7 +606,7 @@ describe('createLocalProjectMcpContextPorts', () => {
|
|
|
603
606
|
})),
|
|
604
607
|
generateSources: vi.fn(),
|
|
605
608
|
};
|
|
606
|
-
const ports = createLocalProjectMcpContextPorts(project, { semanticLayerCompute });
|
|
609
|
+
const ports = createLocalProjectMcpContextPorts(project, { semanticLayerCompute, embeddingService: null });
|
|
607
610
|
await expect(ports.semanticLayer?.query({
|
|
608
611
|
connectionId: 'warehouse',
|
|
609
612
|
query: {
|
|
@@ -670,6 +673,7 @@ describe('createLocalProjectMcpContextPorts', () => {
|
|
|
670
673
|
const ports = createLocalProjectMcpContextPorts(project, {
|
|
671
674
|
semanticLayerCompute: compute,
|
|
672
675
|
queryExecutor,
|
|
676
|
+
embeddingService: null,
|
|
673
677
|
});
|
|
674
678
|
const result = await ports.semanticLayer?.query({
|
|
675
679
|
connectionId: 'warehouse',
|
|
@@ -123,7 +123,6 @@ describe('@ktx/context package exports', () => {
|
|
|
123
123
|
expect(root.assertSearchBackendConformanceCase).toBeTypeOf('function');
|
|
124
124
|
expect(root.assertSearchBackendCapabilities).toBeTypeOf('function');
|
|
125
125
|
expect(root.createLocalKtxEmbeddingProviderFromConfig).toBeTypeOf('function');
|
|
126
|
-
expect(root.MANAGED_SENTENCE_TRANSFORMERS_BASE_URL).toBe('managed:local-embeddings');
|
|
127
126
|
expect(agent).toBeDefined();
|
|
128
127
|
expect(agent.AgentRunnerService).toBeTypeOf('function');
|
|
129
128
|
expect(root.AgentRunnerService).toBeTypeOf('function');
|
|
@@ -31,7 +31,7 @@ const vertexProviderSchema = z
|
|
|
31
31
|
.describe('Google Vertex AI provider configuration.');
|
|
32
32
|
const sentenceTransformersSchema = z
|
|
33
33
|
.strictObject({
|
|
34
|
-
base_url: z.string().default('').describe('Base URL of the sentence-transformers HTTP server.
|
|
34
|
+
base_url: z.string().default('').describe('Base URL of the sentence-transformers HTTP server. Leave empty (or omit) to use the project-managed local daemon.'),
|
|
35
35
|
pathPrefix: z.string().optional().describe('Optional URL path prefix prepended to embedding requests.'),
|
|
36
36
|
})
|
|
37
37
|
.describe('Sentence-transformers embedding server configuration.');
|
|
@@ -736,16 +736,16 @@ describe('local scan enrichment', () => {
|
|
|
736
736
|
executor.close();
|
|
737
737
|
}
|
|
738
738
|
});
|
|
739
|
-
it('resolves gateway LLM providers and
|
|
739
|
+
it('resolves gateway LLM providers and passes injected embedding provider through to scan enrichment', () => {
|
|
740
740
|
const createKtxLlmProvider = vi.fn(() => ({
|
|
741
741
|
getModel: vi.fn().mockReturnValue({ modelId: 'provider/language-model', provider: 'gateway' }),
|
|
742
742
|
}));
|
|
743
|
-
const
|
|
743
|
+
const embeddingProvider = {
|
|
744
744
|
dimensions: 1536,
|
|
745
745
|
maxBatchSize: 8,
|
|
746
746
|
embed: vi.fn(),
|
|
747
747
|
[['embed', 'Many'].join('')]: vi.fn(),
|
|
748
|
-
}
|
|
748
|
+
};
|
|
749
749
|
const providers = createLocalScanEnrichmentProvidersFromConfig({
|
|
750
750
|
mode: 'llm',
|
|
751
751
|
embeddings: {
|
|
@@ -763,12 +763,11 @@ describe('local scan enrichment', () => {
|
|
|
763
763
|
models: { default: 'provider/language-model' },
|
|
764
764
|
}, {
|
|
765
765
|
createKtxLlmProvider: createKtxLlmProvider,
|
|
766
|
-
createKtxEmbeddingProvider: createKtxEmbeddingProvider,
|
|
767
766
|
env: { OPENAI_API_KEY: 'openai-key' }, // pragma: allowlist secret
|
|
767
|
+
embeddingProvider: embeddingProvider,
|
|
768
768
|
});
|
|
769
769
|
expect(providers?.embedding?.dimensions).toBe(1536);
|
|
770
770
|
expect(providers?.embedding?.maxBatchSize).toBe(8);
|
|
771
771
|
expect(createKtxLlmProvider).toHaveBeenCalledWith(expect.objectContaining({ backend: 'gateway', modelSlots: { default: 'provider/language-model' } }));
|
|
772
|
-
expect(createKtxEmbeddingProvider).toHaveBeenCalledWith(expect.objectContaining({ backend: 'openai', model: 'provider/embedding-model' }));
|
|
773
772
|
});
|
|
774
773
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { createKtxEmbeddingProvider, createKtxLlmProvider } from '@ktx/llm';
|
|
1
|
+
import type { createKtxEmbeddingProvider, createKtxLlmProvider, KtxEmbeddingProvider } from '@ktx/llm';
|
|
2
2
|
import { type LocalIngestRunRecord, type SourceAdapter } from '../ingest/index.js';
|
|
3
3
|
import type { KtxProjectLlmConfig, KtxScanEnrichmentConfig } from '../project/config.js';
|
|
4
4
|
import type { KtxLocalProject } from '../project/index.js';
|
|
@@ -21,6 +21,7 @@ export interface RunLocalScanOptions {
|
|
|
21
21
|
enrichmentProviders?: KtxLocalScanEnrichmentProviders | null;
|
|
22
22
|
enrichmentStateStore?: SqliteLocalScanEnrichmentStateStore | null;
|
|
23
23
|
progress?: KtxProgressPort;
|
|
24
|
+
embeddingProvider?: KtxEmbeddingProvider | null;
|
|
24
25
|
}
|
|
25
26
|
export interface LocalScanRunResult {
|
|
26
27
|
runId: string;
|
|
@@ -58,6 +59,7 @@ interface LocalScanEnrichmentProviderDeps {
|
|
|
58
59
|
createKtxEmbeddingProvider?: typeof createKtxEmbeddingProvider;
|
|
59
60
|
env?: NodeJS.ProcessEnv;
|
|
60
61
|
projectDir?: string;
|
|
62
|
+
embeddingProvider?: KtxEmbeddingProvider | null;
|
|
61
63
|
}
|
|
62
64
|
export declare function createLocalScanEnrichmentProvidersFromConfig(config: KtxScanEnrichmentConfig, llmConfig: KtxProjectLlmConfig, deps?: LocalScanEnrichmentProviderDeps): KtxLocalScanEnrichmentProviders | null;
|
|
63
65
|
export { filterSnapshotTables, resolveEnabledTables } from './enabled-tables.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createDefaultLocalIngestAdapters, getLocalStageOnlyIngestStatus, runLocalStageOnlyIngest, } from '../ingest/index.js';
|
|
2
|
-
import {
|
|
2
|
+
import { createLocalKtxLlmRuntimeFromConfig, KtxScanEmbeddingPortAdapter } from '../llm/index.js';
|
|
3
3
|
import { ktxLocalStateDbPath } from '../project/local-state-db.js';
|
|
4
4
|
import { redactKtxScanReport } from './credentials.js';
|
|
5
5
|
import { filterSnapshotTables, resolveEnabledTables } from './enabled-tables.js';
|
|
@@ -65,7 +65,7 @@ export function createLocalScanEnrichmentProvidersFromConfig(config, llmConfig,
|
|
|
65
65
|
...deps,
|
|
66
66
|
projectDir: deps.projectDir,
|
|
67
67
|
});
|
|
68
|
-
const embeddingProvider =
|
|
68
|
+
const embeddingProvider = deps.embeddingProvider ?? null;
|
|
69
69
|
if (!llmRuntime || !embeddingProvider) {
|
|
70
70
|
return null;
|
|
71
71
|
}
|
|
@@ -227,6 +227,7 @@ export async function runLocalScan(options) {
|
|
|
227
227
|
? options.enrichmentProviders
|
|
228
228
|
: createLocalScanEnrichmentProvidersFromConfig(options.project.config.scan.enrichment, options.project.config.llm, {
|
|
229
229
|
projectDir: options.project.projectDir,
|
|
230
|
+
embeddingProvider: options.embeddingProvider ?? null,
|
|
230
231
|
})
|
|
231
232
|
: null;
|
|
232
233
|
await options.progress?.update(0.15, 'Inspecting database schema');
|