micro-models-agent 0.28.17 → 0.29.1

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 (94) hide show
  1. package/dist/cli/commands.js +3 -116
  2. package/dist/cli/main.js +8 -35
  3. package/dist/cli/repl.js +611 -110
  4. package/dist/cli/setup.js +12 -32
  5. package/dist/config/config.js +30 -46
  6. package/dist/config/defaults.js +1 -10
  7. package/dist/config/security.js +8 -15
  8. package/dist/core/agent-moe.js +12 -24
  9. package/dist/core/agent.js +47 -281
  10. package/dist/core/bootstrap.js +36 -52
  11. package/dist/core/session-logger.js +2 -35
  12. package/dist/i18n/en.json +15 -79
  13. package/dist/i18n/index.js +9 -12
  14. package/dist/i18n/ru.json +15 -79
  15. package/dist/index.js +13 -13
  16. package/dist/llm/openai-compat.js +10 -39
  17. package/dist/logger/app-logger.js +16 -83
  18. package/dist/main.js +625 -243
  19. package/dist/modules/browser/session.js +60 -108
  20. package/dist/modules/context/history.js +15 -0
  21. package/dist/modules/context/manager.js +10 -119
  22. package/dist/modules/execution/auditor.js +39 -33
  23. package/dist/modules/execution/index.js +6 -8
  24. package/dist/modules/execution/module.js +32 -474
  25. package/dist/modules/execution/moe-executor.js +40 -97
  26. package/dist/modules/execution/planner.js +13 -63
  27. package/dist/modules/execution/stuck-detector.js +39 -252
  28. package/dist/modules/execution/tracker.js +7 -21
  29. package/dist/modules/execution/verifier.js +17 -46
  30. package/dist/modules/hallucination/confidence.js +2 -7
  31. package/dist/modules/hallucination/consistency.js +42 -8
  32. package/dist/modules/hallucination/detector.js +21 -26
  33. package/dist/modules/hallucination/factual.js +150 -170
  34. package/dist/modules/hallucination/index.js +4 -5
  35. package/dist/modules/index.js +5 -5
  36. package/dist/modules/mcp/client.js +2 -8
  37. package/dist/modules/memory/store.js +0 -4
  38. package/dist/modules/plugins/builtin/lint-on-write.js +38 -143
  39. package/dist/modules/processes/detect.js +34 -0
  40. package/dist/modules/processes/index.js +2 -1
  41. package/dist/modules/processes/registry.js +35 -125
  42. package/dist/modules/processes/runner.js +110 -9
  43. package/dist/modules/security/audit-log.js +10 -30
  44. package/dist/modules/security/command-validator.js +16 -42
  45. package/dist/modules/security/content-scanner.js +8 -9
  46. package/dist/modules/security/network-validator.js +2 -2
  47. package/dist/modules/security/path-validator.js +10 -64
  48. package/dist/modules/security/security-policies.js +67 -221
  49. package/dist/modules/security/session-encryption.js +25 -42
  50. package/dist/modules/session/manager.js +10 -15
  51. package/dist/modules/session/store.js +8 -62
  52. package/dist/modules/skills/index.js +3 -2
  53. package/dist/modules/skills/matcher.js +27 -0
  54. package/dist/modules/skills/module.js +23 -10
  55. package/dist/tools/bash.js +90 -287
  56. package/dist/tools/create-dir.js +1 -0
  57. package/dist/tools/delete-file.js +1 -0
  58. package/dist/tools/edit-file.js +8 -10
  59. package/dist/tools/executor.js +7 -57
  60. package/dist/tools/grep-tool.js +29 -51
  61. package/dist/tools/index.js +40 -55
  62. package/dist/tools/load-skill.js +18 -14
  63. package/dist/tools/move-file.js +2 -3
  64. package/dist/tools/pipeline-run.js +1 -1
  65. package/dist/tools/read-file.js +5 -15
  66. package/dist/tools/search-history.js +22 -42
  67. package/dist/tools/subagent.js +12 -21
  68. package/dist/tools/web-browse.js +25 -54
  69. package/dist/tools/web-fetch.js +34 -60
  70. package/dist/tools/web-search.js +20 -39
  71. package/dist/tools/write-file.js +10 -13
  72. package/dist/ui/diff.js +16 -9
  73. package/dist/ui/renderer.js +6 -69
  74. package/package.json +1 -1
  75. package/dist/cli/repl-commands.js +0 -633
  76. package/dist/core/workspace.js +0 -76
  77. package/dist/logger/file-log.js +0 -151
  78. package/dist/modules/certification/cli.js +0 -176
  79. package/dist/modules/certification/fact-checker.js +0 -84
  80. package/dist/modules/certification/loader.js +0 -111
  81. package/dist/modules/certification/manifest.js +0 -50
  82. package/dist/modules/certification/runner.js +0 -162
  83. package/dist/modules/certification/scenarios.js +0 -124
  84. package/dist/modules/certification/types.js +0 -1
  85. package/dist/modules/execution/plan-coverage.js +0 -68
  86. package/dist/modules/execution/plan-persister.js +0 -46
  87. package/dist/modules/execution/plan-store.js +0 -159
  88. package/dist/modules/hallucination/js-identifiers.js +0 -72
  89. package/dist/modules/hallucination/llm-judge.js +0 -103
  90. package/dist/modules/lsp/client.js +0 -235
  91. package/dist/modules/lsp/config.js +0 -81
  92. package/dist/modules/lsp/index.js +0 -3
  93. package/dist/modules/lsp/module.js +0 -68
  94. package/dist/modules/lsp/types.js +0 -1
