micro-models-agent 0.29.2 → 0.31.0
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/dist/main.js +367 -37
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -2224,6 +2224,8 @@ var init_defaults = __esm(() => {
|
|
|
2224
2224
|
enabled: true,
|
|
2225
2225
|
headless: true,
|
|
2226
2226
|
maxElements: 30,
|
|
2227
|
+
maxContentChars: 2500,
|
|
2228
|
+
maxConsoleEntries: 20,
|
|
2227
2229
|
viewportWidth: 1280,
|
|
2228
2230
|
viewportHeight: 720,
|
|
2229
2231
|
navigationTimeout: 15000
|
|
@@ -2263,7 +2265,13 @@ var init_defaults = __esm(() => {
|
|
|
2263
2265
|
stableSystemPrompt: true,
|
|
2264
2266
|
maxParallelChunkQueries: 4
|
|
2265
2267
|
},
|
|
2266
|
-
lsp: DEFAULT_LSP_CONFIG
|
|
2268
|
+
lsp: DEFAULT_LSP_CONFIG,
|
|
2269
|
+
updater: {
|
|
2270
|
+
enabled: true,
|
|
2271
|
+
checkOnStart: true,
|
|
2272
|
+
autoInstall: true,
|
|
2273
|
+
intervalMs: 0
|
|
2274
|
+
}
|
|
2267
2275
|
};
|
|
2268
2276
|
});
|
|
2269
2277
|
|
|
@@ -2778,6 +2786,10 @@ Use this knowledge to answer the user's question.`,
|
|
|
2778
2786
|
"browser.no_page_short": "No page",
|
|
2779
2787
|
"browser.no_elements": "(no interactive elements on page)",
|
|
2780
2788
|
"browser.more_elements": "... and more elements not shown. Use scroll or search to find others.",
|
|
2789
|
+
"browser.content_header": "Content:",
|
|
2790
|
+
"browser.console_header": "Console:",
|
|
2791
|
+
"browser.network_errors_header": "Network errors:",
|
|
2792
|
+
"browser.truncated": "... (truncated)",
|
|
2781
2793
|
"pipeline.invalid": "Invalid pipeline: name and steps required",
|
|
2782
2794
|
"pipeline.step_missing_fields": "Step missing required fields (id, agent, prompt): {step}",
|
|
2783
2795
|
"pipeline.circular": "Circular dependency: {stepId}",
|
|
@@ -2832,8 +2844,13 @@ Use this knowledge to answer the user's question.`,
|
|
|
2832
2844
|
"ctx.compactions": "compactions: {count}",
|
|
2833
2845
|
"ctx.quality": "quality: {percent}%",
|
|
2834
2846
|
"ctx.delta_pos": "ctx +{tokens}",
|
|
2835
|
-
"ctx.delta_neg": "ctx -{tokens}
|
|
2836
|
-
"ctx.delta_zero": "ctx
|
|
2847
|
+
"ctx.delta_neg": "ctx -{tokens} ",
|
|
2848
|
+
"ctx.delta_zero": "ctx +0",
|
|
2849
|
+
"updater.check_error": "[updater] update check failed: {error}",
|
|
2850
|
+
"updater.available": "[updater] Update available: {current} → {latest}. Run `npm install -g micro-models-agent` to upgrade.",
|
|
2851
|
+
"updater.installing": "[updater] Installing {latest} globally (current: {current})…",
|
|
2852
|
+
"updater.installed": "[updater] Installed {latest}. Restart MMA to use it (was {current}).",
|
|
2853
|
+
"updater.install_failed": "[updater] Failed to install {latest}: {error}. Update manually with `npm install -g micro-models-agent`."
|
|
2837
2854
|
};
|
|
2838
2855
|
});
|
|
2839
2856
|
|
|
@@ -3346,6 +3363,10 @@ var init_ru = __esm(() => {
|
|
|
3346
3363
|
"browser.no_page_short": "Нет страницы",
|
|
3347
3364
|
"browser.no_elements": "(нет интерактивных элементов на странице)",
|
|
3348
3365
|
"browser.more_elements": "... и другие элементы не показаны. Используйте прокрутку или поиск.",
|
|
3366
|
+
"browser.content_header": "Содержимое:",
|
|
3367
|
+
"browser.console_header": "Консоль:",
|
|
3368
|
+
"browser.network_errors_header": "Сетевые ошибки:",
|
|
3369
|
+
"browser.truncated": "... (обрезано)",
|
|
3349
3370
|
"pipeline.invalid": "Невалидный пайплайн: требуются name и steps",
|
|
3350
3371
|
"pipeline.step_missing_fields": "Шаг не содержит обязательных полей (id, agent, prompt): {step}",
|
|
3351
3372
|
"pipeline.circular": "Циклическая зависимость: {stepId}",
|
|
@@ -3403,7 +3424,12 @@ var init_ru = __esm(() => {
|
|
|
3403
3424
|
"ctx.delta_neg": "контекст -{tokens} ↓",
|
|
3404
3425
|
"ctx.delta_zero": "контекст ±0",
|
|
3405
3426
|
"file.notfound_resolved": "Файл не найден: {path} (резолвится в {resolved})",
|
|
3406
|
-
"bash.echo_write_blocked": "Запись файлов через echo/printf ненадёжна в Windows cmd.exe (кавычки и многострочность ломаются). Используй инструмент write_file вместо этого (цель: {path})."
|
|
3427
|
+
"bash.echo_write_blocked": "Запись файлов через echo/printf ненадёжна в Windows cmd.exe (кавычки и многострочность ломаются). Используй инструмент write_file вместо этого (цель: {path}).",
|
|
3428
|
+
"updater.check_error": "[updater] Ошибка проверки обновления: {error}",
|
|
3429
|
+
"updater.available": "[updater] Доступно обновление: {current} → {latest}. Выполните `npm install -g micro-models-agent` для обновления.",
|
|
3430
|
+
"updater.installing": "[updater] Установка {latest} глобально (текущая: {current})…",
|
|
3431
|
+
"updater.installed": "[updater] Установлена {latest}. Перезапустите MMA для применения (была {current}).",
|
|
3432
|
+
"updater.install_failed": "[updater] Не удалось установить {latest}: {error}. Обновите вручную: `npm install -g micro-models-agent`."
|
|
3407
3433
|
};
|
|
3408
3434
|
});
|
|
3409
3435
|
|
|
@@ -13644,6 +13670,22 @@ var init_recall = __esm(() => {
|
|
|
13644
13670
|
};
|
|
13645
13671
|
});
|
|
13646
13672
|
|
|
13673
|
+
// src/modules/browser/types.ts
|
|
13674
|
+
var DEFAULT_BROWSER_CONFIG;
|
|
13675
|
+
var init_types = __esm(() => {
|
|
13676
|
+
DEFAULT_BROWSER_CONFIG = {
|
|
13677
|
+
headless: true,
|
|
13678
|
+
maxElements: 30,
|
|
13679
|
+
maxContentChars: 2500,
|
|
13680
|
+
maxConsoleEntries: 20,
|
|
13681
|
+
screenshotMaxWidth: 1280,
|
|
13682
|
+
cookieDir: "",
|
|
13683
|
+
viewportWidth: 1280,
|
|
13684
|
+
viewportHeight: 720,
|
|
13685
|
+
navigationTimeout: 15000
|
|
13686
|
+
};
|
|
13687
|
+
});
|
|
13688
|
+
|
|
13647
13689
|
// src/modules/browser/snapshot.ts
|
|
13648
13690
|
function inferRole(tag, type) {
|
|
13649
13691
|
const t2 = tag.toLowerCase();
|
|
@@ -13731,35 +13773,69 @@ function extractInteractiveElements(html, maxElements = 30) {
|
|
|
13731
13773
|
}
|
|
13732
13774
|
return elements;
|
|
13733
13775
|
}
|
|
13734
|
-
function
|
|
13776
|
+
function truncateText(text, maxChars) {
|
|
13777
|
+
if (maxChars <= 0)
|
|
13778
|
+
return "";
|
|
13779
|
+
if (text.length <= maxChars)
|
|
13780
|
+
return text;
|
|
13781
|
+
const cut = text.slice(0, maxChars);
|
|
13782
|
+
const lastNewline = cut.lastIndexOf(`
|
|
13783
|
+
`);
|
|
13784
|
+
const safe = lastNewline > maxChars * 0.6 ? cut.slice(0, lastNewline) : cut;
|
|
13785
|
+
return `${safe}
|
|
13786
|
+
${t("browser.truncated")}`;
|
|
13787
|
+
}
|
|
13788
|
+
function formatSnapshot(snapshot, maxContentChars = DEFAULT_BROWSER_CONFIG.maxContentChars) {
|
|
13735
13789
|
const lines = [];
|
|
13736
13790
|
lines.push(`Page: "${snapshot.title}"`);
|
|
13737
13791
|
lines.push(`URL: ${snapshot.url}`);
|
|
13738
13792
|
lines.push("");
|
|
13739
13793
|
if (snapshot.elements.length === 0 && !snapshot.truncated) {
|
|
13740
13794
|
lines.push(t("browser.no_elements"));
|
|
13741
|
-
|
|
13742
|
-
|
|
13795
|
+
} else {
|
|
13796
|
+
for (const el of snapshot.elements) {
|
|
13797
|
+
let line = `[${el.index}] ${el.role}`;
|
|
13798
|
+
if (el.name)
|
|
13799
|
+
line += ` "${el.name}"`;
|
|
13800
|
+
if (el.href)
|
|
13801
|
+
line += ` → ${el.href}`;
|
|
13802
|
+
if (el.value)
|
|
13803
|
+
line += ` = "${el.value}"`;
|
|
13804
|
+
lines.push(line);
|
|
13805
|
+
}
|
|
13806
|
+
if (snapshot.truncated) {
|
|
13807
|
+
lines.push("");
|
|
13808
|
+
lines.push(t("browser.more_elements"));
|
|
13809
|
+
}
|
|
13743
13810
|
}
|
|
13744
|
-
|
|
13745
|
-
let line = `[${el.index}] ${el.role}`;
|
|
13746
|
-
if (el.name)
|
|
13747
|
-
line += ` "${el.name}"`;
|
|
13748
|
-
if (el.href)
|
|
13749
|
-
line += ` → ${el.href}`;
|
|
13750
|
-
if (el.value)
|
|
13751
|
-
line += ` = "${el.value}"`;
|
|
13752
|
-
lines.push(line);
|
|
13753
|
-
}
|
|
13754
|
-
if (snapshot.truncated) {
|
|
13811
|
+
if (snapshot.content) {
|
|
13755
13812
|
lines.push("");
|
|
13756
|
-
lines.push(t("browser.
|
|
13813
|
+
lines.push(t("browser.content_header"));
|
|
13814
|
+
for (const line of truncateText(snapshot.content, maxContentChars).split(`
|
|
13815
|
+
`)) {
|
|
13816
|
+
lines.push(`- ${line}`);
|
|
13817
|
+
}
|
|
13818
|
+
}
|
|
13819
|
+
if (snapshot.console.length > 0) {
|
|
13820
|
+
lines.push("");
|
|
13821
|
+
lines.push(t("browser.console_header"));
|
|
13822
|
+
for (const entry of snapshot.console) {
|
|
13823
|
+
lines.push(`[${entry.type}] ${entry.text}`);
|
|
13824
|
+
}
|
|
13825
|
+
}
|
|
13826
|
+
if (snapshot.networkErrors.length > 0) {
|
|
13827
|
+
lines.push("");
|
|
13828
|
+
lines.push(t("browser.network_errors_header"));
|
|
13829
|
+
for (const err of snapshot.networkErrors) {
|
|
13830
|
+
lines.push(`${err.method} ${err.url} → ${err.error}`);
|
|
13831
|
+
}
|
|
13757
13832
|
}
|
|
13758
13833
|
return lines.join(`
|
|
13759
13834
|
`);
|
|
13760
13835
|
}
|
|
13761
13836
|
var init_snapshot = __esm(() => {
|
|
13762
13837
|
init_i18n();
|
|
13838
|
+
init_types();
|
|
13763
13839
|
});
|
|
13764
13840
|
|
|
13765
13841
|
// src/modules/browser/actions.ts
|
|
@@ -13806,6 +13882,36 @@ function buildIndexInjectionScript() {
|
|
|
13806
13882
|
});
|
|
13807
13883
|
`;
|
|
13808
13884
|
}
|
|
13885
|
+
function buildTextExtractionScript() {
|
|
13886
|
+
return `
|
|
13887
|
+
const contentTags = new Set(['h1','h2','h3','h4','h5','h6','p','li','article','main','section','blockquote','pre','td','th','dt','dd','figcaption']);
|
|
13888
|
+
const out = [];
|
|
13889
|
+
const seen = new Set();
|
|
13890
|
+
const isHidden = (el) => {
|
|
13891
|
+
const st = window.getComputedStyle(el);
|
|
13892
|
+
return st.display === 'none' || st.visibility === 'hidden';
|
|
13893
|
+
};
|
|
13894
|
+
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, {
|
|
13895
|
+
acceptNode: (node) => {
|
|
13896
|
+
const tag = node.tagName ? node.tagName.toLowerCase() : '';
|
|
13897
|
+
if (!contentTags.has(tag)) return NodeFilter.FILTER_SKIP;
|
|
13898
|
+
if (isHidden(node)) return NodeFilter.FILTER_REJECT;
|
|
13899
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
13900
|
+
}
|
|
13901
|
+
});
|
|
13902
|
+
let node;
|
|
13903
|
+
while ((node = walker.nextNode())) {
|
|
13904
|
+
const tag = node.tagName.toLowerCase();
|
|
13905
|
+
const text = (node.textContent || '').replace(/\\s+/g, ' ').trim();
|
|
13906
|
+
if (!text) continue;
|
|
13907
|
+
if (seen.has(text)) continue;
|
|
13908
|
+
seen.add(text);
|
|
13909
|
+
const line = text.length > 200 ? text.slice(0, 200) + '…' : text;
|
|
13910
|
+
out.push('[' + tag + '] ' + line);
|
|
13911
|
+
}
|
|
13912
|
+
return out.join('\\n');
|
|
13913
|
+
`;
|
|
13914
|
+
}
|
|
13809
13915
|
|
|
13810
13916
|
// src/modules/browser/cookie-store.ts
|
|
13811
13917
|
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
@@ -13839,6 +13945,33 @@ import {
|
|
|
13839
13945
|
chromium
|
|
13840
13946
|
} from "playwright";
|
|
13841
13947
|
|
|
13948
|
+
class ConsoleBuffer {
|
|
13949
|
+
entries = [];
|
|
13950
|
+
maxEntries;
|
|
13951
|
+
constructor(maxEntries = 20) {
|
|
13952
|
+
this.maxEntries = maxEntries;
|
|
13953
|
+
}
|
|
13954
|
+
add(type, text) {
|
|
13955
|
+
const clean = String(text).replace(/\s+/g, " ").trim();
|
|
13956
|
+
if (!clean)
|
|
13957
|
+
return;
|
|
13958
|
+
const line = clean.length > CONSOLE_MAX_LINE ? clean.slice(0, CONSOLE_MAX_LINE) + "…" : clean;
|
|
13959
|
+
this.entries.push({ type, text: line });
|
|
13960
|
+
if (this.entries.length > this.maxEntries) {
|
|
13961
|
+
this.entries.splice(0, this.entries.length - this.maxEntries);
|
|
13962
|
+
}
|
|
13963
|
+
}
|
|
13964
|
+
clear() {
|
|
13965
|
+
this.entries = [];
|
|
13966
|
+
}
|
|
13967
|
+
getAll() {
|
|
13968
|
+
return [...this.entries];
|
|
13969
|
+
}
|
|
13970
|
+
get size() {
|
|
13971
|
+
return this.entries.length;
|
|
13972
|
+
}
|
|
13973
|
+
}
|
|
13974
|
+
|
|
13842
13975
|
class BrowserActionTracker {
|
|
13843
13976
|
history = [];
|
|
13844
13977
|
threshold;
|
|
@@ -13877,9 +14010,12 @@ class BrowserSession {
|
|
|
13877
14010
|
elementCount: 0
|
|
13878
14011
|
};
|
|
13879
14012
|
actionTracker = new BrowserActionTracker(3);
|
|
14013
|
+
consoleBuffer;
|
|
14014
|
+
networkErrors = [];
|
|
13880
14015
|
constructor(config) {
|
|
13881
14016
|
this.config = config;
|
|
13882
14017
|
this.cookieStore = new CookieStore(config.cookieDir);
|
|
14018
|
+
this.consoleBuffer = new ConsoleBuffer(config.maxConsoleEntries);
|
|
13883
14019
|
}
|
|
13884
14020
|
getState() {
|
|
13885
14021
|
return { ...this.state };
|
|
@@ -13965,6 +14101,20 @@ class BrowserSession {
|
|
|
13965
14101
|
}
|
|
13966
14102
|
this.page = await this.context.newPage();
|
|
13967
14103
|
this.page.setDefaultTimeout(this.config.navigationTimeout);
|
|
14104
|
+
this.page.on("console", (msg) => {
|
|
14105
|
+
this.consoleBuffer.add(msg.type(), msg.text());
|
|
14106
|
+
});
|
|
14107
|
+
this.page.on("pageerror", (err) => {
|
|
14108
|
+
this.consoleBuffer.add("pageerror", `Page error: ${err.message}`);
|
|
14109
|
+
});
|
|
14110
|
+
this.page.on("requestfailed", (req) => {
|
|
14111
|
+
const failure = req.failure();
|
|
14112
|
+
this.networkErrors.push({
|
|
14113
|
+
method: req.method(),
|
|
14114
|
+
url: req.url(),
|
|
14115
|
+
error: failure?.errorText || "unknown"
|
|
14116
|
+
});
|
|
14117
|
+
});
|
|
13968
14118
|
}
|
|
13969
14119
|
async saveCookies() {
|
|
13970
14120
|
if (!this.context)
|
|
@@ -13979,6 +14129,12 @@ class BrowserSession {
|
|
|
13979
14129
|
const html = await this.page.content();
|
|
13980
14130
|
const url = this.page.url();
|
|
13981
14131
|
const title = await this.page.title();
|
|
14132
|
+
let content = "";
|
|
14133
|
+
try {
|
|
14134
|
+
content = await this.page.evaluate(buildTextExtractionScript());
|
|
14135
|
+
} catch {
|
|
14136
|
+
content = "";
|
|
14137
|
+
}
|
|
13982
14138
|
const allElements = extractInteractiveElements(html, this.config.maxElements + 5);
|
|
13983
14139
|
const truncated = allElements.length > this.config.maxElements;
|
|
13984
14140
|
const elements = allElements.slice(0, this.config.maxElements);
|
|
@@ -13988,7 +14144,15 @@ class BrowserSession {
|
|
|
13988
14144
|
title,
|
|
13989
14145
|
elementCount: elements.length
|
|
13990
14146
|
};
|
|
13991
|
-
return formatSnapshot({
|
|
14147
|
+
return formatSnapshot({
|
|
14148
|
+
url,
|
|
14149
|
+
title,
|
|
14150
|
+
elements,
|
|
14151
|
+
content,
|
|
14152
|
+
console: this.consoleBuffer.getAll(),
|
|
14153
|
+
networkErrors: this.networkErrors.slice(-5),
|
|
14154
|
+
truncated
|
|
14155
|
+
});
|
|
13992
14156
|
}
|
|
13993
14157
|
async open(url) {
|
|
13994
14158
|
if (!url)
|
|
@@ -14001,6 +14165,8 @@ class BrowserSession {
|
|
|
14001
14165
|
if (!this.page)
|
|
14002
14166
|
return { success: false, output: t("browser.create_page_failed") };
|
|
14003
14167
|
this.actionTracker.reset();
|
|
14168
|
+
this.consoleBuffer.clear();
|
|
14169
|
+
this.networkErrors = [];
|
|
14004
14170
|
try {
|
|
14005
14171
|
await this.page.goto(url, {
|
|
14006
14172
|
waitUntil: "domcontentloaded",
|
|
@@ -14157,26 +14323,13 @@ class BrowserSession {
|
|
|
14157
14323
|
return { success: true, output: t("browser.closed") };
|
|
14158
14324
|
}
|
|
14159
14325
|
}
|
|
14326
|
+
var CONSOLE_MAX_LINE = 200;
|
|
14160
14327
|
var init_session = __esm(() => {
|
|
14161
14328
|
init_snapshot();
|
|
14162
14329
|
init_cookie_store();
|
|
14163
14330
|
init_i18n();
|
|
14164
14331
|
});
|
|
14165
14332
|
|
|
14166
|
-
// src/modules/browser/types.ts
|
|
14167
|
-
var DEFAULT_BROWSER_CONFIG;
|
|
14168
|
-
var init_types = __esm(() => {
|
|
14169
|
-
DEFAULT_BROWSER_CONFIG = {
|
|
14170
|
-
headless: true,
|
|
14171
|
-
maxElements: 30,
|
|
14172
|
-
screenshotMaxWidth: 1280,
|
|
14173
|
-
cookieDir: "",
|
|
14174
|
-
viewportWidth: 1280,
|
|
14175
|
-
viewportHeight: 720,
|
|
14176
|
-
navigationTimeout: 15000
|
|
14177
|
-
};
|
|
14178
|
-
});
|
|
14179
|
-
|
|
14180
14333
|
// src/tools/browser.ts
|
|
14181
14334
|
import { join as join18 } from "path";
|
|
14182
14335
|
function getSession(ctx) {
|
|
@@ -14186,6 +14339,8 @@ function getSession(ctx) {
|
|
|
14186
14339
|
...DEFAULT_BROWSER_CONFIG,
|
|
14187
14340
|
headless: ctx.config.browser?.headless ?? true,
|
|
14188
14341
|
maxElements: ctx.config.browser?.maxElements ?? 30,
|
|
14342
|
+
maxContentChars: ctx.config.browser?.maxContentChars ?? 2500,
|
|
14343
|
+
maxConsoleEntries: ctx.config.browser?.maxConsoleEntries ?? 20,
|
|
14189
14344
|
navigationTimeout: ctx.config.browser?.navigationTimeout ?? 15000,
|
|
14190
14345
|
viewportWidth: ctx.config.browser?.viewportWidth ?? 1280,
|
|
14191
14346
|
viewportHeight: ctx.config.browser?.viewportHeight ?? 720,
|
|
@@ -14214,7 +14369,8 @@ function createBrowserTool() {
|
|
|
14214
14369
|
tags: ["browser", "vision"],
|
|
14215
14370
|
description: [
|
|
14216
14371
|
"Control a headless browser. Navigate pages, click elements, type text, scroll, take screenshots.",
|
|
14217
|
-
"
|
|
14372
|
+
"Each snapshot returns: a numbered list of interactive elements, the visible page text (Content section), browser console messages, and network errors.",
|
|
14373
|
+
"Use the Content section to understand what the page says; use element numbers as targets for click/type.",
|
|
14218
14374
|
"Actions: open (url), click (target), type (target, text), scroll (direction), back, forward, screenshot, snapshot, close, wait (ms)."
|
|
14219
14375
|
].join(" "),
|
|
14220
14376
|
parameters: {
|
|
@@ -16986,6 +17142,7 @@ class BrowserModule {
|
|
|
16986
17142
|
content: [
|
|
16987
17143
|
"You have a headless browser tool. Use it to navigate websites, click links, fill forms, and read page content.",
|
|
16988
17144
|
"Workflow: open(url) → read snapshot → click/type on element numbers → read updated snapshot.",
|
|
17145
|
+
'Each snapshot includes a "Content" section with the visible page text, a "Console" section with browser messages, and network errors. Use these to understand the page, detect JS errors, and verify the result of your actions.',
|
|
16989
17146
|
'Always start with "open" action. Use element numbers from snapshot for click/type targets.',
|
|
16990
17147
|
'Use "screenshot" action only if the model supports vision. Otherwise rely on the text snapshot.'
|
|
16991
17148
|
].join(`
|
|
@@ -29148,9 +29305,180 @@ init_setup();
|
|
|
29148
29305
|
init_config2();
|
|
29149
29306
|
init_i18n();
|
|
29150
29307
|
init_colors();
|
|
29151
|
-
import { existsSync as existsSync46 } from "fs";
|
|
29152
|
-
import { join as join40 } from "path";
|
|
29308
|
+
import { existsSync as existsSync46, readFileSync as readFileSync32 } from "fs";
|
|
29309
|
+
import { join as join40, dirname as dirname13 } from "path";
|
|
29153
29310
|
import { homedir as homedir18 } from "os";
|
|
29311
|
+
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
29312
|
+
|
|
29313
|
+
// src/modules/updater/checker.ts
|
|
29314
|
+
var defaultRunner2 = async (command, args, options) => {
|
|
29315
|
+
const { execFile } = await import("child_process");
|
|
29316
|
+
return new Promise((resolve23) => {
|
|
29317
|
+
execFile(command, args, options, (err) => resolve23({ error: err?.message }));
|
|
29318
|
+
});
|
|
29319
|
+
};
|
|
29320
|
+
|
|
29321
|
+
class Updater {
|
|
29322
|
+
currentVersion;
|
|
29323
|
+
packageName;
|
|
29324
|
+
runner;
|
|
29325
|
+
constructor(currentVersion, packageName, runner) {
|
|
29326
|
+
this.currentVersion = currentVersion;
|
|
29327
|
+
this.packageName = packageName;
|
|
29328
|
+
this.runner = runner ?? defaultRunner2;
|
|
29329
|
+
}
|
|
29330
|
+
getCurrentVersion() {
|
|
29331
|
+
return this.currentVersion;
|
|
29332
|
+
}
|
|
29333
|
+
getPackageName() {
|
|
29334
|
+
return this.packageName;
|
|
29335
|
+
}
|
|
29336
|
+
async check() {
|
|
29337
|
+
try {
|
|
29338
|
+
const response = await fetch(`https://registry.npmjs.org/${this.packageName}`, {
|
|
29339
|
+
headers: { Accept: "application/vnd.npm.install-v1+json" },
|
|
29340
|
+
signal: AbortSignal.timeout(5000)
|
|
29341
|
+
});
|
|
29342
|
+
if (!response.ok) {
|
|
29343
|
+
return { updateAvailable: false, current: this.currentVersion, error: `HTTP ${response.status}` };
|
|
29344
|
+
}
|
|
29345
|
+
const data = await response.json();
|
|
29346
|
+
const latest = data["dist-tags"]?.latest;
|
|
29347
|
+
if (!latest) {
|
|
29348
|
+
return { updateAvailable: false, current: this.currentVersion, error: "No latest tag" };
|
|
29349
|
+
}
|
|
29350
|
+
const updateAvailable = latest !== this.currentVersion;
|
|
29351
|
+
return { updateAvailable, current: this.currentVersion, latest };
|
|
29352
|
+
} catch (e) {
|
|
29353
|
+
return { updateAvailable: false, current: this.currentVersion, error: e.message };
|
|
29354
|
+
}
|
|
29355
|
+
}
|
|
29356
|
+
async install(latest) {
|
|
29357
|
+
try {
|
|
29358
|
+
const res = await this.runner("npm", ["install", "-g", `${this.packageName}@${latest}`], {
|
|
29359
|
+
timeout: 120000,
|
|
29360
|
+
windowsHide: true
|
|
29361
|
+
});
|
|
29362
|
+
if (res.error)
|
|
29363
|
+
return { success: false, error: res.error };
|
|
29364
|
+
return { success: true, installed: latest };
|
|
29365
|
+
} catch (e) {
|
|
29366
|
+
const msg = e?.message ?? String(e);
|
|
29367
|
+
return { success: false, error: msg.split(`
|
|
29368
|
+
`)[0] };
|
|
29369
|
+
}
|
|
29370
|
+
}
|
|
29371
|
+
}
|
|
29372
|
+
// src/modules/updater/module.ts
|
|
29373
|
+
init_i18n();
|
|
29374
|
+
init_colors();
|
|
29375
|
+
|
|
29376
|
+
class UpdaterModule {
|
|
29377
|
+
name = "updater";
|
|
29378
|
+
updater;
|
|
29379
|
+
config;
|
|
29380
|
+
logger;
|
|
29381
|
+
started = false;
|
|
29382
|
+
timer = null;
|
|
29383
|
+
installEnabled = true;
|
|
29384
|
+
constructor(config, currentVersion, packageName, logger, installRunner) {
|
|
29385
|
+
this.config = config;
|
|
29386
|
+
this.updater = new Updater(currentVersion, packageName, installRunner);
|
|
29387
|
+
this.logger = logger ?? {
|
|
29388
|
+
info: () => {},
|
|
29389
|
+
warn: (m) => console.warn(pc2.yellow(m)),
|
|
29390
|
+
error: (m) => console.error(pc2.red(m))
|
|
29391
|
+
};
|
|
29392
|
+
}
|
|
29393
|
+
setInstallEnabled(enabled2) {
|
|
29394
|
+
this.installEnabled = enabled2;
|
|
29395
|
+
}
|
|
29396
|
+
getUpdater() {
|
|
29397
|
+
return this.updater;
|
|
29398
|
+
}
|
|
29399
|
+
isStarted() {
|
|
29400
|
+
return this.started;
|
|
29401
|
+
}
|
|
29402
|
+
start() {
|
|
29403
|
+
if (this.started || !this.config.enabled)
|
|
29404
|
+
return;
|
|
29405
|
+
this.started = true;
|
|
29406
|
+
this.runLoop();
|
|
29407
|
+
}
|
|
29408
|
+
stop() {
|
|
29409
|
+
this.started = false;
|
|
29410
|
+
if (this.timer) {
|
|
29411
|
+
clearTimeout(this.timer);
|
|
29412
|
+
this.timer = null;
|
|
29413
|
+
}
|
|
29414
|
+
}
|
|
29415
|
+
async runLoop() {
|
|
29416
|
+
while (this.started) {
|
|
29417
|
+
await this.checkOnce();
|
|
29418
|
+
if (!this.started)
|
|
29419
|
+
return;
|
|
29420
|
+
if (this.config.intervalMs > 0) {
|
|
29421
|
+
await new Promise((r) => this.timer = setTimeout(r, this.config.intervalMs));
|
|
29422
|
+
} else {
|
|
29423
|
+
this.started = false;
|
|
29424
|
+
}
|
|
29425
|
+
}
|
|
29426
|
+
}
|
|
29427
|
+
async runOnce() {
|
|
29428
|
+
const result = await this.updater.check();
|
|
29429
|
+
if (result.error) {
|
|
29430
|
+
this.logger.info(t("updater.check_error", { error: result.error }));
|
|
29431
|
+
return;
|
|
29432
|
+
}
|
|
29433
|
+
if (!result.updateAvailable || !result.latest)
|
|
29434
|
+
return;
|
|
29435
|
+
if (this.config.autoInstall && this.installEnabled) {
|
|
29436
|
+
this.logger.info(t("updater.installing", {
|
|
29437
|
+
current: result.current,
|
|
29438
|
+
latest: result.latest
|
|
29439
|
+
}));
|
|
29440
|
+
const install = await this.updater.install(result.latest);
|
|
29441
|
+
if (install.success) {
|
|
29442
|
+
this.logger.info(t("updater.installed", { current: result.current, latest: result.latest }));
|
|
29443
|
+
} else {
|
|
29444
|
+
this.logger.warn(t("updater.install_failed", {
|
|
29445
|
+
current: result.current,
|
|
29446
|
+
latest: result.latest,
|
|
29447
|
+
error: install.error ?? ""
|
|
29448
|
+
}));
|
|
29449
|
+
}
|
|
29450
|
+
} else {
|
|
29451
|
+
this.logger.info(t("updater.available", { current: result.current, latest: result.latest }));
|
|
29452
|
+
}
|
|
29453
|
+
}
|
|
29454
|
+
async checkOnce() {
|
|
29455
|
+
await this.runOnce();
|
|
29456
|
+
}
|
|
29457
|
+
}
|
|
29458
|
+
// src/cli/main.ts
|
|
29459
|
+
function readVersion5() {
|
|
29460
|
+
const here = dirname13(fileURLToPath5(import.meta.url));
|
|
29461
|
+
const candidates = [
|
|
29462
|
+
join40(here, "..", "..", "package.json"),
|
|
29463
|
+
join40(here, "..", "package.json")
|
|
29464
|
+
];
|
|
29465
|
+
for (const p of candidates) {
|
|
29466
|
+
if (existsSync46(p)) {
|
|
29467
|
+
try {
|
|
29468
|
+
const raw = JSON.parse(readFileSync32(p, "utf8"));
|
|
29469
|
+
if (raw.version)
|
|
29470
|
+
return raw.version;
|
|
29471
|
+
} catch {}
|
|
29472
|
+
}
|
|
29473
|
+
}
|
|
29474
|
+
return "0.0.0";
|
|
29475
|
+
}
|
|
29476
|
+
function startAutoUpdate(config) {
|
|
29477
|
+
try {
|
|
29478
|
+
const module = new UpdaterModule(config.updater, readVersion5(), "micro-models-agent");
|
|
29479
|
+
module.start();
|
|
29480
|
+
} catch {}
|
|
29481
|
+
}
|
|
29154
29482
|
async function main() {
|
|
29155
29483
|
const program2 = createProgram();
|
|
29156
29484
|
program2.parse(process.argv);
|
|
@@ -29167,6 +29495,7 @@ async function main() {
|
|
|
29167
29495
|
if (program2.args.length > 0) {
|
|
29168
29496
|
const prompt = program2.args.join(" ");
|
|
29169
29497
|
const { agent, config } = await bootstrap(undefined, projectDir, noAgentsMd, exitOnComplete);
|
|
29498
|
+
startAutoUpdate(config);
|
|
29170
29499
|
if (jsonMode) {
|
|
29171
29500
|
const result2 = await agent.run(prompt);
|
|
29172
29501
|
agent.shutdown();
|
|
@@ -29276,6 +29605,7 @@ async function main() {
|
|
|
29276
29605
|
baseDir,
|
|
29277
29606
|
logger
|
|
29278
29607
|
} = await bootstrap(undefined, projectDir, noAgentsMd, exitOnComplete);
|
|
29608
|
+
startAutoUpdate(config);
|
|
29279
29609
|
const repl = new Repl(agent, config, sessionManager, skillsModule, pluginManager, configDir, baseDir, noAgentsMd, logger);
|
|
29280
29610
|
repl.start();
|
|
29281
29611
|
}
|