mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-10-26 02:04:37 +08:00
feat(cli): install local embedding runtime on demand
This commit is contained in:
1 parent
93fc26fb83
commit
f96fef7b46
29 files changed
+741
-55
No files matched your search
+3
-1
@@ -17,13 +17,14 @@ import { registerQueryCommands } from './query/register'
|
||||
import { registerManifestCommand } from './query/manifest'
|
||||
import { registerImportCommand } from './import/command'
|
||||
import { registerValidateCommand } from './validate/command'
|
||||
import { registerRuntimeCommand } from './semantic-index/runtime-command'
|
||||
|
||||
const program = new Command()
|
||||
|
||||
program.name('chatlab').description('ChatLab - Chat history analysis tool').version(getVersion(), '-v, --version')
|
||||
|
||||
program.hook('preAction', async (_thisCommand, actionCommand) => {
|
||||
if (actionCommand.name() === 'update') return
|
||||
if (actionCommand.name() === 'update' || actionCommand.parent?.name() === 'runtime') return
|
||||
const { checkForUpdatesInteractive } = await import('./update-checker')
|
||||
await checkForUpdatesInteractive()
|
||||
})
|
||||
@@ -53,6 +54,7 @@ registerManifestCommand(program, getVersion())
|
||||
|
||||
registerImportCommand(program)
|
||||
registerValidateCommand(program)
|
||||
registerRuntimeCommand(program)
|
||||
|
||||
program
|
||||
.command('formats')
|
||||
|
||||
@@ -34,6 +34,7 @@ import { createCliRunAgentStream } from '../ai/agent-stream-runner'
|
||||
import { initSync, cleanupSync } from '../sync'
|
||||
import { resolveCliPath } from '../paths'
|
||||
import { assertCliDataDirCompatible } from '../runtime-compat'
|
||||
import { resolveCliLocalEmbeddingRuntimeConfig } from '../semantic-index/local-runtime'
|
||||
|
||||
let server: FastifyInstance | null = null
|
||||
let dbManager: DatabaseManager | null = null
|
||||
@@ -169,6 +170,7 @@ export async function startHttpServer(options?: HttpServerOptions): Promise<{
|
||||
pathProvider,
|
||||
runtime,
|
||||
nativeBinding,
|
||||
localEmbeddingRuntime: resolveCliLocalEmbeddingRuntimeConfig(pathProvider.getAiDataDir()),
|
||||
workerEntryUrl: import.meta.url.endsWith('.ts')
|
||||
? undefined
|
||||
: new URL('./semantic-index-worker.mjs', import.meta.url),
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import path from 'node:path'
|
||||
import test from 'node:test'
|
||||
import { LOCAL_EMBEDDING_RUNTIME_DIR_ENV, resolveCliLocalEmbeddingRuntimeConfig } from './local-runtime'
|
||||
|
||||
test('uses a platform-specific managed runtime below the CLI AI directory by default', () => {
|
||||
assert.deepEqual(resolveCliLocalEmbeddingRuntimeConfig('/tmp/chatlab-ai', {}), {
|
||||
baseDir: path.join('/tmp/chatlab-ai', 'runtime', 'local-embedding'),
|
||||
installMode: 'auto',
|
||||
})
|
||||
})
|
||||
|
||||
test('treats an explicit runtime directory as preinstalled', () => {
|
||||
assert.deepEqual(
|
||||
resolveCliLocalEmbeddingRuntimeConfig('/tmp/chatlab-ai', {
|
||||
[LOCAL_EMBEDDING_RUNTIME_DIR_ENV]: '/opt/chatlab/local-embedding',
|
||||
}),
|
||||
{
|
||||
baseDir: '/opt/chatlab/local-embedding',
|
||||
installMode: 'preinstalled',
|
||||
}
|
||||
)
|
||||
})
|
||||
@@ -0,0 +1,34 @@
|
||||
import path from 'node:path'
|
||||
import { createLocalEmbeddingRuntimeManager, type LocalEmbeddingRuntimeConfig } from '@openchatlab/node-runtime'
|
||||
|
||||
export const LOCAL_EMBEDDING_RUNTIME_DIR_ENV = 'CHATLAB_LOCAL_EMBEDDING_RUNTIME_DIR'
|
||||
|
||||
export function resolveCliLocalEmbeddingRuntimeConfig(
|
||||
aiDataDir: string,
|
||||
env: NodeJS.ProcessEnv = process.env
|
||||
): LocalEmbeddingRuntimeConfig {
|
||||
const preinstalledDir = env[LOCAL_EMBEDDING_RUNTIME_DIR_ENV]?.trim()
|
||||
if (preinstalledDir) {
|
||||
return {
|
||||
baseDir: path.resolve(preinstalledDir),
|
||||
installMode: 'preinstalled',
|
||||
}
|
||||
}
|
||||
return {
|
||||
baseDir: path.join(aiDataDir, 'runtime', 'local-embedding'),
|
||||
installMode: 'auto',
|
||||
}
|
||||
}
|
||||
|
||||
export async function installCliLocalEmbeddingRuntime(
|
||||
aiDataDir: string,
|
||||
env: NodeJS.ProcessEnv = process.env
|
||||
): Promise<string> {
|
||||
const config = resolveCliLocalEmbeddingRuntimeConfig(aiDataDir, env)
|
||||
const manager = createLocalEmbeddingRuntimeManager({
|
||||
...config,
|
||||
// The build-time installer populates a directory that normal app startup treats as read-only.
|
||||
installMode: 'auto',
|
||||
})
|
||||
return await manager.ensureInstalled()
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import path from 'node:path'
|
||||
import os from 'node:os'
|
||||
import type { Command } from 'commander'
|
||||
import { installCliLocalEmbeddingRuntime } from './local-runtime'
|
||||
|
||||
const LOCAL_EMBEDDING_COMPONENT = 'local-embedding'
|
||||
|
||||
export function registerRuntimeCommand(program: Command): void {
|
||||
program
|
||||
.command('runtime', { hidden: true })
|
||||
.command('install <component>', { hidden: true })
|
||||
.action(async (component: string) => {
|
||||
if (component !== LOCAL_EMBEDDING_COMPONENT) {
|
||||
throw new Error(`Unknown ChatLab runtime component: ${component}`)
|
||||
}
|
||||
const aiDataDir = path.join(os.homedir(), '.chatlab', 'ai')
|
||||
const runtimeDir = await installCliLocalEmbeddingRuntime(aiDataDir)
|
||||
console.log(`Local embedding runtime installed: ${runtimeDir}`)
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user