micro-models-agent 0.51.1 → 0.52.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.
Files changed (107) hide show
  1. package/dist/cli/commands.js +162 -38
  2. package/dist/cli/completer.js +5 -5
  3. package/dist/cli/main.js +42 -54
  4. package/dist/cli/repl-commands.js +138 -38
  5. package/dist/cli/repl.js +175 -89
  6. package/dist/cli/run-result.js +11 -0
  7. package/dist/cli/security-commands.js +6 -6
  8. package/dist/cli/setup.js +21 -15
  9. package/dist/config/config.js +54 -27
  10. package/dist/config/defaults.js +17 -0
  11. package/dist/config/domains.js +179 -0
  12. package/dist/config/index.js +2 -1
  13. package/dist/config/security.js +28 -8
  14. package/dist/core/agent.js +162 -30
  15. package/dist/core/bootstrap.js +94 -17
  16. package/dist/core/crash-handler.js +51 -0
  17. package/dist/core/environment.js +199 -0
  18. package/dist/core/session-logger.js +60 -6
  19. package/dist/core/version.js +2 -0
  20. package/dist/i18n/en.json +120 -39
  21. package/dist/i18n/ru.json +91 -10
  22. package/dist/llm/openai-compat.js +191 -53
  23. package/dist/llm/orchestrator.js +5 -3
  24. package/dist/logger/app-logger.js +50 -4
  25. package/dist/main.js +1288 -635
  26. package/dist/modules/browser/session.js +4 -0
  27. package/dist/modules/certification/cli.js +58 -19
  28. package/dist/modules/certification/loader.js +2 -1
  29. package/dist/modules/certification/manifest.js +22 -14
  30. package/dist/modules/certification/runner.js +91 -5
  31. package/dist/modules/certification/scenarios.js +290 -7
  32. package/dist/modules/context/fact-extractor.js +6 -0
  33. package/dist/modules/context/manager.js +19 -2
  34. package/dist/modules/execution/audit-runners.js +61 -7
  35. package/dist/modules/execution/execution-plugin.js +219 -60
  36. package/dist/modules/execution/module.js +207 -18
  37. package/dist/modules/execution/moe-executor.js +33 -20
  38. package/dist/modules/execution/plan-store.js +39 -0
  39. package/dist/modules/execution/plan-tool.js +188 -19
  40. package/dist/modules/execution/planner.js +27 -23
  41. package/dist/modules/execution/stuck-detector.js +244 -8
  42. package/dist/modules/execution/tracker.js +8 -6
  43. package/dist/modules/execution/verifier.js +15 -2
  44. package/dist/modules/hallucination/detector.js +4 -0
  45. package/dist/modules/hallucination/factual.js +45 -5
  46. package/dist/modules/indexer/module.js +1 -0
  47. package/dist/modules/lsp/client.js +123 -12
  48. package/dist/modules/lsp/index.js +1 -1
  49. package/dist/modules/lsp/module.js +30 -2
  50. package/dist/modules/lsp/probe.js +11 -1
  51. package/dist/modules/lsp/startup-check.js +5 -2
  52. package/dist/modules/plugins/builtin/lint-on-write.js +144 -41
  53. package/dist/modules/plugins/manager.js +57 -13
  54. package/dist/modules/pricing/index.js +61 -0
  55. package/dist/modules/pricing/prices.js +129 -0
  56. package/dist/modules/providers/create.js +22 -0
  57. package/dist/modules/providers/fallback.js +79 -0
  58. package/dist/modules/providers/health.js +46 -0
  59. package/dist/modules/providers/index.js +5 -0
  60. package/dist/modules/providers/manager.js +161 -0
  61. package/dist/modules/providers/presets.js +128 -0
  62. package/dist/modules/providers/registry.js +22 -0
  63. package/dist/modules/providers/types.js +1 -0
  64. package/dist/modules/registry.js +1 -0
  65. package/dist/modules/security/command-validator.js +14 -0
  66. package/dist/modules/security/encryption.js +6 -6
  67. package/dist/modules/security/network-validator.js +17 -0
  68. package/dist/modules/security/path-validator.js +22 -26
  69. package/dist/modules/session/store.js +10 -10
  70. package/dist/tools/approve.js +1 -0
  71. package/dist/tools/attach-image.js +12 -0
  72. package/dist/tools/bash.js +27 -4
  73. package/dist/tools/browser.js +1 -0
  74. package/dist/tools/chunk-query.js +1 -0
  75. package/dist/tools/create-dir.js +1 -0
  76. package/dist/tools/delete-file.js +1 -0
  77. package/dist/tools/download-file.js +1 -0
  78. package/dist/tools/edit-file.js +2 -1
  79. package/dist/tools/enable-tools.js +1 -0
  80. package/dist/tools/executor.js +17 -7
  81. package/dist/tools/file-info.js +1 -0
  82. package/dist/tools/glob-tool.js +1 -0
  83. package/dist/tools/grep-tool.js +54 -13
  84. package/dist/tools/list-dir.js +1 -0
  85. package/dist/tools/load-skill.js +1 -0
  86. package/dist/tools/mcp-call.js +1 -0
  87. package/dist/tools/move-file.js +1 -0
  88. package/dist/tools/path-utils.js +51 -1
  89. package/dist/tools/pipeline-run.js +1 -0
  90. package/dist/tools/process-kill.js +11 -0
  91. package/dist/tools/process-list.js +1 -0
  92. package/dist/tools/process-log.js +9 -0
  93. package/dist/tools/question.js +1 -0
  94. package/dist/tools/read-file.js +94 -6
  95. package/dist/tools/recall.js +1 -0
  96. package/dist/tools/remember.js +1 -0
  97. package/dist/tools/scope-check.js +7 -5
  98. package/dist/tools/search-history.js +1 -0
  99. package/dist/tools/subagent.js +4 -4
  100. package/dist/tools/web-browse.js +1 -0
  101. package/dist/tools/web-fetch.js +27 -6
  102. package/dist/tools/web-search.js +70 -43
  103. package/dist/tools/write-file.js +1 -0
  104. package/dist/ui/line-editor.js +142 -23
  105. package/dist/ui/line-math.js +8 -4
  106. package/dist/ui/renderer.js +57 -7
  107. package/package.json +50 -48
