rename klo to ktx

This commit is contained in:
Andrey Avtomonov 2026-05-10 23:51:24 +02:00
parent 1a42152e6f
commit 3ce510b55b
704 changed files with 10205 additions and 10255 deletions

View file

@ -1,6 +0,0 @@
"""Portable compute package for KLO."""
PACKAGE_NAME = "klo-daemon"
VERSION = "0.1.0"
__all__ = ["PACKAGE_NAME", "VERSION"]

View file

@ -1,6 +0,0 @@
from klo_daemon import PACKAGE_NAME, VERSION
def test_package_metadata() -> None:
assert PACKAGE_NAME == "klo-daemon"
assert VERSION == "0.1.0"

View file

@ -1,17 +1,17 @@
# klo-daemon
# ktx-daemon
`klo-daemon` is the portable Python compute package for KLO.
`ktx-daemon` is the portable Python compute package for KTX.
It supports portable compute in two modes:
- One-shot commands, used by default by `@klo/context`.
- One-shot commands, used by default by `@ktx/context`.
- An explicit HTTP server for long-running local MCP sessions.
## One-shot semantic query
```bash
printf '%s\n' '{"sources":[],"query":{"measures":[],"dimensions":[]},"dialect":"postgres"}' \
| klo-daemon semantic-query
| ktx-daemon semantic-query
```
## One-shot source generation
@ -20,7 +20,7 @@ Generate semantic-layer sources from schema scan data:
```bash
printf '%s\n' '{"tables":[{"name":"orders","db":"public","columns":[{"name":"id","type":"integer","primary_key":true}]}],"links":[],"dialect":"postgres"}' \
| klo-daemon semantic-generate-sources
| ktx-daemon semantic-generate-sources
```
## One-shot database introspection
@ -29,7 +29,7 @@ Introspect a Postgres database schema:
```bash
printf '%s\n' '{"connection_id":"warehouse","driver":"postgres","url":"postgresql://readonly@example.test/warehouse","schemas":["public"]}' \
| klo-daemon database-introspect
| ktx-daemon database-introspect
```
## One-shot LookML parsing
@ -38,7 +38,7 @@ Parse LookML projects into resolved, KSL-ready structures:
```bash
printf '%s\n' '{"files":[{"path":"views/orders.view.lkml","content":"view: orders { sql_table_name: public.orders ;; measure: order_count { type: count } }"}],"dialect":"postgres"}' \
| klo-daemon lookml-parse
| ktx-daemon lookml-parse
```
## One-shot embeddings
@ -47,14 +47,14 @@ Compute text embeddings locally:
```bash
printf '%s\n' '{"text":"hello"}' \
| klo-daemon embedding-compute
| ktx-daemon embedding-compute
```
Compute text embeddings locally in bulk:
```bash
printf '%s\n' '{"texts":["hello","world"]}' \
| klo-daemon embedding-compute-bulk
| ktx-daemon embedding-compute-bulk
```
## One-shot code execution
@ -63,7 +63,7 @@ Execute Python code with the current in-process boundary:
```bash
printf '%s\n' '{"code":"result = 1 + 2"}' \
| klo-daemon code-execute
| ktx-daemon code-execute
```
## HTTP compute server
@ -71,13 +71,13 @@ printf '%s\n' '{"code":"result = 1 + 2"}' \
Start the HTTP compute server with code execution disabled:
```bash
klo-daemon serve-http --host 127.0.0.1 --port 8765
ktx-daemon serve-http --host 127.0.0.1 --port 8765
```
Enable HTTP code execution explicitly:
```bash
klo-daemon serve-http --host 127.0.0.1 --port 8765 --enable-code-execution
ktx-daemon serve-http --host 127.0.0.1 --port 8765 --enable-code-execution
```
Available HTTP endpoints:
@ -99,6 +99,6 @@ Code execution is off by default. When enabled, it runs Python `exec` in the
daemon process with the same in-process boundary as the one-shot
`code-execute` command and does not provide OS-level sandboxing.
HTTP code execution uses the standalone KLO boundary. It does not forward
HTTP code execution uses the standalone KTX boundary. It does not forward
caller authorization headers to a host app and does not connect scratchpad or
visualization helpers to host application APIs.

