micro-models-agent 2.11.0 → 2.13.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 (356) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/assets/app.js +22 -2
  3. package/dist/assets/index.html +39 -9
  4. package/dist/assets/js/dom.js +15 -0
  5. package/dist/assets/js/feed.js +129 -10
  6. package/dist/assets/js/sidebar.js +512 -0
  7. package/dist/assets/js/tabs.js +30 -5
  8. package/dist/assets/setup.js +267 -8
  9. package/dist/assets/styles.css +168 -3
  10. package/dist/cli/cache-line.js +1 -0
  11. package/dist/cli/command-suggest.js +5 -4
  12. package/dist/cli/commands.js +231 -122
  13. package/dist/cli/completer.js +132 -31
  14. package/dist/cli/index.js +1 -0
  15. package/dist/cli/json-payload.js +4 -4
  16. package/dist/cli/main.js +166 -61
  17. package/dist/cli/onboarding-commands.js +126 -0
  18. package/dist/cli/plugin-commands.js +2 -1
  19. package/dist/cli/relaunch.js +16 -13
  20. package/dist/cli/repl-commands-lsp.js +75 -0
  21. package/dist/cli/repl-commands-skills.js +105 -0
  22. package/dist/cli/repl-commands.js +589 -266
  23. package/dist/cli/repl.js +436 -177
  24. package/dist/cli/run-result.js +5 -6
  25. package/dist/cli/security-commands.js +37 -28
  26. package/dist/cli/setup-order.js +4 -55
  27. package/dist/cli/setup-prompt.js +3 -2
  28. package/dist/cli/setup.js +27 -107
  29. package/dist/cli/web-command.js +98 -0
  30. package/dist/config/budget.js +5 -5
  31. package/dist/config/config.js +103 -96
  32. package/dist/config/defaults.js +38 -8
  33. package/dist/config/domains.js +24 -27
  34. package/dist/config/env.js +46 -0
  35. package/dist/config/experts.js +2 -0
  36. package/dist/config/index.js +1 -0
  37. package/dist/config/paths.js +56 -0
  38. package/dist/config/redact.js +44 -0
  39. package/dist/config/registry-extra.js +334 -0
  40. package/dist/config/registry.js +584 -0
  41. package/dist/config/security.js +35 -36
  42. package/dist/config/timeouts.js +74 -0
  43. package/dist/config/utils.js +16 -15
  44. package/dist/core/agent/artifact-progress.js +59 -0
  45. package/dist/core/agent/artifact-resolve.js +79 -0
  46. package/dist/core/agent/audit-gate.js +7 -3
  47. package/dist/core/agent/compaction.js +2 -2
  48. package/dist/core/agent/constants.js +33 -4
  49. package/dist/core/agent/context-log.js +454 -0
  50. package/dist/core/agent/context-renderer.js +5 -0
  51. package/dist/core/agent/critic-gate.js +132 -0
  52. package/dist/core/agent/hallucination-gate.js +148 -38
  53. package/dist/core/agent/loop-state.js +15 -0
  54. package/dist/core/agent/prefix-monitor.js +1 -1
  55. package/dist/core/agent/reasoning-resolver.js +10 -1
  56. package/dist/core/agent/token-tracker.js +7 -4
  57. package/dist/core/agent/tool-batch.js +93 -18
  58. package/dist/core/agent/tool-images.js +18 -0
  59. package/dist/core/agent/tool-output.js +65 -11
  60. package/dist/core/agent/tool-pairing.js +60 -0
  61. package/dist/core/agent-moe.js +25 -24
  62. package/dist/core/agent.js +429 -108
  63. package/dist/core/bootstrap/agent-phase.js +66 -0
  64. package/dist/core/bootstrap/config-phase.js +86 -0
  65. package/dist/core/bootstrap/modules-phase.js +269 -0
  66. package/dist/core/bootstrap/provider-phase.js +183 -0
  67. package/dist/core/bootstrap/session-phase.js +204 -0
  68. package/dist/core/bootstrap/state.js +94 -0
  69. package/dist/core/bootstrap/workspace-phase.js +115 -0
  70. package/dist/core/bootstrap.js +92 -660
  71. package/dist/core/crash-handler.js +17 -7
  72. package/dist/core/environment.js +37 -12
  73. package/dist/core/host-plan.js +43 -0
  74. package/dist/core/host.js +23 -0
  75. package/dist/core/index.js +1 -0
  76. package/dist/core/prompt-builder.js +17 -1
  77. package/dist/core/prompt-overflow.js +42 -43
  78. package/dist/core/session-logger.js +122 -30
  79. package/dist/core/system-prompt.js +117 -0
  80. package/dist/core/version.js +6 -4
  81. package/dist/core/web-host.js +34 -0
  82. package/dist/core/workspace.js +19 -15
  83. package/dist/i18n/en.json +89 -3
  84. package/dist/i18n/index.js +37 -3
  85. package/dist/i18n/ru.json +89 -3
  86. package/dist/index.js +7 -3
  87. package/dist/llm/image-utils.js +55 -64
  88. package/dist/llm/llm-errors.js +9 -0
  89. package/dist/llm/model-loader.js +10 -32
  90. package/dist/llm/models-dev.js +121 -0
  91. package/dist/llm/openai-compat.js +146 -73
  92. package/dist/llm/orchestrator.js +33 -11
  93. package/dist/llm/provider-budget.js +2 -2
  94. package/dist/llm/provider-context.js +233 -0
  95. package/dist/llm/provider.js +1 -1
  96. package/dist/llm/response.js +5 -0
  97. package/dist/llm/token-counter.js +27 -11
  98. package/dist/logger/app-logger.js +48 -22
  99. package/dist/logger/file-log.js +28 -19
  100. package/dist/logger/index.js +1 -0
  101. package/dist/main.js +888 -139
  102. package/dist/migration/backup.js +14 -3
  103. package/dist/migration/detect.js +12 -3
  104. package/dist/migration/index.js +1 -0
  105. package/dist/modules/artifacts/store.js +9 -8
  106. package/dist/modules/browser/actions.js +6 -0
  107. package/dist/modules/browser/bridge-client.js +14 -12
  108. package/dist/modules/browser/bridge-path.js +4 -4
  109. package/dist/modules/browser/console-buffer.js +37 -0
  110. package/dist/modules/browser/cookie-store.js +5 -0
  111. package/dist/modules/browser/driver-types.js +1 -0
  112. package/dist/modules/browser/driver.js +19 -11
  113. package/dist/modules/browser/index.js +3 -1
  114. package/dist/modules/browser/module.js +2 -1
  115. package/dist/modules/browser/session.js +10 -30
  116. package/dist/modules/browser/snapshot.js +19 -13
  117. package/dist/modules/browser/types.js +1 -0
  118. package/dist/modules/certification/cli.js +28 -20
  119. package/dist/modules/certification/fact-checker.js +9 -1
  120. package/dist/modules/certification/loader.js +9 -2
  121. package/dist/modules/certification/manifest.js +83 -21
  122. package/dist/modules/certification/runner.js +23 -13
  123. package/dist/modules/certification/scenarios.js +20 -20
  124. package/dist/modules/certification/syntax-scenarios.js +1 -2
  125. package/dist/modules/context/chunk-query.js +11 -9
  126. package/dist/modules/context/fact-extractor.js +37 -39
  127. package/dist/modules/context/index.js +1 -0
  128. package/dist/modules/context/manager.js +106 -80
  129. package/dist/modules/critic/client.js +176 -0
  130. package/dist/modules/critic/evidence.js +81 -0
  131. package/dist/modules/critic/provider.js +45 -0
  132. package/dist/modules/critic/tools.js +78 -0
  133. package/dist/modules/critic/types.js +1 -0
  134. package/dist/modules/execution/audit-runners.js +28 -34
  135. package/dist/modules/execution/auditor.js +53 -49
  136. package/dist/modules/execution/execution-plugin.js +142 -102
  137. package/dist/modules/execution/index.js +1 -1
  138. package/dist/modules/execution/input-from.js +37 -13
  139. package/dist/modules/execution/module.js +368 -191
  140. package/dist/modules/execution/moe-executor.js +53 -26
  141. package/dist/modules/execution/plan-actions.js +320 -202
  142. package/dist/modules/execution/plan-checks.js +35 -0
  143. package/dist/modules/execution/plan-coverage.js +36 -33
  144. package/dist/modules/execution/plan-steps.js +11 -3
  145. package/dist/modules/execution/plan-store.js +83 -17
  146. package/dist/modules/execution/plan-tool.js +89 -35
  147. package/dist/modules/execution/plan-validator.js +30 -10
  148. package/dist/modules/execution/planner.js +22 -13
  149. package/dist/modules/execution/stuck-detector.js +196 -93
  150. package/dist/modules/execution/tracker.js +22 -8
  151. package/dist/modules/execution/verifier.js +69 -48
  152. package/dist/modules/execution/windows-commands.js +12 -12
  153. package/dist/modules/hallucination/artifact-claim.js +93 -0
  154. package/dist/modules/hallucination/confidence.js +13 -11
  155. package/dist/modules/hallucination/consistency.js +10 -2
  156. package/dist/modules/hallucination/detector.js +10 -5
  157. package/dist/modules/hallucination/factual.js +43 -26
  158. package/dist/modules/hallucination/index.js +1 -0
  159. package/dist/modules/hallucination/js-identifiers.js +44 -45
  160. package/dist/modules/hallucination/llm-judge.js +17 -12
  161. package/dist/modules/hallucination/success-claim.js +59 -0
  162. package/dist/modules/indexer/cache.js +52 -4
  163. package/dist/modules/indexer/index.js +1 -0
  164. package/dist/modules/indexer/map-command.js +2 -4
  165. package/dist/modules/indexer/map-select.js +16 -16
  166. package/dist/modules/indexer/module.js +47 -12
  167. package/dist/modules/indexer/project-profile.js +8 -7
  168. package/dist/modules/indexer/symbols.js +15 -15
  169. package/dist/modules/indexer/walker.js +159 -29
  170. package/dist/modules/lsp/check-tool.js +7 -5
  171. package/dist/modules/lsp/client.js +39 -39
  172. package/dist/modules/lsp/command.js +17 -24
  173. package/dist/modules/lsp/config.js +12 -11
  174. package/dist/modules/lsp/index.js +1 -0
  175. package/dist/modules/lsp/module.js +48 -46
  176. package/dist/modules/lsp/probe.js +13 -14
  177. package/dist/modules/lsp/project-root.js +14 -17
  178. package/dist/modules/lsp/startup-check.js +18 -16
  179. package/dist/modules/mcp/client.js +59 -62
  180. package/dist/modules/mcp/index.js +1 -0
  181. package/dist/modules/mcp/module.js +66 -37
  182. package/dist/modules/mcp/registry.js +5 -0
  183. package/dist/modules/memory/index.js +1 -0
  184. package/dist/modules/memory/module.js +12 -8
  185. package/dist/modules/memory/search.js +4 -1
  186. package/dist/modules/memory/store.js +40 -2
  187. package/dist/modules/onboarding/init.js +47 -0
  188. package/dist/modules/onboarding/meet.js +30 -0
  189. package/dist/modules/onboarding/mode.js +30 -0
  190. package/dist/modules/onboarding/prompts.js +43 -0
  191. package/dist/modules/pipelines/engine.js +10 -0
  192. package/dist/modules/pipelines/index.js +1 -0
  193. package/dist/modules/pipelines/parser.js +4 -1
  194. package/dist/modules/pipelines/template.js +4 -0
  195. package/dist/modules/plugins/builtin/lint-on-write.js +80 -67
  196. package/dist/modules/plugins/builtin/notify.js +2 -0
  197. package/dist/modules/plugins/index.js +1 -0
  198. package/dist/modules/plugins/loader.js +18 -3
  199. package/dist/modules/plugins/manager.js +37 -17
  200. package/dist/modules/pricing/index.js +10 -11
  201. package/dist/modules/pricing/prices.js +12 -12
  202. package/dist/modules/processes/index.js +1 -0
  203. package/dist/modules/processes/kill-tree.js +27 -31
  204. package/dist/modules/processes/registry.js +44 -25
  205. package/dist/modules/processes/runner.js +4 -4
  206. package/dist/modules/providers/capabilities.js +28 -0
  207. package/dist/modules/providers/create.js +3 -4
  208. package/dist/modules/providers/factory.js +7 -7
  209. package/dist/modules/providers/fallback.js +12 -12
  210. package/dist/modules/providers/health.js +4 -4
  211. package/dist/modules/providers/manager.js +50 -19
  212. package/dist/modules/providers/naming.js +15 -0
  213. package/dist/modules/providers/preflight.js +71 -0
  214. package/dist/modules/providers/presets.js +39 -8
  215. package/dist/modules/providers/registry.js +7 -2
  216. package/dist/modules/reasoning/policy.js +8 -6
  217. package/dist/modules/reasoning/probe.js +30 -25
  218. package/dist/modules/security/audit-log.js +19 -36
  219. package/dist/modules/security/audit-notifier.js +35 -75
  220. package/dist/modules/security/command-validator.js +99 -51
  221. package/dist/modules/security/content-scanner.js +8 -8
  222. package/dist/modules/security/data-sanitizer.js +9 -16
  223. package/dist/modules/security/encryption.js +32 -52
  224. package/dist/modules/security/index.js +2 -1
  225. package/dist/modules/security/network-validator.js +120 -43
  226. package/dist/modules/security/path-validator.js +61 -46
  227. package/dist/modules/security/protected-paths.js +73 -0
  228. package/dist/modules/security/rate-limiter.js +17 -49
  229. package/dist/modules/security/security-policies.js +25 -57
  230. package/dist/modules/security/session-encryption.js +32 -71
  231. package/dist/modules/security/session-isolation.js +15 -28
  232. package/dist/modules/session/auto-name.js +63 -0
  233. package/dist/modules/session/export.js +98 -0
  234. package/dist/modules/session/index.js +1 -0
  235. package/dist/modules/session/manager.js +79 -28
  236. package/dist/modules/session/module.js +4 -3
  237. package/dist/modules/session/store.js +57 -20
  238. package/dist/modules/setup/answers.js +35 -0
  239. package/dist/modules/setup/apply.js +79 -0
  240. package/dist/modules/setup/discovery.js +72 -0
  241. package/dist/modules/skills/index.js +1 -0
  242. package/dist/modules/skills/loader.js +9 -1
  243. package/dist/modules/skills/module.js +11 -0
  244. package/dist/modules/updater/changelog-reader.js +15 -16
  245. package/dist/modules/updater/checker.js +9 -4
  246. package/dist/modules/updater/dev-detect.js +7 -6
  247. package/dist/modules/updater/index.js +1 -0
  248. package/dist/modules/updater/module.js +17 -15
  249. package/dist/modules/user-profile/compressor.js +2 -0
  250. package/dist/modules/user-profile/index.js +1 -0
  251. package/dist/modules/user-profile/profile.js +10 -1
  252. package/dist/modules/webui/answer-api.js +29 -0
  253. package/dist/modules/webui/assets.js +50 -0
  254. package/dist/modules/webui/body.js +21 -0
  255. package/dist/modules/webui/commands-settings.js +209 -0
  256. package/dist/modules/webui/commands-shared.js +60 -0
  257. package/dist/modules/webui/commands.js +174 -0
  258. package/dist/modules/webui/config-api.js +134 -0
  259. package/dist/modules/webui/file-api.js +202 -0
  260. package/dist/modules/webui/forward.js +159 -0
  261. package/dist/modules/webui/history-api.js +112 -0
  262. package/dist/modules/webui/host-state.js +60 -0
  263. package/dist/modules/webui/i18n-api.js +9 -0
  264. package/dist/modules/webui/limits.js +6 -0
  265. package/dist/modules/webui/log-forward.js +20 -0
  266. package/dist/modules/webui/memory-commands.js +64 -0
  267. package/dist/modules/webui/model-cache.js +18 -0
  268. package/dist/modules/webui/module.js +148 -0
  269. package/dist/modules/webui/persist.js +24 -0
  270. package/dist/modules/webui/prompt-io.js +97 -0
  271. package/dist/modules/webui/providers-api.js +337 -0
  272. package/dist/modules/webui/providers-view.js +56 -0
  273. package/dist/modules/webui/reasoning-view.js +15 -0
  274. package/dist/modules/webui/run-agent.js +81 -0
  275. package/dist/modules/webui/server.js +284 -0
  276. package/dist/modules/webui/sessions-api.js +178 -0
  277. package/dist/modules/webui/settings-api.js +561 -0
  278. package/dist/modules/webui/setup-api.js +201 -0
  279. package/dist/modules/webui/state.js +74 -0
  280. package/dist/modules/webui/util.js +261 -0
  281. package/dist/output/bus.js +7 -2
  282. package/dist/output/channel.js +80 -28
  283. package/dist/output/format.js +2 -1
  284. package/dist/output/index.js +1 -0
  285. package/dist/output/json-sink.js +5 -3
  286. package/dist/output/machine.js +4 -3
  287. package/dist/output/session-sink.js +4 -4
  288. package/dist/tools/approve.js +4 -0
  289. package/dist/tools/attach-image.js +5 -4
  290. package/dist/tools/auto-fixer.js +26 -44
  291. package/dist/tools/auto-tags.js +83 -0
  292. package/dist/tools/bash.js +193 -116
  293. package/dist/tools/browser.js +76 -31
  294. package/dist/tools/chunk-query.js +14 -6
  295. package/dist/tools/create-dir.js +9 -5
  296. package/dist/tools/delete-file.js +9 -5
  297. package/dist/tools/download-file.js +32 -7
  298. package/dist/tools/edit-file.js +52 -14
  299. package/dist/tools/enable-tools.js +6 -6
  300. package/dist/tools/executor.js +132 -27
  301. package/dist/tools/file-info.js +3 -1
  302. package/dist/tools/filter-tools.js +3 -3
  303. package/dist/tools/glob-tool.js +4 -1
  304. package/dist/tools/grep-tool.js +13 -10
  305. package/dist/tools/hidden-tools-block.js +6 -6
  306. package/dist/tools/index.js +16 -8
  307. package/dist/tools/list-dir.js +4 -2
  308. package/dist/tools/load-skill.js +7 -0
  309. package/dist/tools/mcp-call.js +15 -4
  310. package/dist/tools/meet-done.js +14 -0
  311. package/dist/tools/move-file.js +14 -7
  312. package/dist/tools/path-utils.js +29 -29
  313. package/dist/tools/pipeline-run.js +29 -7
  314. package/dist/tools/preview.js +1 -1
  315. package/dist/tools/process-ids.js +31 -0
  316. package/dist/tools/process-kill.js +9 -16
  317. package/dist/tools/process-list.js +1 -0
  318. package/dist/tools/process-log.js +11 -16
  319. package/dist/tools/process-wait.js +63 -0
  320. package/dist/tools/prompt-io.js +4 -3
  321. package/dist/tools/question.js +172 -25
  322. package/dist/tools/read-file.js +55 -34
  323. package/dist/tools/recall.js +14 -8
  324. package/dist/tools/registry.js +6 -5
  325. package/dist/tools/remember.js +8 -4
  326. package/dist/tools/scope-request.js +11 -6
  327. package/dist/tools/search-history.js +5 -2
  328. package/dist/tools/session-info.js +2 -0
  329. package/dist/tools/set-thinking.js +8 -4
  330. package/dist/tools/subagent.js +59 -39
  331. package/dist/tools/syntax-validator.js +292 -90
  332. package/dist/tools/user-input.js +22 -18
  333. package/dist/tools/web-browse.js +9 -3
  334. package/dist/tools/web-fetch.js +12 -23
  335. package/dist/tools/web-search.js +7 -5
  336. package/dist/tools/write-file.js +45 -15
  337. package/dist/ui/action-log.js +13 -0
  338. package/dist/ui/box.js +4 -3
  339. package/dist/ui/colors.js +2 -0
  340. package/dist/ui/diff.js +6 -5
  341. package/dist/ui/index.js +1 -0
  342. package/dist/ui/line-editor.js +230 -122
  343. package/dist/ui/line-math.js +10 -2
  344. package/dist/ui/md-formatter.js +57 -37
  345. package/dist/ui/output.js +8 -3
  346. package/dist/ui/plan-view.js +21 -10
  347. package/dist/ui/renderer.js +393 -67
  348. package/dist/ui/spinner.js +16 -5
  349. package/dist/ui/table.js +15 -17
  350. package/dist/ui/theme.js +143 -0
  351. package/dist/utils/child-run.js +20 -0
  352. package/dist/utils/error.js +1 -1
  353. package/dist/utils/index.js +2 -0
  354. package/dist/utils/retry.js +2 -2
  355. package/dist/utils/truncate.js +1 -1
  356. package/package.json +1 -1