@@ -1,4 +1,5 @@
1
1
  import { pc } from "../ui/colors";
2
+ import { readMmaVersion } from "../core/version";
2
3
  import { renderTable } from "../ui/table";
3
4
  import { t } from "../i18n/index";
4
5
  import { runSetup } from "./setup";
@@ -6,26 +7,8 @@ import { saveConfig } from "../config/config";
6
7
  import { getMessageText } from "../llm/provider";
7
8
  import { join, dirname } from "path";
8
9
  import { homedir } from "os";
9
- import { existsSync, readFileSync } from "fs";
10
- import { fileURLToPath } from "url";
11
- function readVersion() {
12
- const here = dirname(fileURLToPath(import.meta.url));
13
- const candidates = [join(here, "..", "..", "package.json"), join(here, "..", "package.json")];
14
- for (const p of candidates) {
15
- if (existsSync(p)) {
16
- try {
17
- const raw = JSON.parse(readFileSync(p, "utf8"));
18
- if (raw.version)
19
- return raw.version;
20
- }
21
- catch {
22
- // Broken package.json — fall through to the next candidate
23
- }
24
- }
25
- }
26
- return "0.0.0";
27
- }
28
- const version = readVersion();
10
+ import { existsSync } from "fs";
11
+ const version = readMmaVersion();
29
12
  export const COMMAND_GROUPS = {
30
13
  help: "general",
31
14
  exit: "general",
@@ -41,6 +24,7 @@ export const COMMAND_GROUPS = {
41
24
  reload: "agent",
42
25
  wizard: "agent",
43
26
  sysprompt: "agent",
27
+ lsp: "agent",
44
28
  sessions: "session",
45
29
  new: "session",
46
30
  resume: "session",
@@ -162,7 +146,14 @@ function registerMmaCommands(ctx) {
162
146
  const sys = Math.floor(ctxW * cfg.contextBudget.systemPrompt);
163
147
  const res = Math.floor(ctxW * cfg.contextBudget.responseReserve);
164
148
  console.log(`${t("repl.model")} ${cfg.model}`);
165
- console.log(`${t("repl.provider")} ${cfg.provider.type} → ${cfg.provider.baseUrl}`);
149
+ const providers = ctx.agent.listProviders();
150
+ const active = providers.find((p) => p.active);
151
+ if (active) {
152
+ console.log(`${t("repl.provider")} ${active.label} (${pc.dim(active.type)}) → ${pc.dim(active.baseUrl)}`);
153
+ }
154
+ else {
155
+ console.log(`${t("repl.provider")} ${cfg.provider.type} → ${cfg.provider.baseUrl}`);
156
+ }
166
157
  console.log(`${t("repl.context")} ${ctxW} (sys:${sys} res:${res} hist:${ctxW - sys - res})`);
167
158
  console.log(`${t("repl.max_iters")} ${cfg.maxToolIterations}`);
168
159
  console.log(`${t("repl.stuck_thresh")} ${cfg.stuckThreshold}`);
@@ -175,6 +166,31 @@ function registerMmaCommands(ctx) {
175
166
  }
176
167
  },
177
168
  });
