@iola_adm/iola-cli 0.1.67 → 0.1.68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/cli.js +48 -7
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -4077,18 +4077,14 @@ async function listAiModels(provider) {
|
|
|
4077
4077
|
}
|
|
4078
4078
|
|
|
4079
4079
|
const payload = await response.json();
|
|
4080
|
-
|
|
4080
|
+
const models = (payload.models || []).map((model) => ({
|
|
4081
4081
|
id: model.name,
|
|
4082
4082
|
provider: "ollama",
|
|
4083
4083
|
note: model.modified_at ? `updated ${model.modified_at}` : "local",
|
|
4084
4084
|
}));
|
|
4085
|
+
return models.length > 0 ? models : getRecommendedOllamaModels("not installed");
|
|
4085
4086
|
} catch {
|
|
4086
|
-
return
|
|
4087
|
-
{ id: "llama3.2:1b", provider: "ollama", note: "recommended low RAM" },
|
|
4088
|
-
{ id: "llama3.2:3b", provider: "ollama", note: "recommended standard" },
|
|
4089
|
-
{ id: "qwen3:4b", provider: "ollama", note: "recommended balanced" },
|
|
4090
|
-
{ id: "qwen3:8b", provider: "ollama", note: "recommended good GPU" },
|
|
4091
|
-
];
|
|
4087
|
+
return getRecommendedOllamaModels("recommended");
|
|
4092
4088
|
}
|
|
4093
4089
|
}
|
|
4094
4090
|
|
|
@@ -4139,6 +4135,15 @@ async function listAiModels(provider) {
|
|
|
4139
4135
|
];
|
|
4140
4136
|
}
|
|
4141
4137
|
|
|
4138
|
+
function getRecommendedOllamaModels(notePrefix = "recommended") {
|
|
4139
|
+
return [
|
|
4140
|
+
{ id: "llama3.2:1b", provider: "ollama", note: `${notePrefix} low RAM` },
|
|
4141
|
+
{ id: "llama3.2:3b", provider: "ollama", note: `${notePrefix} standard` },
|
|
4142
|
+
{ id: "qwen3:4b", provider: "ollama", note: `${notePrefix} balanced` },
|
|
4143
|
+
{ id: "qwen3:8b", provider: "ollama", note: `${notePrefix} good GPU` },
|
|
4144
|
+
];
|
|
4145
|
+
}
|
|
4146
|
+
|
|
4142
4147
|
async function printAiProfiles() {
|
|
4143
4148
|
const config = await loadConfig();
|
|
4144
4149
|
const active = getActiveProfileName(config);
|
|
@@ -4455,6 +4460,10 @@ async function chooseAiModel(provider) {
|
|
|
4455
4460
|
async function switchModelTarget(target, model) {
|
|
4456
4461
|
const config = await loadConfig();
|
|
4457
4462
|
const provider = target === "local" ? "ollama" : target;
|
|
4463
|
+
if (provider === "ollama") {
|
|
4464
|
+
const ready = await ensureOllamaModelAvailable(model, config);
|
|
4465
|
+
if (!ready) return;
|
|
4466
|
+
}
|
|
4458
4467
|
const profileName = provider === "ollama" ? "local" : provider;
|
|
4459
4468
|
const currentProfile = config.ai.profiles?.[profileName] || buildProfileFromOptions(provider, { model });
|
|
4460
4469
|
const profile = {
|
|
@@ -4480,6 +4489,38 @@ async function switchModelTarget(target, model) {
|
|
|
4480
4489
|
console.log(`Активная модель: ${profileName} (${provider}, ${model})`);
|
|
4481
4490
|
}
|
|
4482
4491
|
|
|
4492
|
+
async function ensureOllamaModelAvailable(model, config = null) {
|
|
4493
|
+
if (await isOllamaModelInstalled(model, config)) return true;
|
|
4494
|
+
|
|
4495
|
+
const command = await resolveOllamaCommand();
|
|
4496
|
+
if (!command) {
|
|
4497
|
+
console.log("Ollama CLI не найден в PATH, хотя локальный API может отвечать.");
|
|
4498
|
+
console.log("Откройте новый PowerShell или запустите мастер: iola ai setup ollama");
|
|
4499
|
+
return false;
|
|
4500
|
+
}
|
|
4501
|
+
|
|
4502
|
+
const shouldInstall = await confirm(`Локальная модель ${model} не скачана. Скачать через "ollama pull ${model}"? [Y/n] `);
|
|
4503
|
+
if (!shouldInstall) {
|
|
4504
|
+
console.log("Переключение на локальную модель отменено.");
|
|
4505
|
+
return false;
|
|
4506
|
+
}
|
|
4507
|
+
|
|
4508
|
+
await runCommand(command, ["pull", model], { inherit: true });
|
|
4509
|
+
return true;
|
|
4510
|
+
}
|
|
4511
|
+
|
|
4512
|
+
async function isOllamaModelInstalled(model, loadedConfig = null) {
|
|
4513
|
+
try {
|
|
4514
|
+
const config = loadedConfig || await loadConfig();
|
|
4515
|
+
const response = await fetch(`${config.ai.profiles?.local?.baseUrl || "http://127.0.0.1:11434"}/api/tags`);
|
|
4516
|
+
if (!response.ok) return false;
|
|
4517
|
+
const payload = await response.json();
|
|
4518
|
+
return (payload.models || []).some((entry) => entry.name === model);
|
|
4519
|
+
} catch {
|
|
4520
|
+
return false;
|
|
4521
|
+
}
|
|
4522
|
+
}
|
|
4523
|
+
|
|
4483
4524
|
async function askText(question) {
|
|
4484
4525
|
if (!process.stdin.isTTY) return "";
|
|
4485
4526
|
const rl = readline.createInterface({ input, output });
|