@iola_adm/iola-cli 0.1.94 → 0.1.96
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 +49 -2
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -33,7 +33,7 @@ const LOCAL_CONFIG_FILE = path.join(PROJECT_IOLA_DIR, "local.json");
|
|
|
33
33
|
const BROWSER_RUNTIME_DIR = path.join(CONFIG_DIR, "browser-runtime");
|
|
34
34
|
const BROWSER_RUNTIME_PACKAGE = path.join(BROWSER_RUNTIME_DIR, "node_modules", "playwright", "package.json");
|
|
35
35
|
const INDEXABLE_EXTENSIONS = /\.(md|txt|csv|json|html|docx|xlsx|pptx|pdf)$/i;
|
|
36
|
-
const LOCAL_TOOLS = ["search_data", "search_entities", "resolve_entity_field", "get_card", "export_report", "file_read", "browser_open"];
|
|
36
|
+
const LOCAL_TOOLS = ["search_data", "search_entities", "resolve_entity_field", "get_card", "export_report", "file_read", "browser_open", "get_current_date"];
|
|
37
37
|
const LEGACY_LOCAL_TOOLS = ["search_local", "export_data", "run_report", "save_view"];
|
|
38
38
|
const FILE_TOOLS = ["files_tree", "files_read", "files_search", "files_write", "files_patch"];
|
|
39
39
|
const ALL_LOCAL_TOOLS = [...LOCAL_TOOLS, ...FILE_TOOLS];
|
|
@@ -6436,6 +6436,11 @@ async function localToolAsk(question, providerConfig, options) {
|
|
|
6436
6436
|
if (!options.quiet) console.log(guarded);
|
|
6437
6437
|
return guarded;
|
|
6438
6438
|
}
|
|
6439
|
+
const casualAnswer = buildCasualDirectAnswer(question);
|
|
6440
|
+
if (casualAnswer) {
|
|
6441
|
+
if (!options.quiet) console.log(casualAnswer);
|
|
6442
|
+
return casualAnswer;
|
|
6443
|
+
}
|
|
6439
6444
|
await ensureLocalData();
|
|
6440
6445
|
const plan = await buildLocalToolPlan(question, providerConfig, options);
|
|
6441
6446
|
if (plan.directAnswer) {
|
|
@@ -6489,6 +6494,23 @@ function guardNonPublicQuestion(question) {
|
|
|
6489
6494
|
return "";
|
|
6490
6495
|
}
|
|
6491
6496
|
|
|
6497
|
+
function buildCasualDirectAnswer(question) {
|
|
6498
|
+
const normalized = String(question || "").toLocaleLowerCase("ru-RU").trim();
|
|
6499
|
+
if (/^(кто ты|что ты|какая ты модель|что ты за модель|что за модель|какая модель|назови модель|ты какая модель|ты кто)([?.!\s]*)$/iu.test(normalized)) {
|
|
6500
|
+
return "Я IOLA, первая городская модель искусственного интеллекта Йошкар-Олы. Работаю локально в CLI и отвечаю по открытым городским данным через проверяемые слои и API.";
|
|
6501
|
+
}
|
|
6502
|
+
if (/^(привет|здравствуй|здравствуйте|добрый день|доброе утро|добрый вечер|hi|hello|hey)([!.?\s]+(как дела|как ты|что нового)[?.!\s]*)?$/iu.test(normalized)) {
|
|
6503
|
+
return "Привет. Работаю нормально. Могу помочь с открытыми данными Йошкар-Олы: школами, детскими садами, адресами, телефонами, сайтами и ИНН.";
|
|
6504
|
+
}
|
|
6505
|
+
if (/^(как дела|как ты|что нового|ты тут|ты здесь)[?.!\s]*$/iu.test(normalized)) {
|
|
6506
|
+
return "Я на месте. Могу искать и проверять открытые городские данные.";
|
|
6507
|
+
}
|
|
6508
|
+
if (/^(спасибо|благодарю)[!.?\s]*$/iu.test(normalized)) {
|
|
6509
|
+
return "Пожалуйста.";
|
|
6510
|
+
}
|
|
6511
|
+
return "";
|
|
6512
|
+
}
|
|
6513
|
+
|
|
6492
6514
|
function printToolPlan(plan) {
|
|
6493
6515
|
console.log("План выполнения:");
|
|
6494
6516
|
plan.steps.forEach((step, index) => {
|
|
@@ -6534,7 +6556,12 @@ async function buildLocalToolPlan(question, providerConfig, options) {
|
|
|
6534
6556
|
function normalizeIolaRouterPlan(raw, question, options = {}) {
|
|
6535
6557
|
const payload = typeof raw === "string" ? parseJsonObject(raw) : raw;
|
|
6536
6558
|
if (payload.action === "tool_call") {
|
|
6537
|
-
const tool = payload.tool
|
|
6559
|
+
const tool = normalizeIolaToolName(payload.tool);
|
|
6560
|
+
if (!availableToolNames(options).includes(tool)) {
|
|
6561
|
+
const casualAnswer = buildCasualDirectAnswer(question);
|
|
6562
|
+
if (casualAnswer) return { directAnswer: casualAnswer };
|
|
6563
|
+
return inferToolPlan(question, options);
|
|
6564
|
+
}
|
|
6538
6565
|
return { steps: [{ tool, args: payload.args || {} }] };
|
|
6539
6566
|
}
|
|
6540
6567
|
if (payload.action === "direct_answer") {
|
|
@@ -6552,6 +6579,12 @@ function normalizeIolaRouterPlan(raw, question, options = {}) {
|
|
|
6552
6579
|
throw new Error(`IOLA router вернул неподдерживаемое действие: ${payload.action || "unknown"}`);
|
|
6553
6580
|
}
|
|
6554
6581
|
|
|
6582
|
+
function normalizeIolaToolName(tool) {
|
|
6583
|
+
if (tool === "get_entity_field") return "resolve_entity_field";
|
|
6584
|
+
if (tool === "current_date" || tool === "date_now" || tool === "today") return "get_current_date";
|
|
6585
|
+
return tool;
|
|
6586
|
+
}
|
|
6587
|
+
|
|
6555
6588
|
function parseJsonObject(text) {
|
|
6556
6589
|
const match = String(text).match(/\{[\s\S]*\}/);
|
|
6557
6590
|
if (!match) throw new Error("JSON-план не найден.");
|
|
@@ -6704,6 +6737,9 @@ async function executeToolPlan(plan, options = {}) {
|
|
|
6704
6737
|
const text = await runBrowserAutomation("text", { url: step.args?.url, waitMs: Number(step.args?.waitMs || 0), timeout: Number(step.args?.timeout || 30000), viewport: step.args?.viewport || "1366x768" });
|
|
6705
6738
|
current = [{ url: step.args?.url, text }];
|
|
6706
6739
|
outputs.push({ tool: step.tool, rows: 1 });
|
|
6740
|
+
} else if (step.tool === "get_current_date") {
|
|
6741
|
+
current = [getCurrentDateInfo()];
|
|
6742
|
+
outputs.push({ tool: step.tool, rows: current.length });
|
|
6707
6743
|
} else if (String(step.tool || "").startsWith("mcp:")) {
|
|
6708
6744
|
const result = await callConfiguredMcpTool(step.tool, step.args || {});
|
|
6709
6745
|
current = Array.isArray(result) ? result : [result];
|
|
@@ -6742,6 +6778,16 @@ async function executeToolPlan(plan, options = {}) {
|
|
|
6742
6778
|
return { rows: current, outputs };
|
|
6743
6779
|
}
|
|
6744
6780
|
|
|
6781
|
+
function getCurrentDateInfo() {
|
|
6782
|
+
const now = new Date();
|
|
6783
|
+
return {
|
|
6784
|
+
name: "текущая дата",
|
|
6785
|
+
date: new Intl.DateTimeFormat("ru-RU", { dateStyle: "long" }).format(now),
|
|
6786
|
+
time: new Intl.DateTimeFormat("ru-RU", { timeStyle: "short" }).format(now),
|
|
6787
|
+
iso: now.toISOString(),
|
|
6788
|
+
};
|
|
6789
|
+
}
|
|
6790
|
+
|
|
6745
6791
|
function getLocalMcpToolNames() {
|
|
6746
6792
|
return mcpTools().map((tool) => `mcp:iola-local:${tool.name}`);
|
|
6747
6793
|
}
|
|
@@ -6824,6 +6870,7 @@ function formatToolResult(result, options) {
|
|
|
6824
6870
|
const name = row.entity.name || row.entity.inn || "организация";
|
|
6825
6871
|
return `${name}: ${row.field} = ${row.value ?? "не указано"}`;
|
|
6826
6872
|
}
|
|
6873
|
+
if (row.date && row.time) return `Сегодня ${row.date}, ${row.time}.`;
|
|
6827
6874
|
return `${row.name || row.check || row.inn || "строка"}: ${row.address || row.phone || row.email || row.website || row.count || ""}`;
|
|
6828
6875
|
}).join("\n");
|
|
6829
6876
|
}
|