mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-10 08:05:14 +02:00
- Block project-aware commands when ktx.yaml is absent and render a
friendly "run ktx setup" message (plain or JSON) instead of leaking
ENOENT or "Project: ..." noise.
- Make ktx status project detect the missing config and emit the same
message via a shared renderMissingProjectMessage helper.
- Move the managed Python daemon state, stdout, and stderr files out of
the shared runtime root into {projectDir}/.ktx/runtime so multiple
projects no longer share a single daemon record.
- Simplify the runtime install root to ~/.ktx/runtime on every platform
and split the daemon-specific paths into managedPythonDaemonLayout,
threading projectDir through start, stop, and stop-all paths.
98 lines
2.8 KiB
TypeScript
98 lines
2.8 KiB
TypeScript
import {
|
|
MANAGED_SENTENCE_TRANSFORMERS_BASE_URL,
|
|
MANAGED_SENTENCE_TRANSFORMERS_BASE_URL_ENV,
|
|
} from '@ktx/context';
|
|
import type { KtxProjectEmbeddingConfig } from '@ktx/context/project';
|
|
import type { KtxEmbeddingConfig } from '@ktx/llm';
|
|
import type { KtxCliIo } from './cli-runtime.js';
|
|
import {
|
|
ensureManagedPythonCommandRuntime,
|
|
type KtxManagedPythonInstallPolicy,
|
|
type ManagedPythonCommandRuntime,
|
|
} from './managed-python-command.js';
|
|
import { startManagedPythonDaemon, type ManagedPythonDaemonStartResult } from './managed-python-daemon.js';
|
|
|
|
export interface ManagedLocalEmbeddingsDaemon {
|
|
baseUrl: string;
|
|
env: Record<typeof MANAGED_SENTENCE_TRANSFORMERS_BASE_URL_ENV, string>;
|
|
}
|
|
|
|
export interface ManagedLocalEmbeddingsOptions {
|
|
cliVersion: string;
|
|
projectDir: string;
|
|
installPolicy: KtxManagedPythonInstallPolicy;
|
|
io: KtxCliIo;
|
|
ensureRuntime?: (options: {
|
|
cliVersion: string;
|
|
installPolicy: KtxManagedPythonInstallPolicy;
|
|
io: KtxCliIo;
|
|
feature: 'local-embeddings';
|
|
}) => Promise<ManagedPythonCommandRuntime>;
|
|
startDaemon?: (options: {
|
|
cliVersion: string;
|
|
projectDir: string;
|
|
features: ['local-embeddings'];
|
|
force: boolean;
|
|
}) => Promise<ManagedPythonDaemonStartResult>;
|
|
}
|
|
|
|
export function managedLocalEmbeddingProjectConfig(input: {
|
|
model: string;
|
|
dimensions: number;
|
|
}): KtxProjectEmbeddingConfig {
|
|
return {
|
|
backend: 'sentence-transformers',
|
|
model: input.model,
|
|
dimensions: input.dimensions,
|
|
sentenceTransformers: {
|
|
base_url: MANAGED_SENTENCE_TRANSFORMERS_BASE_URL,
|
|
pathPrefix: '',
|
|
},
|
|
};
|
|
}
|
|
|
|
export function managedLocalEmbeddingHealthConfig(input: {
|
|
baseUrl: string;
|
|
model: string;
|
|
dimensions: number;
|
|
}): KtxEmbeddingConfig {
|
|
return {
|
|
backend: 'sentence-transformers',
|
|
model: input.model,
|
|
dimensions: input.dimensions,
|
|
sentenceTransformers: {
|
|
baseURL: input.baseUrl,
|
|
pathPrefix: '',
|
|
},
|
|
};
|
|
}
|
|
|
|
export async function ensureManagedLocalEmbeddingsDaemon(
|
|
options: ManagedLocalEmbeddingsOptions,
|
|
): Promise<ManagedLocalEmbeddingsDaemon> {
|
|
const ensureRuntime = options.ensureRuntime ?? ensureManagedPythonCommandRuntime;
|
|
const startDaemon = options.startDaemon ?? startManagedPythonDaemon;
|
|
|
|
await ensureRuntime({
|
|
cliVersion: options.cliVersion,
|
|
installPolicy: options.installPolicy,
|
|
io: options.io,
|
|
feature: 'local-embeddings',
|
|
});
|
|
const daemon = await startDaemon({
|
|
cliVersion: options.cliVersion,
|
|
projectDir: options.projectDir,
|
|
features: ['local-embeddings'],
|
|
force: false,
|
|
});
|
|
|
|
const verb = daemon.status === 'started' ? 'Started' : 'Using';
|
|
options.io.stderr.write(`${verb} KTX local embeddings daemon: ${daemon.baseUrl}\n`);
|
|
|
|
return {
|
|
baseUrl: daemon.baseUrl,
|
|
env: {
|
|
[MANAGED_SENTENCE_TRANSFORMERS_BASE_URL_ENV]: daemon.baseUrl,
|
|
},
|
|
};
|
|
}
|