micro-models-agent 0.29.1 → 0.30.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 +272 -22
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -2263,7 +2263,13 @@ var init_defaults = __esm(() => {
|
|
|
2263
2263
|
stableSystemPrompt: true,
|
|
2264
2264
|
maxParallelChunkQueries: 4
|
|
2265
2265
|
},
|
|
2266
|
-
lsp: DEFAULT_LSP_CONFIG
|
|
2266
|
+
lsp: DEFAULT_LSP_CONFIG,
|
|
2267
|
+
updater: {
|
|
2268
|
+
enabled: true,
|
|
2269
|
+
checkOnStart: true,
|
|
2270
|
+
autoInstall: true,
|
|
2271
|
+
intervalMs: 0
|
|
2272
|
+
}
|
|
2267
2273
|
};
|
|
2268
2274
|
});
|
|
2269
2275
|
|
|
@@ -2304,6 +2310,7 @@ var init_en = __esm(() => {
|
|
|
2304
2310
|
"error.response_blocked": "Response blocked: {reason}",
|
|
2305
2311
|
"error.max_iters": "Max iterations ({max}) reached",
|
|
2306
2312
|
"error.empty_response": "Model returned an empty response after retries",
|
|
2313
|
+
"error.audit_failed": "Task could not be verified as complete: {summary}",
|
|
2307
2314
|
"error.grep_failed": "Grep failed: {message}",
|
|
2308
2315
|
"error.search_failed": "Search failed: {message}",
|
|
2309
2316
|
"error.fetch_failed": "Fetch failed: {message}",
|
|
@@ -2448,6 +2455,8 @@ Command: {command}`,
|
|
|
2448
2455
|
"plan.step_status": "Step {step}: {status}",
|
|
2449
2456
|
"plan.no_active": "No active plan",
|
|
2450
2457
|
"plan.step_not_found": "Step not found",
|
|
2458
|
+
"plan.step_already_done": "Step {step} is already marked done. Stop re-marking it — either continue with the next step or investigate why progress appears stuck.",
|
|
2459
|
+
"plan.order_blocked": 'Cannot mark step {step} done: step {first} ("{desc}") is not finished yet. Complete earlier steps first, or mark step {first} status=skipped if it is not needed.',
|
|
2451
2460
|
"plan.show_header": "Plan status:",
|
|
2452
2461
|
"plan.show_empty": "(plan has no steps)",
|
|
2453
2462
|
"plan.list_header": "Plans:",
|
|
@@ -2829,8 +2838,13 @@ Use this knowledge to answer the user's question.`,
|
|
|
2829
2838
|
"ctx.compactions": "compactions: {count}",
|
|
2830
2839
|
"ctx.quality": "quality: {percent}%",
|
|
2831
2840
|
"ctx.delta_pos": "ctx +{tokens}",
|
|
2832
|
-
"ctx.delta_neg": "ctx -{tokens}
|
|
2833
|
-
"ctx.delta_zero": "ctx
|
|
2841
|
+
"ctx.delta_neg": "ctx -{tokens} ",
|
|
2842
|
+
"ctx.delta_zero": "ctx +0",
|
|
2843
|
+
"updater.check_error": "[updater] update check failed: {error}",
|
|
2844
|
+
"updater.available": "[updater] Update available: {current} → {latest}. Run `npm install -g micro-models-agent` to upgrade.",
|
|
2845
|
+
"updater.installing": "[updater] Installing {latest} globally (current: {current})…",
|
|
2846
|
+
"updater.installed": "[updater] Installed {latest}. Restart MMA to use it (was {current}).",
|
|
2847
|
+
"updater.install_failed": "[updater] Failed to install {latest}: {error}. Update manually with `npm install -g micro-models-agent`."
|
|
2834
2848
|
};
|
|
2835
2849
|
});
|
|
2836
2850
|
|
|
@@ -2870,6 +2884,7 @@ var init_ru = __esm(() => {
|
|
|
2870
2884
|
"error.response_blocked": "Ответ заблокирован: {reason}",
|
|
2871
2885
|
"error.max_iters": "Достигнут максимум итераций ({max})",
|
|
2872
2886
|
"error.empty_response": "Модель вернула пустой ответ после повторных попыток",
|
|
2887
|
+
"error.audit_failed": "Задача не может быть подтверждена как выполненная: {summary}",
|
|
2873
2888
|
"error.grep_failed": "Ошибка grep: {message}",
|
|
2874
2889
|
"error.search_failed": "Ошибка поиска: {message}",
|
|
2875
2890
|
"error.fetch_failed": "Ошибка загрузки: {message}",
|
|
@@ -3013,6 +3028,8 @@ var init_ru = __esm(() => {
|
|
|
3013
3028
|
"plan.step_status": "Шаг {step}: {status}",
|
|
3014
3029
|
"plan.no_active": "Нет активного плана",
|
|
3015
3030
|
"plan.step_not_found": "Шаг не найден",
|
|
3031
|
+
"plan.step_already_done": "Шаг {step} уже отмечен выполненным. Прекратите повторную отметку — переходите к следующему шагу или выясните, почему прогресс заблокирован.",
|
|
3032
|
+
"plan.order_blocked": "Нельзя отметить шаг {step} выполненным: шаг {first} («{desc}») ещё не завершён. Сначала завершите предыдущие шаги или отметьте шаг {first} status=skipped, если он не нужен.",
|
|
3016
3033
|
"plan.show_header": "Статус плана:",
|
|
3017
3034
|
"plan.show_empty": "(в плане нет шагов)",
|
|
3018
3035
|
"plan.list_header": "Планы:",
|
|
@@ -3397,7 +3414,12 @@ var init_ru = __esm(() => {
|
|
|
3397
3414
|
"ctx.delta_neg": "контекст -{tokens} ↓",
|
|
3398
3415
|
"ctx.delta_zero": "контекст ±0",
|
|
3399
3416
|
"file.notfound_resolved": "Файл не найден: {path} (резолвится в {resolved})",
|
|
3400
|
-
"bash.echo_write_blocked": "Запись файлов через echo/printf ненадёжна в Windows cmd.exe (кавычки и многострочность ломаются). Используй инструмент write_file вместо этого (цель: {path})."
|
|
3417
|
+
"bash.echo_write_blocked": "Запись файлов через echo/printf ненадёжна в Windows cmd.exe (кавычки и многострочность ломаются). Используй инструмент write_file вместо этого (цель: {path}).",
|
|
3418
|
+
"updater.check_error": "[updater] Ошибка проверки обновления: {error}",
|
|
3419
|
+
"updater.available": "[updater] Доступно обновление: {current} → {latest}. Выполните `npm install -g micro-models-agent` для обновления.",
|
|
3420
|
+
"updater.installing": "[updater] Установка {latest} глобально (текущая: {current})…",
|
|
3421
|
+
"updater.installed": "[updater] Установлена {latest}. Перезапустите MMA для применения (была {current}).",
|
|
3422
|
+
"updater.install_failed": "[updater] Не удалось установить {latest}: {error}. Обновите вручную: `npm install -g micro-models-agent`."
|
|
3401
3423
|
};
|
|
3402
3424
|
});
|
|
3403
3425
|
|
|
@@ -7469,7 +7491,7 @@ function emptyCliRunHint(command, output, code) {
|
|
|
7469
7491
|
return null;
|
|
7470
7492
|
return "the command exited 0 but printed NOTHING to stdout. If this should run a CLI program, the file probably has no entry point: read it with read_file and check the code actually calls its main function with command-line arguments (e.g. main(process.argv[2])) and prints results with console.log.";
|
|
7471
7493
|
}
|
|
7472
|
-
var BASH_GRACE_MS = 5000, SPAWN_SETTLE_MS = 100, bashGraceMs, UNIX_TO_WIN_HINTS, UNIX_TO_WIN_TRANSLATE, NEVER_TOOL_CALLS, CLI_FILE_RUN_RE, bashTool;
|
|
7494
|
+
var BASH_GRACE_MS = 5000, SPAWN_SETTLE_MS = 100, bashGraceMs, FAILING_FIRST_WORDS, HARD_BLOCK_THRESHOLD = 3, UNIX_TO_WIN_HINTS, UNIX_TO_WIN_TRANSLATE, NEVER_TOOL_CALLS, CLI_FILE_RUN_RE, bashTool;
|
|
7473
7495
|
var init_bash = __esm(() => {
|
|
7474
7496
|
init_command_validator();
|
|
7475
7497
|
init_audit_log();
|
|
@@ -7478,6 +7500,7 @@ var init_bash = __esm(() => {
|
|
|
7478
7500
|
init_processes();
|
|
7479
7501
|
init_i18n();
|
|
7480
7502
|
bashGraceMs = BASH_GRACE_MS;
|
|
7503
|
+
FAILING_FIRST_WORDS = new Map;
|
|
7481
7504
|
UNIX_TO_WIN_HINTS = {
|
|
7482
7505
|
ls: "Use the list_dir tool instead.",
|
|
7483
7506
|
pwd: "Use the file_info tool instead.",
|
|
@@ -7629,13 +7652,22 @@ ${output2}`;
|
|
|
7629
7652
|
if (!output2 && code !== 0) {
|
|
7630
7653
|
output2 = `(exit code ${code})`;
|
|
7631
7654
|
}
|
|
7632
|
-
if (platform2() === "win32"
|
|
7655
|
+
if (platform2() === "win32") {
|
|
7633
7656
|
const firstWord = command.trim().split(/\s+/)[0]?.split(/[\\/]/).pop();
|
|
7634
|
-
|
|
7635
|
-
|
|
7636
|
-
|
|
7657
|
+
if (firstWord && firstWord in UNIX_TO_WIN_HINTS) {
|
|
7658
|
+
if (code === 0) {
|
|
7659
|
+
FAILING_FIRST_WORDS.delete(firstWord);
|
|
7660
|
+
} else {
|
|
7661
|
+
const failures = (FAILING_FIRST_WORDS.get(firstWord) || 0) + 1;
|
|
7662
|
+
FAILING_FIRST_WORDS.set(firstWord, failures);
|
|
7663
|
+
if (failures >= HARD_BLOCK_THRESHOLD) {
|
|
7664
|
+
output2 = `STOP using "${firstWord}" — it does not work in this cmd.exe shell and has failed ${failures} times in a row. ${UNIX_TO_WIN_HINTS[firstWord]}`;
|
|
7665
|
+
} else {
|
|
7666
|
+
output2 = `${output2}
|
|
7637
7667
|
|
|
7638
|
-
Hint: "${firstWord}" may not work on Windows. ${
|
|
7668
|
+
Hint: "${firstWord}" may not work on Windows. ${UNIX_TO_WIN_HINTS[firstWord]}`;
|
|
7669
|
+
}
|
|
7670
|
+
}
|
|
7639
7671
|
}
|
|
7640
7672
|
}
|
|
7641
7673
|
if (securityConfig?.logCommands) {
|
|
@@ -10392,6 +10424,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
10392
10424
|
this.abortController = new AbortController;
|
|
10393
10425
|
let iteration = 0;
|
|
10394
10426
|
let lastText = "";
|
|
10427
|
+
let lastForcedCompactionIteration = -FORCED_COMPACTION_COOLDOWN;
|
|
10395
10428
|
let hallucinationRetries = 0;
|
|
10396
10429
|
let lastToolSignature = "";
|
|
10397
10430
|
let apiPromptTokens = 0;
|
|
@@ -10405,6 +10438,8 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
10405
10438
|
let emptyResponseRetries = 0;
|
|
10406
10439
|
const MAX_EMPTY_RESPONSE_RETRIES = 2;
|
|
10407
10440
|
let emptyResponseExhausted = false;
|
|
10441
|
+
let auditFailed = false;
|
|
10442
|
+
let lastAuditSummary = "";
|
|
10408
10443
|
let repeatedToolCount = 0;
|
|
10409
10444
|
const MAX_REPEATED_TOOL_CALLS = 2;
|
|
10410
10445
|
const allToolsForBudget = toolExecutor.getToolDefinitions(this.deps.toolTags);
|
|
@@ -10431,7 +10466,8 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
10431
10466
|
const currentTokens = contextManager.getEstimatedTokens();
|
|
10432
10467
|
const budget2 = contextManager.getBudget();
|
|
10433
10468
|
const quality = contextManager.getQuality();
|
|
10434
|
-
if (quality < QUALITY_TRIGGER_THRESHOLD && contextManager.getCompactionCount() > 0) {
|
|
10469
|
+
if (quality < QUALITY_TRIGGER_THRESHOLD && contextManager.getCompactionCount() > 0 && iteration - lastForcedCompactionIteration >= FORCED_COMPACTION_COOLDOWN) {
|
|
10470
|
+
lastForcedCompactionIteration = iteration;
|
|
10435
10471
|
contextManager.compact();
|
|
10436
10472
|
logger.warn(`Low context quality (${quality}%) — forced compaction`);
|
|
10437
10473
|
slog.logCompaction(`quality-triggered compaction (${quality}% < ${QUALITY_TRIGGER_THRESHOLD}%), iteration ${iteration}`, iteration, currentTokens, budget2.history);
|
|
@@ -10794,8 +10830,10 @@ ${warnLine}
|
|
|
10794
10830
|
});
|
|
10795
10831
|
slog.logAudit(audit.summary, iteration);
|
|
10796
10832
|
auditRetries++;
|
|
10833
|
+
lastAuditSummary = audit.summary;
|
|
10797
10834
|
if (auditRetries >= MAX_AUDIT_RETRIES || iteration >= config.maxToolIterations - 1) {
|
|
10798
|
-
logger.warn(`Final audit still incomplete after ${auditRetries} retries —
|
|
10835
|
+
logger.warn(`Final audit still incomplete after ${auditRetries} retries — reporting failure`);
|
|
10836
|
+
auditFailed = true;
|
|
10799
10837
|
break;
|
|
10800
10838
|
}
|
|
10801
10839
|
continue;
|
|
@@ -10823,9 +10861,9 @@ ${warnLine}
|
|
|
10823
10861
|
};
|
|
10824
10862
|
}
|
|
10825
10863
|
return {
|
|
10826
|
-
success: emptyResponseExhausted ? false : true,
|
|
10864
|
+
success: emptyResponseExhausted || auditFailed ? false : true,
|
|
10827
10865
|
text: lastText,
|
|
10828
|
-
error: emptyResponseExhausted ? t("error.empty_response") : undefined,
|
|
10866
|
+
error: emptyResponseExhausted ? t("error.empty_response") : auditFailed ? t("error.audit_failed", { summary: lastAuditSummary }) : undefined,
|
|
10829
10867
|
iterationCount: iteration,
|
|
10830
10868
|
contextUsed: tokensUsed,
|
|
10831
10869
|
contextLimit: budget.history,
|
|
@@ -10890,7 +10928,7 @@ ${warnLine}
|
|
|
10890
10928
|
});
|
|
10891
10929
|
}
|
|
10892
10930
|
}
|
|
10893
|
-
var TOOL_RESULT_MAX_TOKENS_RATIO = 0.3, TOOL_RESULT_ABSOLUTE_MAX_CHARS = 15000, QUALITY_TRIGGER_THRESHOLD = 40;
|
|
10931
|
+
var TOOL_RESULT_MAX_TOKENS_RATIO = 0.3, TOOL_RESULT_ABSOLUTE_MAX_CHARS = 15000, QUALITY_TRIGGER_THRESHOLD = 40, FORCED_COMPACTION_COOLDOWN = 3;
|
|
10894
10932
|
var init_agent = __esm(() => {
|
|
10895
10933
|
init_i18n();
|
|
10896
10934
|
init_colors();
|
|
@@ -10993,7 +11031,8 @@ class ContextManager {
|
|
|
10993
11031
|
getQuality() {
|
|
10994
11032
|
const usedTokens = this.getEstimatedTokens();
|
|
10995
11033
|
const tokenLoad = Math.max(0, 1 - usedTokens / this.budget.history);
|
|
10996
|
-
const
|
|
11034
|
+
const COMPACTION_PENALTY_FLOOR = 0.5;
|
|
11035
|
+
const compactionLoss = Math.max(COMPACTION_PENALTY_FLOOR, 1 - this.compactionCount * 0.15);
|
|
10997
11036
|
const msgCount = this.messages.length || 1;
|
|
10998
11037
|
const errorDensity = Math.max(0, 1 - Math.min(1, this.errorFacts.length / msgCount));
|
|
10999
11038
|
const freshness = Math.max(0, 1 - this.iterationsSinceCompaction / COMPACTION_INTERVAL);
|
|
@@ -11139,6 +11178,9 @@ ${lines.join(`
|
|
|
11139
11178
|
const newErrors = [];
|
|
11140
11179
|
for (const msg of turns) {
|
|
11141
11180
|
const content = getMessageText(msg.content);
|
|
11181
|
+
if (msg.role === "user" && (content.startsWith("<system-summary>") || content.includes("[Compressed:"))) {
|
|
11182
|
+
continue;
|
|
11183
|
+
}
|
|
11142
11184
|
if (msg.role === "tool") {
|
|
11143
11185
|
for (const pattern of filePatterns) {
|
|
11144
11186
|
for (const match of content.matchAll(pattern)) {
|
|
@@ -15592,7 +15634,34 @@ ${display}`,
|
|
|
15592
15634
|
};
|
|
15593
15635
|
}
|
|
15594
15636
|
if (action === "update" && args.step && this.tracker) {
|
|
15595
|
-
|
|
15637
|
+
const stepId = Number(args.step);
|
|
15638
|
+
const target = this.tracker.getStep(stepId);
|
|
15639
|
+
if (!target) {
|
|
15640
|
+
return { success: false, output: t("plan.step_not_found") };
|
|
15641
|
+
}
|
|
15642
|
+
const status = String(args.status || "done");
|
|
15643
|
+
if (status === "done" && target.status === "done") {
|
|
15644
|
+
return {
|
|
15645
|
+
success: false,
|
|
15646
|
+
output: t("plan.step_already_done", {
|
|
15647
|
+
step: String(stepId)
|
|
15648
|
+
})
|
|
15649
|
+
};
|
|
15650
|
+
}
|
|
15651
|
+
if (status === "done") {
|
|
15652
|
+
const blockers = this.tracker.getPlan().steps.filter((s) => s.id < stepId && s.status !== "done" && s.status !== "skipped");
|
|
15653
|
+
if (blockers.length > 0) {
|
|
15654
|
+
return {
|
|
15655
|
+
success: false,
|
|
15656
|
+
output: t("plan.order_blocked", {
|
|
15657
|
+
step: String(stepId),
|
|
15658
|
+
first: String(blockers[0].id),
|
|
15659
|
+
desc: blockers[0].description
|
|
15660
|
+
})
|
|
15661
|
+
};
|
|
15662
|
+
}
|
|
15663
|
+
}
|
|
15664
|
+
this.tracker.updateStepStatus(stepId, status);
|
|
15596
15665
|
if (args.note)
|
|
15597
15666
|
this.tracker.addNote(Number(args.step), String(args.note));
|
|
15598
15667
|
this.tracker.syncCurrentStep();
|
|
@@ -17016,8 +17085,8 @@ class LspClient {
|
|
|
17016
17085
|
}
|
|
17017
17086
|
});
|
|
17018
17087
|
return await diagPromise;
|
|
17019
|
-
} catch {
|
|
17020
|
-
|
|
17088
|
+
} catch (e) {
|
|
17089
|
+
throw e instanceof Error ? e : new Error(String(e));
|
|
17021
17090
|
} finally {
|
|
17022
17091
|
await this.shutdown();
|
|
17023
17092
|
}
|
|
@@ -17249,7 +17318,15 @@ ${items}`;
|
|
|
17249
17318
|
[LSP warnings]:
|
|
17250
17319
|
${items}`;
|
|
17251
17320
|
}
|
|
17252
|
-
} catch {
|
|
17321
|
+
} catch (e) {
|
|
17322
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
17323
|
+
try {
|
|
17324
|
+
_ctx.logger?.warn(`LSP check failed for ${filePath}: ${msg}`);
|
|
17325
|
+
} catch {}
|
|
17326
|
+
result.output += `
|
|
17327
|
+
|
|
17328
|
+
[LSP check failed]: ${msg}`;
|
|
17329
|
+
}
|
|
17253
17330
|
}
|
|
17254
17331
|
};
|
|
17255
17332
|
}
|
|
@@ -29087,9 +29164,180 @@ init_setup();
|
|
|
29087
29164
|
init_config2();
|
|
29088
29165
|
init_i18n();
|
|
29089
29166
|
init_colors();
|
|
29090
|
-
import { existsSync as existsSync46 } from "fs";
|
|
29091
|
-
import { join as join40 } from "path";
|
|
29167
|
+
import { existsSync as existsSync46, readFileSync as readFileSync32 } from "fs";
|
|
29168
|
+
import { join as join40, dirname as dirname13 } from "path";
|
|
29092
29169
|
import { homedir as homedir18 } from "os";
|
|
29170
|
+
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
29171
|
+
|
|
29172
|
+
// src/modules/updater/checker.ts
|
|
29173
|
+
var defaultRunner2 = async (command, args, options) => {
|
|
29174
|
+
const { execFile } = await import("child_process");
|
|
29175
|
+
return new Promise((resolve23) => {
|
|
29176
|
+
execFile(command, args, options, (err) => resolve23({ error: err?.message }));
|
|
29177
|
+
});
|
|
29178
|
+
};
|
|
29179
|
+
|
|
29180
|
+
class Updater {
|
|
29181
|
+
currentVersion;
|
|
29182
|
+
packageName;
|
|
29183
|
+
runner;
|
|
29184
|
+
constructor(currentVersion, packageName, runner) {
|
|
29185
|
+
this.currentVersion = currentVersion;
|
|
29186
|
+
this.packageName = packageName;
|
|
29187
|
+
this.runner = runner ?? defaultRunner2;
|
|
29188
|
+
}
|
|
29189
|
+
getCurrentVersion() {
|
|
29190
|
+
return this.currentVersion;
|
|
29191
|
+
}
|
|
29192
|
+
getPackageName() {
|
|
29193
|
+
return this.packageName;
|
|
29194
|
+
}
|
|
29195
|
+
async check() {
|
|
29196
|
+
try {
|
|
29197
|
+
const response = await fetch(`https://registry.npmjs.org/${this.packageName}`, {
|
|
29198
|
+
headers: { Accept: "application/vnd.npm.install-v1+json" },
|
|
29199
|
+
signal: AbortSignal.timeout(5000)
|
|
29200
|
+
});
|
|
29201
|
+
if (!response.ok) {
|
|
29202
|
+
return { updateAvailable: false, current: this.currentVersion, error: `HTTP ${response.status}` };
|
|
29203
|
+
}
|
|
29204
|
+
const data = await response.json();
|
|
29205
|
+
const latest = data["dist-tags"]?.latest;
|
|
29206
|
+
if (!latest) {
|
|
29207
|
+
return { updateAvailable: false, current: this.currentVersion, error: "No latest tag" };
|
|
29208
|
+
}
|
|
29209
|
+
const updateAvailable = latest !== this.currentVersion;
|
|
29210
|
+
return { updateAvailable, current: this.currentVersion, latest };
|
|
29211
|
+
} catch (e) {
|
|
29212
|
+
return { updateAvailable: false, current: this.currentVersion, error: e.message };
|
|
29213
|
+
}
|
|
29214
|
+
}
|
|
29215
|
+
async install(latest) {
|
|
29216
|
+
try {
|
|
29217
|
+
const res = await this.runner("npm", ["install", "-g", `${this.packageName}@${latest}`], {
|
|
29218
|
+
timeout: 120000,
|
|
29219
|
+
windowsHide: true
|
|
29220
|
+
});
|
|
29221
|
+
if (res.error)
|
|
29222
|
+
return { success: false, error: res.error };
|
|
29223
|
+
return { success: true, installed: latest };
|
|
29224
|
+
} catch (e) {
|
|
29225
|
+
const msg = e?.message ?? String(e);
|
|
29226
|
+
return { success: false, error: msg.split(`
|
|
29227
|
+
`)[0] };
|
|
29228
|
+
}
|
|
29229
|
+
}
|
|
29230
|
+
}
|
|
29231
|
+
// src/modules/updater/module.ts
|
|
29232
|
+
init_i18n();
|
|
29233
|
+
init_colors();
|
|
29234
|
+
|
|
29235
|
+
class UpdaterModule {
|
|
29236
|
+
name = "updater";
|
|
29237
|
+
updater;
|
|
29238
|
+
config;
|
|
29239
|
+
logger;
|
|
29240
|
+
started = false;
|
|
29241
|
+
timer = null;
|
|
29242
|
+
installEnabled = true;
|
|
29243
|
+
constructor(config, currentVersion, packageName, logger, installRunner) {
|
|
29244
|
+
this.config = config;
|
|
29245
|
+
this.updater = new Updater(currentVersion, packageName, installRunner);
|
|
29246
|
+
this.logger = logger ?? {
|
|
29247
|
+
info: () => {},
|
|
29248
|
+
warn: (m) => console.warn(pc2.yellow(m)),
|
|
29249
|
+
error: (m) => console.error(pc2.red(m))
|
|
29250
|
+
};
|
|
29251
|
+
}
|
|
29252
|
+
setInstallEnabled(enabled2) {
|
|
29253
|
+
this.installEnabled = enabled2;
|
|
29254
|
+
}
|
|
29255
|
+
getUpdater() {
|
|
29256
|
+
return this.updater;
|
|
29257
|
+
}
|
|
29258
|
+
isStarted() {
|
|
29259
|
+
return this.started;
|
|
29260
|
+
}
|
|
29261
|
+
start() {
|
|
29262
|
+
if (this.started || !this.config.enabled)
|
|
29263
|
+
return;
|
|
29264
|
+
this.started = true;
|
|
29265
|
+
this.runLoop();
|
|
29266
|
+
}
|
|
29267
|
+
stop() {
|
|
29268
|
+
this.started = false;
|
|
29269
|
+
if (this.timer) {
|
|
29270
|
+
clearTimeout(this.timer);
|
|
29271
|
+
this.timer = null;
|
|
29272
|
+
}
|
|
29273
|
+
}
|
|
29274
|
+
async runLoop() {
|
|
29275
|
+
while (this.started) {
|
|
29276
|
+
await this.checkOnce();
|
|
29277
|
+
if (!this.started)
|
|
29278
|
+
return;
|
|
29279
|
+
if (this.config.intervalMs > 0) {
|
|
29280
|
+
await new Promise((r) => this.timer = setTimeout(r, this.config.intervalMs));
|
|
29281
|
+
} else {
|
|
29282
|
+
this.started = false;
|
|
29283
|
+
}
|
|
29284
|
+
}
|
|
29285
|
+
}
|
|
29286
|
+
async runOnce() {
|
|
29287
|
+
const result = await this.updater.check();
|
|
29288
|
+
if (result.error) {
|
|
29289
|
+
this.logger.info(t("updater.check_error", { error: result.error }));
|
|
29290
|
+
return;
|
|
29291
|
+
}
|
|
29292
|
+
if (!result.updateAvailable || !result.latest)
|
|
29293
|
+
return;
|
|
29294
|
+
if (this.config.autoInstall && this.installEnabled) {
|
|
29295
|
+
this.logger.info(t("updater.installing", {
|
|
29296
|
+
current: result.current,
|
|
29297
|
+
latest: result.latest
|
|
29298
|
+
}));
|
|
29299
|
+
const install = await this.updater.install(result.latest);
|
|
29300
|
+
if (install.success) {
|
|
29301
|
+
this.logger.info(t("updater.installed", { current: result.current, latest: result.latest }));
|
|
29302
|
+
} else {
|
|
29303
|
+
this.logger.warn(t("updater.install_failed", {
|
|
29304
|
+
current: result.current,
|
|
29305
|
+
latest: result.latest,
|
|
29306
|
+
error: install.error ?? ""
|
|
29307
|
+
}));
|
|
29308
|
+
}
|
|
29309
|
+
} else {
|
|
29310
|
+
this.logger.info(t("updater.available", { current: result.current, latest: result.latest }));
|
|
29311
|
+
}
|
|
29312
|
+
}
|
|
29313
|
+
async checkOnce() {
|
|
29314
|
+
await this.runOnce();
|
|
29315
|
+
}
|
|
29316
|
+
}
|
|
29317
|
+
// src/cli/main.ts
|
|
29318
|
+
function readVersion5() {
|
|
29319
|
+
const here = dirname13(fileURLToPath5(import.meta.url));
|
|
29320
|
+
const candidates = [
|
|
29321
|
+
join40(here, "..", "..", "package.json"),
|
|
29322
|
+
join40(here, "..", "package.json")
|
|
29323
|
+
];
|
|
29324
|
+
for (const p of candidates) {
|
|
29325
|
+
if (existsSync46(p)) {
|
|
29326
|
+
try {
|
|
29327
|
+
const raw = JSON.parse(readFileSync32(p, "utf8"));
|
|
29328
|
+
if (raw.version)
|
|
29329
|
+
return raw.version;
|
|
29330
|
+
} catch {}
|
|
29331
|
+
}
|
|
29332
|
+
}
|
|
29333
|
+
return "0.0.0";
|
|
29334
|
+
}
|
|
29335
|
+
function startAutoUpdate(config) {
|
|
29336
|
+
try {
|
|
29337
|
+
const module = new UpdaterModule(config.updater, readVersion5(), "micro-models-agent");
|
|
29338
|
+
module.start();
|
|
29339
|
+
} catch {}
|
|
29340
|
+
}
|
|
29093
29341
|
async function main() {
|
|
29094
29342
|
const program2 = createProgram();
|
|
29095
29343
|
program2.parse(process.argv);
|
|
@@ -29106,6 +29354,7 @@ async function main() {
|
|
|
29106
29354
|
if (program2.args.length > 0) {
|
|
29107
29355
|
const prompt = program2.args.join(" ");
|
|
29108
29356
|
const { agent, config } = await bootstrap(undefined, projectDir, noAgentsMd, exitOnComplete);
|
|
29357
|
+
startAutoUpdate(config);
|
|
29109
29358
|
if (jsonMode) {
|
|
29110
29359
|
const result2 = await agent.run(prompt);
|
|
29111
29360
|
agent.shutdown();
|
|
@@ -29215,6 +29464,7 @@ async function main() {
|
|
|
29215
29464
|
baseDir,
|
|
29216
29465
|
logger
|
|
29217
29466
|
} = await bootstrap(undefined, projectDir, noAgentsMd, exitOnComplete);
|
|
29467
|
+
startAutoUpdate(config);
|
|
29218
29468
|
const repl = new Repl(agent, config, sessionManager, skillsModule, pluginManager, configDir, baseDir, noAgentsMd, logger);
|
|
29219
29469
|
repl.start();
|
|
29220
29470
|
}
|