import fs from "node:fs/promises"; import os from "node:os"; import { autocomplete, intro, isCancel, outro, text } from "@clack/prompts"; import chalk from "chalk"; const home = os.homedir(); const configPath = `${home}/.lmc_config.json`; export interface AppConfig { baseURL: string; model: string; } export async function initConfig(old: AppConfig | null): Promise { console.log(); intro(chalk.blue("Welcome to LMC. Let's make a new config!")); const baseURL = await text({ message: "What's your base URL:", defaultValue: old?.baseURL ?? "http://127.0.0.1:8080/v1", placeholder: old?.baseURL ?? "http://127.0.0.1:8080/v1", }); if (isCancel(baseURL)) process.exit(1); const models = await getModels(baseURL); const initialValue = models.includes(old?.model ?? "") ? old?.model : models[0]; const model = await autocomplete({ message: "Choose a default model:", initialValue, placeholder: initialValue ?? "Start typing...", options: models.map((model) => ({ value: model })), validate: (value) => models.includes(typeof value === "string" ? value : "") ? undefined : `Unable to find model "${value}"`, }); if (!model || isCancel(model)) process.exit(1); const config = { baseURL, model } satisfies AppConfig; await fs.writeFile(configPath, JSON.stringify(config, null, " ")); outro(chalk.green("Configuration saved!")); return config; } type Models = { data: { created: number; id: string; object: "model"; owned_by: string; }[]; }; async function getModels(url: string) { const response = await fetch(`${url}/models`); const models = (await response.json()) as Models; return models.data.map((model) => model.id); } export async function loadConfig( configFlag: boolean | undefined, ): Promise { let config: AppConfig; try { const text = await fs.readFile(configPath, "utf8"); config = JSON.parse(text); } catch { if (configFlag) return null; console.error(`Config not found at ${configPath}`); return null; } return config; }