import { execSync } from "node:child_process"; import { MODELS, getChatModels, getAutocompleteModels, getModelById } from "../registry/models.js"; import { loadConfig, saveConfig, getActiveChatModel, getActiveAutocompleteModel } from "../runtime-config.js"; import { createLauncherScripts } from "../steps/scripts.js"; import { writeTuiConfig } from "../steps/aider-config.js"; import { log, err } from "../log.js"; import { runPassthrough } from "../util.js"; const BOLD = "\x1b[1m"; const GREEN = "\x1b[0;32m"; const DIM = "\x1b[2m"; const RESET = "\x1b[0m"; function isPulled(ollamaTag: string): boolean { try { const output = execSync("ollama list", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }); return output.includes(ollamaTag); } catch { return false; } } export function listModels(): void { const activeChatId = getActiveChatModel().id; const activeAutoId = getActiveAutocompleteModel().id; console.log(`\n${BOLD}Chat models:${RESET}`); for (const m of getChatModels()) { const active = m.id === activeChatId ? ` ${GREEN}<- active${RESET}` : ""; const pulled = isPulled(m.ollamaTag) ? "" : ` ${DIM}(not pulled)${RESET}`; console.log( ` ${BOLD}${m.id}${RESET} ${m.name} ${DIM}${m.ollamaTag}${RESET}${active}${pulled}`, ); } console.log(`\n${BOLD}Autocomplete models:${RESET}`); for (const m of getAutocompleteModels()) { const active = m.id === activeAutoId ? ` ${GREEN}<- active${RESET}` : ""; const pulled = isPulled(m.ollamaTag) ? "" : ` ${DIM}(not pulled)${RESET}`; console.log( ` ${BOLD}${m.id}${RESET} ${m.name} ${DIM}${m.ollamaTag}${RESET}${active}${pulled}`, ); } console.log(""); } export async function setChatModel(id: string): Promise { const model = getModelById(id); if (!model) { err(`Unknown model: ${id}\nAvailable: ${MODELS.map((m) => m.id).join(", ")}`); } if (model.role !== "chat") { err(`${id} is an ${model.role} model, not a chat model.`); } const config = loadConfig(); config.chatModel = id; saveConfig(config); log(`Chat model set to ${model.name}`); // Pull if needed if (!isPulled(model.ollamaTag)) { log(`Pulling ${model.name} (${model.ollamaTag})...`); runPassthrough(`ollama pull ${model.ollamaTag}`); } // Regenerate configs await createLauncherScripts(); await writeTuiConfig(); log("Configs regenerated."); } export async function setAutocompleteModel(id: string): Promise { const model = getModelById(id); if (!model) { err(`Unknown model: ${id}\nAvailable: ${MODELS.map((m) => m.id).join(", ")}`); } if (model.role !== "autocomplete") { err(`${id} is a ${model.role} model, not an autocomplete model.`); } const config = loadConfig(); config.autocompleteModel = id; saveConfig(config); log(`Autocomplete model set to ${model.name}`); // Pull if needed if (!isPulled(model.ollamaTag)) { log(`Pulling ${model.name} (${model.ollamaTag})...`); runPassthrough(`ollama pull ${model.ollamaTag}`); } await createLauncherScripts(); await writeTuiConfig(); log("Configs regenerated."); }