@@ -1,5 +1,6 @@
1
+ /** Утилиты вывода тулов: лимиты, усечение, сводки ошибок. */
1
2
  import { t } from "../../i18n/index";
2
- import { TOOL_RESULT_MAX_TOKENS_RATIO, TOOL_RESULT_ABSOLUTE_MAX_CHARS, TOOL_ARGS_SUMMARY_MAX_CHARS, } from "./constants";
3
+ import { TOOL_RESULT_MAX_TOKENS_RATIO, TOOL_RESULT_ABSOLUTE_MAX_CHARS, TOOL_ARGS_SUMMARY_MAX_CHARS, TOOL_ARG_VALUE_MAX_CHARS, } from "./constants";
3
4
  /**
4
5
  * Макс. число символов результата тула при заданном остатке бюджета и
5
6
  * признаке того, что тул сам ограничивает свой вывод.
@@ -22,27 +23,63 @@ export function truncateToolOutput(output, budget, currentTokens, bounded) {
22
23
  return output;
23
24
  const truncated = output.slice(0, maxChars);
24
25
  const removedChars = output.length - maxChars;
25
- return truncated + `\n\n${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
26
+ return `${truncated}\n\n${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
26
27
  }
27
28
  /**
28
- * JSON-сериализация аргументов тула для <system-summary>, ограниченная по
29
- * размеру. Большой аргумент (content у write_file) не должен дублироваться в
30
- * сводке поверх role:"tool" сообщения, которое уже несёт результат.
29
+ * Компактная сигнатура аргументов тула для <system-summary>.
30
+ *
31
+ * Длинные строковые значения (content/new_string/text/…) сворачиваются до
32
+ * `…(N chars)`: их полный текст уже есть в assistant-сообщении с tool_calls
33
+ * и в role:"tool" результате, поэтому дублировать тело в сводке не нужно.
34
+ * Короткие скаляры (path/command/pattern/url) сохраняются как есть.
35
+ * Реализация не привязана к конкретным тулам — правило общее для любых args.
31
36
  */
