micro-models-agent 2.16.1 → 2.17.2

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 (428) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +8 -3
  3. package/dist/assets/app.js +1 -314
  4. package/dist/assets/hljs.js +5 -1244
  5. package/dist/assets/index.html +11 -0
  6. package/dist/assets/js/api.js +1 -28
  7. package/dist/assets/js/core/menus.js +1 -0
  8. package/dist/assets/js/core/store/feed.js +1 -0
  9. package/dist/assets/js/core/store/index.js +1 -0
  10. package/dist/assets/js/core/store/session.js +1 -0
  11. package/dist/assets/js/core/store/settings.js +1 -0
  12. package/dist/assets/js/core/store/tabs.js +1 -0
  13. package/dist/assets/js/dialog.js +1 -105
  14. package/dist/assets/js/dom.js +1 -178
  15. package/dist/assets/js/feed/core.js +1 -0
  16. package/dist/assets/js/feed/history.js +1 -0
  17. package/dist/assets/js/feed/plan.js +1 -0
  18. package/dist/assets/js/feed/question.js +3 -0
  19. package/dist/assets/js/feed/sidebar.js +1 -0
  20. package/dist/assets/js/feed/stream.js +1 -0
  21. package/dist/assets/js/feed/turn.js +5 -0
  22. package/dist/assets/js/feed.js +1 -1250
  23. package/dist/assets/js/format.js +2 -122
  24. package/dist/assets/js/i18n.js +1 -46
  25. package/dist/assets/js/rail.js +1 -114
  26. package/dist/assets/js/session/cmdk.js +1 -0
  27. package/dist/assets/js/session/composer.js +1 -0
  28. package/dist/assets/js/session/sessions-menu.js +1 -0
  29. package/dist/assets/js/session/tabs.js +1 -0
  30. package/dist/assets/js/settings/controls.js +1 -0
  31. package/dist/assets/js/settings/editors.js +1 -0
  32. package/dist/assets/js/settings/form.js +1 -0
  33. package/dist/assets/js/settings/modal.js +1 -0
  34. package/dist/assets/js/settings/panels.js +1 -0
  35. package/dist/assets/js/settings/providers.js +1 -0
  36. package/dist/assets/js/settings/search.js +1 -0
  37. package/dist/assets/js/settings/subdialog.js +1 -0
  38. package/dist/assets/js/settings/write.js +1 -0
  39. package/dist/assets/js/settings.js +1 -1914
  40. package/dist/assets/js/sidebar/core.js +1 -0
  41. package/dist/assets/js/sidebar/lsp.js +2 -0
  42. package/dist/assets/js/sidebar/map.js +1 -0
  43. package/dist/assets/js/sidebar/state.js +1 -0
  44. package/dist/assets/js/sidebar/trace.js +5 -0
  45. package/dist/assets/js/sidebar.js +1 -705
  46. package/dist/assets/js/store.js +1 -82
  47. package/dist/assets/js/subdialog.js +1 -0
  48. package/dist/assets/md.js +1 -291
  49. package/dist/assets/setup.js +3 -816
  50. package/dist/assets/smd.js +29 -1665
  51. package/dist/assets/styles.css +1 -1598
  52. package/dist/certification/certifications.json +1 -494
  53. package/dist/i18n/en.json +1 -1851
  54. package/dist/i18n/ru.json +1 -1854
  55. package/dist/main.js +815 -55797
  56. package/dist/modules/browser/bridge-server.mjs +2 -252
  57. package/package.json +10 -5
  58. package/dist/assets/js/settings-controls.js +0 -452
  59. package/dist/assets/js/tabs.js +0 -867
  60. package/dist/cli/cache-line.js +0 -31
  61. package/dist/cli/command-suggest.js +0 -39
  62. package/dist/cli/commands.js +0 -781
  63. package/dist/cli/completer.js +0 -268
  64. package/dist/cli/index.js +0 -3
  65. package/dist/cli/json-payload.js +0 -32
  66. package/dist/cli/main.js +0 -346
  67. package/dist/cli/onboarding-commands.js +0 -126
  68. package/dist/cli/plugin-commands.js +0 -38
  69. package/dist/cli/relaunch.js +0 -40
  70. package/dist/cli/repl-commands-lsp.js +0 -75
  71. package/dist/cli/repl-commands-skills.js +0 -105
  72. package/dist/cli/repl-commands.js +0 -1218
  73. package/dist/cli/repl.js +0 -1238
  74. package/dist/cli/run-result.js +0 -38
  75. package/dist/cli/security-commands.js +0 -177
  76. package/dist/cli/setup-order.js +0 -6
  77. package/dist/cli/setup-prompt.js +0 -50
  78. package/dist/cli/setup.js +0 -161
  79. package/dist/cli/web-command.js +0 -98
  80. package/dist/config/budget.js +0 -48
  81. package/dist/config/config.js +0 -345
  82. package/dist/config/defaults.js +0 -197
  83. package/dist/config/domains.js +0 -135
  84. package/dist/config/env.js +0 -46
  85. package/dist/config/experts.js +0 -17
  86. package/dist/config/index.js +0 -5
  87. package/dist/config/paths.js +0 -56
  88. package/dist/config/redact.js +0 -44
  89. package/dist/config/registry-extra.js +0 -334
  90. package/dist/config/registry.js +0 -584
  91. package/dist/config/security.js +0 -212
  92. package/dist/config/timeouts.js +0 -74
  93. package/dist/config/types.js +0 -1
  94. package/dist/config/utils.js +0 -57
  95. package/dist/core/agent/artifact-progress.js +0 -59
  96. package/dist/core/agent/artifact-resolve.js +0 -79
  97. package/dist/core/agent/audit-gate.js +0 -53
  98. package/dist/core/agent/compaction.js +0 -89
  99. package/dist/core/agent/constants.js +0 -90
  100. package/dist/core/agent/context-log.js +0 -454
  101. package/dist/core/agent/context-renderer.js +0 -45
  102. package/dist/core/agent/critic-gate.js +0 -132
  103. package/dist/core/agent/hallucination-gate.js +0 -197
  104. package/dist/core/agent/loop-state.js +0 -68
  105. package/dist/core/agent/prefix-monitor.js +0 -101
  106. package/dist/core/agent/reasoning-resolver.js +0 -65
  107. package/dist/core/agent/token-tracker.js +0 -99
  108. package/dist/core/agent/tool-batch.js +0 -312
  109. package/dist/core/agent/tool-images.js +0 -18
  110. package/dist/core/agent/tool-output.js +0 -116
  111. package/dist/core/agent/tool-pairing.js +0 -60
  112. package/dist/core/agent-moe.js +0 -248
  113. package/dist/core/agent.js +0 -1299
  114. package/dist/core/bootstrap/agent-phase.js +0 -66
  115. package/dist/core/bootstrap/config-phase.js +0 -86
  116. package/dist/core/bootstrap/modules-phase.js +0 -269
  117. package/dist/core/bootstrap/provider-phase.js +0 -183
  118. package/dist/core/bootstrap/session-phase.js +0 -204
  119. package/dist/core/bootstrap/state.js +0 -94
  120. package/dist/core/bootstrap/workspace-phase.js +0 -115
  121. package/dist/core/bootstrap.js +0 -112
  122. package/dist/core/crash-handler.js +0 -62
  123. package/dist/core/environment.js +0 -224
  124. package/dist/core/host-plan.js +0 -43
  125. package/dist/core/host.js +0 -23
  126. package/dist/core/index.js +0 -3
  127. package/dist/core/prompt-builder.js +0 -95
  128. package/dist/core/prompt-overflow.js +0 -306
  129. package/dist/core/session-logger.js +0 -375
  130. package/dist/core/system-prompt.js +0 -117
  131. package/dist/core/types.js +0 -1
  132. package/dist/core/version.js +0 -28
  133. package/dist/core/web-host.js +0 -34
  134. package/dist/core/workspace.js +0 -80
  135. package/dist/i18n/index.js +0 -80
  136. package/dist/index.js +0 -30
  137. package/dist/llm/cache-usage.js +0 -76
  138. package/dist/llm/image-utils.js +0 -138
  139. package/dist/llm/index.js +0 -4
  140. package/dist/llm/llm-errors.js +0 -50
  141. package/dist/llm/model-loader.js +0 -86
  142. package/dist/llm/models-dev.js +0 -121
  143. package/dist/llm/openai-compat.js +0 -756
  144. package/dist/llm/orchestrator.js +0 -294
  145. package/dist/llm/provider-budget.js +0 -68
  146. package/dist/llm/provider-context.js +0 -233
  147. package/dist/llm/provider.js +0 -9
  148. package/dist/llm/response.js +0 -44
  149. package/dist/llm/stream-state.js +0 -26
  150. package/dist/llm/token-counter.js +0 -83
  151. package/dist/llm/types.js +0 -1
  152. package/dist/logger/app-logger.js +0 -212
  153. package/dist/logger/file-log.js +0 -160
  154. package/dist/logger/index.js +0 -2
  155. package/dist/migration/backup.js +0 -56
  156. package/dist/migration/detect.js +0 -61
  157. package/dist/migration/index.js +0 -3
  158. package/dist/modules/artifacts/store.js +0 -62
  159. package/dist/modules/browser/actions.js +0 -79
  160. package/dist/modules/browser/bridge-client.js +0 -203
  161. package/dist/modules/browser/bridge-path.js +0 -10
  162. package/dist/modules/browser/console-buffer.js +0 -37
  163. package/dist/modules/browser/cookie-store.js +0 -29
  164. package/dist/modules/browser/driver-types.js +0 -1
  165. package/dist/modules/browser/driver.js +0 -186
  166. package/dist/modules/browser/index.js +0 -9
  167. package/dist/modules/browser/module.js +0 -30
  168. package/dist/modules/browser/session.js +0 -322
  169. package/dist/modules/browser/snapshot.js +0 -154
  170. package/dist/modules/browser/types.js +0 -13
  171. package/dist/modules/certification/cli.js +0 -264
  172. package/dist/modules/certification/fact-checker.js +0 -90
  173. package/dist/modules/certification/loader.js +0 -127
  174. package/dist/modules/certification/manifest.js +0 -231
  175. package/dist/modules/certification/runner.js +0 -233
  176. package/dist/modules/certification/scenarios.js +0 -586
  177. package/dist/modules/certification/syntax-scenarios.js +0 -50
  178. package/dist/modules/certification/types.js +0 -1
  179. package/dist/modules/context/chunk-query.js +0 -122
  180. package/dist/modules/context/fact-extractor.js +0 -170
  181. package/dist/modules/context/history.js +0 -15
  182. package/dist/modules/context/index.js +0 -2
  183. package/dist/modules/context/manager.js +0 -482
  184. package/dist/modules/critic/client.js +0 -176
  185. package/dist/modules/critic/evidence.js +0 -81
  186. package/dist/modules/critic/provider.js +0 -45
  187. package/dist/modules/critic/tools.js +0 -78
  188. package/dist/modules/critic/types.js +0 -1
  189. package/dist/modules/execution/audit-runners.js +0 -206
  190. package/dist/modules/execution/auditor.js +0 -222
  191. package/dist/modules/execution/execution-plugin.js +0 -478
  192. package/dist/modules/execution/index.js +0 -8
  193. package/dist/modules/execution/input-from.js +0 -70
  194. package/dist/modules/execution/module.js +0 -891
  195. package/dist/modules/execution/moe-executor.js +0 -443
  196. package/dist/modules/execution/plan-actions.js +0 -642
  197. package/dist/modules/execution/plan-checks.js +0 -35
  198. package/dist/modules/execution/plan-coverage.js +0 -71
  199. package/dist/modules/execution/plan-persister.js +0 -46
  200. package/dist/modules/execution/plan-steps.js +0 -31
  201. package/dist/modules/execution/plan-store.js +0 -274
  202. package/dist/modules/execution/plan-tool.js +0 -249
  203. package/dist/modules/execution/plan-validator.js +0 -197
  204. package/dist/modules/execution/planner.js +0 -103
  205. package/dist/modules/execution/stuck-detector.js +0 -834
  206. package/dist/modules/execution/tracker.js +0 -92
  207. package/dist/modules/execution/transient-error.js +0 -30
  208. package/dist/modules/execution/types.js +0 -1
  209. package/dist/modules/execution/verifier.js +0 -343
  210. package/dist/modules/execution/windows-commands.js +0 -52
  211. package/dist/modules/hallucination/artifact-claim.js +0 -93
  212. package/dist/modules/hallucination/confidence.js +0 -81
  213. package/dist/modules/hallucination/consistency.js +0 -37
  214. package/dist/modules/hallucination/detector.js +0 -57
  215. package/dist/modules/hallucination/factual.js +0 -205
  216. package/dist/modules/hallucination/index.js +0 -6
  217. package/dist/modules/hallucination/js-identifiers.js +0 -261
  218. package/dist/modules/hallucination/llm-judge.js +0 -116
  219. package/dist/modules/hallucination/success-claim.js +0 -59
  220. package/dist/modules/index.js +0 -5
  221. package/dist/modules/indexer/cache.js +0 -88
  222. package/dist/modules/indexer/index.js +0 -4
  223. package/dist/modules/indexer/map-command.js +0 -33
  224. package/dist/modules/indexer/map-select.js +0 -87
  225. package/dist/modules/indexer/module.js +0 -293
  226. package/dist/modules/indexer/project-profile.js +0 -184
  227. package/dist/modules/indexer/symbols.js +0 -189
  228. package/dist/modules/indexer/walker.js +0 -285
  229. package/dist/modules/lsp/check-tool.js +0 -61
  230. package/dist/modules/lsp/client.js +0 -406
  231. package/dist/modules/lsp/command.js +0 -53
  232. package/dist/modules/lsp/config.js +0 -189
  233. package/dist/modules/lsp/index.js +0 -4
  234. package/dist/modules/lsp/module.js +0 -295
  235. package/dist/modules/lsp/probe.js +0 -86
  236. package/dist/modules/lsp/project-root.js +0 -69
  237. package/dist/modules/lsp/startup-check.js +0 -154
  238. package/dist/modules/lsp/types.js +0 -1
  239. package/dist/modules/mcp/client.js +0 -445
  240. package/dist/modules/mcp/index.js +0 -4
  241. package/dist/modules/mcp/module.js +0 -295
  242. package/dist/modules/mcp/registry.js +0 -20
  243. package/dist/modules/memory/index.js +0 -2
  244. package/dist/modules/memory/module.js +0 -101
  245. package/dist/modules/memory/search.js +0 -45
  246. package/dist/modules/memory/store.js +0 -107
  247. package/dist/modules/onboarding/init.js +0 -47
  248. package/dist/modules/onboarding/meet.js +0 -30
  249. package/dist/modules/onboarding/mode.js +0 -30
  250. package/dist/modules/onboarding/prompts.js +0 -43
  251. package/dist/modules/pipelines/engine.js +0 -70
  252. package/dist/modules/pipelines/index.js +0 -4
  253. package/dist/modules/pipelines/parser.js +0 -59
  254. package/dist/modules/pipelines/template.js +0 -18
  255. package/dist/modules/plugins/builtin/lint-on-write.js +0 -377
  256. package/dist/modules/plugins/builtin/notify.js +0 -11
  257. package/dist/modules/plugins/index.js +0 -2
  258. package/dist/modules/plugins/loader.js +0 -85
  259. package/dist/modules/plugins/manager.js +0 -244
  260. package/dist/modules/plugins/types.js +0 -1
  261. package/dist/modules/pricing/index.js +0 -70
  262. package/dist/modules/pricing/prices.js +0 -147
  263. package/dist/modules/processes/detect.js +0 -34
  264. package/dist/modules/processes/index.js +0 -4
  265. package/dist/modules/processes/kill-tree.js +0 -52
  266. package/dist/modules/processes/registry.js +0 -294
  267. package/dist/modules/processes/runner.js +0 -23
  268. package/dist/modules/providers/cache.js +0 -23
  269. package/dist/modules/providers/capabilities.js +0 -28
  270. package/dist/modules/providers/create.js +0 -21
  271. package/dist/modules/providers/factory.js +0 -28
  272. package/dist/modules/providers/fallback.js +0 -81
  273. package/dist/modules/providers/health.js +0 -47
  274. package/dist/modules/providers/index.js +0 -6
  275. package/dist/modules/providers/manager.js +0 -207
  276. package/dist/modules/providers/naming.js +0 -15
  277. package/dist/modules/providers/preflight.js +0 -71
  278. package/dist/modules/providers/presets.js +0 -232
  279. package/dist/modules/providers/registry.js +0 -27
  280. package/dist/modules/providers/types.js +0 -1
  281. package/dist/modules/reasoning/policy.js +0 -42
  282. package/dist/modules/reasoning/probe.js +0 -116
  283. package/dist/modules/registry.js +0 -48
  284. package/dist/modules/security/audit-log.js +0 -119
  285. package/dist/modules/security/audit-notifier.js +0 -267
  286. package/dist/modules/security/command-validator.js +0 -272
  287. package/dist/modules/security/content-scanner.js +0 -53
  288. package/dist/modules/security/data-sanitizer.js +0 -82
  289. package/dist/modules/security/encryption.js +0 -216
  290. package/dist/modules/security/index.js +0 -15
  291. package/dist/modules/security/network-validator.js +0 -236
  292. package/dist/modules/security/path-validator.js +0 -261
  293. package/dist/modules/security/protected-paths.js +0 -73
  294. package/dist/modules/security/rate-limiter.js +0 -98
  295. package/dist/modules/security/security-policies.js +0 -499
  296. package/dist/modules/security/session-encryption.js +0 -182
  297. package/dist/modules/security/session-isolation.js +0 -75
  298. package/dist/modules/session/auto-name.js +0 -63
  299. package/dist/modules/session/export.js +0 -98
  300. package/dist/modules/session/index.js +0 -4
  301. package/dist/modules/session/manager.js +0 -234
  302. package/dist/modules/session/module.js +0 -33
  303. package/dist/modules/session/store.js +0 -295
  304. package/dist/modules/session/types.js +0 -1
  305. package/dist/modules/setup/answers.js +0 -35
  306. package/dist/modules/setup/apply.js +0 -79
  307. package/dist/modules/setup/discovery.js +0 -72
  308. package/dist/modules/skills/index.js +0 -3
  309. package/dist/modules/skills/loader.js +0 -86
  310. package/dist/modules/skills/matcher.js +0 -27
  311. package/dist/modules/skills/module.js +0 -141
  312. package/dist/modules/types.js +0 -1
  313. package/dist/modules/updater/changelog-reader.js +0 -93
  314. package/dist/modules/updater/checker.js +0 -101
  315. package/dist/modules/updater/dev-detect.js +0 -18
  316. package/dist/modules/updater/index.js +0 -4
  317. package/dist/modules/updater/module.js +0 -129
  318. package/dist/modules/user-profile/compressor.js +0 -18
  319. package/dist/modules/user-profile/index.js +0 -2
  320. package/dist/modules/user-profile/profile.js +0 -77
  321. package/dist/modules/webui/answer-api.js +0 -29
  322. package/dist/modules/webui/assets.js +0 -50
  323. package/dist/modules/webui/body.js +0 -21
  324. package/dist/modules/webui/commands-settings.js +0 -209
  325. package/dist/modules/webui/commands-shared.js +0 -60
  326. package/dist/modules/webui/commands.js +0 -174
  327. package/dist/modules/webui/config-api.js +0 -134
  328. package/dist/modules/webui/file-api.js +0 -202
  329. package/dist/modules/webui/forward.js +0 -159
  330. package/dist/modules/webui/history-api.js +0 -112
  331. package/dist/modules/webui/host-state.js +0 -60
  332. package/dist/modules/webui/i18n-api.js +0 -9
  333. package/dist/modules/webui/limits.js +0 -6
  334. package/dist/modules/webui/log-forward.js +0 -20
  335. package/dist/modules/webui/memory-commands.js +0 -64
  336. package/dist/modules/webui/model-cache.js +0 -18
  337. package/dist/modules/webui/module.js +0 -148
  338. package/dist/modules/webui/persist.js +0 -24
  339. package/dist/modules/webui/prompt-io.js +0 -97
  340. package/dist/modules/webui/providers-api.js +0 -337
  341. package/dist/modules/webui/providers-view.js +0 -56
  342. package/dist/modules/webui/reasoning-view.js +0 -15
  343. package/dist/modules/webui/run-agent.js +0 -81
  344. package/dist/modules/webui/server.js +0 -284
  345. package/dist/modules/webui/sessions-api.js +0 -178
  346. package/dist/modules/webui/settings-api.js +0 -561
  347. package/dist/modules/webui/setup-api.js +0 -201
  348. package/dist/modules/webui/state.js +0 -74
  349. package/dist/modules/webui/util.js +0 -261
  350. package/dist/output/bus.js +0 -37
  351. package/dist/output/channel.js +0 -285
  352. package/dist/output/format.js +0 -15
  353. package/dist/output/index.js +0 -8
  354. package/dist/output/json-sink.js +0 -24
  355. package/dist/output/machine.js +0 -9
  356. package/dist/output/session-sink.js +0 -27
  357. package/dist/output/types.js +0 -1
  358. package/dist/tools/approve.js +0 -41
  359. package/dist/tools/attach-image.js +0 -102
  360. package/dist/tools/auto-fixer.js +0 -180
  361. package/dist/tools/auto-tags.js +0 -83
  362. package/dist/tools/bash.js +0 -649
  363. package/dist/tools/browser.js +0 -160
  364. package/dist/tools/chunk-query.js +0 -112
  365. package/dist/tools/create-dir.js +0 -60
  366. package/dist/tools/delete-file.js +0 -67
  367. package/dist/tools/download-file.js +0 -142
  368. package/dist/tools/edit-file.js +0 -136
  369. package/dist/tools/enable-tools.js +0 -59
  370. package/dist/tools/executor.js +0 -304
  371. package/dist/tools/file-info.js +0 -49
  372. package/dist/tools/filter-tools.js +0 -17
  373. package/dist/tools/glob-tool.js +0 -37
  374. package/dist/tools/grep-tool.js +0 -142
  375. package/dist/tools/hidden-tools-block.js +0 -37
  376. package/dist/tools/index.js +0 -88
  377. package/dist/tools/list-dir.js +0 -53
  378. package/dist/tools/load-skill.js +0 -51
  379. package/dist/tools/mcp-call.js +0 -80
  380. package/dist/tools/meet-done.js +0 -14
  381. package/dist/tools/move-file.js +0 -94
  382. package/dist/tools/path-utils.js +0 -108
  383. package/dist/tools/pipeline-run.js +0 -167
  384. package/dist/tools/preview.js +0 -2
  385. package/dist/tools/process-ids.js +0 -31
  386. package/dist/tools/process-kill.js +0 -33
  387. package/dist/tools/process-list.js +0 -38
  388. package/dist/tools/process-log.js +0 -49
  389. package/dist/tools/process-wait.js +0 -63
  390. package/dist/tools/prompt-io.js +0 -29
  391. package/dist/tools/question.js +0 -288
  392. package/dist/tools/read-file.js +0 -200
  393. package/dist/tools/recall.js +0 -124
  394. package/dist/tools/registry.js +0 -48
  395. package/dist/tools/remember.js +0 -72
  396. package/dist/tools/scope-check.js +0 -32
  397. package/dist/tools/scope-request.js +0 -96
  398. package/dist/tools/search-history.js +0 -88
  399. package/dist/tools/session-info.js +0 -46
  400. package/dist/tools/set-thinking.js +0 -75
  401. package/dist/tools/subagent.js +0 -257
  402. package/dist/tools/syntax-validator.js +0 -379
  403. package/dist/tools/types.js +0 -1
  404. package/dist/tools/user-input.js +0 -134
  405. package/dist/tools/web-browse.js +0 -93
  406. package/dist/tools/web-fetch.js +0 -108
  407. package/dist/tools/web-search.js +0 -107
  408. package/dist/tools/write-file.js +0 -128
  409. package/dist/ui/action-log.js +0 -13
  410. package/dist/ui/box.js +0 -78
  411. package/dist/ui/colors.js +0 -6
  412. package/dist/ui/diff.js +0 -189
  413. package/dist/ui/index.js +0 -7
  414. package/dist/ui/line-editor.js +0 -1083
  415. package/dist/ui/line-math.js +0 -98
  416. package/dist/ui/md-formatter.js +0 -322
  417. package/dist/ui/output.js +0 -19
  418. package/dist/ui/plan-view.js +0 -109
  419. package/dist/ui/renderer.js +0 -589
  420. package/dist/ui/spinner.js +0 -91
  421. package/dist/ui/table.js +0 -142
  422. package/dist/ui/theme.js +0 -143
  423. package/dist/utils/child-run.js +0 -20
  424. package/dist/utils/error.js +0 -4
  425. package/dist/utils/index.js +0 -6
  426. package/dist/utils/retry.js +0 -17
  427. package/dist/utils/sleep.js +0 -23
  428. package/dist/utils/truncate.js +0 -9
