micro-models-agent 2.10.0 → 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/dist/assets/app.js +22 -4
- package/dist/assets/index.html +29 -0
- package/dist/assets/js/dom.js +2 -1
- package/dist/assets/js/feed.js +38 -26
- package/dist/assets/js/format.js +1 -1
- package/dist/assets/js/rail.js +114 -0
- package/dist/assets/js/settings-controls.js +2 -2
- package/dist/assets/js/settings.js +246 -51
- package/dist/assets/js/store.js +3 -0
- package/dist/assets/js/tabs.js +104 -2
- package/dist/assets/styles.css +215 -66
- package/dist/cli/cache-line.js +1 -0
- package/dist/cli/command-suggest.js +5 -4
- package/dist/cli/commands.js +231 -122
- package/dist/cli/completer.js +132 -31
- package/dist/cli/index.js +1 -0
- package/dist/cli/json-payload.js +4 -4
- package/dist/cli/main.js +166 -61
- package/dist/cli/onboarding-commands.js +126 -0
- package/dist/cli/plugin-commands.js +2 -1
- package/dist/cli/relaunch.js +16 -13
- package/dist/cli/repl-commands-lsp.js +75 -0
- package/dist/cli/repl-commands-skills.js +105 -0
- package/dist/cli/repl-commands.js +589 -266
- package/dist/cli/repl.js +436 -177
- package/dist/cli/run-result.js +5 -6
- package/dist/cli/security-commands.js +37 -28
- package/dist/cli/setup-order.js +4 -55
- package/dist/cli/setup-prompt.js +3 -2
- package/dist/cli/setup.js +27 -107
- package/dist/cli/web-command.js +98 -0
- package/dist/config/budget.js +5 -5
- package/dist/config/config.js +103 -96
- package/dist/config/defaults.js +38 -8
- package/dist/config/domains.js +24 -27
- package/dist/config/env.js +46 -0
- package/dist/config/experts.js +2 -0
- package/dist/config/index.js +1 -0
- package/dist/config/paths.js +56 -0
- package/dist/config/redact.js +44 -0
- package/dist/config/registry-extra.js +334 -0
- package/dist/config/registry.js +584 -0
- package/dist/config/security.js +35 -36
- package/dist/config/timeouts.js +74 -0
- package/dist/config/utils.js +16 -15
- package/dist/core/agent/artifact-progress.js +59 -0
- package/dist/core/agent/artifact-resolve.js +79 -0
- package/dist/core/agent/audit-gate.js +7 -3
- package/dist/core/agent/compaction.js +2 -2
- package/dist/core/agent/constants.js +33 -4
- package/dist/core/agent/context-log.js +454 -0
- package/dist/core/agent/context-renderer.js +5 -0
- package/dist/core/agent/critic-gate.js +132 -0
- package/dist/core/agent/hallucination-gate.js +148 -38
- package/dist/core/agent/loop-state.js +15 -0
- package/dist/core/agent/prefix-monitor.js +1 -1
- package/dist/core/agent/reasoning-resolver.js +10 -1
- package/dist/core/agent/token-tracker.js +7 -4
- package/dist/core/agent/tool-batch.js +93 -18
- package/dist/core/agent/tool-images.js +18 -0
- package/dist/core/agent/tool-output.js +65 -11
- package/dist/core/agent/tool-pairing.js +60 -0
- package/dist/core/agent-moe.js +25 -24
- package/dist/core/agent.js +429 -108
- package/dist/core/bootstrap/agent-phase.js +66 -0
- package/dist/core/bootstrap/config-phase.js +86 -0
- package/dist/core/bootstrap/modules-phase.js +269 -0
- package/dist/core/bootstrap/provider-phase.js +183 -0
- package/dist/core/bootstrap/session-phase.js +204 -0
- package/dist/core/bootstrap/state.js +94 -0
- package/dist/core/bootstrap/workspace-phase.js +115 -0
- package/dist/core/bootstrap.js +92 -660
- package/dist/core/crash-handler.js +17 -7
- package/dist/core/environment.js +37 -12
- package/dist/core/host-plan.js +43 -0
- package/dist/core/host.js +23 -0
- package/dist/core/index.js +1 -0
- package/dist/core/prompt-builder.js +17 -1
- package/dist/core/prompt-overflow.js +42 -43
- package/dist/core/session-logger.js +122 -30
- package/dist/core/system-prompt.js +117 -0
- package/dist/core/version.js +6 -4
- package/dist/core/web-host.js +34 -0
- package/dist/core/workspace.js +19 -15
- package/dist/i18n/en.json +106 -21
- package/dist/i18n/index.js +37 -3
- package/dist/i18n/ru.json +109 -21
- package/dist/index.js +7 -3
- package/dist/llm/image-utils.js +55 -64
- package/dist/llm/llm-errors.js +9 -0
- package/dist/llm/model-loader.js +10 -32
- package/dist/llm/models-dev.js +121 -0
- package/dist/llm/openai-compat.js +146 -73
- package/dist/llm/orchestrator.js +33 -11
- package/dist/llm/provider-budget.js +2 -2
- package/dist/llm/provider-context.js +233 -0
- package/dist/llm/provider.js +1 -1
- package/dist/llm/response.js +5 -0
- package/dist/llm/token-counter.js +27 -11
- package/dist/logger/app-logger.js +48 -22
- package/dist/logger/file-log.js +28 -19
- package/dist/logger/index.js +1 -0
- package/dist/main.js +24285 -22447
- package/dist/migration/backup.js +14 -3
- package/dist/migration/detect.js +12 -3
- package/dist/migration/index.js +1 -0
- package/dist/modules/artifacts/store.js +9 -8
- package/dist/modules/browser/actions.js +6 -0
- package/dist/modules/browser/bridge-client.js +14 -12
- package/dist/modules/browser/bridge-path.js +4 -4
- package/dist/modules/browser/console-buffer.js +37 -0
- package/dist/modules/browser/cookie-store.js +5 -0
- package/dist/modules/browser/driver-types.js +1 -0
- package/dist/modules/browser/driver.js +19 -11
- package/dist/modules/browser/index.js +3 -1
- package/dist/modules/browser/module.js +2 -1
- package/dist/modules/browser/session.js +10 -30
- package/dist/modules/browser/snapshot.js +19 -13
- package/dist/modules/browser/types.js +1 -0
- package/dist/modules/certification/cli.js +28 -20
- package/dist/modules/certification/fact-checker.js +9 -1
- package/dist/modules/certification/loader.js +9 -2
- package/dist/modules/certification/manifest.js +83 -21
- package/dist/modules/certification/runner.js +23 -13
- package/dist/modules/certification/scenarios.js +20 -20
- package/dist/modules/certification/syntax-scenarios.js +1 -2
- package/dist/modules/context/chunk-query.js +11 -9
- package/dist/modules/context/fact-extractor.js +37 -39
- package/dist/modules/context/index.js +1 -0
- package/dist/modules/context/manager.js +106 -80
- package/dist/modules/critic/client.js +176 -0
- package/dist/modules/critic/evidence.js +81 -0
- package/dist/modules/critic/provider.js +45 -0
- package/dist/modules/critic/tools.js +78 -0
- package/dist/modules/critic/types.js +1 -0
- package/dist/modules/execution/audit-runners.js +28 -34
- package/dist/modules/execution/auditor.js +53 -49
- package/dist/modules/execution/execution-plugin.js +142 -102
- package/dist/modules/execution/index.js +1 -1
- package/dist/modules/execution/input-from.js +37 -13
- package/dist/modules/execution/module.js +368 -191
- package/dist/modules/execution/moe-executor.js +53 -26
- package/dist/modules/execution/plan-actions.js +320 -202
- package/dist/modules/execution/plan-checks.js +35 -0
- package/dist/modules/execution/plan-coverage.js +36 -33
- package/dist/modules/execution/plan-steps.js +11 -3
- package/dist/modules/execution/plan-store.js +83 -17
- package/dist/modules/execution/plan-tool.js +89 -35
- package/dist/modules/execution/plan-validator.js +30 -10
- package/dist/modules/execution/planner.js +22 -13
- package/dist/modules/execution/stuck-detector.js +196 -93
- package/dist/modules/execution/tracker.js +22 -8
- package/dist/modules/execution/verifier.js +69 -48
- package/dist/modules/execution/windows-commands.js +12 -12
- package/dist/modules/hallucination/artifact-claim.js +93 -0
- package/dist/modules/hallucination/confidence.js +13 -11
- package/dist/modules/hallucination/consistency.js +10 -2
- package/dist/modules/hallucination/detector.js +10 -5
- package/dist/modules/hallucination/factual.js +43 -26
- package/dist/modules/hallucination/index.js +1 -0
- package/dist/modules/hallucination/js-identifiers.js +44 -45
- package/dist/modules/hallucination/llm-judge.js +17 -12
- package/dist/modules/hallucination/success-claim.js +59 -0
- package/dist/modules/indexer/cache.js +52 -4
- package/dist/modules/indexer/index.js +1 -0
- package/dist/modules/indexer/map-command.js +2 -4
- package/dist/modules/indexer/map-select.js +16 -16
- package/dist/modules/indexer/module.js +47 -12
- package/dist/modules/indexer/project-profile.js +8 -7
- package/dist/modules/indexer/symbols.js +15 -15
- package/dist/modules/indexer/walker.js +159 -29
- package/dist/modules/lsp/check-tool.js +7 -5
- package/dist/modules/lsp/client.js +39 -39
- package/dist/modules/lsp/command.js +17 -24
- package/dist/modules/lsp/config.js +12 -11
- package/dist/modules/lsp/index.js +1 -0
- package/dist/modules/lsp/module.js +48 -46
- package/dist/modules/lsp/probe.js +13 -14
- package/dist/modules/lsp/project-root.js +14 -17
- package/dist/modules/lsp/startup-check.js +18 -16
- package/dist/modules/mcp/client.js +59 -62
- package/dist/modules/mcp/index.js +1 -0
- package/dist/modules/mcp/module.js +66 -37
- package/dist/modules/mcp/registry.js +5 -0
- package/dist/modules/memory/index.js +1 -0
- package/dist/modules/memory/module.js +12 -8
- package/dist/modules/memory/search.js +4 -1
- package/dist/modules/memory/store.js +40 -2
- package/dist/modules/onboarding/init.js +47 -0
- package/dist/modules/onboarding/meet.js +30 -0
- package/dist/modules/onboarding/mode.js +30 -0
- package/dist/modules/onboarding/prompts.js +43 -0
- package/dist/modules/pipelines/engine.js +10 -0
- package/dist/modules/pipelines/index.js +1 -0
- package/dist/modules/pipelines/parser.js +4 -1
- package/dist/modules/pipelines/template.js +4 -0
- package/dist/modules/plugins/builtin/lint-on-write.js +80 -67
- package/dist/modules/plugins/builtin/notify.js +2 -0
- package/dist/modules/plugins/index.js +1 -0
- package/dist/modules/plugins/loader.js +18 -3
- package/dist/modules/plugins/manager.js +37 -17
- package/dist/modules/pricing/index.js +10 -11
- package/dist/modules/pricing/prices.js +12 -12
- package/dist/modules/processes/index.js +1 -0
- package/dist/modules/processes/kill-tree.js +27 -31
- package/dist/modules/processes/registry.js +44 -25
- package/dist/modules/processes/runner.js +4 -4
- package/dist/modules/providers/capabilities.js +28 -0
- package/dist/modules/providers/create.js +3 -4
- package/dist/modules/providers/factory.js +7 -7
- package/dist/modules/providers/fallback.js +12 -12
- package/dist/modules/providers/health.js +4 -4
- package/dist/modules/providers/manager.js +50 -19
- package/dist/modules/providers/naming.js +15 -0
- package/dist/modules/providers/preflight.js +71 -0
- package/dist/modules/providers/presets.js +39 -8
- package/dist/modules/providers/registry.js +7 -2
- package/dist/modules/reasoning/policy.js +8 -6
- package/dist/modules/reasoning/probe.js +30 -25
- package/dist/modules/security/audit-log.js +19 -36
- package/dist/modules/security/audit-notifier.js +35 -75
- package/dist/modules/security/command-validator.js +99 -51
- package/dist/modules/security/content-scanner.js +8 -8
- package/dist/modules/security/data-sanitizer.js +9 -16
- package/dist/modules/security/encryption.js +32 -52
- package/dist/modules/security/index.js +2 -1
- package/dist/modules/security/network-validator.js +120 -43
- package/dist/modules/security/path-validator.js +61 -46
- package/dist/modules/security/protected-paths.js +73 -0
- package/dist/modules/security/rate-limiter.js +17 -49
- package/dist/modules/security/security-policies.js +25 -57
- package/dist/modules/security/session-encryption.js +32 -71
- package/dist/modules/security/session-isolation.js +15 -28
- package/dist/modules/session/auto-name.js +63 -0
- package/dist/modules/session/export.js +98 -0
- package/dist/modules/session/index.js +1 -0
- package/dist/modules/session/manager.js +79 -28
- package/dist/modules/session/module.js +4 -3
- package/dist/modules/session/store.js +57 -20
- package/dist/modules/setup/answers.js +35 -0
- package/dist/modules/setup/apply.js +79 -0
- package/dist/modules/setup/discovery.js +72 -0
- package/dist/modules/skills/index.js +1 -0
- package/dist/modules/skills/loader.js +9 -1
- package/dist/modules/skills/module.js +11 -0
- package/dist/modules/updater/changelog-reader.js +15 -16
- package/dist/modules/updater/checker.js +9 -4
- package/dist/modules/updater/dev-detect.js +7 -6
- package/dist/modules/updater/index.js +1 -0
- package/dist/modules/updater/module.js +17 -15
- package/dist/modules/user-profile/compressor.js +2 -0
- package/dist/modules/user-profile/index.js +1 -0
- package/dist/modules/user-profile/profile.js +10 -1
- package/dist/modules/webui/answer-api.js +29 -0
- package/dist/modules/webui/assets.js +50 -0
- package/dist/modules/webui/body.js +21 -0
- package/dist/modules/webui/commands-settings.js +209 -0
- package/dist/modules/webui/commands-shared.js +60 -0
- package/dist/modules/webui/commands.js +174 -0
- package/dist/modules/webui/config-api.js +134 -0
- package/dist/modules/webui/file-api.js +202 -0
- package/dist/modules/webui/forward.js +159 -0
- package/dist/modules/webui/history-api.js +112 -0
- package/dist/modules/webui/host-state.js +60 -0
- package/dist/modules/webui/i18n-api.js +9 -0
- package/dist/modules/webui/limits.js +6 -0
- package/dist/modules/webui/log-forward.js +20 -0
- package/dist/modules/webui/memory-commands.js +64 -0
- package/dist/modules/webui/model-cache.js +18 -0
- package/dist/modules/webui/module.js +148 -0
- package/dist/modules/webui/persist.js +24 -0
- package/dist/modules/webui/prompt-io.js +97 -0
- package/dist/modules/webui/providers-api.js +337 -0
- package/dist/modules/webui/providers-view.js +56 -0
- package/dist/modules/webui/reasoning-view.js +15 -0
- package/dist/modules/webui/run-agent.js +81 -0
- package/dist/modules/webui/server.js +284 -0
- package/dist/modules/webui/sessions-api.js +178 -0
- package/dist/modules/webui/settings-api.js +561 -0
- package/dist/modules/webui/setup-api.js +201 -0
- package/dist/modules/webui/state.js +74 -0
- package/dist/modules/webui/util.js +261 -0
- package/dist/output/bus.js +7 -2
- package/dist/output/channel.js +80 -28
- package/dist/output/format.js +2 -1
- package/dist/output/index.js +1 -0
- package/dist/output/json-sink.js +5 -3
- package/dist/output/machine.js +4 -3
- package/dist/output/session-sink.js +4 -4
- package/dist/tools/approve.js +4 -0
- package/dist/tools/attach-image.js +5 -4
- package/dist/tools/auto-fixer.js +26 -44
- package/dist/tools/auto-tags.js +83 -0
- package/dist/tools/bash.js +193 -116
- package/dist/tools/browser.js +76 -31
- package/dist/tools/chunk-query.js +14 -6
- package/dist/tools/create-dir.js +9 -5
- package/dist/tools/delete-file.js +9 -5
- package/dist/tools/download-file.js +32 -7
- package/dist/tools/edit-file.js +52 -14
- package/dist/tools/enable-tools.js +6 -6
- package/dist/tools/executor.js +132 -27
- package/dist/tools/file-info.js +3 -1
- package/dist/tools/filter-tools.js +3 -3
- package/dist/tools/glob-tool.js +4 -1
- package/dist/tools/grep-tool.js +13 -10
- package/dist/tools/hidden-tools-block.js +6 -6
- package/dist/tools/index.js +16 -8
- package/dist/tools/list-dir.js +4 -2
- package/dist/tools/load-skill.js +7 -0
- package/dist/tools/mcp-call.js +15 -4
- package/dist/tools/meet-done.js +14 -0
- package/dist/tools/move-file.js +14 -7
- package/dist/tools/path-utils.js +29 -29
- package/dist/tools/pipeline-run.js +29 -7
- package/dist/tools/preview.js +1 -1
- package/dist/tools/process-ids.js +31 -0
- package/dist/tools/process-kill.js +9 -16
- package/dist/tools/process-list.js +1 -0
- package/dist/tools/process-log.js +11 -16
- package/dist/tools/process-wait.js +63 -0
- package/dist/tools/prompt-io.js +4 -3
- package/dist/tools/question.js +172 -25
- package/dist/tools/read-file.js +55 -34
- package/dist/tools/recall.js +14 -8
- package/dist/tools/registry.js +6 -5
- package/dist/tools/remember.js +8 -4
- package/dist/tools/scope-request.js +11 -6
- package/dist/tools/search-history.js +5 -2
- package/dist/tools/session-info.js +2 -0
- package/dist/tools/set-thinking.js +8 -4
- package/dist/tools/subagent.js +59 -39
- package/dist/tools/syntax-validator.js +292 -90
- package/dist/tools/user-input.js +22 -18
- package/dist/tools/web-browse.js +9 -3
- package/dist/tools/web-fetch.js +12 -23
- package/dist/tools/web-search.js +7 -5
- package/dist/tools/write-file.js +45 -15
- package/dist/ui/action-log.js +13 -0
- package/dist/ui/box.js +4 -3
- package/dist/ui/colors.js +2 -0
- package/dist/ui/diff.js +6 -5
- package/dist/ui/index.js +1 -0
- package/dist/ui/line-editor.js +230 -122
- package/dist/ui/line-math.js +10 -2
- package/dist/ui/md-formatter.js +57 -37
- package/dist/ui/output.js +8 -3
- package/dist/ui/plan-view.js +21 -10
- package/dist/ui/renderer.js +393 -67
- package/dist/ui/spinner.js +16 -5
- package/dist/ui/table.js +15 -17
- package/dist/ui/theme.js +143 -0
- package/dist/utils/child-run.js +20 -0
- package/dist/utils/error.js +1 -1
- package/dist/utils/index.js +2 -0
- package/dist/utils/retry.js +2 -2
- package/dist/utils/truncate.js +1 -1
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** Глобальные обработчики падений: запись краша в ~/.mma/logs/crash.jsonl. */
|
|
1
2
|
import { appendFileSync, mkdirSync } from "fs";
|
|
2
3
|
import { join } from "path";
|
|
3
4
|
import { homedir } from "os";
|
|
@@ -5,9 +6,15 @@ import { collectEnvironment } from "./environment";
|
|
|
5
6
|
import { sanitizeLogMessage } from "../modules/security/data-sanitizer";
|
|
6
7
|
import { t } from "../i18n/index";
|
|
7
8
|
import { errMsg } from "../utils";
|
|
8
|
-
|
|
9
|
+
import { globalLogsDir } from "../config/paths";
|
|
10
|
+
/** Каталог краш-логов. */
|
|
11
|
+
export const CRASH_LOG_DIR = globalLogsDir();
|
|
12
|
+
/** Имя файла краш-лога. */
|
|
9
13
|
export const CRASH_LOG_FILE = "crash.jsonl";
|
|
10
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Строит санитизированную запись о падении. Окружение снимается в момент
|
|
16
|
+
* краша (без сканирования тулов).
|
|
17
|
+
*/
|
|
11
18
|
export function formatCrashEntry(type, err) {
|
|
12
19
|
const message = errMsg(err);
|
|
13
20
|
const stack = err instanceof Error && err.stack ? err.stack : message;
|
|
@@ -19,20 +26,23 @@ export function formatCrashEntry(type, err) {
|
|
|
19
26
|
environment: collectEnvironment({ configDir: homedir(), scanTools: false }),
|
|
20
27
|
};
|
|
21
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Дописывает запись в краш-лог. Best-effort: отчёт о краше никогда не роняет процесс.
|
|
31
|
+
*/
|
|
22
32
|
export function writeCrashEntry(dir, entry) {
|
|
23
33
|
try {
|
|
24
34
|
mkdirSync(dir, { recursive: true });
|
|
25
|
-
appendFileSync(join(dir, CRASH_LOG_FILE), JSON.stringify(entry)
|
|
35
|
+
appendFileSync(join(dir, CRASH_LOG_FILE), `${JSON.stringify(entry)}\n`, "utf-8");
|
|
26
36
|
}
|
|
27
37
|
catch {
|
|
28
|
-
// Best
|
|
38
|
+
// Best-effort — отчёт о краше не должен ронять процесс
|
|
29
39
|
}
|
|
30
40
|
}
|
|
31
41
|
let installed = false;
|
|
32
42
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
43
|
+
* Ставит глобальные обработчики. uncaughtException логируется и завершает
|
|
44
|
+
* процесс (exit 1 — продолжение в битом состоянии недопустимо);
|
|
45
|
+
* unhandledRejection только логируется (цикл продолжает работу).
|
|
36
46
|
*/
|
|
37
47
|
export function installCrashHandlers() {
|
|
38
48
|
if (installed)
|
package/dist/core/environment.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** Отчёт об окружении: рантайм, ОС, тулы, провайдер, Playwright. */
|
|
1
2
|
import { existsSync, readFileSync, readdirSync } from "fs";
|
|
2
3
|
import { spawnSync } from "child_process";
|
|
3
4
|
import { createRequire } from "module";
|
|
@@ -8,7 +9,7 @@ import { env } from "process";
|
|
|
8
9
|
import { readMmaVersion } from "./version";
|
|
9
10
|
import { sanitizeUrl } from "../modules/security/network-validator";
|
|
10
11
|
import { t } from "../i18n/index";
|
|
11
|
-
/**
|
|
12
|
+
/** Тулы, проверяемые в PATH (только реальные бинари, без .cmd-шимов). */
|
|
12
13
|
const TOOL_CHECKS = ["bun", "node", "git", "python"];
|
|
13
14
|
function readEngineRequirement() {
|
|
14
15
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
@@ -22,12 +23,16 @@ function readEngineRequirement() {
|
|
|
22
23
|
return String(raw.engines.node);
|
|
23
24
|
}
|
|
24
25
|
catch {
|
|
25
|
-
//
|
|
26
|
+
// Битый package.json — пропускаем
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
return ">=20";
|
|
29
30
|
}
|
|
30
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Проверяет версию against минимума из requirement (напр. `>=20`).
|
|
33
|
+
* @param version проверяемая версия; @param requirement требование engines.
|
|
34
|
+
* @returns true, если версия не ниже минимальной.
|
|
35
|
+
*/
|
|
31
36
|
export function satisfiesMinimum(version, requirement) {
|
|
32
37
|
const minMatch = requirement.match(/(\d+)(?:\.(\d+))?(?:\.(\d+))?/);
|
|
33
38
|
if (!minMatch)
|
|
@@ -51,6 +56,10 @@ export function satisfiesMinimum(version, requirement) {
|
|
|
51
56
|
}
|
|
52
57
|
return true;
|
|
53
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Детектит рантайм (Bun vs Node) и сверяет Node с engines из package.json.
|
|
61
|
+
* @returns информация о рантайме.
|
|
62
|
+
*/
|
|
54
63
|
export function detectRuntime() {
|
|
55
64
|
const bun = globalThis.Bun;
|
|
56
65
|
const isBun = typeof bun !== "undefined" && typeof bun?.version !== "undefined";
|
|
@@ -62,9 +71,9 @@ export function detectRuntime() {
|
|
|
62
71
|
runtimeVersion,
|
|
63
72
|
nodeVersion: process.version,
|
|
64
73
|
engine,
|
|
65
|
-
// engines.node
|
|
66
|
-
//
|
|
67
|
-
//
|
|
74
|
+
// engines.node — про Node-рантайм. Bun проходит через встроенный Node
|
|
75
|
+
// (process.version); версию самого Bun с требованием не сравниваем
|
|
76
|
+
// (Bun 1.x всегда выглядел бы «слишком старым»).
|
|
68
77
|
engineOk: satisfiesMinimum(process.version, engine),
|
|
69
78
|
};
|
|
70
79
|
}
|
|
@@ -85,7 +94,10 @@ function toolVersion(cmd) {
|
|
|
85
94
|
return "missing";
|
|
86
95
|
}
|
|
87
96
|
}
|
|
88
|
-
/**
|
|
97
|
+
/**
|
|
98
|
+
* Каталог бинарников браузеров Playwright (env-переменная приоритетнее).
|
|
99
|
+
* @returns путь к каталогу браузеров.
|
|
100
|
+
*/
|
|
89
101
|
export function playwrightBrowsersDir() {
|
|
90
102
|
if (process.env.PLAYWRIGHT_BROWSERS_PATH)
|
|
91
103
|
return process.env.PLAYWRIGHT_BROWSERS_PATH;
|
|
@@ -93,14 +105,17 @@ export function playwrightBrowsersDir() {
|
|
|
93
105
|
? join(homedir(), "AppData", "Local", "ms-playwright")
|
|
94
106
|
: join(homedir(), ".cache", "ms-playwright");
|
|
95
107
|
}
|
|
96
|
-
/**
|
|
108
|
+
/**
|
|
109
|
+
* Наличие/версия пакета Playwright + скачаны ли бинарники браузеров.
|
|
110
|
+
* @returns installed/version/browsersDir/browsersInstalled.
|
|
111
|
+
*/
|
|
97
112
|
export function playwrightInfo() {
|
|
98
113
|
let installed = false;
|
|
99
114
|
let version = "";
|
|
100
115
|
const browsersDir = playwrightBrowsersDir();
|
|
101
116
|
try {
|
|
102
|
-
//
|
|
103
|
-
//
|
|
117
|
+
// Правило №12: резолв с диска в рантайме — работает и в src/, и в dist/,
|
|
118
|
+
// и под Bun, и под Node (мост тоже через createRequire).
|
|
104
119
|
const require = createRequire(import.meta.url);
|
|
105
120
|
const pkgPath = require.resolve("playwright/package.json");
|
|
106
121
|
installed = existsSync(pkgPath);
|
|
@@ -120,7 +135,10 @@ export function playwrightInfo() {
|
|
|
120
135
|
}
|
|
121
136
|
return { installed, version, browsersDir, browsersInstalled };
|
|
122
137
|
}
|
|
123
|
-
/**
|
|
138
|
+
/**
|
|
139
|
+
* Чистая проверка требований — варнинги из отчёта, без сайд-эффектов.
|
|
140
|
+
* @param report отчёт collectEnvironment; @returns список варнингов.
|
|
141
|
+
*/
|
|
124
142
|
export function checkEnvironmentRequirements(report) {
|
|
125
143
|
const warnings = [];
|
|
126
144
|
if (report.runtime.runtime === "node") {
|
|
@@ -148,6 +166,10 @@ export function checkEnvironmentRequirements(report) {
|
|
|
148
166
|
}
|
|
149
167
|
return warnings;
|
|
150
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* Собирает полный отчёт об окружении (рантайм, ОС, тулы, провайдер).
|
|
171
|
+
* @param opts configDir/baseDir/config/scanTools; @returns готовый отчёт.
|
|
172
|
+
*/
|
|
151
173
|
export function collectEnvironment(opts) {
|
|
152
174
|
const runtime = detectRuntime();
|
|
153
175
|
const tools = {};
|
|
@@ -192,7 +214,10 @@ export function collectEnvironment(opts) {
|
|
|
192
214
|
report.warnings = checkEnvironmentRequirements(report);
|
|
193
215
|
return report;
|
|
194
216
|
}
|
|
195
|
-
/**
|
|
217
|
+
/**
|
|
218
|
+
* Компактная строка для человека + полный отчёт в JSONL-лог.
|
|
219
|
+
* @param report отчёт окружения; @param logger логгер сессии.
|
|
220
|
+
*/
|
|
196
221
|
export function logEnvironment(report, logger) {
|
|
197
222
|
logger.info(`Environment: ${report.os.platform} ${report.os.arch} | ${report.runtime.runtime} ${report.runtime.runtimeVersion} (node ${report.runtime.nodeVersion}) | mma ${report.mmaVersion} | ${report.provider?.model ?? "no provider"}`);
|
|
198
223
|
logger.logStructured("environment", report);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Чистая проекция плана модуля исполнения в план снапшота хоста.
|
|
3
|
+
* @param plan план в форме ActivePlanLike; @returns план снапшота либо null.
|
|
4
|
+
*/
|
|
5
|
+
export function planSnapshotFromModule(plan) {
|
|
6
|
+
if (!plan)
|
|
7
|
+
return null;
|
|
8
|
+
return {
|
|
9
|
+
steps: plan.steps.map((s) => ({ text: s.text, status: s.status })),
|
|
10
|
+
currentIndex: plan.currentIndex,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Планы несут пятый статус (`skipped`) без `currentIndex`. Маппим на контракт
|
|
15
|
+
* хоста: skipped — settled, читается как done; текущий индекс — первый шаг
|
|
16
|
+
* не в done/skipped.
|
|
17
|
+
*/
|
|
18
|
+
function toPlanStepStatus(status) {
|
|
19
|
+
switch (status) {
|
|
20
|
+
case "skipped":
|
|
21
|
+
return "done";
|
|
22
|
+
case "pending":
|
|
23
|
+
case "in_progress":
|
|
24
|
+
case "done":
|
|
25
|
+
case "failed":
|
|
26
|
+
return status;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Адаптирует реальный `Plan` модуля исполнения под вход снапшота.
|
|
31
|
+
* @param plan план исполнения; @returns ActivePlanLike либо null.
|
|
32
|
+
*/
|
|
33
|
+
export function adaptActivePlan(plan) {
|
|
34
|
+
if (!plan)
|
|
35
|
+
return null;
|
|
36
|
+
return {
|
|
37
|
+
steps: plan.steps.map((s) => ({
|
|
38
|
+
text: s.description,
|
|
39
|
+
status: toPlanStepStatus(s.status),
|
|
40
|
+
})),
|
|
41
|
+
currentIndex: plan.steps.findIndex((s) => s.status !== "done" && s.status !== "skipped"),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { defaultOutputBus } from "../output/bus";
|
|
2
|
+
/**
|
|
3
|
+
* Строит HostBridge для плагинов (`ctx.hostBridge`). Веб-клиенты (и любой
|
|
4
|
+
* плагин) шлют сообщения через ТОТ ЖЕ runAgent-путь, что и терминальный ввод:
|
|
5
|
+
* рендеринг, лог сессии и single-flight guard общие, без дублирования.
|
|
6
|
+
*/
|
|
7
|
+
export function createHostBridge(opts) {
|
|
8
|
+
return {
|
|
9
|
+
isBusy: opts.isBusy,
|
|
10
|
+
async submit(text, o) {
|
|
11
|
+
if (opts.isBusy())
|
|
12
|
+
throw new Error("agent is busy");
|
|
13
|
+
for (const url of o?.images ?? [])
|
|
14
|
+
opts.addPendingImage(url);
|
|
15
|
+
return opts.runAgent(text);
|
|
16
|
+
},
|
|
17
|
+
interrupt() {
|
|
18
|
+
if (opts.isBusy())
|
|
19
|
+
opts.interruptRun();
|
|
20
|
+
},
|
|
21
|
+
subscribeOutput: (fn) => defaultOutputBus.subscribe(fn),
|
|
22
|
+
};
|
|
23
|
+
}
|
package/dist/core/index.js
CHANGED
|
@@ -6,22 +6,38 @@ const PRIORITY_ORDER = {
|
|
|
6
6
|
};
|
|
7
7
|
function blockLabel(content) {
|
|
8
8
|
const firstLine = content.split("\n")[0].trim();
|
|
9
|
-
return firstLine.length > 70 ? firstLine.slice(0, 67)
|
|
9
|
+
return firstLine.length > 70 ? `${firstLine.slice(0, 67)}...` : firstLine;
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Собирает системный промпт из блоков: essential всегда, остальные по
|
|
13
|
+
* приоритету, пока влезают в бюджет.
|
|
14
|
+
*/
|
|
11
15
|
export class PromptBuilder {
|
|
12
16
|
blocks = [];
|
|
13
17
|
budget;
|
|
14
18
|
constructor(budget) {
|
|
15
19
|
this.budget = budget;
|
|
16
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Добавляет один блок.
|
|
23
|
+
* @param block блок промпта с приоритетом и оценкой токенов.
|
|
24
|
+
*/
|
|
17
25
|
addBlock(block) {
|
|
18
26
|
this.blocks.push(block);
|
|
19
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Добавляет несколько блоков.
|
|
30
|
+
* @param blocks массив блоков промпта.
|
|
31
|
+
*/
|
|
20
32
|
addBlocks(blocks) {
|
|
21
33
|
for (const b of blocks) {
|
|
22
34
|
this.blocks.push(b);
|
|
23
35
|
}
|
|
24
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Строит промпт: essential-блоки всегда, остальные по приоритету в бюджет.
|
|
39
|
+
* @returns промпт, исключённое и поблочная разбивка.
|
|
40
|
+
*/
|
|
25
41
|
build() {
|
|
26
42
|
const essential = [];
|
|
27
43
|
const nonEssential = [];
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
/** Переполнение системного промпта: dry-run, суммаризация, подсказки. */
|
|
2
2
|
import { createHash } from "crypto";
|
|
3
3
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
4
4
|
import { join } from "path";
|
|
5
5
|
import { PromptBuilder } from "./prompt-builder";
|
|
6
6
|
import { estimateTokens } from "../llm/token-counter";
|
|
7
7
|
import { t } from "../i18n/index";
|
|
8
|
-
/**
|
|
8
|
+
/** Цена model-facing hint-блока в токенах (верхняя граница для аллокации). */
|
|
9
9
|
export const HINT_BLOCK_TOKENS = 60;
|
|
10
|
-
/**
|
|
10
|
+
/** Грубый фактор символов на токен для жёсткого усечения. */
|
|
11
11
|
const CHARS_PER_TOKEN = 4;
|
|
12
12
|
const KIND_ORDER = ["instructions", "project-map"];
|
|
13
13
|
const KIND_LABEL = {
|
|
@@ -19,9 +19,8 @@ const KIND_SOURCE_FILE = {
|
|
|
19
19
|
"project-map": "",
|
|
20
20
|
};
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* first LLM call (the real resolution).
|
|
22
|
+
* Статический dry-run бюджета системного промпта: какие kind-блоки не влезают.
|
|
23
|
+
* Нужен bootstrap для стартового баннера и Agent перед первым LLM-вызовом.
|
|
25
24
|
*/
|
|
26
25
|
export function dryRunOverflow(allBlocks, systemBudget) {
|
|
27
26
|
const builder = new PromptBuilder(systemBudget);
|
|
@@ -51,13 +50,13 @@ function readCache(cacheDir, key) {
|
|
|
51
50
|
}
|
|
52
51
|
}
|
|
53
52
|
catch {
|
|
54
|
-
//
|
|
53
|
+
// Легаси plain-text запись — считаем попаданием суммаризации
|
|
55
54
|
return { mode: "summary", text: raw };
|
|
56
55
|
}
|
|
57
56
|
return null;
|
|
58
57
|
}
|
|
59
58
|
catch {
|
|
60
|
-
//
|
|
59
|
+
// Битый кэш — идём на повторную суммаризацию
|
|
61
60
|
}
|
|
62
61
|
return null;
|
|
63
62
|
}
|
|
@@ -67,16 +66,16 @@ function writeCache(cacheDir, key, entry) {
|
|
|
67
66
|
writeFileSync(join(cacheDir, `${key}.md`), JSON.stringify(entry), "utf-8");
|
|
68
67
|
}
|
|
69
68
|
catch {
|
|
70
|
-
// Best-effort —
|
|
69
|
+
// Best-effort — падение кэша не должно ронять агента
|
|
71
70
|
}
|
|
72
71
|
}
|
|
73
|
-
/**
|
|
72
|
+
/** Собирает полный текстовый ответ через стриминговый API провайдера. */
|
|
74
73
|
async function collectText(provider, prompt, maxTokens) {
|
|
75
74
|
let text = "";
|
|
76
|
-
// Reasoning
|
|
77
|
-
//
|
|
78
|
-
// 2x
|
|
79
|
-
//
|
|
75
|
+
// Reasoning выкл: думающая модель сожгла бы cap на <think> до любого
|
|
76
|
+
// суммаризирующего контента (наблюдалось на qwen3.5-9b).
|
|
77
|
+
// 2x запас сверх цели: оценки токенов эвристичны, а clamp ниже держит
|
|
78
|
+
// реальный cap независимо от ответа модели.
|
|
80
79
|
for await (const chunk of provider.chat([{ role: "user", content: prompt }], undefined, undefined, {
|
|
81
80
|
maxTokens: maxTokens * 2,
|
|
82
81
|
reasoningEffort: "none",
|
|
@@ -96,17 +95,16 @@ function truncateToTokens(content, maxTokens) {
|
|
|
96
95
|
cut = cut.slice(0, lastBreak);
|
|
97
96
|
return `${cut.trimEnd()}\n\n[...truncated — read the full file for details...]`;
|
|
98
97
|
}
|
|
99
|
-
/**
|
|
98
|
+
/** Однострочная метка по первой строке (для варнингов/логов). */
|
|
100
99
|
function blockLabel(content) {
|
|
101
100
|
const first = content.split("\n")[0].trim();
|
|
102
101
|
return first.length > 60 ? `${first.slice(0, 57)}...` : first;
|
|
103
102
|
}
|
|
104
103
|
/**
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
* remaining budget, later blocks get whatever is left.
|
|
104
|
+
* Суммаризирует (или, не вышло, усекает) блоки сверх бюджета, чтобы инструкции
|
|
105
|
+
* проекта/карта всё равно дошли до модели. Суммаризации кэшируются на диске
|
|
106
|
+
* (ключ: kind + контент + бюджет). Порядок — KIND_ORDER; первый забирает весь
|
|
107
|
+
* остаток бюджета, остальным — что останется.
|
|
110
108
|
*/
|
|
111
109
|
export async function resolvePromptOverflow(opts) {
|
|
112
110
|
const { overflow, includedTokens, systemBudget, provider, cacheDir, logger } = opts;
|
|
@@ -114,10 +112,10 @@ export async function resolvePromptOverflow(opts) {
|
|
|
114
112
|
const replacements = [];
|
|
115
113
|
const warnings = [];
|
|
116
114
|
let used = includedTokens;
|
|
117
|
-
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
//
|
|
115
|
+
const unresolved = [];
|
|
116
|
+
// Dry-run bootstrap лишь предупреждает, что блоки «будут суммаризированы
|
|
117
|
+
// перед первым запуском». Без нотиса тут первый промпт выглядит зависшим,
|
|
118
|
+
// пока модель переписывает AGENTS.md / карту — показываем явно.
|
|
121
119
|
if (sorted.length > 0) {
|
|
122
120
|
logger?.warn(t("prompt.overflow.compressing", { count: String(sorted.length) }));
|
|
123
121
|
}
|
|
@@ -147,8 +145,8 @@ export async function resolvePromptOverflow(opts) {
|
|
|
147
145
|
try {
|
|
148
146
|
const prompt = [
|
|
149
147
|
`Summarize the following ${KIND_LABEL[kind]} document.`,
|
|
150
|
-
// 3
|
|
151
|
-
//
|
|
148
|
+
// 3 символа/токен (не 4): нелатиница (кириллица и т.п.) — ~2–3 символа
|
|
149
|
+
// на токен, поэтому цель x4 уводит суммаризацию за clamp.
|
|
152
150
|
`Target length: at most ${targetChars} characters (~${maxTokens} tokens). Be strict about it.`,
|
|
153
151
|
`Preserve concrete facts: file paths, commands, rules, naming conventions, workflow steps.`,
|
|
154
152
|
`Keep the structure (headings / bullet lists). Output ONLY the summary text.`,
|
|
@@ -158,10 +156,9 @@ export async function resolvePromptOverflow(opts) {
|
|
|
158
156
|
`--- DOCUMENT END ---`,
|
|
159
157
|
].join("\n");
|
|
160
158
|
text = await collectText(provider, prompt, maxTokens);
|
|
161
|
-
//
|
|
162
|
-
//
|
|
163
|
-
//
|
|
164
|
-
// compliance much likelier — before falling back to the hard clamp.
|
|
159
|
+
// Маленькие модели регулярно игнорируют лимит длины (наблюдалось: 9B
|
|
160
|
+
// выдала ~4700 символов при цели 3170). Один retry самокомпрессии на
|
|
161
|
+
// перелёт — короткий вход резко повышает послушание — затем жёсткий clamp.
|
|
165
162
|
let retries = 0;
|
|
166
163
|
while (text && estimateTokens(text) > maxTokens && retries < 1) {
|
|
167
164
|
retries++;
|
|
@@ -186,7 +183,7 @@ export async function resolvePromptOverflow(opts) {
|
|
|
186
183
|
}
|
|
187
184
|
}
|
|
188
185
|
if (!text) {
|
|
189
|
-
//
|
|
186
|
+
// Нет провайдера или суммаризация упала — фолбэк жёсткого усечения.
|
|
190
187
|
mode = "truncate";
|
|
191
188
|
logger?.warn(t("prompt.overflow.truncating", {
|
|
192
189
|
label: blockLabel(block.content),
|
|
@@ -194,7 +191,7 @@ export async function resolvePromptOverflow(opts) {
|
|
|
194
191
|
}));
|
|
195
192
|
text = truncateToTokens(block.content, maxTokens);
|
|
196
193
|
}
|
|
197
|
-
//
|
|
194
|
+
// LLM перелетают: держим cap независимо от источника текста.
|
|
198
195
|
if (estimateTokens(text) > maxTokens) {
|
|
199
196
|
if (mode === "summary") {
|
|
200
197
|
mode = "truncate";
|
|
@@ -238,6 +235,10 @@ export async function resolvePromptOverflow(opts) {
|
|
|
238
235
|
: null;
|
|
239
236
|
return { replacements, hintBlock, warnings };
|
|
240
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* Резолвит источник активного окна контекста (запись провайдера или глобал).
|
|
240
|
+
* @param config конфиг приложения; @returns источник и значение окна.
|
|
241
|
+
*/
|
|
241
242
|
export function resolveContextWindowSource(config) {
|
|
242
243
|
const entries = config.provider.entries ?? [];
|
|
243
244
|
const activeLabel = config.provider.active;
|
|
@@ -249,9 +250,8 @@ export function resolveContextWindowSource(config) {
|
|
|
249
250
|
return { source: "global", value: config.contextWindow };
|
|
250
251
|
}
|
|
251
252
|
/**
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
* provider entry override (must be edited in the provider domain file).
|
|
253
|
+
* Человеческая подсказка, как поднять окно контекста: глобал (`mma context <N>`)
|
|
254
|
+
* или override записи провайдера (править файл домена провайдера).
|
|
255
255
|
*/
|
|
256
256
|
export function contextWindowHint(config, configDir, recommended) {
|
|
257
257
|
const src = resolveContextWindowSource(config);
|
|
@@ -261,29 +261,28 @@ export function contextWindowHint(config, configDir, recommended) {
|
|
|
261
261
|
return `edit "${join(configDir, "config", "provider.json")}" → provider.entries[label="${src.label}"].contextWindow = ${recommended}`;
|
|
262
262
|
}
|
|
263
263
|
/**
|
|
264
|
-
*
|
|
265
|
-
*
|
|
264
|
+
* Ближайший стандартный размер контекста, чей системный бюджет (10%)
|
|
265
|
+
* вмещает `neededSystemTokens`. Фолбэк — крупнейший известный.
|
|
266
266
|
*/
|
|
267
267
|
export function recommendContextSize(neededSystemTokens) {
|
|
268
268
|
const sizes = [8192, 16384, 32768, 65536, 131072, 262144];
|
|
269
269
|
return (sizes.find((s) => Math.floor(s * 0.1) >= neededSystemTokens) ?? sizes[sizes.length - 1]);
|
|
270
270
|
}
|
|
271
|
-
/**
|
|
271
|
+
/** Окно контекста, чтобы доля `systemFraction` покрыла `neededTokens`. */
|
|
272
272
|
export function requiredContextWindow(neededTokens, systemFraction) {
|
|
273
273
|
const fraction = systemFraction > 0 ? systemFraction : 0.1;
|
|
274
274
|
return Math.ceil(neededTokens / fraction);
|
|
275
275
|
}
|
|
276
|
-
/**
|
|
276
|
+
/** Доля системного промпта ТЕКУЩЕГО окна, чтобы покрыть `neededTokens`. */
|
|
277
277
|
export function requiredSystemFraction(neededTokens, contextWindow) {
|
|
278
278
|
if (contextWindow <= 0)
|
|
279
279
|
return 1;
|
|
280
280
|
return Math.min(1, Math.ceil((neededTokens / contextWindow) * 100) / 100);
|
|
281
281
|
}
|
|
282
282
|
/**
|
|
283
|
-
*
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
* or a bigger share of the current window.
|
|
283
|
+
* Локализованный конкретный фикс переполненного системного промпта. Вместо
|
|
284
|
+
* грубого стандартного размера (проект 32K прыгал бы сразу на 131072) даёт
|
|
285
|
+
* сырое требование и оба рычага: больше окно или больше доля текущего окна.
|
|
287
286
|
*/
|
|
288
287
|
export function overflowHint(config, configDir, neededTokens) {
|
|
289
288
|
const fraction = config.contextBudget?.systemPrompt ?? 0.1;
|