32
37
  export function summarizeToolArgs(args) {
33
- let s;
34
- try {
35
- s = JSON.stringify(args);
38
+ if (args === undefined || args === null)
39
+ return "";
40
+ if (typeof args !== "object") {
41
+ const s = String(args);
42
+ return s ? ` (${s.slice(0, TOOL_ARGS_SUMMARY_MAX_CHARS)})` : "";
36
43
  }
37
- catch {
38
- s = String(args);
44
+ const parts = [];
45
+ for (const [key, value] of Object.entries(args)) {
46
+ let rendered;
47
+ if (typeof value === "string") {
48
+ rendered =
49
+ value.length > TOOL_ARG_VALUE_MAX_CHARS
50
+ ? `${key}:…(${value.length} chars)`
51
+ : `${key}:${value}`;
52
+ }
53
+ else {
54
+ let json;
55
+ try {
56
+ json = JSON.stringify(value);
57
+ }
58
+ catch {
59
+ json = String(value);
60
+ }
61
+ rendered =
62
+ json && json.length > TOOL_ARG_VALUE_MAX_CHARS ? `${key}:…` : `${key}:${json}`;
63
+ }
64
+ parts.push(rendered);
65
+ if (parts.join(", ").length > TOOL_ARGS_SUMMARY_MAX_CHARS)
66
+ break;
39
67
  }
40
- if (!s || s === "{}")
68
+ const s = parts.join(", ");
69
+ if (!s)
41
70
  return "";
42
71
  if (s.length <= TOOL_ARGS_SUMMARY_MAX_CHARS)
43
72
  return ` (${s})`;
44
73
  return ` (${s.slice(0, TOOL_ARGS_SUMMARY_MAX_CHARS)}…(${s.length} chars total))`;
45
74
  }
75
+ /**
76
+ * Является ли путь исполняемым shell-скриптом (обёрткой). Обобщённо, без
77
+ * привязки к языку проекта: используется, чтобы заметить попытку обойти
78
+ * security-блокировку через свежесозданный скрипт.
79
+ */
80
+ export function isExecutableScriptPath(filePath) {
81
+ return /\.[a-z0-9]+$/i.test(filePath) && /\.(bat|cmd|sh|bash|ps1|zsh|fish)$/i.test(filePath);
82
+ }
46
83
  /**
47
84
  * Компактная пользовательская строка для упавшего тула.
48
85
  *
@@ -60,3 +97,20 @@ export function compactToolError(output, max = 200) {
60
97
  }
61
98
  return "";
62
99
  }
100
+ /**
101
+ * Превращает model-facing падение тула в спокойную локализованную сводку.
102
+ *
103
+ * Отказы security/protected-path — мягкие гарды (агент должен спросить
104
+ * пользователя), поэтому рисуются варнингом, а сырые маркеры
105
+ * `[SECURITY BLOCKED]` / `[PROTECTED PATH]` в чат не попадают.
106
+ */
107
+ export function toolFailureSummary(output, max = 200) {
108
+ const text = String(output ?? "");
109
+ if (text.includes("[SECURITY BLOCKED]")) {
110
+ return { text: t("tool.ui.security_blocked"), severity: "warn" };
111
+ }
112
+ if (text.includes("[PROTECTED PATH]")) {
113
+ return { text: t("tool.ui.protected_path"), severity: "warn" };
114
+ }
115
+ return { text: compactToolError(text, max), severity: "error" };
116
+ }
@@ -0,0 +1,60 @@
1
+ /** Заглушка результата для незавершённого вызова. */
2
+ export const UNRESOLVED_TOOL_RESULT = "[Result unavailable]";
3
+ /**
4
+ * Приводит историю к валидному позиционному спариванию `assistant(tool_calls)`
5
+ * → непрерывный `tool`-блок. Не мутирует входные сообщения (кроме безопасного
6
+ * клонирования при merge) — возвращает новый массив.
7
+ * @param messages активная история; @returns нормализованная копия.
8
+ */
9
+ export function repairToolCallPairing(messages) {
10
+ const out = [];
11
+ let pending = [];
12
+ // Закрывает незавершённые вызовы стабами, сохраняя их порядок.
13
+ const closePending = () => {
14
+ for (const call of pending) {
15
+ out.push({
16
+ role: "tool",
17
+ name: call.name,
18
+ content: UNRESOLVED_TOOL_RESULT,
19
+ tool_call_id: call.id,
20
+ success: false,
21
+ blocked: true,
22
+ });
23
+ }
24
+ pending = [];
25
+ };
26
+ for (const msg of messages) {
27
+ if (msg.role === "assistant" && msg.tool_calls?.length) {
28
+ const last = out[out.length - 1];
29
+ if (last?.role === "assistant" && last.tool_calls?.length) {
30
+ // Подряд идущие assistant(tool_calls) — слить в один ход: провайдер
31
+ // видит второй assistant до ответов на первый и тоже падает.
32
+ const merged = {
33
+ ...last,
34
+ tool_calls: [...last.tool_calls, ...msg.tool_calls],
35
+ };
36
+ out[out.length - 1] = merged;
37
+ pending = merged.tool_calls.map((tc) => ({ id: tc.id, name: tc.function.name }));
38
+ continue;
39
+ }
40
+ closePending();
41
+ out.push(msg);
42
+ pending = msg.tool_calls.map((tc) => ({ id: tc.id, name: tc.function.name }));
43
+ continue;
44
+ }
45
+ if (msg.role === "tool" && msg.tool_call_id) {
46
+ if (pending.some((c) => c.id === msg.tool_call_id)) {
47
+ out.push(msg);
48
+ pending = pending.filter((c) => c.id !== msg.tool_call_id);
49
+ }
50
+ // Осиротевший tool (нет объявленного вызова) — отбросить.
51
+ continue;
52
+ }
53
+ // Любая другая роль (user/system/assistant без tool_calls) разрывает блок:
54
+ // незавершённые вызовы закрываем ПЕРЕД ней.
55
+ closePending();
56
+ out.push(msg);
57
+ }
58
+ closePending();
59
+ return out;
60
+ }
@@ -4,12 +4,13 @@ import { MoEExecutor } from "../modules/execution/moe-executor";
4
4
  import { StepVerifier } from "../modules/execution/verifier";
5
5
  import { newAbortError } from "../modules/execution/moe-executor";
6
6
  import { t } from "../i18n/index";
7
+ /** Дефолтный лимит циклов re-plan MoE. */
7
8
  export const DEFAULT_MOE_MAX_REPLAN_CYCLES = 3;
8
9
  /**
9
- * Execute the MoE (Mixture of Experts) path: plan → validate → execute → verify,
10
- * with a re-plan loop driven by the orchestrator's verifyAndMerge decision.
11
- * Returns a fallback signal when MoE cannot proceed so the caller can fall
12
- * back to the single-agent loop.
10
+ * Исполняет MoE-путь (Mixture of Experts): план → валидация → исполнение →
11
+ * верификация, с re-plan циклом по решению verifyAndMerge оркестратора.
12
+ * Возвращает сигнал фолбэка, когда MoE не может продолжить: вызывающий
13
+ * откатывается в одиночный цикл агента.
13
14
  */
14
15
  export async function runWithMoE(deps, input, fallback, opts = {}) {
15
16
  const { config, llmProvider, logger, toolExecutor, baseDir } = deps;
@@ -19,8 +20,8 @@ export async function runWithMoE(deps, input, fallback, opts = {}) {
19
20
  if (signal?.aborted)
20
21
  throw newAbortError();
21
22
  };
22
- // Orchestration one-liners are machine-facing: emit them to the chat only
23
- // when the user opted into verbose UI (config.ui.verbose).
23
+ // Однострочники оркестрации — machine-facing: в чат только при
24
+ // включённом verbose UI (config.ui.verbose).
24
25
  const verbose = config.ui?.verbose === true;
25
26
  const status = (message) => {
26
27
  if (verbose)
@@ -40,17 +41,17 @@ export async function runWithMoE(deps, input, fallback, opts = {}) {
40
41
  }, llmProvider, { getSessionId: () => sessionId });
41
42
  }
42
43
  if (!orchestrator.isEnabled()) {
43
- // Visible at default log level: a user who enabled moe.enabled must be
44
- // able to tell why MoE never kicked in (missing orchestrator.model).
45
- logger.warn("MoE enabled but no orchestrator model configured — falling back to single-agent. Set orchestrator.model to activate MoE.");
44
+ // Видно на дефолтном лог-уровне: включивший moe.enabled должен понимать,
45
+ // почему MoE не стартовал (нет orchestrator.model).
46
+ logger.warn(t("moe.no_orchestrator"));
46
47
  return fallback();
47
48
  }
48
- status("🤖 Planning with MoE mode...\n");
49
+ status(t("moe.planning"));
49
50
  onPhase?.("thinking");
50
51
  const planResult = await orchestrator.plan(input, undefined, signal);
51
52
  onPhase?.("done");
52
53
  if ("error" in planResult) {
53
- logger.warn(`MoE plan failed: ${planResult.error} — falling back to single-agent`);
54
+ logger.warn(t("moe.plan_failed", { error: planResult.error }));
54
55
  emit("moe_plan", { status: "error", error: planResult.error });
55
56
  return fallback();
56
57
  }
@@ -66,30 +67,30 @@ export async function runWithMoE(deps, input, fallback, opts = {}) {
66
67
  for (let cycle = 1; cycle <= maxCycles; cycle++) {
67
68
  ensureNotAborted();
68
69
  if (cycle > 1) {
69
- status(t("moe.replan_started", { cycle, max: maxCycles }) + "\n");
70
+ status(`${t("moe.replan_started", { cycle, max: maxCycles })}\n`);
70
71
  emit("moe_replan", {
71
72
  cycle,
72
73
  title: currentPlan.title,
73
74
  subtaskIds: currentPlan.subtasks.map((s) => s.id),
74
75
  });
75
76
  }
76
- // Validate every plan before executing it — never trust an LLM-produced
77
- // plan, including re-plans produced by verifyAndMerge.
77
+ // Валидируем каждый план до исполнения — LLM-плану не доверяем никогда,
78
+ // включая re-plan от verifyAndMerge.
78
79
  const validation = validatePlan(currentPlan, config);
79
80
  if (!validation.valid) {
80
81
  const applied = applyAutoFixes(currentPlan, validation.autoFixes);
81
82
  const retry = validatePlan(applied, config);
82
83
  if (!retry.valid) {
83
- logger.warn(`MoE plan validation failed: ${retry.errors.join("; ")}`);
84
+ logger.diagnostic("warn", `MoE plan validation failed: ${retry.errors.join("; ")}`);
84
85
  if (cycle === 1) {
85
- status(`⚠️ Plan validation failed. Falling back to single-agent mode.\n`);
86
+ status(t("moe.plan_fallback"));
86
87
  return fallback();
87
88
  }
88
89
  return partialFailure(mergedResults, retry.errors.join("; "));
89
90
  }
90
91
  currentPlan = applied;
91
92
  if (validation.autoFixes.length > 0) {
92
- status(`🔧 Auto-fixed ${validation.autoFixes.length} plan issues.\n`);
93
+ status(t("moe.plan_autofixed", { count: String(validation.autoFixes.length) }));
93
94
  }
94
95
  }
95
96
  const executor = deps.executorOverride ??
@@ -106,20 +107,20 @@ export async function runWithMoE(deps, input, fallback, opts = {}) {
106
107
  onScopeRequest: async (subtaskId, req) => {
107
108
  const decision = await orchestrator.resolveScopeRequest(subtaskId, req, signal);
108
109
  if (decision.action === "approve") {
109
- status(t("moe.scope_approved", {
110
+ status(`${t("moe.scope_approved", {
110
111
  subtask: subtaskId,
111
112
  files: [...decision.write, ...decision.read].join(", "),
112
- }) + "\n");
113
+ })}\n`);
113
114
  }
114
115
  else {
115
- status(t("moe.scope_rejected", { subtask: subtaskId }) + "\n");
116
+ status(`${t("moe.scope_rejected", { subtask: subtaskId })}\n`);
116
117
  }
117
118
  return decision;
118
119
  },
119
120
  });
120
- status(t("moe.executing", { count: String(currentPlan.subtasks.length), cycle: String(cycle) }) + "\n");
121
- // Selective re-plan (Plan 5.1): subtasks already successfully executed in
122
- // an earlier cycle are carried over — only failed/new ones re-execute.
121
+ status(`${t("moe.executing", { count: String(currentPlan.subtasks.length), cycle: String(cycle) })}\n`);
122
+ // Селективный re-plan (Plan 5.1): успешные сабтаски прошлого цикла
123
+ // переносятся — переисполняются только упавшие/новые.
123
124
  const skipIds = new Set();
124
125
  const carriedResults = [];
125
126
  for (const s of currentPlan.subtasks) {
@@ -198,7 +199,7 @@ export async function runWithMoE(deps, input, fallback, opts = {}) {
198
199
  return buildFinalResult(mergedResults, verification.success, verifyResult);
199
200
  }
200
201
  if (!verifyResult.plan || !Array.isArray(verifyResult.plan.subtasks)) {
201
- // Verifier asked for a re-plan but produced none usable — stop honestly.
202
+ // Верификатор просил re-plan, но годного не дал — останавливаемся честно.
202
203
  return partialFailure(mergedResults, verifyResult.explanation || "re-plan requested but no plan returned");
203
204
  }
204
205
  currentPlan = verifyResult.plan;