@iola_adm/iola-cli 0.2.4 → 0.2.5
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 +12 -0
- package/package.json +1 -1
- package/src/cli.js +188 -2
- package/wiki/Home.md +3 -0
- package/wiki/Yandex-Geocoder-API-key.md +72 -0
- package/wiki//320/232/320/276/320/274/320/260/320/275/320/264/321/213.md +9 -0
- package/wiki//320/234/320/260/321/201/321/202/320/265/321/200-/320/275/320/260/321/201/321/202/321/200/320/276/320/271/320/272/320/270.md +8 -0
- 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 +97 -0
package/README.md
CHANGED
|
@@ -156,6 +156,16 @@ iola ai setup gigachat --model GigaChat-2
|
|
|
156
156
|
|
|
157
157
|
У GigaChat для физических лиц есть Freemium-лимит на токены; для больших объемов используются платные пакеты. У YandexGPT тарификация идет через Yandex Cloud по токенам и квотам аккаунта, актуальные бесплатные гранты или лимиты нужно проверять в консоли Yandex Cloud.
|
|
158
158
|
|
|
159
|
+
Геокодер для пользовательских geo-skills:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
iola geo key set yandex
|
|
163
|
+
iola geo key doctor
|
|
164
|
+
iola geo geocode "Йошкар-Ола, улица Петрова, 15"
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Инструкция по получению ключа: [Yandex Geocoder API key](https://github.com/adm-iola/iola-cli/wiki/Yandex-Geocoder-API-key).
|
|
168
|
+
|
|
159
169
|
Зарубежные API-ключи:
|
|
160
170
|
|
|
161
171
|
- OpenAI Platform: регистрация `https://platform.openai.com/`, ключи `https://platform.openai.com/api-keys`;
|
|
@@ -182,6 +192,8 @@ iola version --check
|
|
|
182
192
|
- [Первый запуск](https://github.com/adm-iola/iola-cli/wiki/Первый-запуск)
|
|
183
193
|
- [Мастер настройки](https://github.com/adm-iola/iola-cli/wiki/Мастер-настройки)
|
|
184
194
|
- [AI-профили](https://github.com/adm-iola/iola-cli/wiki/AI-профили)
|
|
195
|
+
- [Yandex Geocoder API key](https://github.com/adm-iola/iola-cli/wiki/Yandex-Geocoder-API-key)
|
|
196
|
+
- [Скиллы для жителей](https://github.com/adm-iola/iola-cli/wiki/Скиллы-для-жителей)
|
|
185
197
|
- [Локальный инструментальный агент](https://github.com/adm-iola/iola-cli/wiki/Локальный-инструментальный-агент)
|
|
186
198
|
- [Skills и toolsets](https://github.com/adm-iola/iola-cli/wiki/Skills-и-toolsets)
|
|
187
199
|
- [Локальные файлы](https://github.com/adm-iola/iola-cli/wiki/Локальные-файлы)
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -440,6 +440,7 @@ const COMMANDS = new Map([
|
|
|
440
440
|
["health", checkHealth],
|
|
441
441
|
["layers", listLayers],
|
|
442
442
|
["data", handleData],
|
|
443
|
+
["geo", handleGeo],
|
|
443
444
|
["schools", listSchools],
|
|
444
445
|
["kindergartens", listKindergartens],
|
|
445
446
|
["search", searchAll],
|
|
@@ -653,6 +654,9 @@ Usage:
|
|
|
653
654
|
iola kindergartens [--limit 10] [--search TEXT] [--where FIELD=VALUE] [--columns a,b,c] [--format table|json|csv]
|
|
654
655
|
iola kindergartens get --inn INN [--json]
|
|
655
656
|
iola search TEXT [--limit 5] [--format table|json|csv]
|
|
657
|
+
iola geo key set yandex
|
|
658
|
+
iola geo key doctor
|
|
659
|
+
iola geo geocode "Йошкар-Ола, ул. Петрова, 15"
|
|
656
660
|
iola mcp-info [--json]
|
|
657
661
|
iola setup codex
|
|
658
662
|
iola onboard
|
|
@@ -1881,6 +1885,7 @@ async function doctor(args = []) {
|
|
|
1881
1885
|
modelAvailable: await checkConfiguredModel({ ai: activeAiProfile }),
|
|
1882
1886
|
openaiKey: process.env.OPENAI_API_KEY ? "env" : secrets.openai?.apiKey ? "local" : "missing",
|
|
1883
1887
|
openrouterKey: process.env.OPENROUTER_API_KEY ? "env" : secrets.openrouter?.apiKey ? "local" : "missing",
|
|
1888
|
+
yandexGeocoderKey: (process.env.YANDEX_GEOCODER_API_KEY || process.env.YANDEX_MAPS_API_KEY) ? "env" : secrets.yandexGeocoder?.apiKey ? "local" : "missing",
|
|
1884
1889
|
ollama: diagnostics.ollama.installed ? diagnostics.ollama.version : "not-installed",
|
|
1885
1890
|
},
|
|
1886
1891
|
skills: {
|
|
@@ -2565,6 +2570,8 @@ async function handleWiki(args) {
|
|
|
2565
2570
|
["Первый запуск", `${base}/Первый-запуск`],
|
|
2566
2571
|
["Мастер настройки", `${base}/Мастер-настройки`],
|
|
2567
2572
|
["AI-профили", `${base}/AI-профили`],
|
|
2573
|
+
["Yandex Geocoder API key", `${base}/Yandex-Geocoder-API-key`],
|
|
2574
|
+
["Скиллы для жителей", `${base}/Скиллы-для-жителей`],
|
|
2568
2575
|
["Локальный инструментальный агент", `${base}/Локальный-инструментальный-агент`],
|
|
2569
2576
|
["Skills и toolsets", `${base}/Skills-и-toolsets`],
|
|
2570
2577
|
["Локальные файлы", `${base}/Локальные-файлы`],
|
|
@@ -5323,6 +5330,176 @@ async function deleteAiKey(provider) {
|
|
|
5323
5330
|
console.log(`Локальный ключ ${provider} удален.`);
|
|
5324
5331
|
}
|
|
5325
5332
|
|
|
5333
|
+
async function handleGeo(args) {
|
|
5334
|
+
const [command, subcommand, ...rest] = args;
|
|
5335
|
+
|
|
5336
|
+
if (command === "key") {
|
|
5337
|
+
await handleGeoKey([subcommand, ...rest]);
|
|
5338
|
+
return;
|
|
5339
|
+
}
|
|
5340
|
+
|
|
5341
|
+
if (command === "geocode") {
|
|
5342
|
+
await geoGeocode([subcommand, ...rest].filter(Boolean));
|
|
5343
|
+
return;
|
|
5344
|
+
}
|
|
5345
|
+
|
|
5346
|
+
if (command === "doctor" || command === "status") {
|
|
5347
|
+
await printGeoKeyStatus({ check: command === "doctor" });
|
|
5348
|
+
return;
|
|
5349
|
+
}
|
|
5350
|
+
|
|
5351
|
+
throw new Error(`Команды geo:
|
|
5352
|
+
iola geo key set yandex
|
|
5353
|
+
iola geo key status
|
|
5354
|
+
iola geo key doctor
|
|
5355
|
+
iola geo key delete yandex
|
|
5356
|
+
iola geo geocode "Йошкар-Ола, ул. Петрова, 15"`);
|
|
5357
|
+
}
|
|
5358
|
+
|
|
5359
|
+
async function handleGeoKey(args) {
|
|
5360
|
+
const [action, provider = "yandex"] = args;
|
|
5361
|
+
if (provider !== "yandex") {
|
|
5362
|
+
throw new Error("Сейчас поддерживается только провайдер: yandex");
|
|
5363
|
+
}
|
|
5364
|
+
|
|
5365
|
+
if (action === "set") {
|
|
5366
|
+
await setYandexGeocoderKey();
|
|
5367
|
+
return;
|
|
5368
|
+
}
|
|
5369
|
+
|
|
5370
|
+
if (action === "status") {
|
|
5371
|
+
await printGeoKeyStatus();
|
|
5372
|
+
return;
|
|
5373
|
+
}
|
|
5374
|
+
|
|
5375
|
+
if (action === "doctor" || action === "check") {
|
|
5376
|
+
await printGeoKeyStatus({ check: true });
|
|
5377
|
+
return;
|
|
5378
|
+
}
|
|
5379
|
+
|
|
5380
|
+
if (action === "delete") {
|
|
5381
|
+
const secrets = await loadSecrets();
|
|
5382
|
+
delete secrets.yandexGeocoder;
|
|
5383
|
+
await saveSecrets(secrets);
|
|
5384
|
+
console.log("Локальный ключ yandex geocoder удален.");
|
|
5385
|
+
return;
|
|
5386
|
+
}
|
|
5387
|
+
|
|
5388
|
+
throw new Error("Команды geo key: set yandex, status, doctor, delete yandex.");
|
|
5389
|
+
}
|
|
5390
|
+
|
|
5391
|
+
async function setYandexGeocoderKey() {
|
|
5392
|
+
if (!process.stdin.isTTY) {
|
|
5393
|
+
throw new Error("Для сохранения ключа запустите команду в интерактивном терминале.");
|
|
5394
|
+
}
|
|
5395
|
+
|
|
5396
|
+
const key = (await askText("Введите YANDEX_GEOCODER_API_KEY: ")).trim();
|
|
5397
|
+
if (!key) throw new Error("Ключ пустой, сохранение отменено.");
|
|
5398
|
+
|
|
5399
|
+
const secrets = await loadSecrets();
|
|
5400
|
+
secrets.yandexGeocoder = { apiKey: key };
|
|
5401
|
+
await saveSecrets(secrets);
|
|
5402
|
+
console.log(`Ключ yandex geocoder сохранен локально: ${SECRETS_FILE}`);
|
|
5403
|
+
|
|
5404
|
+
const shouldCheck = await confirm("Проверить ключ запросом к Yandex Geocoder? [Y/n] ");
|
|
5405
|
+
if (shouldCheck) await checkYandexGeocoderKey({ print: true });
|
|
5406
|
+
}
|
|
5407
|
+
|
|
5408
|
+
async function printGeoKeyStatus(options = {}) {
|
|
5409
|
+
const key = await getYandexGeocoderKey();
|
|
5410
|
+
const rows = [{
|
|
5411
|
+
provider: "yandex-geocoder",
|
|
5412
|
+
env: (process.env.YANDEX_GEOCODER_API_KEY || process.env.YANDEX_MAPS_API_KEY) ? "yes" : "no",
|
|
5413
|
+
local: (await loadSecrets()).yandexGeocoder?.apiKey ? "yes" : "no",
|
|
5414
|
+
status: key ? "configured" : "missing",
|
|
5415
|
+
}];
|
|
5416
|
+
printTable(rows, [
|
|
5417
|
+
["provider", "Провайдер"],
|
|
5418
|
+
["env", "Env"],
|
|
5419
|
+
["local", "Локально"],
|
|
5420
|
+
["status", "Статус"],
|
|
5421
|
+
]);
|
|
5422
|
+
if (options.check) await checkYandexGeocoderKey({ print: true });
|
|
5423
|
+
}
|
|
5424
|
+
|
|
5425
|
+
async function geoGeocode(args) {
|
|
5426
|
+
const query = args.join(" ").trim();
|
|
5427
|
+
if (!query) throw new Error('Адрес обязателен. Пример: iola geo geocode "Йошкар-Ола, ул. Петрова, 15"');
|
|
5428
|
+
const result = await callYandexGeocoder(query);
|
|
5429
|
+
if (!result) {
|
|
5430
|
+
console.log("Yandex Geocoder не вернул результат.");
|
|
5431
|
+
return;
|
|
5432
|
+
}
|
|
5433
|
+
printKeyValue(result);
|
|
5434
|
+
}
|
|
5435
|
+
|
|
5436
|
+
async function checkYandexGeocoderKey(options = {}) {
|
|
5437
|
+
try {
|
|
5438
|
+
const result = await callYandexGeocoder("Йошкар-Ола");
|
|
5439
|
+
if (!result?.coordinates) throw new Error("Yandex Geocoder вернул пустой результат.");
|
|
5440
|
+
if (options.print) {
|
|
5441
|
+
console.log(`Yandex Geocoder: ok (${result.name || result.address || result.coordinates})`);
|
|
5442
|
+
}
|
|
5443
|
+
return true;
|
|
5444
|
+
} catch (error) {
|
|
5445
|
+
if (options.print) {
|
|
5446
|
+
console.log(`Yandex Geocoder: error - ${error instanceof Error ? error.message : String(error)}`);
|
|
5447
|
+
}
|
|
5448
|
+
return false;
|
|
5449
|
+
}
|
|
5450
|
+
}
|
|
5451
|
+
|
|
5452
|
+
async function callYandexGeocoder(query) {
|
|
5453
|
+
const apiKey = await getYandexGeocoderKey();
|
|
5454
|
+
if (!apiKey) {
|
|
5455
|
+
throw new Error("Yandex Geocoder API key не найден. Выполните iola geo key set yandex или задайте YANDEX_GEOCODER_API_KEY.");
|
|
5456
|
+
}
|
|
5457
|
+
|
|
5458
|
+
const url = new URL("https://geocode-maps.yandex.ru/v1/");
|
|
5459
|
+
url.searchParams.set("apikey", apiKey);
|
|
5460
|
+
url.searchParams.set("geocode", query);
|
|
5461
|
+
url.searchParams.set("format", "json");
|
|
5462
|
+
url.searchParams.set("lang", "ru_RU");
|
|
5463
|
+
url.searchParams.set("results", "1");
|
|
5464
|
+
|
|
5465
|
+
let response;
|
|
5466
|
+
try {
|
|
5467
|
+
response = await fetch(url, { signal: AbortSignal.timeout(15000) });
|
|
5468
|
+
} catch (error) {
|
|
5469
|
+
throw new Error(formatProviderFetchError("Yandex Geocoder", error));
|
|
5470
|
+
}
|
|
5471
|
+
|
|
5472
|
+
if (!response.ok) {
|
|
5473
|
+
const text = await response.text();
|
|
5474
|
+
if (response.status === 403 && /Invalid api key/i.test(text)) {
|
|
5475
|
+
throw new Error(`Yandex Geocoder request failed: ${response.status} ${response.statusText}\nInvalid api key. Если ключ только что создан, подождите до 15 минут: Yandex указывает, что активация ключа может занять до 15 минут.`);
|
|
5476
|
+
}
|
|
5477
|
+
throw new Error(`Yandex Geocoder request failed: ${response.status} ${response.statusText}\n${sanitizeSecretFromText(text, apiKey)}`);
|
|
5478
|
+
}
|
|
5479
|
+
|
|
5480
|
+
const payload = await response.json();
|
|
5481
|
+
const member = payload?.response?.GeoObjectCollection?.featureMember?.[0];
|
|
5482
|
+
const object = member?.GeoObject;
|
|
5483
|
+
if (!object) return null;
|
|
5484
|
+
const point = object.Point?.pos || "";
|
|
5485
|
+
const [lon, lat] = point.split(/\s+/);
|
|
5486
|
+
return {
|
|
5487
|
+
name: object.name || "",
|
|
5488
|
+
address: object.metaDataProperty?.GeocoderMetaData?.text || object.description || "",
|
|
5489
|
+
precision: object.metaDataProperty?.GeocoderMetaData?.precision || "",
|
|
5490
|
+
coordinates: lat && lon ? `${lat}, ${lon}` : point,
|
|
5491
|
+
map: lat && lon ? `https://yandex.ru/maps/?pt=${lon},${lat}&z=16&l=map` : "",
|
|
5492
|
+
};
|
|
5493
|
+
}
|
|
5494
|
+
|
|
5495
|
+
async function getYandexGeocoderKey() {
|
|
5496
|
+
if (process.env.YANDEX_GEOCODER_API_KEY || process.env.YANDEX_MAPS_API_KEY) {
|
|
5497
|
+
return process.env.YANDEX_GEOCODER_API_KEY || process.env.YANDEX_MAPS_API_KEY;
|
|
5498
|
+
}
|
|
5499
|
+
const secrets = await loadSecrets();
|
|
5500
|
+
return secrets.yandexGeocoder?.apiKey || "";
|
|
5501
|
+
}
|
|
5502
|
+
|
|
5326
5503
|
function openDatabase() {
|
|
5327
5504
|
const db = new DatabaseSync(DB_FILE);
|
|
5328
5505
|
db.exec("PRAGMA busy_timeout = 5000;");
|
|
@@ -9251,6 +9428,11 @@ async function onboard(args = []) {
|
|
|
9251
9428
|
await chooseAndSaveApiModel("gigachat");
|
|
9252
9429
|
}
|
|
9253
9430
|
}
|
|
9431
|
+
if (components.includes("yandex-geocoder")) {
|
|
9432
|
+
if (process.stdin.isTTY) {
|
|
9433
|
+
await setYandexGeocoderKey();
|
|
9434
|
+
}
|
|
9435
|
+
}
|
|
9254
9436
|
if (components.includes("codex")) {
|
|
9255
9437
|
await installCodexIfMissing();
|
|
9256
9438
|
await aiSetup(["codex"]);
|
|
@@ -9299,6 +9481,7 @@ async function chooseOnboardComponents(status = null) {
|
|
|
9299
9481
|
11: "index",
|
|
9300
9482
|
12: "browser",
|
|
9301
9483
|
13: "ollama",
|
|
9484
|
+
14: "yandex-geocoder",
|
|
9302
9485
|
};
|
|
9303
9486
|
return [...selected].map((item) => map[item] || item).filter(Boolean);
|
|
9304
9487
|
} finally {
|
|
@@ -9311,13 +9494,14 @@ function isOnboardExitAnswer(answer) {
|
|
|
9311
9494
|
}
|
|
9312
9495
|
|
|
9313
9496
|
async function getOnboardComponentStatus() {
|
|
9314
|
-
const [config, readiness, browser, archive, codexVersion, ollamaVersion] = await Promise.all([
|
|
9497
|
+
const [config, readiness, browser, archive, codexVersion, ollamaVersion, yandexGeocoderKey] = await Promise.all([
|
|
9315
9498
|
loadConfig(),
|
|
9316
9499
|
getAiReadiness(),
|
|
9317
9500
|
getBrowserStatus(),
|
|
9318
9501
|
findCommand(["7z", "7zz", "7za"], ["--help"]).catch(() => null),
|
|
9319
9502
|
getCommandVersion("codex", ["--version"]),
|
|
9320
9503
|
getOllamaVersion(),
|
|
9504
|
+
getYandexGeocoderKey(),
|
|
9321
9505
|
]);
|
|
9322
9506
|
const workspaceReady = existsSync(PROJECT_CONTEXT_FILE) || existsSync(PROJECT_CONTEXT_DIR_FILE) || existsSync(PROJECT_IOLA_DIR);
|
|
9323
9507
|
const policyReady = (config.toolsets?.enabled || []).includes("analyst");
|
|
@@ -9335,6 +9519,7 @@ async function getOnboardComponentStatus() {
|
|
|
9335
9519
|
archive: Boolean(archive),
|
|
9336
9520
|
index: false,
|
|
9337
9521
|
browser: browser.installed === "yes",
|
|
9522
|
+
"yandex-geocoder": Boolean(yandexGeocoderKey),
|
|
9338
9523
|
};
|
|
9339
9524
|
}
|
|
9340
9525
|
|
|
@@ -9353,6 +9538,7 @@ function onboardComponentRows(status) {
|
|
|
9353
9538
|
["11", "index", "Индекс локальных документов", "настраивается под выбранную папку"],
|
|
9354
9539
|
["12", "browser", "Browser runtime", "Playwright/Chromium установлен"],
|
|
9355
9540
|
["13", "ollama", "Ollama", "опциональный локальный runtime"],
|
|
9541
|
+
["14", "yandex-geocoder", "Yandex Geocoder API", "ключ геокодера сохранен или есть в env"],
|
|
9356
9542
|
];
|
|
9357
9543
|
return rows.map(([number, key, title, hint]) => ({ number, key, title, hint, status: status[key] ? "готово" : "не настроено" }));
|
|
9358
9544
|
}
|
|
@@ -9367,7 +9553,7 @@ function defaultOnboardSelection(status) {
|
|
|
9367
9553
|
}
|
|
9368
9554
|
|
|
9369
9555
|
function defaultOnboardComponents(status) {
|
|
9370
|
-
const map = { 1: "workspace", 2: "policy", 3: "iola", 4: "yandexgpt", 5: "gigachat", 6: "openai", 7: "openrouter", 8: "codex", 9: "codex-mcp", 10: "archive", 11: "index", 12: "browser", 13: "ollama" };
|
|
9556
|
+
const map = { 1: "workspace", 2: "policy", 3: "iola", 4: "yandexgpt", 5: "gigachat", 6: "openai", 7: "openrouter", 8: "codex", 9: "codex-mcp", 10: "archive", 11: "index", 12: "browser", 13: "ollama", 14: "yandex-geocoder" };
|
|
9371
9557
|
return defaultOnboardSelection(status).map((item) => map[item]).filter(Boolean);
|
|
9372
9558
|
}
|
|
9373
9559
|
|
package/wiki/Home.md
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
- выгрузка CSV/JSON;
|
|
12
12
|
- работа с локальной моделью Ollama;
|
|
13
13
|
- работа с YandexGPT, GigaChat, OpenAI, OpenRouter и Codex CLI;
|
|
14
|
+
- geo-сценарии для жителей через Yandex Geocoder API;
|
|
14
15
|
- подключение публичного MCP-сервера.
|
|
15
16
|
|
|
16
17
|
Быстрый старт:
|
|
@@ -28,6 +29,8 @@ iola ask "найди школу 29"
|
|
|
28
29
|
- [Первый запуск](Первый-запуск)
|
|
29
30
|
- [Мастер настройки](Мастер-настройки)
|
|
30
31
|
- [AI-профили](AI-профили)
|
|
32
|
+
- [Yandex Geocoder API key](Yandex-Geocoder-API-key)
|
|
33
|
+
- [Скиллы для жителей](Скиллы-для-жителей)
|
|
31
34
|
- [Локальный инструментальный агент](Локальный-инструментальный-агент)
|
|
32
35
|
- [Skills и toolsets](Skills-и-toolsets)
|
|
33
36
|
- [Локальные файлы](Локальные-файлы)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Yandex Geocoder API key
|
|
2
|
+
|
|
3
|
+
Эта инструкция нужна для подключения геокодера Яндекса к `iola-cli`.
|
|
4
|
+
|
|
5
|
+
Геокодер нужен жителям для вопросов вида:
|
|
6
|
+
|
|
7
|
+
- что находится рядом с моим адресом;
|
|
8
|
+
- где находится школа или детский сад;
|
|
9
|
+
- какой объект ближе;
|
|
10
|
+
- открыть объект на карте;
|
|
11
|
+
- не перепутать Йошкар-Олу, Семеновку и другие населенные пункты.
|
|
12
|
+
|
|
13
|
+
## Получение ключа
|
|
14
|
+
|
|
15
|
+
1. Откройте Кабинет разработчика Яндекса: `https://developer.tech.yandex.ru/services/`.
|
|
16
|
+
2. Войдите в аккаунт Яндекса.
|
|
17
|
+
3. В списке `API интерфейсы` найдите `API Геокодера`.
|
|
18
|
+
4. Откройте `API Геокодера`.
|
|
19
|
+
5. Проверьте блок тарифа. На момент проверки 02.06.2026 в кабинете был показан тариф `Бесплатный с ограничениями` и счетчик `1000` запросов в сутки.
|
|
20
|
+
6. В блоке `Ключи API` нажмите `Новый ключ`.
|
|
21
|
+
7. В поле `Название ключа` введите понятное имя, например `iola-cli geocoder`.
|
|
22
|
+
8. Нажмите `Добавить ключ`.
|
|
23
|
+
9. После создания ключ появится в списке ключей API Геокодера.
|
|
24
|
+
10. Скопируйте значение ключа. Это значение будет `YANDEX_GEOCODER_API_KEY`.
|
|
25
|
+
|
|
26
|
+
Важно: новый ключ может начать работать не сразу. В документации Яндекса указано, что активация ключа может занять до 15 минут. Если CLI пишет `Invalid api key` сразу после создания ключа, подождите и повторите проверку.
|
|
27
|
+
|
|
28
|
+
## Сохранение в CLI
|
|
29
|
+
|
|
30
|
+
Запустите:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
iola geo key set yandex
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
CLI попросит ввести:
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
YANDEX_GEOCODER_API_KEY
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Ключ сохраняется локально на устройстве пользователя в `~/.iola/secrets.json`.
|
|
43
|
+
|
|
44
|
+
Проверить сохранение:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
iola geo key status
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Проверить рабочий запрос к API:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
iola geo key doctor
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Проверить геокодирование адреса:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
iola geo geocode "Йошкар-Ола, улица Петрова, 15"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
CLI также понимает переменные окружения:
|
|
63
|
+
|
|
64
|
+
- `YANDEX_GEOCODER_API_KEY`;
|
|
65
|
+
- `YANDEX_MAPS_API_KEY`.
|
|
66
|
+
|
|
67
|
+
## Официальные ссылки
|
|
68
|
+
|
|
69
|
+
- Кабинет разработчика: `https://developer.tech.yandex.ru/services/`
|
|
70
|
+
- API Геокодера: `https://developer.tech.yandex.ru/services/2`
|
|
71
|
+
- Документация Geocoder API: `https://yandex.com/maps-api/docs/geocoder-api/`
|
|
72
|
+
- Формат запроса: `https://yandex.com/maps-api/docs/geocoder-api/request.html`
|
|
@@ -26,6 +26,15 @@ iola card "школа 29"
|
|
|
26
26
|
iola data schools --format csv --output schools.csv
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
Геокодер:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
iola geo key set yandex
|
|
33
|
+
iola geo key status
|
|
34
|
+
iola geo key doctor
|
|
35
|
+
iola geo geocode "Йошкар-Ола, улица Петрова, 15"
|
|
36
|
+
```
|
|
37
|
+
|
|
29
38
|
Локальная БД:
|
|
30
39
|
|
|
31
40
|
```bash
|
|
@@ -86,6 +86,14 @@ iola index folder ./docs
|
|
|
86
86
|
|
|
87
87
|
Если runtime уже установлен, пункт показывается как `готово`.
|
|
88
88
|
|
|
89
|
+
### 14. Yandex Geocoder API
|
|
90
|
+
|
|
91
|
+
Сохраняет ключ Yandex Geocoder API локально у пользователя и проверяет его тестовым запросом.
|
|
92
|
+
|
|
93
|
+
Нужен для будущих geo-skills: поиск объектов рядом с адресом, ссылки на карту, определение расстояний и уточнение населенного пункта.
|
|
94
|
+
|
|
95
|
+
Инструкция по получению ключа: [Yandex Geocoder API key](Yandex-Geocoder-API-key).
|
|
96
|
+
|
|
89
97
|
## Повторный запуск
|
|
90
98
|
|
|
91
99
|
Если компонент уже настроен, его можно не выбирать. Если нужно переустановить или обновить компонент, выберите его номер вручную.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Скиллы для жителей
|
|
2
|
+
|
|
3
|
+
Эта страница фиксирует пользовательские skills, которые стоит развивать в `iola-cli`.
|
|
4
|
+
|
|
5
|
+
Цель этих skills - помогать жителю города в бытовых вопросах: где находится объект, что рядом, какой объект ближе, как открыть место на карте. Это не административный аудит данных.
|
|
6
|
+
|
|
7
|
+
## Geo skills
|
|
8
|
+
|
|
9
|
+
Для geo skills нужен ключ `Yandex Geocoder API`.
|
|
10
|
+
|
|
11
|
+
### nearby
|
|
12
|
+
|
|
13
|
+
Находит городские объекты рядом с адресом пользователя.
|
|
14
|
+
|
|
15
|
+
Примеры:
|
|
16
|
+
|
|
17
|
+
- `какие детские сады рядом с Петрова 15`;
|
|
18
|
+
- `какие школы ближе к улице Машиностроителей`;
|
|
19
|
+
- `что из городских учреждений рядом с домом`.
|
|
20
|
+
|
|
21
|
+
На первом этапе работает по слоям `schools` и `kindergartens`. Позже можно подключить МФЦ, поликлиники, остановки, спортобъекты и учреждения культуры.
|
|
22
|
+
|
|
23
|
+
### route-context
|
|
24
|
+
|
|
25
|
+
Объясняет, где находится объект, простым языком: адрес, ориентиры, что рядом, ссылка на карту.
|
|
26
|
+
|
|
27
|
+
Это не полноценный навигатор и не замена маршрутизатору. Skill дает понятный контекст места для жителя.
|
|
28
|
+
|
|
29
|
+
### address-to-services
|
|
30
|
+
|
|
31
|
+
По адресу жителя подбирает релевантные городские объекты.
|
|
32
|
+
|
|
33
|
+
Примеры:
|
|
34
|
+
|
|
35
|
+
- ближайшие школы;
|
|
36
|
+
- ближайшие детские сады;
|
|
37
|
+
- будущие слои муниципальных услуг и учреждений.
|
|
38
|
+
|
|
39
|
+
### map-link
|
|
40
|
+
|
|
41
|
+
Добавляет в ответы ссылку на карту.
|
|
42
|
+
|
|
43
|
+
Примеры:
|
|
44
|
+
|
|
45
|
+
- открыть школу на Яндекс.Картах;
|
|
46
|
+
- открыть детский сад на карте;
|
|
47
|
+
- показать точку по координатам.
|
|
48
|
+
|
|
49
|
+
### place-resolver
|
|
50
|
+
|
|
51
|
+
Помогает понять криво написанные адреса, названия и ориентиры.
|
|
52
|
+
|
|
53
|
+
Примеры:
|
|
54
|
+
|
|
55
|
+
- `семеновка школа`;
|
|
56
|
+
- `первомаиская 89`;
|
|
57
|
+
- `садик золотой петушок`;
|
|
58
|
+
- `рядом с вокзалом`.
|
|
59
|
+
|
|
60
|
+
Главная задача - не подставлять похожий, но неправильный объект.
|
|
61
|
+
|
|
62
|
+
### distance
|
|
63
|
+
|
|
64
|
+
Считает расстояние от адреса пользователя до объекта или между объектами.
|
|
65
|
+
|
|
66
|
+
Примеры:
|
|
67
|
+
|
|
68
|
+
- `какой садик ближе к дому`;
|
|
69
|
+
- `как далеко школа 7 от Первомайской 89`;
|
|
70
|
+
- `что ближе: Пчелка или Улыбка`.
|
|
71
|
+
|
|
72
|
+
### area-filter
|
|
73
|
+
|
|
74
|
+
Фильтрует ответы по населенному пункту или району.
|
|
75
|
+
|
|
76
|
+
Примеры:
|
|
77
|
+
|
|
78
|
+
- Йошкар-Ола;
|
|
79
|
+
- Семеновка;
|
|
80
|
+
- другие населенные пункты городского округа, когда они появятся в слоях.
|
|
81
|
+
|
|
82
|
+
Это важно, чтобы не путать объекты с одинаковыми номерами или похожими названиями.
|
|
83
|
+
|
|
84
|
+
## Приоритет реализации
|
|
85
|
+
|
|
86
|
+
Первый этап:
|
|
87
|
+
|
|
88
|
+
1. `nearby`
|
|
89
|
+
2. `place-resolver`
|
|
90
|
+
3. `map-link`
|
|
91
|
+
|
|
92
|
+
Второй этап:
|
|
93
|
+
|
|
94
|
+
1. `distance`
|
|
95
|
+
2. `area-filter`
|
|
96
|
+
3. `route-context`
|
|
97
|
+
4. `address-to-services`
|