169
+ ctx.registerCommand({
170
+ name: "config migrate",
171
+ description: t("cli.migrate_config"),
172
+ action: async () => {
173
+ const { hasDomainFiles } = await import("../config/domains");
174
+ const { loadConfig: loadCfg } = await import("../config/config");
175
+ const configDir = ctx.configDir;
176
+ const configPath = join(configDir, "config.json");
177
+ if (hasDomainFiles(configDir)) {
178
+ console.log(pc.yellow(t("config.migrate_no_legacy")));
179
+ return;
180
+ }
181
+ if (!existsSync(configPath)) {
182
+ console.log(pc.yellow(t("config.migrate_no_legacy")));
183
+ return;
184
+ }
185
+ console.log(t("config.migrate_start"));
186
+ const { config } = loadCfg({ configDir, projectConfigPath: join(configDir, ".mmrc") });
187
+ saveConfig(config, configPath, configDir);
188
+ const { renameSync, readdirSync } = await import("fs");
189
+ renameSync(configPath, configPath + ".bak");
190
+ const domainFiles = readdirSync(join(configDir, "config")).filter((f) => f.endsWith(".json"));
191
+ console.log(pc.green(t("config.migrate_done", { count: String(domainFiles.length) })));
192
+ },
193
+ });
178
194
  ctx.registerCommand({
179
195
  name: "reasoning",
180
196
  description: t("repl.reasoning"),
@@ -190,8 +206,15 @@ function registerMmaCommands(ctx) {
190
206
  description: t("repl.status"),
191
207
  usage: t("repl.status_usage"),
192
208
  action: () => {
209
+ const providers = ctx.agent.listProviders();
210
+ const active = providers.find((p) => p.active);
193
211
  console.log(`${t("repl.model")} ${ctx.config.model}`);
194
- console.log(`${t("repl.provider")} ${ctx.config.provider.type} @ ${ctx.config.provider.baseUrl}`);
212
+ if (active) {
213
+ console.log(`${t("repl.provider")} ${active.label} (${pc.dim(active.type)}) @ ${pc.dim(active.baseUrl)}`);
214
+ }
215
+ else {
216
+ console.log(`${t("repl.provider")} ${ctx.config.provider.type} @ ${ctx.config.provider.baseUrl}`);
217
+ }
195
218
  const meta = ctx.sessionManager?.getActiveMeta();
196
219
  if (meta) {
197
220
  console.log(`${t("repl.session_label")} ${meta.name} (${meta.id}) — ${meta.messageCount} messages`);
@@ -215,7 +238,7 @@ function registerMmaCommands(ctx) {
215
238
  ctx.config.contextWindow = answers.contextWindow;
216
239
  ctx.config.maxToolIterations = answers.maxToolIterations;
217
240
  ctx.config.locale = answers.locale;
218
- saveConfig(ctx.config, configPath);
241
+ saveConfig(ctx.config, configPath, dirname(configPath));
219
242
  await ctx.agent.reconfigure(ctx.config);
220
243
  console.log(pc.green(t("cli.config_saved")));
221
244
  });
@@ -248,8 +271,18 @@ function registerMmaCommands(ctx) {
248
271
  action: async (args) => {
249
272
  const subcmd = args[0];
250
273
  if (!subcmd || subcmd === "list") {
251
- console.log(`${t("repl.provider_current")} ${ctx.config.provider.type}`);
252
- console.log(` ${ctx.config.provider.baseUrl}`);
274
+ const providers = ctx.agent.listProviders();
275
+ if (providers.length === 0) {
276
+ console.log(`${t("repl.provider_current")} ${ctx.config.provider.type}`);
277
+ console.log(` ${ctx.config.provider.baseUrl}`);
278
+ }
279
+ else {
280
+ console.log(t("repl.provider_current"));
281
+ for (const p of providers) {
282
+ const marker = p.active ? pc.green("* ") : " ";
283
+ console.log(` ${marker}${p.label} (${pc.dim(p.type)}) ${pc.dim(p.baseUrl)}`);
284
+ }
285
+ }
253
286
  return;
254
287
  }
255
288
  if (subcmd === "use") {
@@ -258,11 +291,14 @@ function registerMmaCommands(ctx) {
258
291
  console.log(t("repl.provider_usage"));
259
292
  return;
260
293
  }
261
- ctx.config.provider.type = name;
262
- const configPath = join(homedir(), ".mma", "config.json");
263
- saveConfig(ctx.config, configPath);
264
- await ctx.agent.reconfigure(ctx.config);
265
- console.log(pc.green(t("repl.provider_set", { name })));
294
+ try {
295
+ await ctx.agent.setProvider(name);
296
+ ctx.refreshModelCache();
297
+ console.log(pc.green(t("repl.provider_set", { name })));
298
+ }
299
+ catch (e) {
300
+ console.log(pc.red(e.message));
301
+ }
266
302
  return;
267
303
  }
268
304
  console.log(t("repl.provider_usage"));
@@ -290,11 +326,12 @@ function registerMmaCommands(ctx) {
290
326
  const models = await provider.listModels();
291
327
  s.stop();
292
328
  if (models.length > 0) {
329
+ ctx.refreshModelCache();
293
330
  console.log(t("cli.available_models"));
294
331
  const { getCertMark } = await import("../modules/certification/manifest");
295
332
  for (const m of models) {
296
333
  const marker = m === ctx.config.model ? pc.green("* ") : " ";
297
- const mark = getCertMark(m, ctx.config.provider.baseUrl, version);
334
+ const mark = getCertMark(m, ctx.config.provider.baseUrl, version, process.cwd());
298
335
  const cert = mark === "certified"
299
336
  ? pc.green("✔")
300
337
  : mark === "stale"
@@ -322,7 +359,7 @@ function registerMmaCommands(ctx) {
322
359
  }
323
360
  ctx.config.model = name;
324
361
  const configPath = join(homedir(), ".mma", "config.json");
325
- saveConfig(ctx.config, configPath);
362
+ saveConfig(ctx.config, configPath, dirname(configPath));
326
363
  await ctx.agent.reconfigure(ctx.config);
327
364
  console.log(pc.green(t("repl.model_set", { name })));
328
365
  return;
@@ -347,7 +384,7 @@ function registerMmaCommands(ctx) {
347
384
  }
348
385
  ctx.config.contextWindow = size;
349
386
  const configPath = join(homedir(), ".mma", "config.json");
350
- saveConfig(ctx.config, configPath);
387
+ saveConfig(ctx.config, configPath, dirname(configPath));
351
388
  await ctx.agent.reconfigure(ctx.config);
352
389
  console.log(pc.green(t("cli.context_set", { size })));
353
390
  },
@@ -359,10 +396,6 @@ function registerMmaCommands(ctx) {
359
396
  action: async () => {
360
397
  console.log(pc.yellow(t("repl.reloading")));
361
398
  if (ctx.sessionManager && ctx.config.session.autoSave) {
362
- const active = ctx.sessionManager.getActiveMeta();
363
- if (active) {
364
- // Session is already auto-saved on each message
365
- }
366
399
  }
367
400
  ctx.agent.shutdown();
368
401
  const { loadConfig } = await import("../config/config");
@@ -371,7 +404,7 @@ function registerMmaCommands(ctx) {
371
404
  const configDir = ctx.configDir;
372
405
  const baseDir = ctx.baseDir;
373
406
  const projectConfigPath = join(baseDir, ".mmrc");
374
- const freshConfig = loadConfig({ configDir, projectConfigPath });
407
+ const { config: freshConfig } = loadConfig({ configDir, projectConfigPath });
375
408
  Object.assign(ctx.config, freshConfig);
376
409
  const { bootstrap } = await import("../core/bootstrap");
377
410
  const result = await bootstrap(configDir, baseDir, false, false);
@@ -421,6 +454,73 @@ function registerMmaCommands(ctx) {
421
454
  }
422
455
  },
423
456
  });
457
+ ctx.registerCommand({
458
+ name: "lsp",
459
+ description: t("repl.lsp"),
460
+ usage: t("repl.lsp_usage"),
461
+ action: async (args) => {
462
+ const subcommand = args[0] || "status";
463
+ // Access LSP module via the agent's module registry
464
+ const lspModule = ctx.agent.getModule("lsp");
465
+ if (!lspModule) {
466
+ console.log(pc.yellow(t("repl.lsp_not_available")));
467
+ return;
468
+ }
469
+ switch (subcommand) {
470
+ case "status": {
471
+ const disabled = lspModule.getDisabledServers();
472
+ const failures = lspModule.getFailureCounts();
473
+ const config = ctx.config.lsp;
474
+ console.log(pc.bold(t("repl.lsp_status_header")));
475
+ console.log(`${t("repl.lsp_enabled")} ${config?.enabled ? pc.green("yes") : pc.red("no")}`);
476
+ if (disabled.length > 0) {
477
+ console.log(pc.yellow(`${t("repl.lsp_disabled_servers")} ${disabled.join(", ")}`));
478
+ }
479
+ if (failures.size > 0) {
480
+ console.log(pc.dim(t("repl.lsp_failure_counts")));
481
+ for (const [server, count] of failures) {
482
+ console.log(pc.dim(` ${server}: ${count}`));
483
+ }
484
+ }
485
+ if (disabled.length === 0 && failures.size === 0) {
486
+ console.log(pc.green(t("repl.lsp_all_ok")));
487
+ }
488
+ break;
489
+ }
490
+ case "restart": {
491
+ console.log(pc.yellow(t("repl.lsp_restarting")));
492
+ lspModule.resetDisabledServers();
493
+ console.log(pc.green(t("repl.lsp_restarted")));
494
+ break;
495
+ }
496
+ case "check": {
497
+ const path = args[1];
498
+ if (!path) {
499
+ console.log(pc.yellow(t("repl.lsp_check_usage")));
500
+ return;
501
+ }
502
+ console.log(pc.dim(t("repl.lsp_checking", { path })));
503
+ // Run lsp_check tool via the agent's tool executor
504
+ try {
505
+ const result = await ctx.agent.deps?.toolExecutor?.execute("lsp_check", { path }, ctx.agent.deps?.toolCtx);
506
+ if (result?.output) {
507
+ console.log(result.output);
508
+ }
509
+ }
510
+ catch (e) {
511
+ console.log(pc.red(t("repl.lsp_check_error", {
512
+ error: e instanceof Error ? e.message : String(e),
513
+ })));
514
+ }
515
+ break;
516
+ }
517
+ default: {
518
+ console.log(pc.dim(t("repl.lsp_usage")));
519
+ break;
520
+ }
521
+ }
522
+ },
523
+ });
424
524
  }
425
525
  function registerSessionCommands(ctx) {
426
526
  if (!ctx.sessionManager)