micro-models-agent 0.40.1 → 0.41.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.
- package/bin/mma.mjs +41 -41
- package/dist/cli/commands.js +9 -19
- package/dist/cli/completer.js +36 -37
- package/dist/cli/index.js +2 -2
- package/dist/cli/main.js +48 -23
- package/dist/cli/plugin-commands.js +36 -0
- package/dist/cli/repl-commands.js +40 -12
- package/dist/cli/repl.js +217 -87
- package/dist/cli/run-result.js +22 -0
- package/dist/cli/security-commands.js +5 -7
- package/dist/cli/setup.js +8 -26
- package/dist/config/config.js +52 -5
- package/dist/config/defaults.js +29 -5
- package/dist/config/experts.js +1 -1
- package/dist/config/index.js +3 -3
- package/dist/config/security.js +3 -10
- package/dist/core/agent-moe.js +2 -10
- package/dist/core/agent.js +273 -82
- package/dist/core/bootstrap.js +80 -13
- package/dist/core/index.js +2 -2
- package/dist/core/prompt-builder.js +23 -2
- package/dist/core/session-logger.js +46 -4
- package/dist/core/version.js +24 -0
- package/dist/i18n/en.json +75 -2
- package/dist/i18n/ru.json +74 -1
- package/dist/index.js +1 -1
- package/dist/llm/image-utils.js +4 -5
- package/dist/llm/index.js +4 -4
- package/dist/llm/model-loader.js +6 -6
- package/dist/llm/openai-compat.js +40 -34
- package/dist/llm/orchestrator.js +33 -29
- package/dist/llm/response.js +9 -9
- package/dist/logger/app-logger.js +1 -1
- package/dist/logger/index.js +1 -1
- package/dist/main.js +2489 -2186
- package/dist/migration/backup.js +13 -13
- package/dist/migration/detect.js +11 -11
- package/dist/migration/index.js +2 -2
- package/dist/modules/artifacts/store.js +61 -0
- package/dist/modules/browser/actions.js +34 -4
- package/dist/modules/browser/bridge-client.js +199 -0
- package/dist/modules/browser/bridge-path.js +10 -0
- package/dist/modules/browser/bridge-server.mjs +202 -202
- package/dist/modules/browser/cookie-store.js +6 -6
- package/dist/modules/browser/driver.js +136 -0
- package/dist/modules/browser/index.js +7 -5
- package/dist/modules/browser/module.js +8 -7
- package/dist/modules/browser/session.js +87 -84
- package/dist/modules/browser/snapshot.js +92 -58
- package/dist/modules/browser/types.js +4 -1
- package/dist/modules/certification/cli.js +2 -4
- package/dist/modules/certification/fact-checker.js +1 -3
- package/dist/modules/certification/loader.js +3 -9
- package/dist/modules/certification/runner.js +1 -4
- package/dist/modules/context/chunk-query.js +100 -0
- package/dist/modules/context/fact-extractor.js +162 -0
- package/dist/modules/context/history.js +15 -0
- package/dist/modules/context/index.js +1 -1
- package/dist/modules/context/manager.js +160 -86
- package/dist/modules/execution/audit-runners.js +152 -0
- package/dist/modules/execution/auditor.js +177 -25
- package/dist/modules/execution/execution-plugin.js +272 -0
- package/dist/modules/execution/module.js +201 -544
- package/dist/modules/execution/moe-executor.js +25 -0
- package/dist/modules/execution/plan-store.js +1 -3
- package/dist/modules/execution/plan-tool.js +508 -0
- package/dist/modules/execution/plan-validator.js +10 -10
- package/dist/modules/execution/planner.js +6 -1
- package/dist/modules/execution/stuck-detector.js +173 -10
- package/dist/modules/execution/verifier.js +86 -42
- package/dist/modules/execution/windows-commands.js +41 -0
- package/dist/modules/hallucination/confidence.js +8 -1
- package/dist/modules/hallucination/detector.js +2 -5
- package/dist/modules/hallucination/factual.js +3 -64
- package/dist/modules/hallucination/index.js +1 -1
- package/dist/modules/hallucination/js-identifiers.js +190 -0
- package/dist/modules/hallucination/llm-judge.js +1 -3
- package/dist/modules/indexer/cache.js +9 -7
- package/dist/modules/indexer/index.js +3 -3
- package/dist/modules/indexer/module.js +95 -42
- package/dist/modules/indexer/project-profile.js +183 -0
- package/dist/modules/indexer/walker.js +17 -17
- package/dist/modules/lsp/check-tool.js +58 -0
- package/dist/modules/lsp/client.js +74 -31
- package/dist/modules/lsp/command.js +60 -0
- package/dist/modules/lsp/config.js +87 -33
- package/dist/modules/lsp/index.js +3 -3
- package/dist/modules/lsp/module.js +185 -21
- package/dist/modules/lsp/probe.js +76 -0
- package/dist/modules/lsp/project-root.js +32 -0
- package/dist/modules/lsp/startup-check.js +141 -0
- package/dist/modules/mcp/module.js +2 -6
- package/dist/modules/memory/index.js +1 -1
- package/dist/modules/memory/module.js +71 -23
- package/dist/modules/memory/search.js +11 -9
- package/dist/modules/memory/store.js +13 -13
- package/dist/modules/pipelines/engine.js +10 -10
- package/dist/modules/pipelines/index.js +3 -3
- package/dist/modules/pipelines/parser.js +17 -14
- package/dist/modules/pipelines/template.js +1 -1
- package/dist/modules/plugins/builtin/lint-on-write.js +21 -16
- package/dist/modules/plugins/builtin/notify.js +3 -2
- package/dist/modules/plugins/index.js +1 -1
- package/dist/modules/plugins/loader.js +59 -17
- package/dist/modules/plugins/manager.js +73 -17
- package/dist/modules/processes/detect.js +34 -0
- package/dist/modules/processes/index.js +1 -1
- package/dist/modules/processes/registry.js +135 -46
- package/dist/modules/registry.js +4 -2
- package/dist/modules/security/audit-notifier.js +39 -39
- package/dist/modules/security/command-validator.js +2 -8
- package/dist/modules/security/data-sanitizer.js +1 -9
- package/dist/modules/security/encryption.js +58 -56
- package/dist/modules/security/network-validator.js +1 -9
- package/dist/modules/security/path-validator.js +1 -3
- package/dist/modules/security/security-policies.js +3 -19
- package/dist/modules/security/session-encryption.js +1 -1
- package/dist/modules/security/session-isolation.js +8 -8
- package/dist/modules/session/index.js +3 -3
- package/dist/modules/session/module.js +5 -5
- package/dist/modules/session/store.js +3 -9
- package/dist/modules/skills/matcher.js +27 -0
- package/dist/modules/skills/module.js +1 -2
- package/dist/modules/updater/checker.js +70 -6
- package/dist/modules/updater/index.js +2 -1
- package/dist/modules/updater/module.js +116 -0
- package/dist/modules/user-profile/compressor.js +2 -2
- package/dist/modules/user-profile/index.js +1 -1
- package/dist/modules/user-profile/profile.js +9 -9
- package/dist/tools/attach-image.js +1 -1
- package/dist/tools/bash.js +178 -19
- package/dist/tools/browser.js +46 -29
- package/dist/tools/chunk-query.js +99 -0
- package/dist/tools/download-file.js +116 -0
- package/dist/tools/enable-tools.js +58 -0
- package/dist/tools/executor.js +4 -5
- package/dist/tools/file-info.js +13 -12
- package/dist/tools/filter-tools.js +9 -2
- package/dist/tools/glob-tool.js +11 -11
- package/dist/tools/grep-tool.js +1 -3
- package/dist/tools/hidden-tools-block.js +37 -0
- package/dist/tools/index.js +13 -2
- package/dist/tools/list-dir.js +18 -17
- package/dist/tools/load-skill.js +1 -3
- package/dist/tools/path-utils.js +4 -4
- package/dist/tools/pipeline-run.js +25 -25
- package/dist/tools/process-kill.js +11 -11
- package/dist/tools/process-list.js +20 -22
- package/dist/tools/process-log.js +22 -18
- package/dist/tools/question.js +1 -3
- package/dist/tools/read-file.js +10 -2
- package/dist/tools/recall.js +44 -37
- package/dist/tools/registry.js +15 -4
- package/dist/tools/remember.js +29 -29
- package/dist/tools/scope-check.js +9 -9
- package/dist/tools/subagent.js +54 -9
- package/dist/tools/user-input.js +1 -1
- package/dist/tools/web-browse.js +3 -3
- package/dist/tools/web-fetch.js +3 -3
- package/dist/tools/web-search.js +3 -3
- package/dist/tools/write-file.js +1 -3
- package/dist/ui/box.js +1 -5
- package/dist/ui/index.js +6 -6
- package/dist/ui/line-editor.js +703 -0
- package/dist/ui/line-math.js +69 -0
- package/dist/ui/md-formatter.js +33 -33
- package/dist/ui/output.js +5 -5
- package/dist/ui/plan-view.js +103 -0
- package/dist/ui/renderer.js +15 -10
- package/dist/ui/table.js +1 -1
- package/package.json +48 -48
package/dist/i18n/ru.json
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"error.response_blocked": "Ответ заблокирован: {reason}",
|
|
28
28
|
"error.max_iters": "Достигнут максимум итераций ({max})",
|
|
29
29
|
"error.empty_response": "Модель вернула пустой ответ после повторных попыток",
|
|
30
|
+
"error.audit_failed": "Задача не может быть подтверждена как выполненная: {summary}",
|
|
30
31
|
"error.grep_failed": "Ошибка grep: {message}",
|
|
31
32
|
"error.search_failed": "Ошибка поиска: {message}",
|
|
32
33
|
"error.fetch_failed": "Ошибка загрузки: {message}",
|
|
@@ -84,9 +85,12 @@
|
|
|
84
85
|
"tool.friendly.web_search": "Поиск в интернете",
|
|
85
86
|
"tool.friendly.web_fetch": "Загрузка страницы",
|
|
86
87
|
"tool.friendly.web_browse": "Просмотр страницы",
|
|
88
|
+
"tool.friendly.download_file": "Скачивание файла",
|
|
87
89
|
"tool.web_fetch_result": "Загружена страница: {url} — {chars} симв., {lines} строк{truncated}",
|
|
88
90
|
"tool.web_browse_result": "Просмотрена страница: {url} — {chars} симв., {lines} строк{truncated}",
|
|
89
91
|
"tool.web_search_result": "Результаты поиска \"{query}\" — {count} результатов",
|
|
92
|
+
"tool.downloaded": "Скачано {url} \u2192 {path} ({size} байт, {type})",
|
|
93
|
+
"tool.download_too_large": "Скачивание заблокировано: файл превышает лимит {max} байт",
|
|
90
94
|
"tool.friendly.browser": "Браузер",
|
|
91
95
|
"tool.friendly.subagent": "Задача подагенту",
|
|
92
96
|
"tool.friendly.question": "Вопрос пользователю",
|
|
@@ -94,8 +98,10 @@
|
|
|
94
98
|
"tool.friendly.search_history": "Поиск в истории",
|
|
95
99
|
"tool.friendly.pipeline_run": "Запуск пайплайна",
|
|
96
100
|
"tool.friendly.mcp_call": "MCP вызов",
|
|
101
|
+
"tool.friendly.lsp_check": "Проверка кода",
|
|
97
102
|
"tool.truncated": "[Обрезано: удалено {tokens} токенов]",
|
|
98
103
|
"tool.subagent_queued": "Задача подагенту добавлена: {task}",
|
|
104
|
+
"tool.subagent_artifact": "Суб-агент завершён. Полный результат сохранён в артефакт: {path}\nИтераций: {iterations}\nСводка:\n{summary}",
|
|
99
105
|
"tool.pipeline_started": "Пайплайн \"{name}\" запущен. Движок пайплайнов — заглушка, задача отправлена.",
|
|
100
106
|
"tool.mcp_call": "MCP вызов: {server}/{tool} с {args}",
|
|
101
107
|
"tool.action_required": "Требуется действие.",
|
|
@@ -116,6 +122,8 @@
|
|
|
116
122
|
"tool.question.unanswered": "Без ответа",
|
|
117
123
|
"tool.question.answered": "Пользователь ответил на ваши вопросы: {formatted}. Теперь продолжайте с учётом ответов.",
|
|
118
124
|
"tool.name_or_task": "Укажите параметр \"name\" или \"task\"",
|
|
125
|
+
"tool.chunk_query_no_query": "chunk_query: требуется строка запроса.",
|
|
126
|
+
"tool.chunk_query_no_input": "chunk_query: укажите input_path или text.",
|
|
119
127
|
"tool.invalid_params": "Неверные параметры",
|
|
120
128
|
"tool.skill_budget": "Скилл \"{name}\" загружен ({tokens} токенов, осталось {remaining} в бюджете скиллов). Контент скилла теперь в системном промпте — перезагрузка после компрессии не нужна.",
|
|
121
129
|
"tool.skill_available_hint": "Доступные скиллы",
|
|
@@ -133,6 +141,7 @@
|
|
|
133
141
|
"proc.started": "Фоновый процесс запущен: {id} (PID {pid}).\nКоманда: {command}",
|
|
134
142
|
"proc.promoted_hint": "Команда всё ещё выполняется через {ms} мс — переведена в фоновый режим",
|
|
135
143
|
"proc.manage_hint": "Проверить вывод: process_log id={id}. Остановить: process_kill id={id}. Список всех: process_list.",
|
|
144
|
+
"proc.output_preview": "Первые строки вывода:\n{lines}",
|
|
136
145
|
"proc.none": "Фоновых процессов нет.",
|
|
137
146
|
"proc.not_found": "Процесс не найден: {id}",
|
|
138
147
|
"proc.killed": "Процесс {id} (PID {pid}) остановлен.",
|
|
@@ -155,12 +164,20 @@
|
|
|
155
164
|
"plan.title_steps": "План \"{title}\" создан с {count} шагами",
|
|
156
165
|
"plan.step_marked": "Шаг {step} отмечен как {status}",
|
|
157
166
|
"plan.aborted": "План отменён",
|
|
167
|
+
"plan.completed_archived": "План {id} завершён ({done}/{total} шагов) — архивирован. Для новой задачи создай новый план (plan create) или дай финальный ответ.",
|
|
158
168
|
"plan.unknown_action": "Неизвестное действие плана: {action}",
|
|
159
169
|
"plan.updated": "План обновлён: {title} ({steps} шагов)",
|
|
160
170
|
"plan.acknowledged": "План {action}: принято",
|
|
161
171
|
"plan.step_status": "Шаг {step}: {status}",
|
|
162
172
|
"plan.no_active": "Нет активного плана",
|
|
163
173
|
"plan.step_not_found": "Шаг не найден",
|
|
174
|
+
"plan.step_already_done": "Шаг {step} уже выполнен — ничего делать не нужно. Прогресс плана:",
|
|
175
|
+
"plan.order_blocked": "Нельзя отметить шаг {step} выполненным: шаг {first} («{desc}») ещё не завершён. Сначала завершите предыдущие шаги или отметьте шаг {first} status=skipped, если он не нужен.",
|
|
176
|
+
"plan.deliverables_missing": "Нельзя отметить шаг {step} выполненным: указанные в нём файлы ещё не существуют: {files}. Сначала создайте эти файлы (или отметьте шаг status=skipped, если они на самом деле не нужны).",
|
|
177
|
+
"plan.kinds_mismatch": "Длина kinds должна совпадать с числом шагов",
|
|
178
|
+
"plan.kinds_invalid": "Недопустимый kind шага: {kinds}. Используй \"create\" или \"delete\".",
|
|
179
|
+
"plan.kinds_not_array": "kinds должен быть массивом значений \"create\" или \"delete\"",
|
|
180
|
+
"plan.deliverables_remain": "Нельзя пометить шаг {step} как выполненный: указанные файлы всё ещё существуют: {files}. Шаг имеет kind=delete — сначала удали их (или поставь status=skipped, если они должны остаться).",
|
|
164
181
|
"plan.show_header": "Статус плана:",
|
|
165
182
|
"plan.show_empty": "(в плане нет шагов)",
|
|
166
183
|
"plan.list_header": "Планы:",
|
|
@@ -170,9 +187,14 @@
|
|
|
170
187
|
"plan.switched": "Переключено на план {id}: {title}",
|
|
171
188
|
"plan.replanned": "План перепланирован: {kept} выполненных шагов сохранено, {steps} новых шагов добавлено",
|
|
172
189
|
"plan.replan_no_steps": "Укажите новые шаги для перепланирования",
|
|
190
|
+
"plan.active_in_progress": "Нельзя создать новый план: активный план {id} уже имеет прогресс ({done}/{total} выполнено, текущий: шаг {current}). Продолжай его — вызови \"plan show\", чтобы увидеть, и продолжай работу. Чтобы заменить план, сначала вызови \"plan abort\", затем \"plan create\".",
|
|
191
|
+
"plan.id_ignored": "примечание: id плана генерируется автоматически; используй \"plan switch\", чтобы активировать существующий план по id.",
|
|
192
|
+
"plan.existing_fresh": "примечание: предыдущий активный план не имел прогресса и сохранён как черновик.",
|
|
173
193
|
"todo.added": "Добавлено {count} задач: {items}",
|
|
174
194
|
"todo.marked_done": "Отмечено выполненными: {count}",
|
|
175
195
|
"todo.no_active": "Нет активных задач",
|
|
196
|
+
"todo.no_items": "Не указаны подзадачи — укажите items для отметки выполненными",
|
|
197
|
+
"todo.subtask_not_found": "Подзадачи не найдены: {items}",
|
|
176
198
|
"todo.unknown_action": "Неизвестное действие todo: {action}",
|
|
177
199
|
"todo.acknowledged": "Todo принято",
|
|
178
200
|
"verify.passed": "Проверка пройдена",
|
|
@@ -182,6 +204,14 @@
|
|
|
182
204
|
"verify.script_passed": "Скрипт '{script}' пройден",
|
|
183
205
|
"verify.script_failed": "Скрипт '{script}' не пройден: {message}",
|
|
184
206
|
"verify.syntax_error": "Синтаксическая ошибка в: {path}",
|
|
207
|
+
"verify.no_files": "Шаг {step} не содержит именованных файлов для проверки — выполни реальную проверку (bun run build / bun test / lsp_check) и подтверди результат.",
|
|
208
|
+
"lsp.unavailable": "статические проверки недоступны (сервер не найден). Проверяйте через собственный build/test проекта.",
|
|
209
|
+
"lsp.check_disabled": "LSP-проверки отключены в конфигурации.",
|
|
210
|
+
"lsp.check_no_path": "Укажите путь (файл или каталог) для проверки.",
|
|
211
|
+
"lsp.check_notfound": "Путь не найден: {path}",
|
|
212
|
+
"lsp.check_unsupported": "Для файла не настроен LSP-сервер: {path}",
|
|
213
|
+
"lsp.check_clean": "Ошибок и предупреждений не обнаружено (проверено файлов: {count}).",
|
|
214
|
+
"lsp.startup_header": "[Существующие ошибки проекта (проверено при старте сессии) — исправьте их перед продолжением]:",
|
|
185
215
|
"cli.description": "Micro Models Agent — ИИ-агент для кодинга на малых моделях",
|
|
186
216
|
"cli.init": "Запустить мастер настройки",
|
|
187
217
|
"cli.config_saved": "Конфигурация сохранена в ~/.mma/config.json",
|
|
@@ -290,6 +320,13 @@
|
|
|
290
320
|
"cli.security.recommended_for": "Рекомендуется для",
|
|
291
321
|
"cli.yes": "Да",
|
|
292
322
|
"cli.no": "Нет",
|
|
323
|
+
"cli.plugins.description": "Управление плагинами",
|
|
324
|
+
"cli.plugins.list": "Список загруженных плагинов (имя, версия, источник)",
|
|
325
|
+
"cli.plugins.all": "Включить встроенные плагины",
|
|
326
|
+
"cli.plugins.only_external": "(встроенные плагины скрыты — используйте --all)",
|
|
327
|
+
"cli.plugins.none": "Плагины не загружены",
|
|
328
|
+
"cli.plugins.header": "Плагины: {count} загружено (MMA v{mma})",
|
|
329
|
+
"cli.plugins.builtin_mark": "●",
|
|
293
330
|
"repl.help": "Показать доступные команды",
|
|
294
331
|
"repl.help_usage": "Использование: /help",
|
|
295
332
|
"repl.exit": "Выйти из REPL",
|
|
@@ -304,6 +341,8 @@
|
|
|
304
341
|
"repl.reasoning_usage": "Использование: /reasoning",
|
|
305
342
|
"repl.status": "Показать статус агента",
|
|
306
343
|
"repl.status_usage": "Использование: /status",
|
|
344
|
+
"repl.plugins": "Список загруженных плагинов",
|
|
345
|
+
"repl.plugins_usage": "Использование: /plugins [--all]",
|
|
307
346
|
"repl.sessions": "Список всех сессий (* активная)",
|
|
308
347
|
"repl.sessions_usage": "Использование: /sessions",
|
|
309
348
|
"repl.new": "Создать новую сессию",
|
|
@@ -330,6 +369,7 @@
|
|
|
330
369
|
"repl.skill_unknown_sub": "Неизвестная подкоманда скилла: {subcmd}",
|
|
331
370
|
"repl.skill_usage": "Использование: /skill [list|loaded|load|unload|search]",
|
|
332
371
|
"repl.agent": "Агент: ",
|
|
372
|
+
"repl.you": "Вы: ",
|
|
333
373
|
"repl.interrupt": "Прервано (Esc)",
|
|
334
374
|
"repl.title": "MMA REPL v{version}",
|
|
335
375
|
"repl.model": "Модель:",
|
|
@@ -347,6 +387,10 @@
|
|
|
347
387
|
"repl.skills_label": "Скиллы:",
|
|
348
388
|
"repl.plugins_label": "Плагины:",
|
|
349
389
|
"repl.mcp_label": "MCP:",
|
|
390
|
+
"repl.lsp_label": "LSP:",
|
|
391
|
+
"repl.lsp_timeout": "таймаут",
|
|
392
|
+
"repl.lsp_failed": "не стартовал",
|
|
393
|
+
"repl.lsp_unknown": "неизвестно",
|
|
350
394
|
"repl.work_dir": "Директория:",
|
|
351
395
|
"repl.agents_label": "Инструкции:",
|
|
352
396
|
"repl.not_found": "не найден",
|
|
@@ -425,6 +469,8 @@
|
|
|
425
469
|
"exec.tool_errors_recovery": "Инструмент {tool} упал {count} раз подряд. Попробуйте альтернативу: создайте файлы напрямую через write_file, используйте другую команду, или пропустите этот шаг через plan update step=N status=skipped с пометкой почему.",
|
|
426
470
|
"exec.repetitive_tool": "Инструмент {tool} вызван {count} раз с одинаковыми аргументами и результатом. Попробуйте другой подход — создайте файлы напрямую, измените аргументы или проверьте статус процесса через process_log.",
|
|
427
471
|
"exec.consecutive_failures_recovery": "{count} инструментов подряд упали. Создавайте файлы напрямую через write_file вместо команд терминала. Проверьте что зависимости установлены (npm install). Не запускайте сборку/тесты пока не созданы все файлы.",
|
|
472
|
+
"exec.read_only_loop": "Нет записи/выполнения за {count} вызовов — агент только читает/исследует.",
|
|
473
|
+
"exec.read_only_loop_recovery": "{count} вызовов только для чтения подряд (read_file/glob/grep/browser) без записи. Хватит исследовать — внесите правку, которую требует задача: прочитайте файл, затем вызовите write_file или edit_file. Если не можете завершить задачу — спросите пользователя, а не перечитывайте одни и те же файлы.",
|
|
428
474
|
"exec.plan_warning": "Текущий шаг плана {step} — \"{description}\", но вызывается {tool} для файлов вне этого шага. Завершите текущий шаг, вызовите plan update step={step} status=done, затем переходите к следующему.",
|
|
429
475
|
"exec.plan_blocked": "{max} вызовов подряд вне текущего шага. Завершите шаг {step} — остальные шаги ждут пока этот не будет выполнен.",
|
|
430
476
|
"exec.off_track": "Шаг {stepId} — \"{description}\", но используется {tool} для другого пути. Вернитесь к текущему шагу.",
|
|
@@ -434,13 +480,18 @@
|
|
|
434
480
|
"exec.step_gate_ok": "[✓] Шаг {step} завершён и проверен. ПЕРЕХОДИМ к шагу {nextStep}: \"{nextDesc}\". Работайте ТОЛЬКО над этим шагом.",
|
|
435
481
|
"exec.step_gate_last": "[✓] Шаг {step} завершён — это был последний шаг. Проверьте всё вместе и предоставьте финальный ответ.]",
|
|
436
482
|
"exec.audit_pass": "[✓] Задача выполнена: {done}/{total} шагов, {files} файлов проверено",
|
|
483
|
+
"exec.audit_pending": "[✗] Задача не выполнена: {done}/{total} шагов — оставшиеся шаги не отмечены выполненными",
|
|
437
484
|
"exec.audit_fail": "[✗] Задача не выполнена: {done}/{total} шагов, {files} файлов отсутствует",
|
|
485
|
+
"exec.audit_leftovers": "[✗] Задача не выполнена: {done}/{total} шагов, {files} файлов из delete-шагов всё ещё существуют",
|
|
486
|
+
"exec.audit_fail_tests": "[✗] Задача не выполнена: {done}/{total} шагов, тесты ПАДАЮТ: {failed} failed / {passed} passed — {detail}",
|
|
438
487
|
"exec.audit_fail_typecheck": "[✗] Задача не выполнена: {done}/{total} шагов, {missing} файлов отсутствует, ошибка typecheck: {typeError}",
|
|
439
488
|
"exec.audit_incomplete": "[⚠ Финальная проверка не пройдена: {summary}. Задача НЕ завершена — продолжайте работу. Оставшиеся шаги: {steps}]",
|
|
440
489
|
"exec.mass_edit_warning": "⚠️ План затрагивает {count} файлов — проверьте полный список перед продолжением.",
|
|
441
490
|
"exec.escalation": "\n\n⚠️ Агент застрял на шаге {stepId} ({description}). Эскалация к пользователю — пожалуйста, подскажите как действовать.",
|
|
442
491
|
"exec.hints": "\n[Подсказки]\n{hints}",
|
|
443
492
|
"exec.file_rewrite_warning": "⚠️ Файл {file} был перезаписан {count} раз. Попробуйте другой подход — текущая стратегия исправлений не работает.",
|
|
493
|
+
"exec.forbidden_cmd": "ПРЕКРАТИ использовать \"{cmd}\" через bash — это не команда Windows cmd.exe, и она уже неоднократно падала в этой сессии. Используй предназначенный тул: grep → тул grep, ls/dir → list_dir, find → glob, rm → delete_file, sed → edit_file, touch → write_file, which → `where`, cp/mv → move_file, diff → read_file. Больше не вызывай bash для этого.",
|
|
494
|
+
"exec.npm_exec_hint": "\"could not determine executable to run\" — у пакета/скрипта нет \"bin\". Используй \"npm run <script>\" (скрипт должен быть в package.json) или \"bunx <pkg>\" для пакета с объявленным bin.",
|
|
444
495
|
"hall.max_retries_exhausted": "Модель вернула пустой или недостаточный ответ после нескольких попыток",
|
|
445
496
|
"hall.short_response": "Слишком короткий или пустой ответ",
|
|
446
497
|
"hall.repetitive": "Слишком повторяющийся ответ ({pct}% совпадение)",
|
|
@@ -466,11 +517,17 @@
|
|
|
466
517
|
"browser.no_page_short": "Нет страницы",
|
|
467
518
|
"browser.no_elements": "(нет интерактивных элементов на странице)",
|
|
468
519
|
"browser.more_elements": "... и другие элементы не показаны. Используйте прокрутку или поиск.",
|
|
520
|
+
"browser.content_header": "Содержимое:",
|
|
521
|
+
"browser.console_header": "Консоль:",
|
|
522
|
+
"browser.network_errors_header": "Сетевые ошибки:",
|
|
523
|
+
"browser.truncated": "... (обрезано)",
|
|
469
524
|
"pipeline.invalid": "Невалидный пайплайн: требуются name и steps",
|
|
470
525
|
"pipeline.step_missing_fields": "Шаг не содержит обязательных полей (id, agent, prompt): {step}",
|
|
471
526
|
"pipeline.circular": "Циклическая зависимость: {stepId}",
|
|
472
527
|
"plugin.loaded": "Загружен плагин: {name}",
|
|
473
528
|
"plugin.skipped": "Пропущен несовместимый плагин: {entry} ({message})",
|
|
529
|
+
"plugin.incompatible": "Пропущен плагин {name}: требуется MMA v{min}, текущая v{current}",
|
|
530
|
+
"plugin.dedup_older": "Плагин {name} v{version} пропущен: уже загружена более новая версия",
|
|
474
531
|
"migration.detected": "[MMA] Обнаружен старый конфиг. {summary}",
|
|
475
532
|
"migration.summary": "[MMA] {summary}",
|
|
476
533
|
"migration.config_bak": "- config → config.json.bak",
|
|
@@ -481,6 +538,7 @@
|
|
|
481
538
|
"ui.success_prefix": "✓ ",
|
|
482
539
|
"ui.warning_prefix": "⚠ ",
|
|
483
540
|
"ui.thinking": "Думаю…",
|
|
541
|
+
"ui.step_context": "шаг {id}: {desc}",
|
|
484
542
|
"indexer.map_header": "Карта проекта",
|
|
485
543
|
"indexer.top_directories": "Основные директории",
|
|
486
544
|
"indexer.files": "Файлы",
|
|
@@ -494,6 +552,10 @@
|
|
|
494
552
|
"indexer.not_indexed": "Проект ещё не проиндексирован",
|
|
495
553
|
"indexer.find_results": "Найдено {count} совпадающих файлов:\n{results}",
|
|
496
554
|
"indexer.no_matches": "Нет совпадающих файлов для \"{query}\"",
|
|
555
|
+
"indexer.duplicates": "Дубликаты basename (проверьте, какой файл реально используется): {names}",
|
|
556
|
+
"indexer.stack_deps": "зависимости",
|
|
557
|
+
"indexer.stack_dev": "dev",
|
|
558
|
+
"indexer.stack_scripts": "скрипты",
|
|
497
559
|
"tool.friendly.project_map": "Карта проекта",
|
|
498
560
|
"config.decryption_warning": "Предупреждение: не удалось расшифровать конфигурацию: {error}",
|
|
499
561
|
"config.encryption_warning": "Предупреждение: не удалось зашифровать конфигурацию: {error}",
|
|
@@ -521,5 +583,16 @@
|
|
|
521
583
|
"ctx.delta_neg": "контекст -{tokens} ↓",
|
|
522
584
|
"ctx.delta_zero": "контекст ±0",
|
|
523
585
|
"file.notfound_resolved": "Файл не найден: {path} (резолвится в {resolved})",
|
|
524
|
-
"bash.echo_write_blocked": "Запись файлов через echo/printf ненадёжна в Windows cmd.exe (кавычки и многострочность ломаются). Используй инструмент write_file вместо этого (цель: {path})."
|
|
586
|
+
"bash.echo_write_blocked": "Запись файлов через echo/printf ненадёжна в Windows cmd.exe (кавычки и многострочность ломаются). Используй инструмент write_file вместо этого (цель: {path}).",
|
|
587
|
+
"updater.check_error": "[updater] Ошибка проверки обновления: {error}",
|
|
588
|
+
"updater.available": "[updater] Доступно обновление: {current} → {latest}. Выполните `npm install -g micro-models-agent` для обновления.",
|
|
589
|
+
"updater.installing": "[updater] Установка {latest} глобально (текущая: {current})…",
|
|
590
|
+
"updater.installed": "[updater] Установлена {latest}. Перезапустите MMA для применения (была {current}).",
|
|
591
|
+
"updater.install_failed": "[updater] Не удалось установить {latest}: {error}. Обновите вручную: `npm install -g micro-models-agent`.",
|
|
592
|
+
"tools.enable_no_tags": "enable_tools требует хотя бы один тег в массиве \"tags\".",
|
|
593
|
+
"tools.enable_no_executor": "Исполнитель тулов недоступен — невозможно перечислить включённые тулы.",
|
|
594
|
+
"tools.enable_already_active": "Теги тулов уже активны: {tags}.",
|
|
595
|
+
"tools.enable_added": "Включены теги тулов: {tags}. Теперь доступны тулы: {tools}",
|
|
596
|
+
"tools.hidden_header": "Дополнительные тулы (включите по требованию через enable_tools или маршрутизируйте через subagent tool_tags):",
|
|
597
|
+
"tool.friendly.enable_tools": "Включить тулы"
|
|
525
598
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { DEFAULTS, loadConfig } from "./config/index";
|
|
2
2
|
export { Logger } from "./logger/index";
|
|
3
3
|
export { PromptBuilder } from "./core/index";
|
|
4
|
-
export { OpenAICompatProvider, TokenCounter, parseChunks, OrchestratorClient
|
|
4
|
+
export { OpenAICompatProvider, TokenCounter, parseChunks, OrchestratorClient } from "./llm/index";
|
|
5
5
|
export { ToolRegistry, ToolExecutor, readFileTool, writeFileTool, editFileTool, globTool, grepTool, listDirTool, createDirTool, deleteFileTool, moveFileTool, fileInfoTool, bashTool, subagentTool, webSearchTool, webFetchTool, webBrowseTool, createLoadSkillTool, pipelineRunTool, mcpCallTool, searchHistoryTool, registerAllTools, } from "./tools/index";
|
|
6
6
|
export { MigrationDetector, BackupManager } from "./migration/index";
|
|
7
7
|
import { MigrationDetector } from "./migration/detect";
|
package/dist/llm/image-utils.js
CHANGED
|
@@ -25,10 +25,7 @@ export async function readClipboardImage() {
|
|
|
25
25
|
try {
|
|
26
26
|
const img = Bun.Image.fromClipboard();
|
|
27
27
|
if (img) {
|
|
28
|
-
const buf = await img
|
|
29
|
-
.resize(800, 800, { fit: "inside" })
|
|
30
|
-
.jpeg({ quality: 60 })
|
|
31
|
-
.buffer();
|
|
28
|
+
const buf = await img.resize(800, 800, { fit: "inside" }).jpeg({ quality: 60 }).buffer();
|
|
32
29
|
return Buffer.from(buf);
|
|
33
30
|
}
|
|
34
31
|
}
|
|
@@ -47,7 +44,9 @@ async function readClipboardFallback() {
|
|
|
47
44
|
const tmpPath = join(process.env.TEMP || process.env.TMP || "/tmp", `mma-clip-${Date.now()}.png`);
|
|
48
45
|
try {
|
|
49
46
|
if (platform() === "linux") {
|
|
50
|
-
execSync(`xclip -selection clipboard -t image/png -o > "${tmpPath}" 2>/dev/null`, {
|
|
47
|
+
execSync(`xclip -selection clipboard -t image/png -o > "${tmpPath}" 2>/dev/null`, {
|
|
48
|
+
timeout: 5000,
|
|
49
|
+
});
|
|
51
50
|
}
|
|
52
51
|
else {
|
|
53
52
|
return null; // macOS/Windows should use Bun.Image
|
package/dist/llm/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { OpenAICompatProvider } from
|
|
2
|
-
export { TokenCounter } from
|
|
3
|
-
export { parseChunks } from
|
|
4
|
-
export { OrchestratorClient } from
|
|
1
|
+
export { OpenAICompatProvider } from "./openai-compat";
|
|
2
|
+
export { TokenCounter } from "./token-counter";
|
|
3
|
+
export { parseChunks } from "./response";
|
|
4
|
+
export { OrchestratorClient } from "./orchestrator";
|
package/dist/llm/model-loader.js
CHANGED
|
@@ -2,8 +2,8 @@ export class ModelLoader {
|
|
|
2
2
|
baseUrl;
|
|
3
3
|
logger;
|
|
4
4
|
constructor(baseUrl, logger) {
|
|
5
|
-
const url = baseUrl.replace(/\/$/,
|
|
6
|
-
this.baseUrl = url.replace(/\/v1\/?$/,
|
|
5
|
+
const url = baseUrl.replace(/\/$/, "");
|
|
6
|
+
this.baseUrl = url.replace(/\/v1\/?$/, "");
|
|
7
7
|
this.logger = logger;
|
|
8
8
|
}
|
|
9
9
|
async ensureModelLoaded(config) {
|
|
@@ -30,7 +30,7 @@ export class ModelLoader {
|
|
|
30
30
|
});
|
|
31
31
|
if (!response.ok)
|
|
32
32
|
return false;
|
|
33
|
-
const data = await response.json();
|
|
33
|
+
const data = (await response.json());
|
|
34
34
|
const models = data.models || [];
|
|
35
35
|
const found = models.find((m) => m.key === model || m.name === model);
|
|
36
36
|
if (!found)
|
|
@@ -56,8 +56,8 @@ export class ModelLoader {
|
|
|
56
56
|
this.logger.info(`Loading model ${config.model} with context_length=${config.contextLength}`);
|
|
57
57
|
this.logger.debug(`POST ${this.baseUrl}/api/v1/models/load`);
|
|
58
58
|
const response = await fetch(`${this.baseUrl}/api/v1/models/load`, {
|
|
59
|
-
method:
|
|
60
|
-
headers: {
|
|
59
|
+
method: "POST",
|
|
60
|
+
headers: { "Content-Type": "application/json" },
|
|
61
61
|
body: JSON.stringify(body),
|
|
62
62
|
signal: AbortSignal.timeout(120000),
|
|
63
63
|
});
|
|
@@ -66,7 +66,7 @@ export class ModelLoader {
|
|
|
66
66
|
this.logger.error(`Model load failed: HTTP ${response.status}: ${error}`);
|
|
67
67
|
return { success: false, error: `HTTP ${response.status}: ${error}` };
|
|
68
68
|
}
|
|
69
|
-
const result = await response.json();
|
|
69
|
+
const result = (await response.json());
|
|
70
70
|
this.logger.debug(`Model load response: ${JSON.stringify(result)}`);
|
|
71
71
|
const loadTime = result.load_time_seconds ?? result.loadTime;
|
|
72
72
|
return {
|
|
@@ -1,6 +1,30 @@
|
|
|
1
1
|
import { TokenCounter } from "./token-counter";
|
|
2
2
|
import { t } from "../i18n/index";
|
|
3
|
-
import { createRateLimiter
|
|
3
|
+
import { createRateLimiter } from "../modules/security/rate-limiter";
|
|
4
|
+
function buildRequestBody(opts) {
|
|
5
|
+
const body = {
|
|
6
|
+
model: opts.model,
|
|
7
|
+
messages: opts.messages,
|
|
8
|
+
stream: opts.stream,
|
|
9
|
+
};
|
|
10
|
+
if (opts.maxTokens !== undefined)
|
|
11
|
+
body.max_tokens = opts.maxTokens;
|
|
12
|
+
if (opts.reasoningEffort) {
|
|
13
|
+
body.reasoning_effort = opts.reasoningEffort;
|
|
14
|
+
}
|
|
15
|
+
if (opts.tools && opts.tools.length > 0) {
|
|
16
|
+
body.tools = opts.tools.map((t) => ({
|
|
17
|
+
type: "function",
|
|
18
|
+
function: {
|
|
19
|
+
name: t.name,
|
|
20
|
+
description: t.description,
|
|
21
|
+
parameters: t.parameters,
|
|
22
|
+
},
|
|
23
|
+
}));
|
|
24
|
+
body.tool_choice = "auto";
|
|
25
|
+
}
|
|
26
|
+
return body;
|
|
27
|
+
}
|
|
4
28
|
export class OpenAICompatProvider {
|
|
5
29
|
model;
|
|
6
30
|
contextWindow;
|
|
@@ -20,14 +44,14 @@ export class OpenAICompatProvider {
|
|
|
20
44
|
};
|
|
21
45
|
this.rateLimiter = createRateLimiter(config.rateLimits);
|
|
22
46
|
}
|
|
23
|
-
async *chat(messages, tools, signal) {
|
|
47
|
+
async *chat(messages, tools, signal, options) {
|
|
24
48
|
// Check rate limit before making request
|
|
25
49
|
if (!this.rateLimiter.canMakeRequest()) {
|
|
26
50
|
throw new Error(`Rate limit exceeded: ${this.rateLimiter.getConfig().maxRequestsPerMinute} requests per minute`);
|
|
27
51
|
}
|
|
28
52
|
// Record this request
|
|
29
53
|
this.rateLimiter.recordRequest();
|
|
30
|
-
const streamResult = this.doStream(messages, tools, signal);
|
|
54
|
+
const streamResult = this.doStream(messages, tools, signal, options);
|
|
31
55
|
let hasToolCall = false;
|
|
32
56
|
let hasText = false;
|
|
33
57
|
let reasoningAcc = "";
|
|
@@ -42,30 +66,21 @@ export class OpenAICompatProvider {
|
|
|
42
66
|
yield chunk;
|
|
43
67
|
}
|
|
44
68
|
if (!hasToolCall && !hasText) {
|
|
45
|
-
const fallback = await this.doNonStreaming(messages, tools, signal);
|
|
69
|
+
const fallback = await this.doNonStreaming(messages, tools, signal, options);
|
|
46
70
|
for (const chunk of fallback) {
|
|
47
71
|
yield chunk;
|
|
48
72
|
}
|
|
49
73
|
}
|
|
50
74
|
}
|
|
51
|
-
async *doStream(messages, tools, signal) {
|
|
52
|
-
const body = {
|
|
75
|
+
async *doStream(messages, tools, signal, options) {
|
|
76
|
+
const body = buildRequestBody({
|
|
53
77
|
model: this.model,
|
|
54
78
|
messages,
|
|
79
|
+
tools,
|
|
55
80
|
stream: true,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
body.tools = tools.map((t) => ({
|
|
60
|
-
type: "function",
|
|
61
|
-
function: {
|
|
62
|
-
name: t.name,
|
|
63
|
-
description: t.description,
|
|
64
|
-
parameters: t.parameters,
|
|
65
|
-
},
|
|
66
|
-
}));
|
|
67
|
-
body.tool_choice = "auto";
|
|
68
|
-
}
|
|
81
|
+
maxTokens: options?.maxTokens ?? this.config.maxCompletionTokens ?? 4096,
|
|
82
|
+
reasoningEffort: options?.reasoningEffort,
|
|
83
|
+
});
|
|
69
84
|
const headers = {
|
|
70
85
|
"Content-Type": "application/json",
|
|
71
86
|
};
|
|
@@ -195,24 +210,15 @@ export class OpenAICompatProvider {
|
|
|
195
210
|
reader.releaseLock();
|
|
196
211
|
}
|
|
197
212
|
}
|
|
198
|
-
async doNonStreaming(messages, tools, signal) {
|
|
199
|
-
const body = {
|
|
213
|
+
async doNonStreaming(messages, tools, signal, options) {
|
|
214
|
+
const body = buildRequestBody({
|
|
200
215
|
model: this.model,
|
|
201
216
|
messages,
|
|
217
|
+
tools,
|
|
202
218
|
stream: false,
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
body.tools = tools.map((t) => ({
|
|
207
|
-
type: "function",
|
|
208
|
-
function: {
|
|
209
|
-
name: t.name,
|
|
210
|
-
description: t.description,
|
|
211
|
-
parameters: t.parameters,
|
|
212
|
-
},
|
|
213
|
-
}));
|
|
214
|
-
body.tool_choice = "auto";
|
|
215
|
-
}
|
|
219
|
+
maxTokens: options?.maxTokens ?? this.config.maxCompletionTokens ?? 4096,
|
|
220
|
+
reasoningEffort: options?.reasoningEffort,
|
|
221
|
+
});
|
|
216
222
|
const headers = {
|
|
217
223
|
"Content-Type": "application/json",
|
|
218
224
|
};
|
package/dist/llm/orchestrator.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { OpenAICompatProvider } from
|
|
2
|
-
import { jsonrepair } from
|
|
1
|
+
import { OpenAICompatProvider } from "./openai-compat";
|
|
2
|
+
import { jsonrepair } from "jsonrepair";
|
|
3
3
|
const PLAN_SYSTEM_PROMPT = `You are a planning assistant for an agent system with multiple expert sub-agents.
|
|
4
4
|
Break down the user's task into subtasks that can be executed by different expert agents.
|
|
5
5
|
|
|
@@ -58,7 +58,7 @@ export class OrchestratorClient {
|
|
|
58
58
|
if (config.provider) {
|
|
59
59
|
this.provider = new OpenAICompatProvider({
|
|
60
60
|
model: config.model,
|
|
61
|
-
baseUrl: config.provider.baseUrl ||
|
|
61
|
+
baseUrl: config.provider.baseUrl || "http://localhost:1234/v1",
|
|
62
62
|
apiKey: config.provider.apiKey,
|
|
63
63
|
retry: config.retry,
|
|
64
64
|
});
|
|
@@ -69,7 +69,7 @@ export class OrchestratorClient {
|
|
|
69
69
|
else {
|
|
70
70
|
this.provider = new OpenAICompatProvider({
|
|
71
71
|
model: config.model,
|
|
72
|
-
baseUrl:
|
|
72
|
+
baseUrl: "http://localhost:1234/v1",
|
|
73
73
|
retry: config.retry,
|
|
74
74
|
});
|
|
75
75
|
}
|
|
@@ -83,15 +83,15 @@ export class OrchestratorClient {
|
|
|
83
83
|
}
|
|
84
84
|
async chat(messages) {
|
|
85
85
|
if (!this.provider)
|
|
86
|
-
throw new Error(
|
|
86
|
+
throw new Error("Orchestrator not enabled");
|
|
87
87
|
const chunks = [];
|
|
88
88
|
for await (const chunk of this.provider.chat(messages)) {
|
|
89
89
|
chunks.push(chunk);
|
|
90
90
|
}
|
|
91
91
|
return chunks
|
|
92
|
-
.filter((c) => c.type ===
|
|
92
|
+
.filter((c) => c.type === "text")
|
|
93
93
|
.map((c) => c.content)
|
|
94
|
-
.join(
|
|
94
|
+
.join("");
|
|
95
95
|
}
|
|
96
96
|
parseJSON(text) {
|
|
97
97
|
try {
|
|
@@ -109,7 +109,9 @@ export class OrchestratorClient {
|
|
|
109
109
|
const repaired = jsonrepair(jsonMatch[0]);
|
|
110
110
|
return JSON.parse(repaired);
|
|
111
111
|
}
|
|
112
|
-
catch {
|
|
112
|
+
catch {
|
|
113
|
+
/* fall through */
|
|
114
|
+
}
|
|
113
115
|
}
|
|
114
116
|
return null;
|
|
115
117
|
}
|
|
@@ -117,10 +119,10 @@ export class OrchestratorClient {
|
|
|
117
119
|
}
|
|
118
120
|
async plan(userPrompt, _context) {
|
|
119
121
|
if (!this.provider)
|
|
120
|
-
return { error:
|
|
122
|
+
return { error: "Orchestrator not enabled — no orchestrator model configured" };
|
|
121
123
|
const messages = [
|
|
122
|
-
{ role:
|
|
123
|
-
{ role:
|
|
124
|
+
{ role: "system", content: PLAN_SYSTEM_PROMPT },
|
|
125
|
+
{ role: "user", content: userPrompt },
|
|
124
126
|
];
|
|
125
127
|
const text = await this.chat(messages);
|
|
126
128
|
const parsed = this.parseJSON(text);
|
|
@@ -131,19 +133,21 @@ export class OrchestratorClient {
|
|
|
131
133
|
}
|
|
132
134
|
async verifyAndMerge(input) {
|
|
133
135
|
if (!this.provider)
|
|
134
|
-
return { type:
|
|
136
|
+
return { type: "final", finalAnswer: input.results.map((r) => r.summary).join("\n") };
|
|
135
137
|
this.replanCycle++;
|
|
136
138
|
if (this.replanCycle > 3) {
|
|
137
139
|
return {
|
|
138
|
-
type:
|
|
139
|
-
finalAnswer: input.results
|
|
140
|
-
|
|
140
|
+
type: "final",
|
|
141
|
+
finalAnswer: input.results
|
|
142
|
+
.map((r) => `${r.subtaskId}: ${r.success ? "OK" : "FAIL"} — ${r.summary}`)
|
|
143
|
+
.join("\n"),
|
|
144
|
+
explanation: "Max re-plan cycles (3) reached. Returning partial results.",
|
|
141
145
|
};
|
|
142
146
|
}
|
|
143
147
|
const context = JSON.stringify(input, null, 2);
|
|
144
148
|
const messages = [
|
|
145
|
-
{ role:
|
|
146
|
-
{ role:
|
|
149
|
+
{ role: "system", content: VERIFY_SYSTEM_PROMPT },
|
|
150
|
+
{ role: "user", content: context },
|
|
147
151
|
];
|
|
148
152
|
const text = await this.chat(messages);
|
|
149
153
|
const parsed = this.parseJSON(text);
|
|
@@ -151,20 +155,20 @@ export class OrchestratorClient {
|
|
|
151
155
|
return parsed;
|
|
152
156
|
}
|
|
153
157
|
return {
|
|
154
|
-
type:
|
|
155
|
-
finalAnswer: input.results.map(r => r.summary).join(
|
|
156
|
-
explanation:
|
|
158
|
+
type: "final",
|
|
159
|
+
finalAnswer: input.results.map((r) => r.summary).join("\n"),
|
|
160
|
+
explanation: "Failed to parse verifier output, returning collected results.",
|
|
157
161
|
};
|
|
158
162
|
}
|
|
159
163
|
async createPlan(task) {
|
|
160
164
|
if (!this.provider)
|
|
161
|
-
throw new Error(
|
|
165
|
+
throw new Error("Orchestrator not enabled");
|
|
162
166
|
const messages = [
|
|
163
167
|
{
|
|
164
|
-
role:
|
|
168
|
+
role: "system",
|
|
165
169
|
content: 'You are a planning assistant. Break down tasks into steps. Respond with JSON only: {"steps": ["step 1", "step 2", ...]}',
|
|
166
170
|
},
|
|
167
|
-
{ role:
|
|
171
|
+
{ role: "user", content: task },
|
|
168
172
|
];
|
|
169
173
|
const text = await this.chat(messages);
|
|
170
174
|
try {
|
|
@@ -176,17 +180,17 @@ export class OrchestratorClient {
|
|
|
176
180
|
}
|
|
177
181
|
async resolveConflict(context) {
|
|
178
182
|
if (!this.provider)
|
|
179
|
-
throw new Error(
|
|
183
|
+
throw new Error("Orchestrator not enabled");
|
|
180
184
|
const messages = [
|
|
181
185
|
{
|
|
182
|
-
role:
|
|
183
|
-
content:
|
|
186
|
+
role: "system",
|
|
187
|
+
content: "You are a conflict resolution assistant. Analyze the situation and recommend the best path forward.",
|
|
184
188
|
},
|
|
185
|
-
{ role:
|
|
189
|
+
{ role: "user", content: context },
|
|
186
190
|
];
|
|
187
|
-
let result =
|
|
191
|
+
let result = "";
|
|
188
192
|
for await (const chunk of this.provider.chat(messages)) {
|
|
189
|
-
if (chunk.type ===
|
|
193
|
+
if (chunk.type === "text" && chunk.content)
|
|
190
194
|
result += chunk.content;
|
|
191
195
|
}
|
|
192
196
|
return result;
|
package/dist/llm/response.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
export function parseChunks(chunks) {
|
|
2
|
-
let text =
|
|
2
|
+
let text = "";
|
|
3
3
|
let reasoning;
|
|
4
4
|
const toolCalls = [];
|
|
5
5
|
let hasToolCalls = false;
|
|
6
6
|
for (const chunk of chunks) {
|
|
7
|
-
if (chunk.type ===
|
|
7
|
+
if (chunk.type === "text" && chunk.content) {
|
|
8
8
|
text += chunk.content;
|
|
9
9
|
}
|
|
10
|
-
if (chunk.type ===
|
|
11
|
-
reasoning = (reasoning ||
|
|
10
|
+
if (chunk.type === "reasoning" && chunk.content) {
|
|
11
|
+
reasoning = (reasoning || "") + chunk.content;
|
|
12
12
|
}
|
|
13
|
-
if (chunk.type ===
|
|
13
|
+
if (chunk.type === "tool_call" && chunk.toolCall) {
|
|
14
14
|
hasToolCalls = true;
|
|
15
15
|
let parsedArgs;
|
|
16
16
|
try {
|
|
@@ -27,13 +27,13 @@ export function parseChunks(chunks) {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
if (hasToolCalls) {
|
|
30
|
-
return { type:
|
|
30
|
+
return { type: "tool_call", calls: toolCalls, reasoning };
|
|
31
31
|
}
|
|
32
32
|
if (reasoning && !text) {
|
|
33
|
-
return { type:
|
|
33
|
+
return { type: "reasoning", content: reasoning };
|
|
34
34
|
}
|
|
35
35
|
if (!text && !reasoning) {
|
|
36
|
-
return { type:
|
|
36
|
+
return { type: "empty" };
|
|
37
37
|
}
|
|
38
|
-
return { type:
|
|
38
|
+
return { type: "text", content: text || "", reasoning };
|
|
39
39
|
}
|
|
@@ -11,7 +11,7 @@ const LEVEL_COLORS = {
|
|
|
11
11
|
error: (s) => pc.red(s),
|
|
12
12
|
};
|
|
13
13
|
function isColorEnabled() {
|
|
14
|
-
return
|
|
14
|
+
return !process.env.NO_COLOR && !process.env.CI && process.stdout.isTTY === true;
|
|
15
15
|
}
|
|
16
16
|
export class Logger {
|
|
17
17
|
level;
|
package/dist/logger/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { Logger } from
|
|
1
|
+
export { Logger } from "./app-logger";
|