mirror of
https://github.com/Kaelio/ktx.git
synced 2026-07-13 11:22:11 +02:00
rename klo to ktx
This commit is contained in:
parent
1a42152e6f
commit
3ce510b55b
704 changed files with 10205 additions and 10255 deletions
|
|
@ -9,8 +9,8 @@ export type {
|
|||
SlSearchMetadata,
|
||||
} from './types.js';
|
||||
export type {
|
||||
KloConnectionInfo,
|
||||
KloQueryResult,
|
||||
KtxConnectionInfo,
|
||||
KtxQueryResult,
|
||||
SlConnectionCatalogPort,
|
||||
SlPythonPort,
|
||||
SlSourcesIndexPort,
|
||||
|
|
|
|||
|
|
@ -2,18 +2,18 @@ import { mkdtemp, rm } from 'node:fs/promises';
|
|||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import type { KloSemanticLayerComputePort } from '../daemon/index.js';
|
||||
import { initKloProject, type KloLocalProject } from '../project/index.js';
|
||||
import type { KtxSemanticLayerComputePort } from '../daemon/index.js';
|
||||
import { initKtxProject, type KtxLocalProject } from '../project/index.js';
|
||||
import { compileLocalSlQuery } from './local-query.js';
|
||||
|
||||
describe('compileLocalSlQuery', () => {
|
||||
let tempDir: string;
|
||||
let project: KloLocalProject;
|
||||
let compute: KloSemanticLayerComputePort;
|
||||
let project: KtxLocalProject;
|
||||
let compute: KtxSemanticLayerComputePort;
|
||||
|
||||
beforeEach(async () => {
|
||||
tempDir = await mkdtemp(join(tmpdir(), 'klo-local-query-'));
|
||||
project = await initKloProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' });
|
||||
tempDir = await mkdtemp(join(tmpdir(), 'ktx-local-query-'));
|
||||
project = await initKtxProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' });
|
||||
project.config.connections.warehouse = { driver: 'postgres', readonly: true };
|
||||
await project.fileStore.writeFile(
|
||||
'semantic-layer/warehouse/orders.yaml',
|
||||
|
|
@ -31,8 +31,8 @@ measures:
|
|||
expr: count(*)
|
||||
joins: []
|
||||
`,
|
||||
'klo',
|
||||
'klo@example.com',
|
||||
'ktx',
|
||||
'ktx@example.com',
|
||||
'Add orders source',
|
||||
);
|
||||
await project.fileStore.writeFile(
|
||||
|
|
@ -46,8 +46,8 @@ joins: []
|
|||
measures: []
|
||||
grain: []
|
||||
`,
|
||||
'klo',
|
||||
'klo@example.com',
|
||||
'ktx',
|
||||
'ktx@example.com',
|
||||
'Add overlay source',
|
||||
);
|
||||
|
||||
|
|
@ -130,8 +130,8 @@ grain: []
|
|||
- name: amount
|
||||
type: number
|
||||
`,
|
||||
'klo',
|
||||
'klo@example.com',
|
||||
'ktx',
|
||||
'ktx@example.com',
|
||||
'Add manifest shard',
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { KloSqlQueryExecutorPort } from '../connections/index.js';
|
||||
import type { KloSemanticLayerComputePort } from '../daemon/index.js';
|
||||
import type { KloLocalProject } from '../project/index.js';
|
||||
import type { KtxSqlQueryExecutorPort } from '../connections/index.js';
|
||||
import type { KtxSemanticLayerComputePort } from '../daemon/index.js';
|
||||
import type { KtxLocalProject } from '../project/index.js';
|
||||
import { loadLocalSlSourceRecords } from './local-sl.js';
|
||||
import type { SemanticLayerQueryExecutionResult, SemanticLayerQueryInput } from './types.js';
|
||||
|
||||
|
|
@ -10,10 +10,10 @@ const COMPILE_ONLY_REASON =
|
|||
export interface CompileLocalSlQueryOptions {
|
||||
connectionId?: string;
|
||||
query: SemanticLayerQueryInput;
|
||||
compute: KloSemanticLayerComputePort;
|
||||
compute: KtxSemanticLayerComputePort;
|
||||
execute?: boolean;
|
||||
maxRows?: number;
|
||||
queryExecutor?: KloSqlQueryExecutorPort;
|
||||
queryExecutor?: KtxSqlQueryExecutorPort;
|
||||
}
|
||||
|
||||
export interface CompileLocalSlQueryResult extends SemanticLayerQueryExecutionResult {
|
||||
|
|
@ -61,7 +61,7 @@ function dialectForDriver(driver: string | undefined): string {
|
|||
return map[normalized] ?? 'postgres';
|
||||
}
|
||||
|
||||
function resolveLocalConnectionId(project: KloLocalProject, requested: string | undefined): string {
|
||||
function resolveLocalConnectionId(project: KtxLocalProject, requested: string | undefined): string {
|
||||
if (requested) {
|
||||
return assertSafeConnectionId(requested);
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ function resolveLocalConnectionId(project: KloLocalProject, requested: string |
|
|||
}
|
||||
|
||||
async function loadComputableSources(
|
||||
project: KloLocalProject,
|
||||
project: KtxLocalProject,
|
||||
connectionId: string,
|
||||
): Promise<Record<string, unknown>[]> {
|
||||
return (await loadLocalSlSourceRecords(project, { connectionId: assertSafeConnectionId(connectionId) }))
|
||||
|
|
@ -88,7 +88,7 @@ function headersFromColumns(columns: Array<Record<string, unknown>>): string[] {
|
|||
}
|
||||
|
||||
export async function compileLocalSlQuery(
|
||||
project: KloLocalProject,
|
||||
project: KtxLocalProject,
|
||||
options: CompileLocalSlQueryOptions,
|
||||
): Promise<CompileLocalSlQueryResult> {
|
||||
const connectionId = resolveLocalConnectionId(project, options.connectionId);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { access, mkdtemp, rm } from 'node:fs/promises';
|
|||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
||||
import { initKloProject, type KloLocalProject } from '../project/index.js';
|
||||
import { initKtxProject, type KtxLocalProject } from '../project/index.js';
|
||||
import {
|
||||
listLocalSlSources,
|
||||
readLocalSlSource,
|
||||
|
|
@ -46,11 +46,11 @@ const SUPPORT_YAML = [
|
|||
|
||||
describe('local semantic-layer helpers', () => {
|
||||
let tempDir: string;
|
||||
let project: KloLocalProject;
|
||||
let project: KtxLocalProject;
|
||||
|
||||
beforeEach(async () => {
|
||||
tempDir = await mkdtemp(join(tmpdir(), 'klo-local-sl-'));
|
||||
project = await initKloProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' });
|
||||
tempDir = await mkdtemp(join(tmpdir(), 'ktx-local-sl-'));
|
||||
project = await initKtxProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' });
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
|
@ -102,8 +102,8 @@ describe('local semantic-layer helpers', () => {
|
|||
- name: amount
|
||||
type: number
|
||||
`,
|
||||
'klo',
|
||||
'klo@example.com',
|
||||
'ktx',
|
||||
'ktx@example.com',
|
||||
'Add manifest shard',
|
||||
);
|
||||
|
||||
|
|
@ -144,8 +144,8 @@ describe('local semantic-layer helpers', () => {
|
|||
- name: amount
|
||||
type: number
|
||||
`,
|
||||
'klo',
|
||||
'klo@example.com',
|
||||
'ktx',
|
||||
'ktx@example.com',
|
||||
'Add manifest shard',
|
||||
);
|
||||
|
||||
|
|
@ -184,7 +184,7 @@ describe('local semantic-layer helpers', () => {
|
|||
}),
|
||||
]);
|
||||
expect(results[0]?.score).toBeGreaterThan(0);
|
||||
await expect(access(join(project.projectDir, '.klo/db.sqlite'))).resolves.toBeUndefined();
|
||||
await expect(access(join(project.projectDir, '.ktx/db.sqlite'))).resolves.toBeUndefined();
|
||||
});
|
||||
|
||||
it('searches all connections with one global hybrid ranking pass', async () => {
|
||||
|
|
@ -260,8 +260,8 @@ describe('local semantic-layer helpers', () => {
|
|||
null,
|
||||
2,
|
||||
)}\n`,
|
||||
'klo',
|
||||
'klo@example.com',
|
||||
'ktx',
|
||||
'ktx@example.com',
|
||||
'Seed dictionary profile',
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { join } from 'node:path';
|
||||
import YAML from 'yaml';
|
||||
import { z } from 'zod';
|
||||
import type { KloEmbeddingPort, KloFileWriteResult } from '../core/index.js';
|
||||
import type { KloLocalProject } from '../project/index.js';
|
||||
import type { KtxEmbeddingPort, KtxFileWriteResult } from '../core/index.js';
|
||||
import type { KtxLocalProject } from '../project/index.js';
|
||||
import { HybridSearchCore, type SearchCandidateGenerator } from '../search/index.js';
|
||||
import { DEFAULT_PRIORITY, resolveDescription } from './descriptions.js';
|
||||
import { sourceDefinitionSchema, sourceOverlaySchema } from './schemas.js';
|
||||
|
|
@ -33,7 +33,7 @@ export interface LocalSlSourceSearchResult extends LocalSlSourceSummary {
|
|||
export interface LocalSlSearchInput {
|
||||
connectionId?: string;
|
||||
query: string;
|
||||
embeddingService?: KloEmbeddingPort | null;
|
||||
embeddingService?: KtxEmbeddingPort | null;
|
||||
limit?: number;
|
||||
backend?: 'pglite-owner-prototype';
|
||||
pglite?: PgliteSlSearchPrototypeOwnerOptions;
|
||||
|
|
@ -52,8 +52,8 @@ export interface LocalSlValidationResult {
|
|||
errors: string[];
|
||||
}
|
||||
|
||||
const LOCAL_AUTHOR = 'klo';
|
||||
const LOCAL_AUTHOR_EMAIL = 'klo@example.com';
|
||||
const LOCAL_AUTHOR = 'ktx';
|
||||
const LOCAL_AUTHOR_EMAIL = 'ktx@example.com';
|
||||
|
||||
function assertSafePathToken(kind: string, value: string): string {
|
||||
if (
|
||||
|
|
@ -191,7 +191,7 @@ function parsedStandaloneSource(parsed: Record<string, unknown>, name: string):
|
|||
}
|
||||
|
||||
export async function loadLocalSlSourceRecords(
|
||||
project: KloLocalProject,
|
||||
project: KtxLocalProject,
|
||||
input: { connectionId: string },
|
||||
): Promise<LocalSlSourceRecord[]> {
|
||||
const connectionId = assertSafeConnectionId(input.connectionId);
|
||||
|
|
@ -255,9 +255,9 @@ export async function validateLocalSlSource(rawYaml: string): Promise<LocalSlVal
|
|||
}
|
||||
|
||||
export async function writeLocalSlSource(
|
||||
project: KloLocalProject,
|
||||
project: KtxLocalProject,
|
||||
input: { connectionId: string; sourceName: string; yaml: string },
|
||||
): Promise<KloFileWriteResult> {
|
||||
): Promise<KtxFileWriteResult> {
|
||||
const validation = await validateLocalSlSource(input.yaml);
|
||||
if (!validation.valid) {
|
||||
throw new Error(`Invalid semantic-layer source: ${validation.errors.join('; ')}`);
|
||||
|
|
@ -279,7 +279,7 @@ export async function writeLocalSlSource(
|
|||
}
|
||||
|
||||
export async function readLocalSlSource(
|
||||
project: KloLocalProject,
|
||||
project: KtxLocalProject,
|
||||
input: { connectionId: string; sourceName: string },
|
||||
): Promise<LocalSlSource | null> {
|
||||
const path = slPath(input.connectionId, input.sourceName);
|
||||
|
|
@ -299,7 +299,7 @@ export async function readLocalSlSource(
|
|||
}
|
||||
|
||||
export async function listLocalSlSources(
|
||||
project: KloLocalProject,
|
||||
project: KtxLocalProject,
|
||||
input: { connectionId?: string } = {},
|
||||
): Promise<LocalSlSourceSummary[]> {
|
||||
if (input.connectionId) {
|
||||
|
|
@ -325,12 +325,12 @@ interface LocalSlSearchCandidate {
|
|||
searchText: string;
|
||||
}
|
||||
|
||||
function sqliteSlDbPath(project: KloLocalProject): string {
|
||||
return join(project.projectDir, '.klo', 'db.sqlite');
|
||||
function sqliteSlDbPath(project: KtxLocalProject): string {
|
||||
return join(project.projectDir, '.ktx', 'db.sqlite');
|
||||
}
|
||||
|
||||
async function loadLocalSlSearchCandidates(
|
||||
project: KloLocalProject,
|
||||
project: KtxLocalProject,
|
||||
input: { connectionId?: string } = {},
|
||||
): Promise<LocalSlSearchCandidate[]> {
|
||||
if (input.connectionId) {
|
||||
|
|
@ -390,9 +390,9 @@ function tokenLaneCandidates(candidates: LocalSlSearchCandidate[], terms: readon
|
|||
|
||||
async function refreshHybridSlIndexes(input: {
|
||||
index: SqliteSlSourcesIndex;
|
||||
project: KloLocalProject;
|
||||
project: KtxLocalProject;
|
||||
candidates: LocalSlSearchCandidate[];
|
||||
embeddingService?: KloEmbeddingPort | null;
|
||||
embeddingService?: KtxEmbeddingPort | null;
|
||||
}): Promise<void> {
|
||||
const candidatesByConnection = new Map<string, LocalSlSearchCandidate[]>();
|
||||
for (const candidate of input.candidates) {
|
||||
|
|
@ -435,7 +435,7 @@ async function refreshHybridSlIndexes(input: {
|
|||
}
|
||||
|
||||
export async function searchLocalSlSources(
|
||||
project: KloLocalProject,
|
||||
project: KtxLocalProject,
|
||||
input: LocalSlSearchInput,
|
||||
): Promise<LocalSlSourceSearchResult[]> {
|
||||
const query = input.query.trim();
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { createServer } from 'node:net';
|
|||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
||||
import { initKloProject, type KloLocalProject } from '../project/index.js';
|
||||
import { initKtxProject, type KtxLocalProject } from '../project/index.js';
|
||||
import { assertSearchBackendConformanceCase } from '../search/index.js';
|
||||
import { searchLocalSlSources, writeLocalSlSource, type LocalSlSourceSearchResult } from './local-sl.js';
|
||||
import { searchLocalSlSourcesWithPglitePrototype } from './pglite-sl-search-prototype.js';
|
||||
|
|
@ -103,7 +103,7 @@ function toConformanceResult(result: LocalSlSourceSearchResult) {
|
|||
};
|
||||
}
|
||||
|
||||
async function seedSemanticLayerProject(project: KloLocalProject): Promise<void> {
|
||||
async function seedSemanticLayerProject(project: KtxLocalProject): Promise<void> {
|
||||
await writeLocalSlSource(project, { connectionId: 'warehouse', sourceName: 'orders', yaml: ORDERS_YAML });
|
||||
await writeLocalSlSource(project, { connectionId: 'finance', sourceName: 'orders', yaml: FINANCE_ORDERS_YAML });
|
||||
await writeLocalSlSource(project, { connectionId: 'warehouse', sourceName: 'customers', yaml: CUSTOMERS_YAML });
|
||||
|
|
@ -152,21 +152,21 @@ async function seedSemanticLayerProject(project: KloLocalProject): Promise<void>
|
|||
null,
|
||||
2,
|
||||
)}\n`,
|
||||
'klo',
|
||||
'klo@example.com',
|
||||
'ktx',
|
||||
'ktx@example.com',
|
||||
'Seed PGlite dictionary profile',
|
||||
);
|
||||
}
|
||||
|
||||
describe('PGlite semantic-layer search prototype', () => {
|
||||
let tempDir: string;
|
||||
let project: KloLocalProject;
|
||||
let project: KtxLocalProject;
|
||||
let pgliteDataDir: string;
|
||||
let port: number;
|
||||
|
||||
beforeEach(async () => {
|
||||
tempDir = await mkdtemp(join(tmpdir(), 'klo-pglite-sl-prototype-'));
|
||||
project = await initKloProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' });
|
||||
tempDir = await mkdtemp(join(tmpdir(), 'ktx-pglite-sl-prototype-'));
|
||||
project = await initKtxProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' });
|
||||
project.config.ingest.embeddings.dimensions = 3;
|
||||
pgliteDataDir = join(tempDir, 'pglite-search');
|
||||
port = await allocatePort();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { mkdir } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
import type { KloEmbeddingPort } from '../core/index.js';
|
||||
import type { KloLocalProject } from '../project/index.js';
|
||||
import type { KtxEmbeddingPort } from '../core/index.js';
|
||||
import type { KtxLocalProject } from '../project/index.js';
|
||||
import { HybridSearchCore, type SearchCandidateGenerator } from '../search/index.js';
|
||||
import { KloPGliteOwnerProcess } from '../search/pglite-owner-process.js';
|
||||
import { KtxPGliteOwnerProcess } from '../search/pglite-owner-process.js';
|
||||
import {
|
||||
listLocalSlSources,
|
||||
loadLocalSlSourceRecords,
|
||||
|
|
@ -23,7 +23,7 @@ export interface PgliteSlSearchPrototypeOwnerOptions {
|
|||
export interface PgliteSlSearchPrototypeInput {
|
||||
connectionId?: string;
|
||||
query: string;
|
||||
embeddingService?: KloEmbeddingPort | null;
|
||||
embeddingService?: KtxEmbeddingPort | null;
|
||||
limit?: number;
|
||||
pglite: PgliteSlSearchPrototypeOwnerOptions;
|
||||
}
|
||||
|
|
@ -50,11 +50,11 @@ function candidateKey(summary: LocalSlSourceSummary): string {
|
|||
return `${summary.connectionId}/${summary.name}`;
|
||||
}
|
||||
|
||||
function pgliteDataDir(project: KloLocalProject, input: PgliteSlSearchPrototypeOwnerOptions): string {
|
||||
return input.dataDir ?? join(project.projectDir, '.klo', 'pglite-search-prototype');
|
||||
function pgliteDataDir(project: KtxLocalProject, input: PgliteSlSearchPrototypeOwnerOptions): string {
|
||||
return input.dataDir ?? join(project.projectDir, '.ktx', 'pglite-search-prototype');
|
||||
}
|
||||
|
||||
function vectorDimensions(project: KloLocalProject): number {
|
||||
function vectorDimensions(project: KtxLocalProject): number {
|
||||
const dimensions = project.config.ingest.embeddings.dimensions;
|
||||
if (!Number.isInteger(dimensions) || dimensions <= 0) {
|
||||
throw new Error(`PGlite SL search prototype needs a positive embedding dimension, got ${String(dimensions)}.`);
|
||||
|
|
@ -67,7 +67,7 @@ function connectionIdsForSearch(input: { connectionId?: string }): string[] | nu
|
|||
}
|
||||
|
||||
async function loadCandidates(
|
||||
project: KloLocalProject,
|
||||
project: KtxLocalProject,
|
||||
input: { connectionId?: string } = {},
|
||||
): Promise<LocalSlSearchCandidate[]> {
|
||||
if (input.connectionId) {
|
||||
|
|
@ -139,7 +139,7 @@ function postgresqlOrTsQuery(query: string): string {
|
|||
return [...new Set(terms)].join(' | ');
|
||||
}
|
||||
|
||||
async function resetPrototypeSchema(owner: KloPGliteOwnerProcess, dimensions: number): Promise<void> {
|
||||
async function resetPrototypeSchema(owner: KtxPGliteOwnerProcess, dimensions: number): Promise<void> {
|
||||
await owner.query(`
|
||||
DROP TABLE IF EXISTS prototype_sl_dictionary_values;
|
||||
DROP TABLE IF EXISTS prototype_sl_sources;
|
||||
|
|
@ -184,7 +184,7 @@ async function resetPrototypeSchema(owner: KloPGliteOwnerProcess, dimensions: nu
|
|||
|
||||
async function sourceEmbeddings(input: {
|
||||
candidates: LocalSlSearchCandidate[];
|
||||
embeddingService?: KloEmbeddingPort | null;
|
||||
embeddingService?: KtxEmbeddingPort | null;
|
||||
dimensions: number;
|
||||
}): Promise<Map<string, number[]> | null> {
|
||||
if (!input.embeddingService) {
|
||||
|
|
@ -209,7 +209,7 @@ async function sourceEmbeddings(input: {
|
|||
}
|
||||
|
||||
async function insertSourceRows(input: {
|
||||
owner: KloPGliteOwnerProcess;
|
||||
owner: KtxPGliteOwnerProcess;
|
||||
candidates: LocalSlSearchCandidate[];
|
||||
embeddings: Map<string, number[]> | null;
|
||||
}): Promise<void> {
|
||||
|
|
@ -246,7 +246,7 @@ async function insertSourceRows(input: {
|
|||
}
|
||||
}
|
||||
|
||||
async function insertDictionaryRows(owner: KloPGliteOwnerProcess, entries: SlDictionaryEntry[]): Promise<void> {
|
||||
async function insertDictionaryRows(owner: KtxPGliteOwnerProcess, entries: SlDictionaryEntry[]): Promise<void> {
|
||||
for (const entry of entries) {
|
||||
await owner.query(
|
||||
`
|
||||
|
|
@ -305,7 +305,7 @@ function groupDictionaryRows(rows: PgliteDictionaryRow[], limit: number) {
|
|||
}
|
||||
|
||||
async function queryLexicalCandidates(input: {
|
||||
owner: KloPGliteOwnerProcess;
|
||||
owner: KtxPGliteOwnerProcess;
|
||||
queryText: string;
|
||||
connectionIds: string[] | null;
|
||||
limit: number;
|
||||
|
|
@ -341,10 +341,10 @@ async function queryLexicalCandidates(input: {
|
|||
}
|
||||
|
||||
async function querySemanticCandidates(input: {
|
||||
owner: KloPGliteOwnerProcess;
|
||||
owner: KtxPGliteOwnerProcess;
|
||||
queryText: string;
|
||||
connectionIds: string[] | null;
|
||||
embeddingService?: KloEmbeddingPort | null;
|
||||
embeddingService?: KtxEmbeddingPort | null;
|
||||
dimensions: number;
|
||||
limit: number;
|
||||
}) {
|
||||
|
|
@ -397,7 +397,7 @@ async function querySemanticCandidates(input: {
|
|||
}
|
||||
|
||||
async function queryDictionaryCandidates(input: {
|
||||
owner: KloPGliteOwnerProcess;
|
||||
owner: KtxPGliteOwnerProcess;
|
||||
queryText: string;
|
||||
connectionIds: string[] | null;
|
||||
limit: number;
|
||||
|
|
@ -437,7 +437,7 @@ async function queryDictionaryCandidates(input: {
|
|||
}
|
||||
|
||||
export async function searchLocalSlSourcesWithPglitePrototype(
|
||||
project: KloLocalProject,
|
||||
project: KtxLocalProject,
|
||||
input: PgliteSlSearchPrototypeInput,
|
||||
): Promise<LocalSlSourceSearchResult[]> {
|
||||
const query = input.query.trim();
|
||||
|
|
@ -453,7 +453,7 @@ export async function searchLocalSlSourcesWithPglitePrototype(
|
|||
const dataDir = pgliteDataDir(project, input.pglite);
|
||||
await mkdir(dataDir, { recursive: true });
|
||||
|
||||
const owner = await KloPGliteOwnerProcess.start({
|
||||
const owner = await KtxPGliteOwnerProcess.start({
|
||||
dataDir,
|
||||
host: input.pglite.host,
|
||||
port: input.pglite.port,
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
import type { SemanticLayerQueryInput, SemanticLayerSource } from './types.js';
|
||||
|
||||
export interface KloConnectionInfo {
|
||||
export interface KtxConnectionInfo {
|
||||
id: string;
|
||||
name: string;
|
||||
connectionType: string;
|
||||
}
|
||||
|
||||
export interface KloQueryResult {
|
||||
export interface KtxQueryResult {
|
||||
headers?: string[];
|
||||
rows?: unknown[][];
|
||||
totalRows?: number;
|
||||
}
|
||||
|
||||
export interface SlConnectionCatalogPort {
|
||||
listEnabledConnections(ids: string[]): Promise<KloConnectionInfo[]>;
|
||||
getConnectionById(connectionId: string): Promise<KloConnectionInfo | null>;
|
||||
executeQuery(connectionId: string, sql: string): Promise<KloQueryResult>;
|
||||
listEnabledConnections(ids: string[]): Promise<KtxConnectionInfo[]>;
|
||||
getConnectionById(connectionId: string): Promise<KtxConnectionInfo | null>;
|
||||
executeQuery(connectionId: string, sql: string): Promise<KtxQueryResult>;
|
||||
}
|
||||
|
||||
export interface SlPythonPort {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { z } from 'zod';
|
||||
|
||||
// Literal vocabularies — kept in lockstep with the Python Pydantic model at
|
||||
// python-service/klo-sl/semantic_layer/models.py (SourceColumn / ColumnRole /
|
||||
// python-service/ktx-sl/semantic_layer/models.py (SourceColumn / ColumnRole /
|
||||
// ColumnVisibility / JoinDeclaration). If these diverge, YAMLs can pass
|
||||
// TypeScript validation at ingest time but fail Python loading at query time.
|
||||
const columnTypeValues = ['string', 'number', 'time', 'boolean'] as const;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import YAML from 'yaml';
|
||||
import type { KloFileStorePort, KloLogger } from '../core/index.js';
|
||||
import type { KtxFileStorePort, KtxLogger } from '../core/index.js';
|
||||
import { noopLogger } from '../core/index.js';
|
||||
import type { SlConnectionCatalogPort, SlPythonPort } from './ports.js';
|
||||
import { isOverlaySource, sourceDefinitionSchema, sourceOverlaySchema } from './schemas.js';
|
||||
|
|
@ -36,10 +36,10 @@ function formatPortError(error: unknown, fallback: string): string {
|
|||
|
||||
export class SemanticLayerService {
|
||||
constructor(
|
||||
private readonly configService: KloFileStorePort,
|
||||
private readonly configService: KtxFileStorePort,
|
||||
private readonly connections: SlConnectionCatalogPort,
|
||||
private readonly python: SlPythonPort,
|
||||
private readonly logger: KloLogger = noopLogger,
|
||||
private readonly logger: KtxLogger = noopLogger,
|
||||
) {}
|
||||
|
||||
/**
|
||||
|
|
@ -49,7 +49,7 @@ export class SemanticLayerService {
|
|||
*/
|
||||
forWorktree(workdir: string): SemanticLayerService {
|
||||
return new SemanticLayerService(
|
||||
this.configService.forWorktree(workdir) as KloFileStorePort,
|
||||
this.configService.forWorktree(workdir) as KtxFileStorePort,
|
||||
this.connections,
|
||||
this.python,
|
||||
this.logger,
|
||||
|
|
|
|||
|
|
@ -2,16 +2,16 @@ import { mkdtemp, rm } from 'node:fs/promises';
|
|||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
||||
import { initKloProject, type KloLocalProject } from '../project/index.js';
|
||||
import { initKtxProject, type KtxLocalProject } from '../project/index.js';
|
||||
import { loadLatestSlDictionaryEntries } from './sl-dictionary-profile.js';
|
||||
|
||||
describe('loadLatestSlDictionaryEntries', () => {
|
||||
let tempDir: string;
|
||||
let project: KloLocalProject;
|
||||
let project: KtxLocalProject;
|
||||
|
||||
beforeEach(async () => {
|
||||
tempDir = await mkdtemp(join(tmpdir(), 'klo-sl-dictionary-profile-'));
|
||||
project = await initKloProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' });
|
||||
tempDir = await mkdtemp(join(tmpdir(), 'ktx-sl-dictionary-profile-'));
|
||||
project = await initKtxProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' });
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
|
@ -63,8 +63,8 @@ describe('loadLatestSlDictionaryEntries', () => {
|
|||
null,
|
||||
2,
|
||||
)}\n`,
|
||||
'klo',
|
||||
'klo@example.com',
|
||||
'ktx',
|
||||
'ktx@example.com',
|
||||
'Seed profile',
|
||||
);
|
||||
|
||||
|
|
@ -98,8 +98,8 @@ describe('loadLatestSlDictionaryEntries', () => {
|
|||
null,
|
||||
2,
|
||||
)}\n`,
|
||||
'klo',
|
||||
'klo@example.com',
|
||||
'ktx',
|
||||
'ktx@example.com',
|
||||
'Seed newer profile',
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { KloLocalProject } from '../project/index.js';
|
||||
import { defaultKloDataDictionarySettings, isKloDataDictionaryCandidate } from '../scan/index.js';
|
||||
import type { KtxLocalProject } from '../project/index.js';
|
||||
import { defaultKtxDataDictionarySettings, isKtxDataDictionaryCandidate } from '../scan/index.js';
|
||||
|
||||
export interface SlDictionaryEntry {
|
||||
connectionId: string;
|
||||
|
|
@ -58,12 +58,12 @@ function columnEntries(connectionId: string, column: RelationshipProfileColumn):
|
|||
}
|
||||
|
||||
const columnType = column.normalizedType ?? column.nativeType ?? '';
|
||||
if (!isKloDataDictionaryCandidate(columnType, columnName)) {
|
||||
if (!isKtxDataDictionaryCandidate(columnType, columnName)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const cardinality = typeof column.distinctCount === 'number' ? column.distinctCount : null;
|
||||
if (cardinality !== null && cardinality > defaultKloDataDictionarySettings.cardinalityThreshold) {
|
||||
if (cardinality !== null && cardinality > defaultKtxDataDictionarySettings.cardinalityThreshold) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ function columnEntries(connectionId: string, column: RelationshipProfileColumn):
|
|||
}));
|
||||
}
|
||||
|
||||
async function latestProfilePath(project: KloLocalProject, connectionId: string): Promise<string | null> {
|
||||
async function latestProfilePath(project: KtxLocalProject, connectionId: string): Promise<string | null> {
|
||||
const root = `raw-sources/${connectionId}/live-database`;
|
||||
let files: string[];
|
||||
try {
|
||||
|
|
@ -94,7 +94,7 @@ async function latestProfilePath(project: KloLocalProject, connectionId: string)
|
|||
}
|
||||
|
||||
export async function loadLatestSlDictionaryEntries(
|
||||
project: KloLocalProject,
|
||||
project: KtxLocalProject,
|
||||
connectionIds: readonly string[],
|
||||
): Promise<SlDictionaryEntry[]> {
|
||||
const entries: SlDictionaryEntry[] = [];
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { KloEmbeddingPort, KloLogger } from '../core/index.js';
|
||||
import type { KtxEmbeddingPort, KtxLogger } from '../core/index.js';
|
||||
import { noopLogger } from '../core/index.js';
|
||||
import { DEFAULT_PRIORITY, resolveDescription } from './descriptions.js';
|
||||
import type { SlSourcesIndexPort } from './ports.js';
|
||||
|
|
@ -74,9 +74,9 @@ export function buildSemanticLayerSourceSearchText(
|
|||
|
||||
export class SlSearchService {
|
||||
constructor(
|
||||
private readonly embeddingService: KloEmbeddingPort,
|
||||
private readonly embeddingService: KtxEmbeddingPort,
|
||||
private readonly slSourcesRepository: SlSourcesIndexPort,
|
||||
private readonly logger: KloLogger = noopLogger,
|
||||
private readonly logger: KtxLogger = noopLogger,
|
||||
) {}
|
||||
|
||||
async indexSources(connectionId: string, sources: SemanticLayerSource[]): Promise<void> {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ describe('SqliteSlSourcesIndex', () => {
|
|||
let dbPath: string;
|
||||
|
||||
beforeEach(async () => {
|
||||
tempDir = await mkdtemp(join(tmpdir(), 'klo-sqlite-sl-index-'));
|
||||
tempDir = await mkdtemp(join(tmpdir(), 'ktx-sqlite-sl-index-'));
|
||||
dbPath = join(tempDir, 'db.sqlite');
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import YAML from 'yaml';
|
||||
import type { GitService, KloFileStorePort } from '../../core/index.js';
|
||||
import type { GitService, KtxFileStorePort } from '../../core/index.js';
|
||||
import { SYSTEM_GIT_AUTHOR } from '../../tools/index.js';
|
||||
import type { SlConnectionCatalogPort, SlSourcesIndexPort } from '../ports.js';
|
||||
import { sourceOverlaySchema } from '../schemas.js';
|
||||
|
|
@ -9,7 +9,7 @@ import { sourceDefinitionSchema } from './base-semantic-layer.tool.js';
|
|||
export interface SlValidationDeps {
|
||||
semanticLayerService: SemanticLayerService;
|
||||
connections: SlConnectionCatalogPort;
|
||||
configService: KloFileStorePort;
|
||||
configService: KtxFileStorePort;
|
||||
gitService: GitService;
|
||||
slSourcesRepository: SlSourcesIndexPort;
|
||||
probeRowCount: number;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue