@iola_adm/iola-cli 0.2.8 → 0.2.10
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/README.md +1 -0
- package/bin/postinstall.js +1 -1
- package/package.json +1 -1
- package/skills/personal-docs/SKILL.md +1 -0
- package/src/cli.js +203 -21
- package/wiki//320/232/320/276/320/274/320/260/320/275/320/264/321/213.md +1 -0
- package/wiki//320/236/320/261/320/273/320/260/321/207/320/275/321/213/320/265-/320/264/320/270/321/201/320/272/320/270.md +12 -1
- package/wiki//320/241/320/272/320/270/320/273/320/273/321/213-/320/264/320/273/321/217-/320/266/320/270/321/202/320/265/320/273/320/265/320/271.md +9 -0
package/README.md
CHANGED
|
@@ -179,6 +179,7 @@ iola geo services "Йошкар-Ола, улица Петрова, 15"
|
|
|
179
179
|
iola cloud setup yandex-disk
|
|
180
180
|
iola cloud setup mailru-cloud
|
|
181
181
|
iola cloud status
|
|
182
|
+
iola cloud mkdir /IOLA/Фото
|
|
182
183
|
iola cloud find "справка" --path /IOLA
|
|
183
184
|
iola cloud upload report.md /IOLA/reports/report.md
|
|
184
185
|
iola cloud share /IOLA/reports/report.md
|
package/bin/postinstall.js
CHANGED
|
@@ -19,7 +19,7 @@ const steps = [
|
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
title: "Проверка локальной модели IOLA",
|
|
22
|
-
args: [cliPath, "ai", "setup", "iola", "--yes", "--quiet", "--optional"],
|
|
22
|
+
args: [cliPath, "ai", "setup", "iola", "--yes", "--quiet", "--optional", "--preserve-active"],
|
|
23
23
|
},
|
|
24
24
|
];
|
|
25
25
|
|
package/package.json
CHANGED
|
@@ -12,6 +12,7 @@ description: Личные документы пользователя в обл
|
|
|
12
12
|
Основные сценарии:
|
|
13
13
|
|
|
14
14
|
- `cloud-find-document` - найти документ в подключенном облаке.
|
|
15
|
+
- `cloud-create-folder` - создать папку на подключенном облачном диске.
|
|
15
16
|
- `cloud-save-result` - сохранить ответ, отчет, карточку или список в облако.
|
|
16
17
|
- `cloud-share-link` - создать публичную ссылку на файл в Яндекс Диске.
|
|
17
18
|
- `cloud-document-pack` - собрать папку с материалами для обращения.
|
package/src/cli.js
CHANGED
|
@@ -1961,9 +1961,10 @@ async function doctor(args = []) {
|
|
|
1961
1961
|
printKeyValue(report.ai);
|
|
1962
1962
|
console.log("");
|
|
1963
1963
|
console.log("Skills/Toolsets/Daemon");
|
|
1964
|
-
|
|
1964
|
+
printKeyValueFull({ ...report.skills, toolsets: report.toolsets.enabled, daemon: report.daemon.status });
|
|
1965
1965
|
console.log("");
|
|
1966
|
-
|
|
1966
|
+
const isLocalAi = ["iola", "ollama"].includes(activeAiProfile.provider);
|
|
1967
|
+
printDiagnostics(diagnostics, isLocalAi ? recommendOllamaModel(diagnostics) : null);
|
|
1967
1968
|
if (options.all) {
|
|
1968
1969
|
console.log("");
|
|
1969
1970
|
console.log("Фичи");
|
|
@@ -2948,6 +2949,14 @@ async function handleCloud(args) {
|
|
|
2948
2949
|
return;
|
|
2949
2950
|
}
|
|
2950
2951
|
|
|
2952
|
+
if (action === "mkdir" || action === "create-folder") {
|
|
2953
|
+
const provider = await getCloudProvider(options.provider);
|
|
2954
|
+
const remotePath = target || `${cloudRootForProvider(provider)}/Новая папка`;
|
|
2955
|
+
const result = await cloudCreateFolder(provider, remotePath);
|
|
2956
|
+
printKeyValue(result);
|
|
2957
|
+
return;
|
|
2958
|
+
}
|
|
2959
|
+
|
|
2951
2960
|
if (action === "upload") {
|
|
2952
2961
|
if (!target) throw new Error('Пример: iola cloud upload report.md /IOLA/reports/report.md');
|
|
2953
2962
|
const provider = await getCloudProvider(options.provider);
|
|
@@ -3004,6 +3013,7 @@ async function handleCloud(args) {
|
|
|
3004
3013
|
iola cloud status|doctor
|
|
3005
3014
|
iola cloud use yandex-disk
|
|
3006
3015
|
iola cloud ls /IOLA
|
|
3016
|
+
iola cloud mkdir /IOLA/Фото
|
|
3007
3017
|
iola cloud find "справка" --path /IOLA
|
|
3008
3018
|
iola cloud upload local.txt /IOLA/local.txt
|
|
3009
3019
|
iola cloud download /IOLA/local.txt ./local.txt
|
|
@@ -3116,6 +3126,18 @@ async function cloudFind(provider, query, options = {}) {
|
|
|
3116
3126
|
throw new Error(`Провайдер не поддерживается: ${provider}`);
|
|
3117
3127
|
}
|
|
3118
3128
|
|
|
3129
|
+
async function cloudCreateFolder(provider, remotePath) {
|
|
3130
|
+
if (provider === "yandex-disk") {
|
|
3131
|
+
await ensureYandexDiskDir(remotePath, { allowExisting: true });
|
|
3132
|
+
return { provider, path: normalizeYandexDiskPath(remotePath), status: "created-or-exists" };
|
|
3133
|
+
}
|
|
3134
|
+
if (provider === "mailru-cloud") {
|
|
3135
|
+
await ensureMailruCloudDir(remotePath);
|
|
3136
|
+
return { provider, path: remotePath, status: "created-or-exists" };
|
|
3137
|
+
}
|
|
3138
|
+
throw new Error(`Провайдер не поддерживается: ${provider}`);
|
|
3139
|
+
}
|
|
3140
|
+
|
|
3119
3141
|
async function cloudShare(provider, remotePath) {
|
|
3120
3142
|
if (provider === "yandex-disk") return yandexDiskShare(remotePath);
|
|
3121
3143
|
throw new Error("Публичные ссылки через CLI сейчас поддерживаются только для Яндекс Диска.");
|
|
@@ -7817,25 +7839,32 @@ async function setupIolaLocal(args) {
|
|
|
7817
7839
|
}
|
|
7818
7840
|
|
|
7819
7841
|
const config = await loadConfig();
|
|
7842
|
+
const localProfile = {
|
|
7843
|
+
provider: "iola",
|
|
7844
|
+
model,
|
|
7845
|
+
runtime,
|
|
7846
|
+
baseUrl: "http://127.0.0.1:11434",
|
|
7847
|
+
repo,
|
|
7848
|
+
ggufRepo,
|
|
7849
|
+
ggufFile,
|
|
7850
|
+
modelDir,
|
|
7851
|
+
};
|
|
7852
|
+
const shouldActivate = !options["preserve-active"];
|
|
7853
|
+
const previousActiveProfile = getActiveProfileName(config);
|
|
7854
|
+
const nextActiveProfile = shouldActivate ? profileName : previousActiveProfile;
|
|
7855
|
+
const nextActiveConfig = nextActiveProfile === profileName
|
|
7856
|
+
? localProfile
|
|
7857
|
+
: (config.ai.profiles?.[nextActiveProfile] || config.ai.profiles?.[previousActiveProfile] || localProfile);
|
|
7820
7858
|
await saveConfig({
|
|
7821
7859
|
ai: {
|
|
7822
7860
|
...config.ai,
|
|
7823
|
-
activeProfile:
|
|
7824
|
-
provider:
|
|
7825
|
-
model,
|
|
7826
|
-
baseUrl:
|
|
7861
|
+
activeProfile: nextActiveProfile,
|
|
7862
|
+
provider: nextActiveConfig.provider,
|
|
7863
|
+
model: nextActiveConfig.model,
|
|
7864
|
+
baseUrl: nextActiveConfig.baseUrl || config.ai.baseUrl,
|
|
7827
7865
|
profiles: {
|
|
7828
7866
|
...(config.ai.profiles || {}),
|
|
7829
|
-
[profileName]:
|
|
7830
|
-
provider: "iola",
|
|
7831
|
-
model,
|
|
7832
|
-
runtime,
|
|
7833
|
-
baseUrl: "http://127.0.0.1:11434",
|
|
7834
|
-
repo,
|
|
7835
|
-
ggufRepo,
|
|
7836
|
-
ggufFile,
|
|
7837
|
-
modelDir,
|
|
7838
|
-
},
|
|
7867
|
+
[profileName]: localProfile,
|
|
7839
7868
|
},
|
|
7840
7869
|
},
|
|
7841
7870
|
});
|
|
@@ -7873,6 +7902,20 @@ async function aiAsk(args, context = {}) {
|
|
|
7873
7902
|
const historyEnabled = !options.bare && !options["no-history"] && isFeatureEnabled("sqlite-history");
|
|
7874
7903
|
const sessionId = historyEnabled && isFeatureEnabled("sessions") ? ensureSessionForAsk(options, providerConfig, question) : null;
|
|
7875
7904
|
const history = context.history || (sessionId ? getSessionAiHistory(sessionId) : []);
|
|
7905
|
+
const cloudAnswer = await buildCloudDirectAnswer(question);
|
|
7906
|
+
if (cloudAnswer) {
|
|
7907
|
+
if (historyEnabled) {
|
|
7908
|
+
recordAskHistory({ question, answer: cloudAnswer, providerConfig, dataContext, error: "", sessionId });
|
|
7909
|
+
appendSessionExchange(sessionId, question, cloudAnswer, dataContext, "");
|
|
7910
|
+
}
|
|
7911
|
+
emitEvent(options, "answer", { length: cloudAnswer.length, sessionId, direct: true, cloud: true });
|
|
7912
|
+
if (options.output) {
|
|
7913
|
+
await assertPermission("writeFiles");
|
|
7914
|
+
await writeFile(options.output, cloudAnswer, "utf8");
|
|
7915
|
+
}
|
|
7916
|
+
if (!options.quiet) console.log(cloudAnswer);
|
|
7917
|
+
return cloudAnswer;
|
|
7918
|
+
}
|
|
7876
7919
|
const geoAnswer = await buildGeoDirectAnswer(question);
|
|
7877
7920
|
if (geoAnswer) {
|
|
7878
7921
|
if (historyEnabled) {
|
|
@@ -7973,6 +8016,119 @@ async function buildDirectDataAnswer(question, dataContext) {
|
|
|
7973
8016
|
].join("\n");
|
|
7974
8017
|
}
|
|
7975
8018
|
|
|
8019
|
+
async function buildCloudDirectAnswer(question) {
|
|
8020
|
+
if (!isCloudQuestion(question)) return "";
|
|
8021
|
+
const normalized = String(question || "").toLocaleLowerCase("ru-RU");
|
|
8022
|
+
try {
|
|
8023
|
+
const provider = await getCloudProvider();
|
|
8024
|
+
if (/(созда|сдела|добав).{0,30}(папк|директор)/iu.test(normalized) || /(папк|директор).{0,30}(созда|сдела|добав)/iu.test(normalized)) {
|
|
8025
|
+
const folderName = extractCloudFolderName(question) || "Новая папка";
|
|
8026
|
+
const remotePath = normalizeCloudUserPath(folderName, provider);
|
|
8027
|
+
const result = await cloudCreateFolder(provider, remotePath);
|
|
8028
|
+
return `Папка создана или уже была на облачном диске: ${result.path}`;
|
|
8029
|
+
}
|
|
8030
|
+
|
|
8031
|
+
if (/(покажи|список|что.+лежит|файлы|папки)/iu.test(normalized)) {
|
|
8032
|
+
const remotePath = extractCloudPath(question) || cloudRootForProvider(provider);
|
|
8033
|
+
const rows = await cloudList(provider, normalizeCloudUserPath(remotePath, provider));
|
|
8034
|
+
if (rows.length === 0) return `В папке ${normalizeCloudUserPath(remotePath, provider)} нет данных.`;
|
|
8035
|
+
return [
|
|
8036
|
+
`Облачный диск ${provider}, папка ${normalizeCloudUserPath(remotePath, provider)}:`,
|
|
8037
|
+
...rows.slice(0, 20).map((row, index) => `${index + 1}. ${row.type === "dir" ? "папка" : "файл"} ${row.name} — ${row.path}`),
|
|
8038
|
+
].join("\n");
|
|
8039
|
+
}
|
|
8040
|
+
|
|
8041
|
+
if (/(найди|поиск|где лежит)/iu.test(normalized)) {
|
|
8042
|
+
const query = cleanupCloudQuery(question);
|
|
8043
|
+
const rows = await cloudFind(provider, query, { path: cloudRootForProvider(provider), limit: 10 });
|
|
8044
|
+
if (rows.length === 0) return `На облачном диске не нашел: ${query}`;
|
|
8045
|
+
return [
|
|
8046
|
+
`Нашел на облачном диске ${provider}:`,
|
|
8047
|
+
...rows.map((row, index) => `${index + 1}. ${row.name} — ${row.path}`),
|
|
8048
|
+
].join("\n");
|
|
8049
|
+
}
|
|
8050
|
+
|
|
8051
|
+
if (/(ссылк|поделись|опубликуй)/iu.test(normalized)) {
|
|
8052
|
+
const remotePath = extractCloudPath(question);
|
|
8053
|
+
if (!remotePath) return "Укажите путь к файлу на облачном диске, например: /IOLA/reports/report.md";
|
|
8054
|
+
const result = await cloudShare(provider, normalizeCloudUserPath(remotePath, provider));
|
|
8055
|
+
return `Публичная ссылка: ${result.publicUrl}`;
|
|
8056
|
+
}
|
|
8057
|
+
|
|
8058
|
+
if (/(сохрани|запиши).{0,40}(на яндекс диске|в облак|на диск)/iu.test(normalized)) {
|
|
8059
|
+
const text = cleanupCloudSaveText(question);
|
|
8060
|
+
if (!text) return "Что сохранить на облачный диск?";
|
|
8061
|
+
const remotePath = `${cloudRootForProvider(provider)}/notes/iola-${timestampForFile()}.txt`;
|
|
8062
|
+
const tempPath = path.join(CONFIG_DIR, `cloud-save-${Date.now()}.txt`);
|
|
8063
|
+
await mkdir(CONFIG_DIR, { recursive: true });
|
|
8064
|
+
await writeFile(tempPath, text, "utf8");
|
|
8065
|
+
try {
|
|
8066
|
+
await cloudUpload(provider, tempPath, remotePath, { overwrite: true });
|
|
8067
|
+
} finally {
|
|
8068
|
+
await rm(tempPath, { force: true }).catch(() => {});
|
|
8069
|
+
}
|
|
8070
|
+
return `Сохранил текст на облачный диск: ${remotePath}`;
|
|
8071
|
+
}
|
|
8072
|
+
} catch (error) {
|
|
8073
|
+
return `Не смог выполнить облачный запрос: ${error instanceof Error ? error.message : String(error)}`;
|
|
8074
|
+
}
|
|
8075
|
+
return "";
|
|
8076
|
+
}
|
|
8077
|
+
|
|
8078
|
+
function isCloudQuestion(question) {
|
|
8079
|
+
return /(яндекс.?диск|yandex.?disk|облак|облачн|на диск|с диска|в диск|cloud|mail\.?ru|публичн.*ссылк|поделиться.*файл)/iu.test(String(question || ""));
|
|
8080
|
+
}
|
|
8081
|
+
|
|
8082
|
+
function normalizeCloudUserPath(value, provider = "yandex-disk") {
|
|
8083
|
+
const root = cloudRootForProvider(provider);
|
|
8084
|
+
let text = String(value || "").trim().replace(/\\/g, "/");
|
|
8085
|
+
text = text.replace(/^["'«»]+|["'«»]+$/gu, "").trim();
|
|
8086
|
+
if (!text) return root;
|
|
8087
|
+
if (text.startsWith("/")) return text;
|
|
8088
|
+
if (normalizeGeoText(text).startsWith(normalizeGeoText(root).replace(/^\//u, ""))) return `/${text.replace(/^\/+/u, "")}`;
|
|
8089
|
+
return `${root.replace(/\/+$/u, "")}/${text.replace(/^\/+/u, "")}`;
|
|
8090
|
+
}
|
|
8091
|
+
|
|
8092
|
+
function extractCloudFolderName(question) {
|
|
8093
|
+
const text = String(question || "").trim();
|
|
8094
|
+
const match = text.match(/(?:папк[ауи]?|директор(?:ию|ия|ии)?)\s+["'«]?([^"'».,!?]+)["'»]?/iu)
|
|
8095
|
+
|| text.match(/(?:названи(?:ем|е)|имя)\s+["'«]?([^"'».,!?]+)["'»]?/iu);
|
|
8096
|
+
if (!match?.[1]) return "";
|
|
8097
|
+
return cleanupCloudObjectName(match[1]);
|
|
8098
|
+
}
|
|
8099
|
+
|
|
8100
|
+
function extractCloudPath(question) {
|
|
8101
|
+
const text = String(question || "").trim();
|
|
8102
|
+
const pathMatch = text.match(/(?:^|\s)(\/IOLA\/[^\s]+|\/[^\s]+)/iu);
|
|
8103
|
+
if (pathMatch?.[1]) return pathMatch[1];
|
|
8104
|
+
const quoted = text.match(/["«]([^"»]+)["»]/u);
|
|
8105
|
+
if (quoted?.[1]) return quoted[1];
|
|
8106
|
+
const afterFolder = text.match(/(?:папк[аеуы]?|файл[ае]?)\s+([^,.!?]+)/iu);
|
|
8107
|
+
return afterFolder?.[1] ? cleanupCloudObjectName(afterFolder[1]) : "";
|
|
8108
|
+
}
|
|
8109
|
+
|
|
8110
|
+
function cleanupCloudObjectName(value) {
|
|
8111
|
+
return String(value || "")
|
|
8112
|
+
.replace(/\b(?:на|в|у меня|яндекс.?диск(?:е)?|диск(?:е)?|облак(?:е|о)?|создай|сделай|добавь|покажи)\b/giu, " ")
|
|
8113
|
+
.replace(/\s+/g, " ")
|
|
8114
|
+
.trim();
|
|
8115
|
+
}
|
|
8116
|
+
|
|
8117
|
+
function cleanupCloudQuery(question) {
|
|
8118
|
+
return String(question || "")
|
|
8119
|
+
.replace(/\b(?:найди|поиск|где лежит|на|в|яндекс.?диск(?:е)?|облак(?:е|о)?|диск(?:е)?|файл|документ)\b/giu, " ")
|
|
8120
|
+
.replace(/[?.!]+$/u, "")
|
|
8121
|
+
.replace(/\s+/g, " ")
|
|
8122
|
+
.trim();
|
|
8123
|
+
}
|
|
8124
|
+
|
|
8125
|
+
function cleanupCloudSaveText(question) {
|
|
8126
|
+
return String(question || "")
|
|
8127
|
+
.replace(/^.*?(?:сохрани|запиши)\s+/iu, "")
|
|
8128
|
+
.replace(/\s+(?:на яндекс диске|в облак[ео]|на диск).*$/iu, "")
|
|
8129
|
+
.trim();
|
|
8130
|
+
}
|
|
8131
|
+
|
|
7976
8132
|
function detectDirectDataFields(normalizedQuestion) {
|
|
7977
8133
|
const fields = [];
|
|
7978
8134
|
if (/(директ|руководител|заведующ|кто возглавляет)/iu.test(normalizedQuestion)) fields.push("head");
|
|
@@ -8256,6 +8412,11 @@ async function localToolAsk(question, providerConfig, options) {
|
|
|
8256
8412
|
if (!options.quiet) console.log(casualAnswer);
|
|
8257
8413
|
return casualAnswer;
|
|
8258
8414
|
}
|
|
8415
|
+
const cloudAnswer = await buildCloudDirectAnswer(question);
|
|
8416
|
+
if (cloudAnswer) {
|
|
8417
|
+
if (!options.quiet) console.log(cloudAnswer);
|
|
8418
|
+
return cloudAnswer;
|
|
8419
|
+
}
|
|
8259
8420
|
const geoAnswer = await buildGeoDirectAnswer(question);
|
|
8260
8421
|
if (geoAnswer) {
|
|
8261
8422
|
if (!options.quiet) console.log(geoAnswer);
|
|
@@ -10554,7 +10715,7 @@ function parseOptions(args) {
|
|
|
10554
10715
|
|
|
10555
10716
|
for (let index = 0; index < args.length; index += 1) {
|
|
10556
10717
|
const arg = args[index];
|
|
10557
|
-
if (arg === "--json" || arg === "--yes" || arg === "--silent" || arg === "--events" || arg === "--stream-json" || arg === "--stdio" || arg === "--system" || arg === "--headed" || arg === "--headless" || arg === "--no-history" || arg === "--summary" || arg === "--all" || arg === "--full" || arg === "--unread" || arg === "--once" || arg === "--local" || arg === "--cache" || arg === "--tools" || arg === "--files" || arg === "--plan" || arg === "--trace" || arg === "--diff" || arg === "--stage" || arg === "--fts" || arg === "--bare" || arg === "--quiet" || arg === "--optional" || arg === "--project" || arg === "--dry-run" || arg === "--no-color" || arg === "--fail-on-empty" || arg === "--debug" || arg === "--fix" || arg === "--append") {
|
|
10718
|
+
if (arg === "--json" || arg === "--yes" || arg === "--silent" || arg === "--events" || arg === "--stream-json" || arg === "--stdio" || arg === "--system" || arg === "--headed" || arg === "--headless" || arg === "--no-history" || arg === "--summary" || arg === "--all" || arg === "--full" || arg === "--unread" || arg === "--once" || arg === "--local" || arg === "--cache" || arg === "--tools" || arg === "--files" || arg === "--plan" || arg === "--trace" || arg === "--diff" || arg === "--stage" || arg === "--fts" || arg === "--bare" || arg === "--quiet" || arg === "--optional" || arg === "--project" || arg === "--dry-run" || arg === "--no-color" || arg === "--fail-on-empty" || arg === "--debug" || arg === "--fix" || arg === "--append" || arg === "--preserve-active") {
|
|
10558
10719
|
result[arg.slice(2)] = true;
|
|
10559
10720
|
} else if (arg === "--check" || arg === "--upgrade-node") {
|
|
10560
10721
|
result.check = true;
|
|
@@ -10809,8 +10970,10 @@ function selectSkillsForPrompt(config, question = "", options = {}) {
|
|
|
10809
10970
|
if (enabled.has("local-model")) selected.add("local-model");
|
|
10810
10971
|
if (enabled.has("open-data") && shouldUseDataContext(question, options)) selected.add("open-data");
|
|
10811
10972
|
if (enabled.has("geo") && isGeoQuestion(normalized)) selected.add("geo");
|
|
10973
|
+
const cloudQuestion = isCloudQuestion(normalized);
|
|
10974
|
+
if (enabled.has("personal-docs") && cloudQuestion) selected.add("personal-docs");
|
|
10812
10975
|
if (enabled.has("reports") && /(отчет|отчёт|выгруз|csv|xlsx|качество|провер)/iu.test(normalized)) selected.add("reports");
|
|
10813
|
-
if (enabled.has("local-files") && (options.files || /(файл|папк|readme|документ|архив)/iu.test(normalized))) selected.add("local-files");
|
|
10976
|
+
if (enabled.has("local-files") && !cloudQuestion && (options.files || /(файл|папк|readme|документ|архив)/iu.test(normalized))) selected.add("local-files");
|
|
10814
10977
|
if (enabled.has("browser-agent") && /(браузер|сайт|страниц|url|https?:\/\/)/iu.test(normalized)) selected.add("browser-agent");
|
|
10815
10978
|
return selected;
|
|
10816
10979
|
}
|
|
@@ -12249,8 +12412,8 @@ async function executeRpc(method, options = {}) {
|
|
|
12249
12412
|
|
|
12250
12413
|
async function getLatestNpmVersion(packageName) {
|
|
12251
12414
|
try {
|
|
12252
|
-
const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`, {
|
|
12253
|
-
headers: { accept: "application/json" },
|
|
12415
|
+
const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest?t=${Date.now()}`, {
|
|
12416
|
+
headers: { accept: "application/json", "cache-control": "no-cache" },
|
|
12254
12417
|
});
|
|
12255
12418
|
|
|
12256
12419
|
if (!response.ok) {
|
|
@@ -12325,8 +12488,11 @@ function printDiagnostics(diagnostics, recommendation) {
|
|
|
12325
12488
|
vram: diagnostics.gpu.vramGb ? `${diagnostics.gpu.vramGb} GB` : "-",
|
|
12326
12489
|
ollama: diagnostics.ollama.installed ? diagnostics.ollama.version : "не установлен",
|
|
12327
12490
|
});
|
|
12491
|
+
if (!recommendation) {
|
|
12492
|
+
return;
|
|
12493
|
+
}
|
|
12328
12494
|
console.log("");
|
|
12329
|
-
console.log("Рекомендация");
|
|
12495
|
+
console.log("Рекомендация локальной модели");
|
|
12330
12496
|
printKeyValue({
|
|
12331
12497
|
profile: recommendation.profile,
|
|
12332
12498
|
model: recommendation.model,
|
|
@@ -12511,6 +12677,9 @@ function sanitizeConfig(config) {
|
|
|
12511
12677
|
if (Array.isArray(next.skills?.enabled) && next.skills.enabled.includes("open-data") && !next.skills.enabled.includes("education")) {
|
|
12512
12678
|
next.skills.enabled = ["education", ...next.skills.enabled];
|
|
12513
12679
|
}
|
|
12680
|
+
if (Array.isArray(next.skills?.enabled) && next.skills.enabled.includes("open-data") && !next.skills.enabled.includes("geo")) {
|
|
12681
|
+
next.skills.enabled = [...next.skills.enabled, "geo"];
|
|
12682
|
+
}
|
|
12514
12683
|
if (Array.isArray(next.skills?.enabled) && next.skills.enabled.includes("local-files") && !next.skills.enabled.includes("personal-docs")) {
|
|
12515
12684
|
next.skills.enabled = [...next.skills.enabled, "personal-docs"];
|
|
12516
12685
|
}
|
|
@@ -12897,6 +13066,19 @@ function printKeyValue(value) {
|
|
|
12897
13066
|
]);
|
|
12898
13067
|
}
|
|
12899
13068
|
|
|
13069
|
+
function printKeyValueFull(value) {
|
|
13070
|
+
const rows = Object.entries(value).map(([key, raw]) => ({
|
|
13071
|
+
key,
|
|
13072
|
+
value: raw == null || raw === "" ? "-" : String(raw),
|
|
13073
|
+
}));
|
|
13074
|
+
const keyWidth = Math.max(4, ...rows.map((row) => visibleLength(row.key)));
|
|
13075
|
+
console.log(`${padCell("Поле", keyWidth)} Значение`);
|
|
13076
|
+
console.log(`${"-".repeat(keyWidth)} ${"-".repeat(8)}`);
|
|
13077
|
+
for (const row of rows) {
|
|
13078
|
+
console.log(`${padCell(row.key, keyWidth)} ${row.value}`);
|
|
13079
|
+
}
|
|
13080
|
+
}
|
|
13081
|
+
|
|
12900
13082
|
function printTable(rows, columns) {
|
|
12901
13083
|
if (rows.length === 0) {
|
|
12902
13084
|
console.log("Нет данных.");
|
|
@@ -50,6 +50,7 @@ iola cloud status
|
|
|
50
50
|
iola cloud doctor
|
|
51
51
|
iola cloud use yandex-disk
|
|
52
52
|
iola cloud ls /IOLA
|
|
53
|
+
iola cloud mkdir /IOLA/Фото
|
|
53
54
|
iola cloud find "справка" --path /IOLA
|
|
54
55
|
iola cloud upload report.md /IOLA/reports/report.md
|
|
55
56
|
iola cloud download /IOLA/reports/report.md ./report.md
|
|
@@ -18,6 +18,7 @@ iola cloud status
|
|
|
18
18
|
iola cloud doctor
|
|
19
19
|
iola cloud use yandex-disk
|
|
20
20
|
iola cloud ls /IOLA
|
|
21
|
+
iola cloud mkdir /IOLA/Фото
|
|
21
22
|
iola cloud find "справка" --path /IOLA
|
|
22
23
|
iola cloud upload report.md /IOLA/reports/report.md
|
|
23
24
|
iola cloud download /IOLA/reports/report.md ./report.md
|
|
@@ -45,7 +46,7 @@ iola cloud backup
|
|
|
45
46
|
5. Нажмите `Перейти к созданию`.
|
|
46
47
|
6. На шаге `Создание приложения` заполните:
|
|
47
48
|
- `Название вашего сервиса`: например `iola-cli`;
|
|
48
|
-
- `Иконка сервиса`: загрузите
|
|
49
|
+
- `Иконка сервиса`: загрузите PNG-иконку до 1 МБ. Готовая иконка iola-cli доступна по ссылке: `https://raw.githubusercontent.com/adm-iola/iola-cli/main/docs/assets/iola-oauth-icon.png`;
|
|
49
50
|
- `Почта для связи`: оставьте свою почту или укажите актуальную.
|
|
50
51
|
7. Нажмите `Продолжить`.
|
|
51
52
|
8. На шаге `Платформы приложений` выберите `Веб-сервисы`.
|
|
@@ -101,6 +102,16 @@ iola cloud doctor
|
|
|
101
102
|
|
|
102
103
|
Обычно такой токен выдается на длительный срок. Если доступ перестал работать, получите новый токен через ту же ссылку авторизации и повторите `iola cloud setup yandex-disk`.
|
|
103
104
|
|
|
105
|
+
После подключения можно работать с облаком обычными фразами в CLI:
|
|
106
|
+
|
|
107
|
+
```text
|
|
108
|
+
создай у меня на яндекс диске папку фото
|
|
109
|
+
покажи что лежит на яндекс диске
|
|
110
|
+
найди на яндекс диске справку
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Такие запросы обрабатывает skill `personal-docs`. Они не требуют включать локальный режим `iola files mode`, потому что это не работа с файлами на ПК.
|
|
114
|
+
|
|
104
115
|
## Облако Mail.ru
|
|
105
116
|
|
|
106
117
|
Облако Mail.ru подключается через WebDAV.
|
|
@@ -114,6 +114,15 @@ iola geo services "Йошкар-Ола, улица Петрова, 15"
|
|
|
114
114
|
|
|
115
115
|
Сохранить ответ CLI, отчет, карточку учреждения или список ближайших объектов в `/IOLA`.
|
|
116
116
|
|
|
117
|
+
### cloud-create-folder
|
|
118
|
+
|
|
119
|
+
Создать папку на подключенном облачном диске.
|
|
120
|
+
|
|
121
|
+
Пример:
|
|
122
|
+
|
|
123
|
+
- `создай у меня на яндекс диске папку фото`;
|
|
124
|
+
- `создай папку документы в облаке`.
|
|
125
|
+
|
|
117
126
|
### cloud-share-link
|
|
118
127
|
|
|
119
128
|
Создать публичную ссылку на файл. В первом контуре поддерживается для Яндекс Диска.
|