View file

@ -1,13 +1,13 @@
[project]
name = "klo-daemon"
name = "ktx-daemon"
version = "0.1.0"
description = "Portable compute package for KLO semantic-layer operations"
description = "Portable compute package for KTX semantic-layer operations"
readme = "README.md"
requires-python = ">=3.13"
license = "Apache-2.0"
dependencies = [
"fastapi>=0.115.0",
"klo-sl",
"ktx-sl",
"lkml>=1.3.7",
"numpy>=2.2.6",
"orjson>=3.11.4",
@ -22,7 +22,7 @@ dependencies = [
]
[project.scripts]
klo-daemon = "klo_daemon.__main__:main"
ktx-daemon = "ktx_daemon.__main__:main"
[project.urls]
Homepage = "https://github.com/kaelio/ktx"
@ -34,7 +34,7 @@ requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["src/klo_daemon"]
packages = ["src/ktx_daemon"]
[dependency-groups]
dev = [
@ -43,7 +43,7 @@ dev = [
]
[tool.uv.sources]
klo-sl = { workspace = true }
ktx-sl = { workspace = true }
[tool.pytest.ini_options]
testpaths = ["tests"]

View file

@ -0,0 +1,6 @@
"""Portable compute package for KTX."""
PACKAGE_NAME = "ktx-daemon"
VERSION = "0.1.0"
__all__ = ["PACKAGE_NAME", "VERSION"]

View file

@ -1,4 +1,4 @@
"""Command entry point for one-shot KLO daemon compute operations."""
"""Command entry point for one-shot KTX daemon compute operations."""
from __future__ import annotations
@ -9,32 +9,32 @@ from typing import Any
from pydantic import ValidationError
from klo_daemon.code_execution import ExecuteCodeRequest, execute_code_response
from klo_daemon.database_introspection import (
from ktx_daemon.code_execution import ExecuteCodeRequest, execute_code_response
from ktx_daemon.database_introspection import (
DatabaseIntrospectionRequest,
introspect_database_response,
)
from klo_daemon.embeddings import (
from ktx_daemon.embeddings import (
ComputeEmbeddingBulkRequest,
ComputeEmbeddingRequest,
compute_embedding_bulk_response,
compute_embedding_response,
)
from klo_daemon.lookml import ParseLookMLRequest, parse_lookml_project
from klo_daemon.semantic_layer import (
from ktx_daemon.lookml import ParseLookMLRequest, parse_lookml_project
from ktx_daemon.semantic_layer import (
SemanticLayerQueryRequest,
ValidateSourcesRequest,
query_semantic_layer,
validate_semantic_layer,
)
from klo_daemon.source_generation import (
from ktx_daemon.source_generation import (
GenerateSourcesRequest,
generate_sources_response,
)
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(prog="klo-daemon")
parser = argparse.ArgumentParser(prog="ktx-daemon")
subcommands = parser.add_subparsers(dest="command", required=True)
subcommands.add_parser("semantic-query", help="Compile a semantic-layer query")
subcommands.add_parser("semantic-validate", help="Validate semantic-layer sources")
@ -64,7 +64,7 @@ def build_parser() -> argparse.ArgumentParser:
)
serve_http = subcommands.add_parser(
"serve-http",
help="Run the KLO daemon portable compute HTTP server",
help="Run the KTX daemon portable compute HTTP server",
)
serve_http.add_argument("--host", default="127.0.0.1")
serve_http.add_argument("--port", type=int, default=8765)
@ -98,7 +98,7 @@ def run_http_server(
) -> None:
import uvicorn
from klo_daemon.app import create_app
from ktx_daemon.app import create_app
uvicorn.run(
create_app(enable_code_execution=enable_code_execution),

View file

@ -1,4 +1,4 @@
"""FastAPI app factory for the KLO daemon semantic compute server."""
"""FastAPI app factory for the KTX daemon semantic compute server."""
from __future__ import annotations
@ -9,18 +9,18 @@ from typing import Any
from fastapi import FastAPI, HTTPException
from fastapi.responses import Response
from klo_daemon.code_execution import (
from ktx_daemon.code_execution import (
ExecuteCodeRequest,
ExecuteCodeResponse,
dumps_numpy_json,
execute_code_response,
)
from klo_daemon.database_introspection import (
from ktx_daemon.database_introspection import (
DatabaseIntrospectionRequest,
DatabaseIntrospectionResponse,
introspect_database_response,
)
from klo_daemon.embeddings import (
from ktx_daemon.embeddings import (
ComputeEmbeddingBulkRequest,
ComputeEmbeddingBulkResponse,
ComputeEmbeddingRequest,
@ -29,12 +29,12 @@ from klo_daemon.embeddings import (
compute_embedding_bulk_response,
compute_embedding_response,
)
from klo_daemon.lookml import (
from ktx_daemon.lookml import (
ParseLookMLRequest,
ParseLookMLResponse,
parse_lookml_project,
)
from klo_daemon.semantic_layer import (
from ktx_daemon.semantic_layer import (
SemanticLayerQueryRequest,
SemanticLayerQueryResponse,
ValidateSourcesRequest,
@ -42,12 +42,12 @@ from klo_daemon.semantic_layer import (
query_semantic_layer,
validate_semantic_layer,
)
from klo_daemon.source_generation import (
from ktx_daemon.source_generation import (
GenerateSourcesRequest,
GenerateSourcesResponse,
generate_sources_response,
)
from klo_daemon.table_identifier import (
from ktx_daemon.table_identifier import (
ParseTableIdentifierBatchRequest,
ParseTableIdentifierBatchResponse,
parse_table_identifier_response,
@ -73,8 +73,8 @@ def create_app(
enable_code_execution: bool = False,
) -> FastAPI:
app = FastAPI(
title="KLO Daemon",
description="Stateless portable compute server for KLO.",
title="KTX Daemon",
description="Stateless portable compute server for KTX.",
version="0.1.0",
)

View file

@ -1,4 +1,4 @@
"""Portable in-process code execution helpers for KLO daemon.
"""Portable in-process code execution helpers for KTX daemon.
This module preserves the host application's current Python execution behavior.
It runs code with Python ``exec`` in the current process and does not provide

View file

@ -1,4 +1,4 @@
"""Portable database introspection helpers for KLO daemon."""
"""Portable database introspection helpers for KTX daemon."""
from __future__ import annotations
@ -183,7 +183,7 @@ def _load_postgres_rows(
connection = psycopg.connect(
request.url,
connect_timeout=request.connection_timeout_seconds,
application_name="klo-daemon-database-introspection",
application_name="ktx-daemon-database-introspection",
row_factory=dict_row,
)
try:

View file

@ -1,4 +1,4 @@
"""Portable embedding compute helpers for KLO daemon."""
"""Portable embedding compute helpers for KTX daemon."""
from __future__ import annotations

View file

@ -1,4 +1,4 @@
"""Semantic-layer compute helpers for the KLO daemon package."""
"""Semantic-layer compute helpers for the KTX daemon package."""
from __future__ import annotations

View file

@ -1,4 +1,4 @@
"""Generate klo-sl YAML source definitions from database schema scan data."""
"""Generate ktx-sl YAML source definitions from database schema scan data."""
from __future__ import annotations
@ -243,7 +243,7 @@ def generate_sources(request: GenerateSourcesRequest) -> list[dict[str, Any]]:
)
sources.append(source.model_dump(exclude_none=True))
logger.info("Generated %d klo-sl source definitions", len(sources))
logger.info("Generated %d ktx-sl source definitions", len(sources))
return sources

View file

@ -2,8 +2,8 @@ from __future__ import annotations
from fastapi.testclient import TestClient
from klo_daemon.app import create_app
from klo_daemon.database_introspection import (
from ktx_daemon.app import create_app
from ktx_daemon.database_introspection import (
DatabaseIntrospectionResponse,
LiveDatabaseColumn,
LiveDatabaseTable,

View file

@ -30,7 +30,7 @@ def run_daemon_command(
src_path = str(Path(__file__).resolve().parents[1] / "src")
env["PYTHONPATH"] = src_path + os.pathsep + env.get("PYTHONPATH", "")
return subprocess.run(
[sys.executable, "-m", "klo_daemon", command],
[sys.executable, "-m", "ktx_daemon", command],
input=json.dumps(payload),
text=True,
capture_output=True,
@ -79,7 +79,7 @@ def test_command_returns_nonzero_for_invalid_json() -> None:
src_path = str(Path(__file__).resolve().parents[1] / "src")
env["PYTHONPATH"] = src_path + os.pathsep + env.get("PYTHONPATH", "")
result = subprocess.run(
[sys.executable, "-m", "klo_daemon", "semantic-query"],
[sys.executable, "-m", "ktx_daemon", "semantic-query"],
input="{",
text=True,
capture_output=True,
@ -94,7 +94,7 @@ def test_command_returns_nonzero_for_invalid_json() -> None:
def test_serve_http_command_starts_uvicorn_without_reading_stdin(
monkeypatch,
) -> None:
from klo_daemon import __main__ as daemon_main
from ktx_daemon import __main__ as daemon_main
calls: list[dict[str, object]] = []
@ -146,7 +146,7 @@ def test_serve_http_command_starts_uvicorn_without_reading_stdin(
def test_serve_http_command_defaults_to_loopback(monkeypatch) -> None:
from klo_daemon import __main__ as daemon_main
from ktx_daemon import __main__ as daemon_main
calls: list[dict[str, object]] = []
@ -180,7 +180,7 @@ def test_serve_http_command_defaults_to_loopback(monkeypatch) -> None:
def test_serve_http_command_can_enable_code_execution(monkeypatch) -> None:
from klo_daemon import __main__ as daemon_main
from ktx_daemon import __main__ as daemon_main
calls: list[dict[str, object]] = []
@ -300,8 +300,8 @@ def test_semantic_generate_sources_command_reads_stdin_and_writes_json() -> None
def test_database_introspect_command_reads_stdin_and_writes_json(
monkeypatch, capsys
) -> None:
from klo_daemon import __main__ as daemon_main
from klo_daemon.database_introspection import (
from ktx_daemon import __main__ as daemon_main
from ktx_daemon.database_introspection import (
DatabaseIntrospectionResponse,
LiveDatabaseColumn,
LiveDatabaseTable,
@ -353,8 +353,8 @@ def test_database_introspect_command_reads_stdin_and_writes_json(
def test_embedding_compute_command_reads_stdin_and_writes_json(
monkeypatch, capsys
) -> None:
from klo_daemon import __main__ as daemon_main
from klo_daemon.embeddings import ComputeEmbeddingResponse
from ktx_daemon import __main__ as daemon_main
from ktx_daemon.embeddings import ComputeEmbeddingResponse
def fake_compute(request):
assert request.text == "hello"
@ -372,8 +372,8 @@ def test_embedding_compute_command_reads_stdin_and_writes_json(
def test_embedding_compute_bulk_command_reads_stdin_and_writes_json(
monkeypatch, capsys
) -> None:
from klo_daemon import __main__ as daemon_main
from klo_daemon.embeddings import ComputeEmbeddingBulkResponse
from ktx_daemon import __main__ as daemon_main
from ktx_daemon.embeddings import ComputeEmbeddingBulkResponse
def fake_compute(request):
assert request.texts == ["hello", "world"]
@ -389,8 +389,8 @@ def test_embedding_compute_bulk_command_reads_stdin_and_writes_json(
def test_code_execute_command_reads_stdin_and_writes_json(monkeypatch, capsys) -> None:
from klo_daemon import __main__ as daemon_main
from klo_daemon.code_execution import ExecuteCodeResponse
from ktx_daemon import __main__ as daemon_main
from ktx_daemon.code_execution import ExecuteCodeResponse
calls: list[dict[str, Any]] = []

View file

@ -9,7 +9,7 @@ import orjson
import pandas as pd
import pytest
from klo_daemon.code_execution import (
from ktx_daemon.code_execution import (
ExecuteCodeRequest,
create_scratchpad_helpers,
detect_visualizations,

View file

@ -2,7 +2,7 @@ from __future__ import annotations
import pytest
from klo_daemon.database_introspection import (
from ktx_daemon.database_introspection import (
DatabaseIntrospectionRequest,
DatabaseIntrospectionRows,
_statement_timeout_config,

View file

@ -2,7 +2,7 @@ from __future__ import annotations
import pytest
from klo_daemon.embeddings import (
from ktx_daemon.embeddings import (
ComputeEmbeddingBulkRequest,
ComputeEmbeddingRequest,
SentenceTransformersEmbeddingProvider,

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from klo_daemon.lookml import (
from ktx_daemon.lookml import (
LookMLFileInput,
ParseLookMLRequest,
parse_lookml_project,

View file

@ -0,0 +1,6 @@
from ktx_daemon import PACKAGE_NAME, VERSION
def test_package_metadata() -> None:
assert PACKAGE_NAME == "ktx-daemon"
assert VERSION == "0.1.0"

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from klo_daemon.semantic_layer import (
from ktx_daemon.semantic_layer import (
SemanticLayerQueryRequest,
ValidateSourcesRequest,
query_semantic_layer,

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from klo_daemon.source_generation import (
from ktx_daemon.source_generation import (
ColumnInput,
GenerateSourcesRequest,
LinkInput,

View file

@ -1,5 +1,5 @@
[project]
name = "klo-sl"
name = "ktx-sl"
version = "0.1.0"
description = "Agent-first semantic layer engine with aggregate locality"
readme = "README.md"

View file

@ -2,8 +2,8 @@
"""Generate semantic layer YAML sources from demo DB metadata.
Usage:
kubectl port-forward -n klo-demo deployment/klo-demo-db 5433:5432 &
KLO_DEMO_DB_PASSWORD=local-demo-password python scripts/gen_b2b_saas_model.py
kubectl port-forward -n ktx-demo deployment/ktx-demo-db 5433:5432 &
KTX_DEMO_DB_PASSWORD=local-demo-password python scripts/gen_b2b_saas_model.py
"""
import os
@ -14,11 +14,11 @@ CONNECTION_ID = "256bc76b-cc47-4d5d-a9fc-5bcfb0364d44"
OUTPUT_DIR = os.path.join(os.path.dirname(__file__), "..", "sources", "b2b_saas")
DB_PARAMS = {
"host": os.environ.get("KLO_DEMO_DB_HOST", "127.0.0.1"),
"port": int(os.environ.get("KLO_DEMO_DB_PORT", "5433")),
"user": os.environ.get("KLO_DEMO_DB_USER", "klo-demo-user"),
"password": os.environ.get("KLO_DEMO_DB_PASSWORD", ""),
"dbname": os.environ.get("KLO_DEMO_DB_NAME", "klo-demo-db"),
"host": os.environ.get("KTX_DEMO_DB_HOST", "127.0.0.1"),
"port": int(os.environ.get("KTX_DEMO_DB_PORT", "5433")),
"user": os.environ.get("KTX_DEMO_DB_USER", "ktx-demo-user"),
"password": os.environ.get("KTX_DEMO_DB_PASSWORD", ""),
"dbname": os.environ.get("KTX_DEMO_DB_NAME", "ktx-demo-db"),
}
# Map DB types to semantic layer types

View file

@ -21,7 +21,7 @@ from semantic_layer.engine import SemanticEngine
SOURCES_DIR = Path(__file__).resolve().parent.parent / "sources" / "b2b_saas"
DB_PATH = Path(
os.environ.get("KLO_B2B_SQLITE_DB", "sample-data-generator/b2b_data.db")
os.environ.get("KTX_B2B_SQLITE_DB", "sample-data-generator/b2b_data.db")
).expanduser()
# sqlglot's sqlite dialect handles most transpilation, but has a few gaps.

Some files were not shown because too many files have changed in this diff Show more