package/dist/cli/setup.js CHANGED
@@ -119,14 +119,12 @@ async function testChat(apiBase, apiKey, model) {
119
119
  return false;
120
120
  }
121
121
  }
122
- export async function runSetup(externalRl) {
122
+ export async function runSetup() {
123
123
  console.log(t("setup.title"));
124
- const rl = externalRl ||
125
- readline.createInterface({
126
- input: process.stdin,
127
- output: process.stdout,
128
- });
129
- const ownRl = !externalRl;
124
+ const rl = readline.createInterface({
125
+ input: process.stdin,
126
+ output: process.stdout,
127
+ });
130
128
  console.log(t("setup.language"));
131
129
  const locale = await ask(rl, t("setup.ui_lang"), "en");
132
130
  setLocale(locale);
@@ -195,20 +193,12 @@ export async function runSetup(externalRl) {
195
193
  let securityBashBlock = false;
196
194
  let securityFlagsBlock = false;
197
195
  let securityPathsDeny = true;
198
- if (configureSecurity.toLowerCase() === "y" ||
199
- configureSecurity.toLowerCase() === "yes") {
200
- securityBashBlock =
201
- (await ask(rl, t("setup.security_bash_block"), "n")).toLowerCase() ===
202
- "y";
203
- securityFlagsBlock =
204
- (await ask(rl, t("setup.security_flags_block"), "n")).toLowerCase() ===
205
- "y";
206
- securityPathsDeny =
207
- (await ask(rl, t("setup.security_paths_deny"), "Y")).toLowerCase() !==
208
- "n";
196
+ if (configureSecurity.toLowerCase() === "y" || configureSecurity.toLowerCase() === "yes") {
197
+ securityBashBlock = (await ask(rl, t("setup.security_bash_block"), "n")).toLowerCase() === "y";
198
+ securityFlagsBlock = (await ask(rl, t("setup.security_flags_block"), "n")).toLowerCase() === "y";
199
+ securityPathsDeny = (await ask(rl, t("setup.security_paths_deny"), "Y")).toLowerCase() !== "n";
209
200
  }
210
- if (ownRl)
211
- rl.close();
201
+ rl.close();
212
202
  const answers = {
213
203
  provider,
214
204
  apiBase,
@@ -229,18 +219,8 @@ export async function runSetup(externalRl) {
229
219
  t("setup.summary_value"),
230
220
  ], [
231
221
  [t("setup.provider_type"), provider, t("setup.model_name"), model],
232
- [
233
- "API Base URL",
234
- apiBase,
235
- t("setup.context_window"),
236
- String(contextWindow),
237
- ],
238
- [
239
- t("setup.api_key"),
240
- apiKey || "not-needed",
241
- t("setup.max_iters"),
242
- String(maxIterations),
243
- ],
222
+ ["API Base URL", apiBase, t("setup.context_window"), String(contextWindow)],
223
+ [t("setup.api_key"), apiKey || "not-needed", t("setup.max_iters"), String(maxIterations)],
244
224
  [t("setup.ui_lang"), locale, "", ""],
245
225
  ], { maxColumns: 4 });
246
226
  for (const l of summary)
@@ -1,12 +1,12 @@
1
- import { existsSync, readFileSync, unlinkSync, writeFileSync, mkdirSync, } from "fs";
2
- import { join, dirname } from "path";
3
- import { DEFAULTS } from "./defaults";
4
- import { DEFAULT_SECURITY_CONFIG } from "./security";
5
- import { t } from "../i18n/index";
6
- import { MigrationDetector } from "../migration/detect";
7
- import { BackupManager } from "../migration/backup";
8
- import { validateExpertConfig } from "./experts";
9
- import { ConfigEncryptor, } from "../modules/security/encryption";
1
+ import { existsSync, readFileSync, unlinkSync, writeFileSync, mkdirSync } from 'fs';
2
+ import { join, dirname } from 'path';
3
+ import { DEFAULTS } from './defaults';
4
+ import { DEFAULT_SECURITY_CONFIG } from './security';
5
+ import { t } from '../i18n/index';
6
+ import { MigrationDetector } from '../migration/detect';
7
+ import { BackupManager } from '../migration/backup';
8
+ import { validateExpertConfig } from './experts';
9
+ import { ConfigEncryptor } from '../modules/security/encryption';
10
10
  /**
11
11
  * Restore RegExp instances in dangerousPatterns that were serialized as {}
12
12
  * (pre-0.8.0 configs) or as {__regex, source, flags} (new format).
@@ -41,12 +41,9 @@ function deepMerge(target, source) {
41
41
  for (const key of Object.keys(source)) {
42
42
  const srcVal = source[key];
43
43
  const tgtVal = target[key];
44
- if (srcVal !== null &&
45
- srcVal !== undefined &&
46
- typeof srcVal === "object" &&
47
- !Array.isArray(srcVal) &&
48
- typeof tgtVal === "object" &&
49
- !Array.isArray(tgtVal)) {
44
+ if (srcVal !== null && srcVal !== undefined &&
45
+ typeof srcVal === 'object' && !Array.isArray(srcVal) &&
46
+ typeof tgtVal === 'object' && !Array.isArray(tgtVal)) {
50
47
  result[key] = deepMerge(tgtVal, srcVal);
51
48
  }
52
49
  else if (srcVal !== undefined) {
@@ -85,12 +82,10 @@ function regexReviver(_key, value) {
85
82
  function loadJSON(path) {
86
83
  try {
87
84
  if (existsSync(path)) {
88
- return JSON.parse(readFileSync(path, "utf-8"), regexReviver);
85
+ return JSON.parse(readFileSync(path, 'utf-8'), regexReviver);
89
86
  }
90
87
  }
91
- catch {
92
- /* ignore malformed files */
93
- }
88
+ catch { /* ignore malformed files */ }
94
89
  return null;
95
90
  }
96
91
  function applyEnvVars(config) {
@@ -108,36 +103,27 @@ function applyEnvVars(config) {
108
103
  result.logLevel = env.MMA_LOG_LEVEL;
109
104
  if (env.MMA_LOCALE)
110
105
  result.locale = env.MMA_LOCALE;
111
- if (env.MMA_CONTEXT_WINDOW) {
112
- const v = parseInt(env.MMA_CONTEXT_WINDOW, 10);
113
- if (!isNaN(v))
114
- result.contextWindow = v;
115
- }
116
- if (env.MMA_MAX_TOOL_ITERATIONS) {
117
- const v = parseInt(env.MMA_MAX_TOOL_ITERATIONS, 10);
118
- if (!isNaN(v))
119
- result.maxToolIterations = v;
120
- }
121
- if (env.MMA_STUCK_THRESHOLD) {
122
- const v = parseInt(env.MMA_STUCK_THRESHOLD, 10);
123
- if (!isNaN(v))
124
- result.stuckThreshold = v;
125
- }
106
+ if (env.MMA_CONTEXT_WINDOW)
107
+ result.contextWindow = parseInt(env.MMA_CONTEXT_WINDOW, 10);
108
+ if (env.MMA_MAX_TOOL_ITERATIONS)
109
+ result.maxToolIterations = parseInt(env.MMA_MAX_TOOL_ITERATIONS, 10);
110
+ if (env.MMA_STUCK_THRESHOLD)
111
+ result.stuckThreshold = parseInt(env.MMA_STUCK_THRESHOLD, 10);
126
112
  if (env.MMA_AUTO_PLAN)
127
- result.autoPlan = env.MMA_AUTO_PLAN === "true";
113
+ result.autoPlan = env.MMA_AUTO_PLAN === 'true';
128
114
  if (env.MMA_MOE_ENABLED)
129
- result.moe = { ...result.moe, enabled: env.MMA_MOE_ENABLED === "true" };
115
+ result.moe = { ...result.moe, enabled: env.MMA_MOE_ENABLED === 'true' };
130
116
  return result;
131
117
  }
132
118
  export function loadConfig(options) {
133
- const globalPath = join(options.configDir, "config.json");
119
+ const globalPath = join(options.configDir, 'config.json');
134
120
  mkdirSync(options.configDir, { recursive: true });
135
121
  const detector = new MigrationDetector(options.configDir);
136
122
  if (detector.needsMigration()) {
137
123
  const backup = new BackupManager(options.configDir);
138
124
  backup.backupConfig();
139
125
  const summary = backup.getBackupSummary();
140
- console.log(t("migration.detected", { summary }));
126
+ console.log(t('migration.detected', { summary }));
141
127
  try {
142
128
  unlinkSync(globalPath);
143
129
  }
@@ -172,7 +158,7 @@ export function loadConfig(options) {
172
158
  }
173
159
  catch (e) {
174
160
  // If decryption fails, log a warning but continue with the config
175
- console.warn(t("config.decryption_warning", { error: e.message }));
161
+ console.warn(t('config.decryption_warning', { error: e.message }));
176
162
  }
177
163
  // Update global audit notifier with config (done in bootstrap.ts)
178
164
  return config;
@@ -180,7 +166,7 @@ export function loadConfig(options) {
180
166
  export function validateConfig(config, allToolTags) {
181
167
  const errors = validateExpertConfig(config, allToolTags);
182
168
  if (errors.length > 0) {
183
- throw new Error(`Config validation failed:\n${errors.join("\n")}`);
169
+ throw new Error(`Config validation failed:\n${errors.join('\n')}`);
184
170
  }
185
171
  }
186
172
  export function saveConfig(config, configPath) {
@@ -189,14 +175,12 @@ export function saveConfig(config, configPath) {
189
175
  // Encrypt sensitive fields before saving
190
176
  try {
191
177
  const encryptor = new ConfigEncryptor();
192
- const encryptedConfig = encryptor.encrypt({
193
- ...config,
194
- });
195
- writeFileSync(configPath, JSON.stringify(encryptedConfig, regexReplacer, 2), "utf-8");
178
+ const encryptedConfig = encryptor.encrypt({ ...config });
179
+ writeFileSync(configPath, JSON.stringify(encryptedConfig, regexReplacer, 2), 'utf-8');
196
180
  }
197
181
  catch (e) {
198
182
  // If encryption fails, save without encryption
199
- console.warn(t("config.encryption_warning", { error: e.message }));
200
- writeFileSync(configPath, JSON.stringify(config, regexReplacer, 2), "utf-8");
183
+ console.warn(t('config.encryption_warning', { error: e.message }));
184
+ writeFileSync(configPath, JSON.stringify(config, regexReplacer, 2), 'utf-8');
201
185
  }
202
186
  }
@@ -1,5 +1,4 @@
1
1
  import { DEFAULT_SECURITY_CONFIG } from "./security";
2
- import { DEFAULT_LSP_CONFIG } from "../modules/lsp/config";
3
2
  export const DEFAULTS = {
4
3
  version: "2.0.0",
5
4
  model: "qwen3.5-9b",
@@ -50,7 +49,7 @@ export const DEFAULTS = {
50
49
  maxDelay: 30000,
51
50
  },
52
51
  maxToolIterations: 1000,
53
- stuckThreshold: 6,
52
+ stuckThreshold: 8,
54
53
  autoPlan: true,
55
54
  showReasoning: false,
56
55
  logLevel: "info",
@@ -70,10 +69,6 @@ export const DEFAULTS = {
70
69
  },
71
70
  ui: {
72
71
  spinner: true,
73
- toolStyle: "inline",
74
- toolComments: true,
75
- showContextStats: false,
76
- showCompaction: true,
77
72
  },
78
73
  mcpServers: {
79
74
  context7: {
@@ -93,8 +88,4 @@ export const DEFAULTS = {
93
88
  isolatePlugins: true,
94
89
  isolateTempFiles: true,
95
90
  },
96
- skills: {
97
- budget: 0.15,
98
- },
99
- lsp: DEFAULT_LSP_CONFIG,
100
91
  };
@@ -3,9 +3,7 @@
3
3
  * These settings provide a balance between security and usability.
4
4
  */
5
5
  export const DEFAULT_SECURITY_CONFIG = {
6
- enabled: false,
7
6
  bash: {
8
- enabled: false,
9
7
  // Commands that are always blocked (dangerous)
10
8
  blacklist: [
11
9
  "rm",
@@ -76,7 +74,6 @@ export const DEFAULT_SECURITY_CONFIG = {
76
74
  dangerousOperators: [">", ">>", "2>", "2>>", "`"],
77
75
  },
78
76
  paths: {
79
- enabled: false,
80
77
  // Glob patterns for paths that are always denied
81
78
  denied: [
82
79
  ".git/",
@@ -98,7 +95,6 @@ export const DEFAULT_SECURITY_CONFIG = {
98
95
  allowed: [],
99
96
  },
100
97
  network: {
101
- enabled: false,
102
98
  // Domains that are always denied
103
99
  deniedDomains: ["localhost", "127.0.0.1", "::1"],
104
100
  // If allowedDomains is non-empty, only these domains are allowed
@@ -119,7 +115,7 @@ export const DEFAULT_SECURITY_CONFIG = {
119
115
  },
120
116
  // Content scanning settings
121
117
  contentScan: {
122
- enabled: false,
118
+ enabled: true,
123
119
  // Patterns that are considered dangerous in file content
124
120
  dangerousPatterns: [
125
121
  /eval\(/,
@@ -146,12 +142,12 @@ export const DEFAULT_SECURITY_CONFIG = {
146
142
  // Audit notification settings
147
143
  auditNotifier: {
148
144
  enabled: false,
149
- minSeverity: "medium",
145
+ minSeverity: 'medium',
150
146
  eventTypes: [
151
- "security_block",
152
- "bash_command",
153
- "file_operation",
154
- "network_request",
147
+ 'security_block',
148
+ 'bash_command',
149
+ 'file_operation',
150
+ 'network_request',
155
151
  ],
156
152
  maxRetries: 3,
157
153
  webhookTimeout: 5000,
@@ -163,7 +159,6 @@ export const DEFAULT_SECURITY_CONFIG = {
163
159
  */
164
160
  export function mergeSecurityConfig(userConfig) {
165
161
  return {
166
- enabled: userConfig?.enabled ?? DEFAULT_SECURITY_CONFIG.enabled,
167
162
  bash: {
168
163
  ...DEFAULT_SECURITY_CONFIG.bash,
169
164
  ...userConfig?.bash,
@@ -176,10 +171,8 @@ export function mergeSecurityConfig(userConfig) {
176
171
  ...DEFAULT_SECURITY_CONFIG.network,
177
172
  ...userConfig?.network,
178
173
  },
179
- maxRecursionDepth: userConfig?.maxRecursionDepth ??
180
- DEFAULT_SECURITY_CONFIG.maxRecursionDepth,
181
- maxFileOperations: userConfig?.maxFileOperations ??
182
- DEFAULT_SECURITY_CONFIG.maxFileOperations,
174
+ maxRecursionDepth: userConfig?.maxRecursionDepth ?? DEFAULT_SECURITY_CONFIG.maxRecursionDepth,
175
+ maxFileOperations: userConfig?.maxFileOperations ?? DEFAULT_SECURITY_CONFIG.maxFileOperations,
183
176
  rateLimits: {
184
177
  ...DEFAULT_SECURITY_CONFIG.rateLimits,
185
178
  ...userConfig?.rateLimits,
@@ -64,30 +64,18 @@ export async function runWithMoE(deps, input, fallback, opts = {}) {
64
64
  ];
65
65
  const verification = await verifier.verifyMoEManifest(plan, config, knownTags);
66
66
  onPhase?.("thinking");
67
- let verifyResult;
68
- try {
69
- verifyResult = await orchestrator.verifyAndMerge({
70
- plan,
71
- results: planResults.results.map((r) => ({
72
- subtaskId: r.subtaskId,
73
- success: r.success,
74
- summary: r.summary,
75
- result: r.result,
76
- error: r.error,
77
- })),
78
- verifierErrors: verification.errors,
79
- verifierWarnings: verification.warnings,
80
- });
81
- }
82
- catch (err) {
83
- onPhase?.("done");
84
- return {
85
- success: false,
86
- text: `MoE verifyAndMerge crashed: ${err.message}`,
87
- error: err.message,
88
- iterationCount: 0,
89
- };
90
- }
67
+ const verifyResult = await orchestrator.verifyAndMerge({
68
+ plan,
69
+ results: planResults.results.map((r) => ({
70
+ subtaskId: r.subtaskId,
71
+ success: r.success,
72
+ summary: r.summary,
73
+ result: r.result,
74
+ error: r.error,
75
+ })),
76
+ verifierErrors: verification.errors,
77
+ verifierWarnings: verification.warnings,
78
+ });
91
79
  onPhase?.("done");
92
80
  const outputLines = [`## MoE Execution Results\n`];
93
81
  for (const r of planResults.results) {