@@ -1,834 +0,0 @@
1
- // Детектор застревания: повторы, фейлы, read-only петли, bash-флейлинг, хинты.
2
- import { t } from "../../i18n/index";
3
- import { isTransientError } from "./transient-error";
4
- const BLOCKING_PATTERNS = [
5
- /EACCES/i,
6
- /permission denied/i,
7
- /EPERM/i,
8
- /ENOENT.*node_modules/i,
9
- /ENOTDIR/i,
10
- /invalid.*token/i,
11
- /unauthorized/i,
12
- /401/i,
13
- /403/i,
14
- ];
15
- /** Классифицирует вывод ошибки: транзиентная / блокирующая / системная. */
16
- export function classifyError(output) {
17
- if (isTransientError(output))
18
- return "transient";
19
- for (const p of BLOCKING_PATTERNS) {
20
- if (p.test(output))
21
- return "blocking";
22
- }
23
- return "systematic";
24
- }
25
- /**
26
- * Тулы только чтения: состояние наблюдают, не меняют. Длинная серия только их
27
- * без write/exec между — модель читает/разведывает, ничего не производя:
28
- * read-only петля, которую детектор обязан подсветить (было: 50+ read_file
29
- * итераций с нулём записей после ложноположительного реджекта готового
30
- * аудита задачи).
31
- */
32
- const READ_ONLY_TOOLS = new Set([
33
- "read_file",
34
- "glob",
35
- "grep",
36
- "list_dir",
37
- "file_info",
38
- "browser",
39
- "web_search",
40
- "web_fetch",
41
- "web_browse",
42
- "search_history",
43
- "recall",
44
- "project_map",
45
- "chunk_query",
46
- "process_list",
47
- "process_log",
48
- "plan",
49
- "plan_step",
50
- "todo",
51
- "verify",
52
- "load_skill",
53
- ]);
54
- /** Подряд read-only вызовов, образующих петлю. */
55
- const READ_ONLY_LOOP_THRESHOLD = 10;
56
- /**
57
- * Bash-флейлинг: ≥BASH_FLAIL_THRESHOLD фейлов в последних BASH_FLAIL_WINDOW
58
- * bash-попытках, независимо от перемежающихся успехов. Per-word hard-stop
59
- * (bash.ts) обходится ротацией команд (wc → cat → Get-Content → …); окно
60
- * ловит саму ротацию (было в ses_mt4x3zbo: 8 фейловых shell-уловок за ~12
61
- * итераций при подсчёте/склейке файлов на Windows).
62
- */
63
- const BASH_FLAIL_WINDOW = 6;
64
- const BASH_FLAIL_THRESHOLD = 4;
65
- const ANSI_RE = /\x1b\[[0-9;]*m/g;
66
- /** Пути (абсолютные/относительные) + опционально :line:col. */
67
- const ERROR_LOC_RE = /(?:[A-Za-z]:[\\/])?(?:[\w.@+-]+[\\/])+[\w.@+-]+\.[a-zA-Z0-9]{1,6}(?::\d+(?::\d+)?)?/g;
68
- const SIGNATURE_MAX_CHARS = 120;
69
- const SEARCHABLE_PATTERNS = [
70
- /error TS\d+/i,
71
- /ERR_[A-Z_]+/,
72
- /ENOENT|EACCES|EPERM|ECONNREFUSED|ETIMEDOUT|ECONNRESET|ENOTFOUND|EADDRINUSE/i,
73
- /Cannot find module|Module not found|ERR_MODULE_NOT_FOUND/i,
74
- /TypeError|ReferenceError|SyntaxError|RangeError/i,
75
- /is not a function|is not defined|is not a constructor/i,
76
- /Cannot read properties of/i,
77
- /failed to (compile|build|resolve|parse)/i,
78
- /fatal error|panic/i,
79
- ];
80
- const RUNTIME_WORDS = [
81
- "bun",
82
- "node",
83
- "deno",
84
- "npm",
85
- "yarn",
86
- "pnpm",
87
- "pip",
88
- "pip3",
89
- "python",
90
- "python3",
91
- "tsc",
92
- "tsx",
93
- "npx",
94
- "go",
95
- "cargo",
96
- "gradle",
97
- "maven",
98
- "make",
99
- ];
100
- const FRAMEWORK_WORDS = [
101
- "react",
102
- "vue",
103
- "angular",
104
- "svelte",
105
- "vite",
106
- "next",
107
- "nest",
108
- "express",
109
- "fastify",
110
- "flask",
111
- "django",
112
- "spring",
113
- "webpack",
114
- "tailwind",
115
- ];
116
- /**
117
- * Стабильная идентичность ошибки: тул + нормализованные первые error-строки
118
- * (ANSI вычищен, пути/локации заменены, пробелы склеены, кап 120 символов).
119
- * Два прогона с одной первопричиной дают одну сигнатуру — она и триггерит
120
- * автопоиск в вебе.
121
- */
122
- export function normalizeErrorSignature(toolName, output) {
123
- if (!output)
124
- return null;
125
- const cleaned = output
126
- .replace(ANSI_RE, "")
127
- .replace(ERROR_LOC_RE, " <path>")
128
- .split("\n")
129
- .map((l) => l.trim())
130
- .filter(Boolean)
131
- .join(" ")
132
- .replace(/\s+/g, " ")
133
- .trim();
134
- if (!cleaned)
135
- return null;
136
- return `${toolName}::${cleaned.slice(0, SIGNATURE_MAX_CHARS)}`;
137
- }
138
- /**
139
- * Гейт автопоиска в вебе: искать стоит только реальный содержательный текст
140
- * ошибки. "Command failed with exit code 1" без деталей — шум, поиск по нему
141
- * лишь жжёт запрос.
142
- */
143
- export function isSearchableError(output) {
144
- if (!output?.trim())
145
- return false;
146
- const text = output.trim();
147
- return SEARCHABLE_PATTERNS.some((p) => p.test(text));
148
- }
149
- /**
150
- * Строит поисковый запрос по падающей ошибке: до 3 чищенных error-строк (пути
151
- * вырезаны) с префиксом рантайма/фреймворка из step/bash-контекста и суффиксом
152
- * "how to fix". На пустом тексте — фолбэк `tool step`. Кап maxQueryChars.
153
- */
154
- export function buildSearchQuery(stepDescription, lastBashCommand, lastErrorOutput, toolName, maxQueryChars) {
155
- const errorText = (lastErrorOutput || "")
156
- .replace(ANSI_RE, "")
157
- .replace(ERROR_LOC_RE, " <path>")
158
- .split("\n")
159
- .map((l) => l.trim())
160
- .filter(Boolean)
161
- .slice(0, 3)
162
- .join(" ")
163
- .replace(/\s+/g, " ")
164
- .trim();
165
- const context = `${stepDescription} ${lastBashCommand}`.toLowerCase();
166
- const runtime = RUNTIME_WORDS.find((w) => context.includes(w)) || "";
167
- const framework = FRAMEWORK_WORDS.find((w) => context.includes(w)) || "";
168
- let query;
169
- if (errorText) {
170
- query =
171
- runtime && !errorText.toLowerCase().includes(runtime) ? `${runtime} ${errorText}` : errorText;
172
- if (framework && !query.toLowerCase().includes(framework))
173
- query = `${query} ${framework}`;
174
- query = `${query} how to fix`;
175
- }
176
- else if (runtime || framework) {
177
- query = `${[runtime, framework, "error", "how to fix"].filter(Boolean).join(" ")}`;
178
- }
179
- else {
180
- query = `${toolName} ${stepDescription} how to fix`;
181
- }
182
- return query.slice(0, maxQueryChars);
183
- }
184
- /** Детектор застревания: счётчики итераций, ошибок, повторов, петель, эскалаций. */
185
- export class StuckDetector {
186
- threshold;
187
- errorThreshold;
188
- iterationsOnCurrentStep = 0;
189
- currentStepId = null;
190
- toolErrors = new Map();
191
- currentStepDescription = "";
192
- recentToolCalls = [];
193
- maxRecentCalls = 10;
194
- repetitionThreshold = 3;
195
- consecutiveFailures = 0;
196
- lastFailedTool = "";
197
- lastErrorOutput = "";
198
- escalationCount = 0;
199
- escalationThreshold = 3;
200
- fileRewriteCount = new Map();
201
- fileRewriteThreshold = 3;
202
- lastBashCommand = "";
203
- lastBashOutput = "";
204
- emptyBashRunCount = 0;
205
- readOnlyStreak = 0;
206
- bashRecent = [];
207
- errorSignatureCounts = new Map();
208
- searchedErrorSignatures = new Set();
209
- webSearchThreshold;
210
- constructor(threshold = 6, errorThreshold = 3, webSearchThreshold = 5) {
211
- this.threshold = threshold;
212
- this.errorThreshold = errorThreshold;
213
- this.webSearchThreshold = webSearchThreshold;
214
- }
215
- recordIteration(stepId) {
216
- if (stepId === this.currentStepId) {
217
- this.iterationsOnCurrentStep++;
218
- }
219
- else {
220
- this.resetStepState(stepId);
221
- }
222
- }
223
- /** Отмечает вызов тула (для детекции повторов; write/exec сбрасывают read-only стрик). */
224
- recordToolCall(name, args) {
225
- const argsKey = JSON.stringify(args);
226
- this.recentToolCalls.push({ name, argsKey });
227
- if (this.recentToolCalls.length > this.maxRecentCalls) {
228
- this.recentToolCalls.shift();
229
- }
230
- // Трекаем подряд read-only стрик. Пишущий/исполняющий тул сбрасывает;
231
- // plan/todo-бухгалтерия считается read-only (не реальный прогресс).
232
- if (READ_ONLY_TOOLS.has(name)) {
233
- this.readOnlyStreak++;
234
- }
235
- else {
236
- this.readOnlyStreak = 0;
237
- }
238
- }
239
- /**
240
- * True после длинной серии read-only вызовов без записей между. Модель
241
- * исследует/петляет, ничего не производя — инжектим recovery-хинт, чтобы
242
- * перестала перечитывать и реально правила файлы.
243
- */
244
- hasReadOnlyLoop() {
245
- return this.readOnlyStreak >= READ_ONLY_LOOP_THRESHOLD;
246
- }
247
- /** Отмечает ошибку тула (счётчики + сигнатура для автопоиска). */
248
- recordToolError(toolName, output) {
249
- this.toolErrors.set(toolName, (this.toolErrors.get(toolName) || 0) + 1);
250
- this.consecutiveFailures++;
251
- this.lastFailedTool = toolName;
252
- if (output)
253
- this.lastErrorOutput = output;
254
- const sig = normalizeErrorSignature(toolName, output);
255
- if (sig) {
256
- this.errorSignatureCounts.set(sig, (this.errorSignatureCounts.get(sig) || 0) + 1);
257
- }
258
- }
259
- /** Последний текст ошибки. */
260
- getLastErrorOutput() {
261
- return this.lastErrorOutput;
262
- }
263
- /**
264
- * Записывает КАЖДЫЙ вызов bash (успех или нет): детекция рассуждает о
265
- * повторных прогонах с пустым выводом, проблемах entry-point и ошибках
266
- * платформы (PowerShell-командлеты в cmd.exe, bash-heredoc'и, …).
267
- */
268
- recordBashOutput(command, output) {
269
- const trimmed = output.trim();
270
- if (command === this.lastBashCommand && !trimmed) {
271
- this.emptyBashRunCount++;
272
- }
273
- else {
274
- this.emptyBashRunCount = 0;
275
- }
276
- this.lastBashCommand = command;
277
- this.lastBashOutput = output;
278
- }
279
- /** Исход одной bash-попытки (успех/фейл) — для детекции флейлинга. */
280
- recordBashAttempt(success) {
281
- this.bashRecent.push(success);
282
- if (this.bashRecent.length > BASH_FLAIL_WINDOW)
283
- this.bashRecent.shift();
284
- }
285
- /** True, если свежие bash-попытки в массе фейлятся — модель флейлит. */
286
- hasBashFlailing() {
287
- if (this.bashRecent.length < BASH_FLAIL_THRESHOLD)
288
- return false;
289
- let failures = 0;
290
- for (const ok of this.bashRecent)
291
- if (!ok)
292
- failures++;
293
- return failures >= BASH_FLAIL_THRESHOLD;
294
- }
295
- /** Последняя bash-команда. */
296
- getLastBashCommand() {
297
- return this.lastBashCommand;
298
- }
299
- /** Вывод последней bash-команды. */
300
- getLastBashOutput() {
301
- return this.lastBashOutput;
302
- }
303
- /** Последний упавший тул. */
304
- getLastFailedTool() {
305
- return this.lastFailedTool;
306
- }
307
- /**
308
- * Первая сигнатура ошибки, чей счётчик повторов достиг порога веб-поиска и
309
- * которая ЕЩЁ не искалась (или размаркирована для ретрая). Именно она
310
- * триггерит автопоиск — не итерации и не per-tool счётчик ошибок.
311
- */
312
- getRepeatedErrorSignature() {
313
- for (const [sig, count] of this.errorSignatureCounts) {
314
- if (count >= this.webSearchThreshold && !this.searchedErrorSignatures.has(sig)) {
315
- return sig;
316
- }
317
- }
318
- return null;
319
- }
320
- /** Счётчик повторов сигнатуры ошибки. */
321
- getErrorSignatureCount(sig) {
322
- return this.errorSignatureCounts.get(sig) || 0;
323
- }
324
- /** Помечает сигнатуру как уже искавшуюся. */
325
- markErrorSearched(sig) {
326
- this.searchedErrorSignatures.add(sig);
327
- }
328
- /** Снимает метку поиска (разрешает один ретрай). */
329
- unmarkErrorSearched(sig) {
330
- this.searchedErrorSignatures.delete(sig);
331
- }
332
- /** True, если сигнатура уже искалась. */
333
- hasErrorSearched(sig) {
334
- return this.searchedErrorSignatures.has(sig);
335
- }
336
- /** Итераций на текущем шаге. */
337
- getIterationsOnCurrentStep() {
338
- return this.iterationsOnCurrentStep;
339
- }
340
- /** Отмечает успешный тул: сброс фейлов, затухание per-tool счётчиков и итераций. */
341
- recordToolSuccess() {
342
- this.consecutiveFailures = 0;
343
- this.lastFailedTool = "";
344
- // NOTE: escalationCount осознанно НЕ сбрасываем. Один тривиальный успех
345
- // (напр. один read_file) раньше его чистил, и shouldEscalate() на флейлящей
346
- // сессии почти не достигался — в ущерб анти-гейминг свойству, которое
347
- // resetStepState() явно хранит.
348
- // Затухание per-tool счётчиков на продуктивных вызовах: рано упавший тул не
349
- // держит варнинг "Tool X failed N times" вечно (ses_mt4fn58c — bash упал 3x,
350
- // варнинг перелоггировался после 30 успешных записей). Свежие фейлы счёт
351
- // набирают заново.
352
- for (const [tool, count] of this.toolErrors) {
353
- if (count <= 1)
354
- this.toolErrors.delete(tool);
355
- else
356
- this.toolErrors.set(tool, count - 1);
357
- }
358
- // Затухание счётчика итераций на продуктивных вызовах: чтение новых файлов,
359
- // записи, правки — всё прогресс. Защита от ложных stuck-варнингов при
360
- // легитимной разведке файлов (напр. чтение 12 файлов в analytic-шаге).
361
- if (this.iterationsOnCurrentStep > 0) {
362
- this.iterationsOnCurrentStep = Math.max(0, this.iterationsOnCurrentStep - 1);
363
- }
364
- }
365
- /** Ставит текущий шаг (сброс per-step состояния при смене). */
366
- setCurrentStep(stepId, description) {
367
- if (stepId !== this.currentStepId) {
368
- this.resetStepState(stepId);
369
- }
370
- this.currentStepDescription = description;
371
- }
372
- /** True, если итераций на шаге больше порога. */
373
- isStuck() {
374
- return this.iterationsOnCurrentStep > this.threshold;
375
- }
376
- /** True, если тул (или любой) ошибался ≥ порога. */
377
- hasRepetitiveErrors(toolName) {
378
- if (toolName) {
379
- return (this.toolErrors.get(toolName) || 0) >= this.errorThreshold;
380
- }
381
- return Array.from(this.toolErrors.values()).some((c) => c >= this.errorThreshold);
382
- }
383
- /** True при повторяющихся вызовах: подряд идентичных или перемежающихся (A,B,A,B,A). */
384
- hasRepetitiveToolCalls() {
385
- if (this.recentToolCalls.length < this.repetitionThreshold)
386
- return false;
387
- const last = this.recentToolCalls[this.recentToolCalls.length - 1];
388
- // Проверка подряд идентичных (исходная логика)
389
- let consecutiveCount = 1;
390
- for (let i = this.recentToolCalls.length - 2; i >= 0; i--) {
391
- if (this.recentToolCalls[i].name === last.name &&
392
- this.recentToolCalls[i].argsKey === last.argsKey) {
393
- consecutiveCount++;
394
- }
395
- else {
396
- break;
397
- }
398
- }
399
- if (consecutiveCount >= this.repetitionThreshold)
400
- return true;
401
- // Плюс перемежающиеся паттерны (A, B, A, B, A): считаем каждую связку
402
- // тул+args в окне и флагуем при ≥ порога
403
- const counts = new Map();
404
- for (const call of this.recentToolCalls) {
405
- const key = `${call.name}::${call.argsKey}`;
406
- counts.set(key, (counts.get(key) || 0) + 1);
407
- }
408
- for (const count of counts.values()) {
409
- if (count >= this.repetitionThreshold)
410
- return true;
411
- }
412
- return false;
413
- }
414
- /** True при ≥ порога подряд фейлов. */
415
- hasConsecutiveFailures() {
416
- return this.consecutiveFailures >= this.errorThreshold;
417
- }
418
- /** Число подряд фейлов. */
419
- getConsecutiveFailuresCount() {
420
- return this.consecutiveFailures;
421
- }
422
- /** Отмечает эскалацию (счётчик для shouldEscalate). */
423
- recordEscalation() {
424
- this.escalationCount++;
425
- }
426
- /** True, если эскалаций набралось на порог. */
427
- shouldEscalate() {
428
- return this.escalationCount >= this.escalationThreshold;
429
- }
430
- /** Сбрасывает счётчик эскалаций. */
431
- resetEscalation() {
432
- this.escalationCount = 0;
433
- }
434
- /** Число эскалаций. */
435
- getEscalationCount() {
436
- return this.escalationCount;
437
- }
438
- /** Хинты по описанию шага + состояниям, ещё не покрытым recovery-сообщением. */
439
- getHints() {
440
- const hints = [];
441
- const desc = this.currentStepDescription.toLowerCase();
442
- if (desc.includes("install") || desc.includes("npm") || desc.includes("pip")) {
443
- hints.push(t("exec.hint_deps"));
444
- }
445
- if (desc.includes("test") || desc.includes("spec")) {
446
- hints.push(t("exec.hint_test"));
447
- }
448
- if (desc.includes("build") || desc.includes("compile")) {
449
- hints.push(t("exec.hint_build"));
450
- }
451
- if (desc.includes("deploy") || desc.includes("publish")) {
452
- hints.push(t("exec.hint_deploy"));
453
- }
454
- // State-based буллеты. Recovery-сообщение (getRecoveryMessage) уже репортит
455
- // ПЕРВИЧНУЮ причину (приоритет: stuck > tool-errors > consecutive >
456
- // repetitive > read-only). Дублировать то же состояние хинтом — задвоить
457
- // гайданс в одном cooldown-блоке. Буллет добавляем, только если recovery
458
- // это состояние НЕ покрывает.
459
- const primary = this.getPrimaryReason();
460
- if (this.hasRepetitiveToolCalls() && primary !== "repetitive") {
461
- hints.push(t("exec.hint_repetitive"));
462
- }
463
- if (this.hasConsecutiveFailures() && primary !== "consecutive") {
464
- hints.push(t("exec.hint_consecutive"));
465
- }
466
- if (this.hasReadOnlyLoop() && primary !== "read-only") {
467
- hints.push(t("exec.hint_read_only"));
468
- }
469
- return hints;
470
- }
471
- /** Actionable-хинты по последней ошибке: рантаймы, синтаксис, сеть, шелл-несоответствия. */
472
- getActionableHints() {
473
- const hints = [];
474
- const error = this.lastErrorOutput;
475
- // Bash-хинты от фейла тула не зависят — срабатывают, даже когда команда
476
- // "успешна" с пустым выводом (потерянный entry point).
477
- const isScriptRun = /(^|[\s&])(bun|node|tsx|ts-node|deno|python|python3)\S*\s+[^|&]+\s+[^\s]+$/.test(this.lastBashCommand);
478
- if (isScriptRun && !this.lastBashOutput.trim() && this.emptyBashRunCount >= 2) {
479
- hints.push(`The command "${this.lastBashCommand}" ran ${this.emptyBashRunCount} times with EMPTY output. The program likely has no entry point — read the file with read_file and check that it actually calls its main function with process.argv / CLI arguments and prints results (console.log). Then run it again.`);
480
- }
481
- if (!error)
482
- return hints;
483
- // Несовместимость рантайма — тул/модуль крашится на этой версии Node
484
- if (/Cannot read properties of undefined|is not a function|is not a constructor/i.test(error)) {
485
- if (/node_modules/.test(error)) {
486
- hints.push("A dependency is incompatible with your Node.js version. Check if there is an alternative package or use a different runtime.");
487
- }
488
- }
489
- // Синтаксические ошибки TypeScript — модель сгенерила невалидный код
490
- if (/TS1005|TS1003|TS1109|TS1128|TS1434/i.test(error)) {
491
- hints.push("TypeScript syntax error. Read the error message carefully — it tells you the exact line and column. Fix the syntax before retrying.");
492
- }
493
- // Ошибки типов TypeScript — модель не понимает типы
494
- if (/TS2322|TS2345|TS2769|TS7006|TS7016/i.test(error)) {
495
- hints.push("TypeScript type mismatch. Check the type signature of the function/API you are using. If a package lacks type declarations, install @types/<package> or use skipLibCheck.");
496
- }
497
- // Модуль не найден — нет зависимости или неверный импорт
498
- if (/Cannot find module|Module not found|ERR_MODULE_NOT_FOUND/i.test(error)) {
499
- hints.push("Module not found. Run npm install or check if the import path is correct.");
500
- }
501
- // Ошибки прав доступа
502
- if (/EACCES|EPERM|permission denied/i.test(error)) {
503
- hints.push("Permission denied. Check file permissions or run with appropriate privileges.");
504
- }
505
- // Сетевые ошибки
506
- if (/ECONNREFUSED|ETIMEDOUT|ENOTFOUND|fetch failed/i.test(error)) {
507
- hints.push("Network error. Check if the server is running and accessible.");
508
- }
509
- // Команда не найдена
510
- if (/is not recognized|command not found|not found in path/i.test(error)) {
511
- hints.push("Command not found. Check if the tool is installed and in PATH.");
512
- }
513
- // Петля перезаписи: один файл безуспешно переписывается
514
- if (this.hasExcessiveRewrites()) {
515
- const file = this.getExcessiveRewriteFile();
516
- hints.push(`File ${file} has been rewritten ${this.getFileRewriteCount(file)} times without success. Stop rewriting and try a fundamentally different approach.`);
517
- }
518
- // Повторные идентичные bash-прогоны с пустым выводом — вероятно, потерянный
519
- // entry point (программа не вызывает main).
520
- // PowerShell-командлеты внутри cmd.exe (шелл-несоответствие Windows).
521
- if (/Write-Host|Get-Content|Select-String|Out-File|Set-Content/i.test(error)) {
522
- hints.push("That looks like a PowerShell cmdlet — the shell here is cmd.exe. Use echo/type for output or the read_file/write_file tools instead.");
523
- }
524
- // Модель выдумала несуществующий Bun API.
525
- if (/Bun\.\w+ is not a function|Bun\.\w+ is not defined|Bun\.\w+ is not a constructor/i.test(error)) {
526
- hints.push("That Bun API does not exist. Verify the API name in the Bun docs — common ones are Bun.file, Bun.write, Bun.spawn, Bun.serve. For file checks use fs.existsSync from node:fs.");
527
- }
528
- // Модель продолжает писать файл, в выводе которого type/syntax ошибка —
529
- // читай реальную ошибку и чини её, не переписывай вслепую.
530
- if (/error TS\d+|typecheck failed|syntax check failed/i.test(error)) {
531
- hints.push("The file still has a type/syntax error (see the error line in the output). Read the file with read_file around the reported line, fix the actual error, then re-run — rewriting the whole file blindly usually makes it worse.");
532
- }
533
- // Bash-heredoc в cmd.exe.
534
- if (/unexpected.*<<|Непредвиденное появление/i.test(error)) {
535
- hints.push("Heredoc (<< EOF) is a bash feature — this shell is cmd.exe and does not support it. Write the file with write_file instead.");
536
- }
537
- return hints;
538
- }
539
- /** Альтернативный тул при рантайм-краше (ts-node→tsx, jest→vitest, …). Null, если нечего предложить. */
540
- getToolAlternative() {
541
- const tool = this.lastFailedTool;
542
- const error = this.lastErrorOutput;
543
- if (!tool)
544
- return null;
545
- // Упавший тул с рантайм-крашем — предлагаем альтернативы
546
- if (/Cannot read properties of undefined|is not a function|TypeError|ReferenceError/i.test(error)) {
547
- // Карта упавших тулов на частые альтернативы
548
- const alternatives = {
549
- "ts-node": "tsx",
550
- jest: "vitest",
551
- mocha: "vitest",
552
- webpack: "vite",
553
- rollup: "vite",
554
- parcel: "vite",
555
- babel: "tsc",
556
- eslint: "biome",
557
- prettier: "biome",
558
- };
559
- for (const [failed, alt] of Object.entries(alternatives)) {
560
- if (tool.includes(failed) || error.includes(failed)) {
561
- return alt;
562
- }
563
- }
564
- }
565
- return null;
566
- }
567
- /** Отмечает перезапись файла (счётчик для детекции петли). */
568
- recordFileRewrite(filePath) {
569
- const count = (this.fileRewriteCount.get(filePath) || 0) + 1;
570
- this.fileRewriteCount.set(filePath, count);
571
- }
572
- /** Число перезаписей файла. */
573
- getFileRewriteCount(filePath) {
574
- return this.fileRewriteCount.get(filePath) || 0;
575
- }
576
- /** True, если какой-то файл переписывается ≥ порога. */
577
- hasExcessiveRewrites() {
578
- return Array.from(this.fileRewriteCount.values()).some((c) => c >= this.fileRewriteThreshold);
579
- }
580
- /** Файл с избыточными перезаписями, или null. */
581
- getExcessiveRewriteFile() {
582
- for (const [file, count] of this.fileRewriteCount) {
583
- if (count >= this.fileRewriteThreshold)
584
- return file;
585
- }
586
- return null;
587
- }
588
- /** Сообщение о повторяющемся туле (+хинт про process_wait для process_log). */
589
- getRepetitiveToolMessage() {
590
- if (!this.hasRepetitiveToolCalls())
591
- return "";
592
- const last = this.recentToolCalls[this.recentToolCalls.length - 1];
593
- const base = t("exec.repetitive_tool", {
594
- tool: last.name,
595
- count: this.repetitionThreshold,
596
- });
597
- // Опрос фонового процесса по одному process_log за раз жжёт LLM-вызов на
598
- // опрос — указываем на одиночное блокирующее ожидание.
599
- if (last.name === "process_log") {
600
- return `${base} ${t("exec.repetitive_process_log_hint")}`;
601
- }
602
- return base;
603
- }
604
- /**
605
- * Стабильная идентичность варнинга для анти-спам дедупа: тот же ключ каждую
606
- * итерацию — спам, НОВЫЙ ключ (или длинная пауза) заслуживает re-warn.
607
- */
608
- getWarningKey() {
609
- if (this.isStuck())
610
- return "stuck";
611
- const errorTool = Array.from(this.toolErrors.entries()).find(([_, c]) => c >= this.errorThreshold);
612
- if (errorTool)
613
- return `tool-errors:${errorTool[0]}`;
614
- if (this.hasBashFlailing())
615
- return "bash-flailing";
616
- if (this.hasConsecutiveFailures())
617
- return "consecutive";
618
- if (this.hasRepetitiveToolCalls())
619
- return "repetitive";
620
- if (this.hasReadOnlyLoop())
621
- return "read-only";
622
- return "";
623
- }
624
- /** Причина застревания для лога (пусто если здоров). */
625
- getStuckReason() {
626
- if (this.isStuck()) {
627
- return t("exec.stuck", {
628
- stepId: String(this.currentStepId ?? "?"),
629
- description: this.currentStepDescription,
630
- iterations: this.iterationsOnCurrentStep,
631
- });
632
- }
633
- const errorTool = Array.from(this.toolErrors.entries()).find(([_, c]) => c >= this.errorThreshold);
634
- if (errorTool) {
635
- return t("exec.tool_errors", { tool: errorTool[0], count: errorTool[1] });
636
- }
637
- if (this.hasBashFlailing()) {
638
- const fails = this.bashRecent.filter((ok) => !ok).length;
639
- return t("exec.bash_flailing", {
640
- fails: String(fails),
641
- window: String(this.bashRecent.length),
642
- });
643
- }
644
- if (this.hasConsecutiveFailures()) {
645
- return t("exec.consecutive_failures", { count: String(this.consecutiveFailures) });
646
- }
647
- // Повторные идентичные вызовы — петля, даже если ничего не фейлится (напр.
648
- // цикл опроса process_log): без этой ветки оставались невидимы —
649
- // getWarningKey репортил "repetitive", но причина не логгировалась.
650
- if (this.hasRepetitiveToolCalls()) {
651
- return this.getRepetitiveToolMessage();
652
- }
653
- if (this.hasReadOnlyLoop()) {
654
- return t("exec.read_only_loop", {
655
- count: String(this.readOnlyStreak),
656
- });
657
- }
658
- return "";
659
- }
660
- /** Recovery-сообщение по первичной причине (пусто если здоров). */
661
- getRecoveryMessage() {
662
- const reason = this.getPrimaryReason();
663
- if (reason === "stuck") {
664
- return t("exec.stuck_recovery", {
665
- iterations: this.iterationsOnCurrentStep,
666
- stepId: String(this.currentStepId ?? "?"),
667
- description: this.currentStepDescription,
668
- });
669
- }
670
- // Per-tool recovery (конкретнее — напр. "bash упал 3 раза")
671
- if (reason === "tool-errors") {
672
- const errorTool = Array.from(this.toolErrors.entries()).find(([_, c]) => c >= this.errorThreshold);
673
- return t("exec.tool_errors_recovery", {
674
- tool: errorTool[0],
675
- count: errorTool[1],
676
- });
677
- }
678
- // Подряд фейлы разных тулов (общее — напр. "5 consecutive failures")
679
- if (reason === "consecutive") {
680
- return t("exec.consecutive_failures_recovery", {
681
- count: this.consecutiveFailures,
682
- });
683
- }
684
- if (reason === "bash-flailing") {
685
- const fails = this.bashRecent.filter((ok) => !ok).length;
686
- return t("exec.bash_flailing_recovery", {
687
- fails: String(fails),
688
- window: String(this.bashRecent.length),
689
- });
690
- }
691
- if (reason === "repetitive") {
692
- return this.getRepetitiveToolMessage();
693
- }
694
- if (reason === "read-only") {
695
- return t("exec.read_only_loop_recovery", {
696
- count: String(this.readOnlyStreak),
697
- });
698
- }
699
- return "";
700
- }
701
- /**
702
- * Классифицирует текущее состояние фейла в стабильный {@link FailureType}
703
- * для диагностики/логов. Null если здоров. `iteration` даёт вызывающий
704
- * (детектор глобальный счётчик цикла не ведёт).
705
- */
706
- classifyFailure(iteration = 0) {
707
- const primary = this.getPrimaryReason();
708
- if (!primary)
709
- return null;
710
- switch (primary) {
711
- case "stuck":
712
- return { type: "timeout", iteration };
713
- case "tool-errors": {
714
- const entry = Array.from(this.toolErrors.entries()).find(([, c]) => c >= this.errorThreshold);
715
- return { type: "error_loop", tool: entry?.[0], count: entry?.[1], iteration };
716
- }
717
- case "consecutive":
718
- return { type: "error_loop", count: this.consecutiveFailures, iteration };
719
- case "repetitive": {
720
- const last = this.recentToolCalls[this.recentToolCalls.length - 1];
721
- return { type: "repeat", tool: last?.name, count: this.repetitionThreshold, iteration };
722
- }
723
- case "bash-flailing": {
724
- const fails = this.bashRecent.filter((ok) => !ok).length;
725
- return { type: "bash_flailing", count: fails, iteration };
726
- }
727
- case "read-only":
728
- return { type: "read_only", count: this.readOnlyStreak, iteration };
729
- }
730
- }
731
- /** Компактный маркер `[STUCK: type=..., tool=..., count=..., iteration=N]`. */
732
- formatFailureDiagnostic(c) {
733
- const parts = [`type=${c.type}`];
734
- if (c.tool)
735
- parts.push(`tool=${c.tool}`);
736
- if (typeof c.count === "number")
737
- parts.push(`count=${c.count}`);
738
- if (c.iteration > 0)
739
- parts.push(`iteration=${c.iteration}`);
740
- return `[STUCK: ${parts.join(", ")}]`;
741
- }
742
- /** Диагностический маркер текущего состояния, или "" если здоров. */
743
- getStuckDiagnostic(iteration = 0) {
744
- const c = this.classifyFailure(iteration);
745
- return c ? this.formatFailureDiagnostic(c) : "";
746
- }
747
- /**
748
- * Единый источник правды приоритета recovery-причины. Общий для
749
- * getRecoveryMessage() и getHints(), чтобы не расходились: bullet состояния,
750
- * которое getRecoveryMessage уже репортит, хинтом НЕ дублируется
751
- * (приоритет: stuck > tool-errors > consecutive > repetitive > read-only).
752
- */
753
- getPrimaryReason() {
754
- if (this.isStuck())
755
- return "stuck";
756
- const errorTool = Array.from(this.toolErrors.entries()).find(([_, c]) => c >= this.errorThreshold);
757
- if (errorTool)
758
- return "tool-errors";
759
- if (this.hasBashFlailing())
760
- return "bash-flailing";
761
- if (this.hasConsecutiveFailures())
762
- return "consecutive";
763
- if (this.hasRepetitiveToolCalls())
764
- return "repetitive";
765
- if (this.hasReadOnlyLoop())
766
- return "read-only";
767
- return null;
768
- }
769
- /** Полный сброс всего состояния детектора. */
770
- reset() {
771
- this.currentStepId = null;
772
- this.iterationsOnCurrentStep = 0;
773
- this.toolErrors.clear();
774
- this.consecutiveFailures = 0;
775
- this.lastFailedTool = "";
776
- this.lastErrorOutput = "";
777
- this.recentToolCalls = [];
778
- this.fileRewriteCount.clear();
779
- this.escalationCount = 0;
780
- this.lastBashCommand = "";
781
- this.lastBashOutput = "";
782
- this.emptyBashRunCount = 0;
783
- this.bashRecent = [];
784
- this.readOnlyStreak = 0;
785
- this.errorSignatureCounts.clear();
786
- this.searchedErrorSignatures.clear();
787
- }
788
- /**
789
- * Сбрасывает только step-прогресс, храня историю вызовов и read-only стрик.
790
- * Нужно, когда план готов, но цикл продолжается (напр. audit-gate реджектнул
791
- * готовую задачу): step-stuck варнинги глушатся, а петля чтения-без-записи
792
- * всё равно детектится.
793
- */
794
- resetStepProgress() {
795
- this.currentStepId = null;
796
- this.iterationsOnCurrentStep = 0;
797
- this.toolErrors.clear();
798
- this.consecutiveFailures = 0;
799
- this.lastFailedTool = "";
800
- this.lastErrorOutput = "";
801
- this.fileRewriteCount.clear();
802
- this.escalationCount = 0;
803
- this.lastBashCommand = "";
804
- this.lastBashOutput = "";
805
- this.emptyBashRunCount = 0;
806
- this.bashRecent = [];
807
- this.errorSignatureCounts.clear();
808
- this.searchedErrorSignatures.clear();
809
- }
810
- /**
811
- * Сбрасывает всё per-step состояние при переходе на новый шаг. Не даёт
812
- * ошибкам и повторам одного шага протекать в следующий (ложные
813
- * stuck/recovery на первой итерации нового шага).
814
- */
815
- resetStepState(stepId) {
816
- this.currentStepId = stepId;
817
- this.iterationsOnCurrentStep = 1;
818
- this.toolErrors.clear();
819
- this.consecutiveFailures = 0;
820
- this.lastFailedTool = "";
821
- this.lastErrorOutput = "";
822
- this.recentToolCalls = [];
823
- this.fileRewriteCount.clear();
824
- this.lastBashCommand = "";
825
- this.lastBashOutput = "";
826
- this.emptyBashRunCount = 0;
827
- this.bashRecent = [];
828
- this.readOnlyStreak = 0;
829
- this.errorSignatureCounts.clear();
830
- this.searchedErrorSignatures.clear();
831
- // escalationCount храним — иначе агент "геймит" детекцию, маркируя шаг
832
- // done и переходя к следующему
833
- }
834
- }