micro-models-agent 2.11.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 +10 -0
- package/dist/assets/js/tabs.js +22 -3
- 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/index.js +37 -3
- 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 +273 -47
- 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,10 +1,10 @@
|
|
|
1
|
-
import { homedir } from "os";
|
|
2
|
-
import { join } from "path";
|
|
3
1
|
import { MemoryStore } from "./store";
|
|
4
2
|
import { rememberTool } from "../../tools/remember";
|
|
5
3
|
import { recallTool } from "../../tools/recall";
|
|
6
4
|
import { estimateTokens } from "../../llm/token-counter";
|
|
5
|
+
import { globalMemoryDir } from "../../config/paths";
|
|
7
6
|
const MEMORY_MD_FILES = ["errors", "conventions", "decisions", "facts"];
|
|
7
|
+
/** Модуль долговременной памяти: системный блок + тулы `remember`/`recall`. */
|
|
8
8
|
export class MemoryModule {
|
|
9
9
|
name = "memory";
|
|
10
10
|
store;
|
|
@@ -13,10 +13,11 @@ export class MemoryModule {
|
|
|
13
13
|
this.store = storeOrDir;
|
|
14
14
|
}
|
|
15
15
|
else {
|
|
16
|
-
const dir = storeOrDir ||
|
|
16
|
+
const dir = storeOrDir || globalMemoryDir();
|
|
17
17
|
this.store = new MemoryStore(dir);
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
+
/** Системный блок: преференсы пользователя + хвост уроков прошлых сессий. */
|
|
20
21
|
getSystemPromptBlock() {
|
|
21
22
|
const parts = [];
|
|
22
23
|
const prefs = this.store.getPreferences();
|
|
@@ -40,9 +41,9 @@ export class MemoryModule {
|
|
|
40
41
|
};
|
|
41
42
|
}
|
|
42
43
|
/**
|
|
43
|
-
*
|
|
44
|
-
* decisions, facts).
|
|
45
|
-
*
|
|
44
|
+
* Ограниченный хвост append-only .md-файлов памяти (errors, conventions,
|
|
45
|
+
* decisions, facts). Именно он делает уроки прошлых сессий видимыми в
|
|
46
|
+
* системном промпте — без него правила ошибок цикла только пишутся.
|
|
46
47
|
*/
|
|
47
48
|
getMemoryTail() {
|
|
48
49
|
const sections = [];
|
|
@@ -63,14 +64,16 @@ export class MemoryModule {
|
|
|
63
64
|
if (sections.length === 0)
|
|
64
65
|
return null;
|
|
65
66
|
let joined = sections.join("\n\n");
|
|
66
|
-
//
|
|
67
|
+
// Жёсткий кап, чтобы огромный errors.md не раздул бюджет системного промпта.
|
|
67
68
|
if (joined.length > 1200)
|
|
68
|
-
joined = joined.slice(0, 1200)
|
|
69
|
+
joined = `${joined.slice(0, 1200)}\n…`;
|
|
69
70
|
return joined;
|
|
70
71
|
}
|
|
72
|
+
/** Тулы модуля: `remember` (запись) и `recall` (чтение/поиск). */
|
|
71
73
|
getToolDefinitions() {
|
|
72
74
|
return [rememberTool, recallTool];
|
|
73
75
|
}
|
|
76
|
+
/** Плагин: тот же блок памяти через хук построения промпта. */
|
|
74
77
|
getPlugin() {
|
|
75
78
|
return {
|
|
76
79
|
name: "memory",
|
|
@@ -91,6 +94,7 @@ export class MemoryModule {
|
|
|
91
94
|
},
|
|
92
95
|
};
|
|
93
96
|
}
|
|
97
|
+
/** Доступ к underlying-хранилищу (для команд `/memory`, тестов). */
|
|
94
98
|
getStore() {
|
|
95
99
|
return this.store;
|
|
96
100
|
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
// Поиск по файлам памяти: подстрока без учёта регистра по .md и preferences.json.
|
|
1
2
|
import { readFileSync, existsSync } from "fs";
|
|
2
3
|
import { join } from "path";
|
|
3
4
|
const MEMORY_FILES = ["conventions", "decisions", "errors", "facts"];
|
|
5
|
+
/** Поисковик по каталогу памяти (создаётся под запрос, состояния нет). */
|
|
4
6
|
export class MemorySearch {
|
|
5
7
|
memoryDir;
|
|
6
8
|
constructor(memoryDir) {
|
|
7
9
|
this.memoryDir = memoryDir;
|
|
8
10
|
}
|
|
11
|
+
/** Ищет подстроку (без учёта регистра) по .md-файлам и преференсам. */
|
|
9
12
|
query(query) {
|
|
10
13
|
const results = [];
|
|
11
14
|
const lowerQuery = query.toLowerCase();
|
|
@@ -21,7 +24,7 @@ export class MemorySearch {
|
|
|
21
24
|
}
|
|
22
25
|
}
|
|
23
26
|
}
|
|
24
|
-
//
|
|
27
|
+
// Поиск по preferences.json
|
|
25
28
|
const prefsPath = join(this.memoryDir, "preferences.json");
|
|
26
29
|
if (existsSync(prefsPath)) {
|
|
27
30
|
try {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
// Хранилище памяти: append-only .md-категории и preferences.json в каталоге.
|
|
1
2
|
import { readFileSync, writeFileSync, appendFileSync, existsSync, mkdirSync } from "fs";
|
|
2
3
|
import { join } from "path";
|
|
3
4
|
import { MemorySearch } from "./search";
|
|
4
5
|
const MEMORY_FILES = ["conventions", "decisions", "errors", "facts"];
|
|
6
|
+
/** Хранилище памяти: категории-заметки с дописыванием и ключ-значение преференсов. */
|
|
5
7
|
export class MemoryStore {
|
|
6
8
|
memoryDir;
|
|
7
9
|
constructor(memoryDir) {
|
|
@@ -19,18 +21,33 @@ export class MemoryStore {
|
|
|
19
21
|
mkdirSync(this.memoryDir, { recursive: true });
|
|
20
22
|
}
|
|
21
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Отклоняет имена вне фиксированных категорий памяти. Без этого
|
|
26
|
+
* подставленная моделью `category` (поле `enum` в схеме тула — подсказка,
|
|
27
|
+
* а не enforcement) могла бы выйти из каталога памяти, например
|
|
28
|
+
* `recall category="../../Users/x/notes"` прочитал бы чужой `notes.md`.
|
|
29
|
+
*/
|
|
30
|
+
fileFor(name) {
|
|
31
|
+
if (!MEMORY_FILES.includes(name)) {
|
|
32
|
+
throw new Error(`unknown memory category: ${name}`);
|
|
33
|
+
}
|
|
34
|
+
return join(this.memoryDir, `${name}.md`);
|
|
35
|
+
}
|
|
36
|
+
/** Читает весь файл категории (пусто, если файла нет). */
|
|
22
37
|
read(name) {
|
|
23
|
-
const path =
|
|
38
|
+
const path = this.fileFor(name);
|
|
24
39
|
if (!existsSync(path))
|
|
25
40
|
return "";
|
|
26
41
|
return readFileSync(path, "utf-8");
|
|
27
42
|
}
|
|
43
|
+
/** Дописывает запись с таймстампом в файл категории. */
|
|
28
44
|
append(name, entry) {
|
|
29
|
-
const path =
|
|
45
|
+
const path = this.fileFor(name);
|
|
30
46
|
const timestamp = new Date().toISOString().replace("T", " ").slice(0, 19);
|
|
31
47
|
const formatted = `- **${timestamp}** — ${entry}\n`;
|
|
32
48
|
appendFileSync(path, formatted, "utf-8");
|
|
33
49
|
}
|
|
50
|
+
/** Ищет подстроку по всем файлам памяти. */
|
|
34
51
|
search(query) {
|
|
35
52
|
const searchModule = new MemorySearch(this.memoryDir);
|
|
36
53
|
return searchModule.query(query);
|
|
@@ -38,6 +55,7 @@ export class MemoryStore {
|
|
|
38
55
|
prefsPath() {
|
|
39
56
|
return join(this.memoryDir, "preferences.json");
|
|
40
57
|
}
|
|
58
|
+
/** Все преференсы пользователя (пусто, если файла нет/бит). */
|
|
41
59
|
getPreferences() {
|
|
42
60
|
const path = this.prefsPath();
|
|
43
61
|
if (!existsSync(path))
|
|
@@ -49,11 +67,13 @@ export class MemoryStore {
|
|
|
49
67
|
return {};
|
|
50
68
|
}
|
|
51
69
|
}
|
|
70
|
+
/** Записывает/обновляет один преференс. */
|
|
52
71
|
setPreference(key, value) {
|
|
53
72
|
const prefs = this.getPreferences();
|
|
54
73
|
prefs[key] = value;
|
|
55
74
|
writeFileSync(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
|
|
56
75
|
}
|
|
76
|
+
/** Удаляет преференс; false, если ключа не было. */
|
|
57
77
|
deletePreference(key) {
|
|
58
78
|
const prefs = this.getPreferences();
|
|
59
79
|
if (!(key in prefs))
|
|
@@ -62,6 +82,24 @@ export class MemoryStore {
|
|
|
62
82
|
writeFileSync(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
|
|
63
83
|
return true;
|
|
64
84
|
}
|
|
85
|
+
/** Удаляет n-ю (с 1) append-only запись (весь её блок) из файла категории. */
|
|
86
|
+
deleteEntry(name, n) {
|
|
87
|
+
const path = join(this.memoryDir, `${name}.md`);
|
|
88
|
+
if (!existsSync(path))
|
|
89
|
+
return false;
|
|
90
|
+
const lines = readFileSync(path, "utf-8").split(/\r?\n/);
|
|
91
|
+
const starts = lines
|
|
92
|
+
.map((l, i) => (l.startsWith("- ") ? i : -1))
|
|
93
|
+
.filter((i) => i >= 0);
|
|
94
|
+
if (n < 1 || n > starts.length)
|
|
95
|
+
return false;
|
|
96
|
+
const start = starts[n - 1];
|
|
97
|
+
const end = n < starts.length ? starts[n] : lines.length;
|
|
98
|
+
lines.splice(start, end - start);
|
|
99
|
+
writeFileSync(path, lines.join("\n"), "utf-8");
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
/** Дописывает структурированное правило «паттерн/причина/решение». */
|
|
65
103
|
appendRule(category, pattern, cause, solution) {
|
|
66
104
|
const entry = `**pattern:** ${pattern}\n **cause:** ${cause}\n **solution:** ${solution}`;
|
|
67
105
|
this.append(category, entry);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Генерация/улучшение AGENTS.md: один прогон агента со строгим allowlist без bash.
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { estimateTokens } from "../../llm/token-counter";
|
|
4
|
+
import { preflightFromConfig } from "../providers/preflight";
|
|
5
|
+
import { INIT_SYSTEM_PROMPT, INIT_TOOLS } from "./prompts";
|
|
6
|
+
import { t } from "../../i18n/index";
|
|
7
|
+
import { pc } from "../../ui/colors";
|
|
8
|
+
/**
|
|
9
|
+
* Генерирует или улучшает AGENTS.md воркспейса. Один прогон агента со
|
|
10
|
+
* строгим allowlist (без bash). Возвращает false, когда провайдер недоступен
|
|
11
|
+
* или уже активен другой онбординг-режим.
|
|
12
|
+
*/
|
|
13
|
+
export async function runInit(ctx, opts = {}) {
|
|
14
|
+
if (ctx.toolCtx.onboarding) {
|
|
15
|
+
ctx.output.writeLine(pc.yellow(t("onboarding.already")));
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
if (process.stdout.isTTY !== true) {
|
|
19
|
+
ctx.output.writeLine(pc.yellow(t("onboarding.non_interactive")));
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
const check = opts.preflight ?? (() => preflightFromConfig(ctx));
|
|
23
|
+
const pre = await check();
|
|
24
|
+
if (!pre.ok) {
|
|
25
|
+
ctx.output.writeLine(pc.yellow(t("repl.init_unavailable", { reason: pre.reason })));
|
|
26
|
+
ctx.output.writeLine(t("repl.meet_unavailable_hint"));
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
const block = {
|
|
30
|
+
content: INIT_SYSTEM_PROMPT,
|
|
31
|
+
priority: "high",
|
|
32
|
+
essential: true,
|
|
33
|
+
estimatedTokens: estimateTokens(INIT_SYSTEM_PROMPT),
|
|
34
|
+
};
|
|
35
|
+
ctx.agent.pushPromptBlock(block);
|
|
36
|
+
ctx.toolCtx.toolAllowlist = [...INIT_TOOLS];
|
|
37
|
+
ctx.toolCtx.writePathAllowlist = [join(ctx.baseDir, "AGENTS.md")];
|
|
38
|
+
try {
|
|
39
|
+
await ctx.runAgent(t("repl.init_start_prompt", { dir: join(ctx.baseDir, "AGENTS.md") }));
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
ctx.agent.removePromptBlock(block);
|
|
43
|
+
ctx.toolCtx.toolAllowlist = undefined;
|
|
44
|
+
ctx.toolCtx.writePathAllowlist = undefined;
|
|
45
|
+
}
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { preflightFromConfig } from "../providers/preflight";
|
|
2
|
+
import { enterMeetMode } from "./mode";
|
|
3
|
+
import { t } from "../../i18n/index";
|
|
4
|
+
import { pc } from "../../ui/colors";
|
|
5
|
+
/**
|
|
6
|
+
* Запускает интервью-знакомство. Проверяет провайдер, входит в meet-режим
|
|
7
|
+
* и делает первый ход агента. Режим живёт между ходами REPL, пока не
|
|
8
|
+
* сработает `meet_done` или пользователь не выйдет.
|
|
9
|
+
* Возвращает false, когда провайдер недоступен (ничего не меняется).
|
|
10
|
+
*/
|
|
11
|
+
export async function runMeet(ctx, opts = {}) {
|
|
12
|
+
if (ctx.toolCtx.onboarding) {
|
|
13
|
+
ctx.output.writeLine(pc.yellow(t("repl.meet_already_hint")));
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
if (process.stdout.isTTY !== true) {
|
|
17
|
+
ctx.output.writeLine(pc.yellow(t("onboarding.non_interactive")));
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const check = opts.preflight ?? (() => preflightFromConfig(ctx));
|
|
21
|
+
const pre = await check();
|
|
22
|
+
if (!pre.ok) {
|
|
23
|
+
ctx.output.writeLine(pc.yellow(t("repl.meet_unavailable", { reason: pre.reason })));
|
|
24
|
+
ctx.output.writeLine(t("repl.meet_unavailable_hint"));
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
enterMeetMode(ctx);
|
|
28
|
+
await ctx.runAgent(t("repl.meet_start_prompt"));
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { estimateTokens } from "../../llm/token-counter";
|
|
2
|
+
import { MEET_SYSTEM_PROMPT, MEET_TOOLS } from "./prompts";
|
|
3
|
+
/**
|
|
4
|
+
* Входит в meet-режим на shared-агенте: режет тулы до allowlist, создаёт
|
|
5
|
+
* shared-состояние онбординга (с блоком гайда) и инжектит гайд интервью.
|
|
6
|
+
* Режим живёт между ходами REPL до `exitMeetMode` (по сентинелу `meet_done`).
|
|
7
|
+
*/
|
|
8
|
+
export function enterMeetMode(ctx) {
|
|
9
|
+
const block = {
|
|
10
|
+
content: MEET_SYSTEM_PROMPT,
|
|
11
|
+
priority: "high",
|
|
12
|
+
essential: true,
|
|
13
|
+
estimatedTokens: estimateTokens(MEET_SYSTEM_PROMPT),
|
|
14
|
+
};
|
|
15
|
+
ctx.toolCtx.toolAllowlist = [...MEET_TOOLS];
|
|
16
|
+
ctx.toolCtx.onboarding = { done: false, block };
|
|
17
|
+
ctx.agent.pushPromptBlock(block);
|
|
18
|
+
}
|
|
19
|
+
/** Выходит из meet-режима: убирает гайд и возвращает полные тулы. */
|
|
20
|
+
export function exitMeetMode(ctx) {
|
|
21
|
+
const block = ctx.toolCtx.onboarding?.block;
|
|
22
|
+
if (block)
|
|
23
|
+
ctx.agent.removePromptBlock(block);
|
|
24
|
+
ctx.toolCtx.toolAllowlist = undefined;
|
|
25
|
+
ctx.toolCtx.onboarding = undefined;
|
|
26
|
+
}
|
|
27
|
+
/** True, когда сентинел-тул сработал в активной meet-сессии. */
|
|
28
|
+
export function isMeetDone(ctx) {
|
|
29
|
+
return ctx.toolCtx.onboarding?.done === true;
|
|
30
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Промпты и allowlist онбординга: интервью «Познакомимся» и автор AGENTS.md.
|
|
2
|
+
/** Тулы, доступные во время интервью (строгий allowlist). */
|
|
3
|
+
export const MEET_TOOLS = ["remember", "question", "meet_done"];
|
|
4
|
+
/** Тулы, доступные при генерации AGENTS.md (строгий allowlist). */
|
|
5
|
+
export const INIT_TOOLS = [
|
|
6
|
+
"read_file",
|
|
7
|
+
"list_dir",
|
|
8
|
+
"glob",
|
|
9
|
+
"grep",
|
|
10
|
+
"project_map",
|
|
11
|
+
"question",
|
|
12
|
+
"write_file",
|
|
13
|
+
"edit_file",
|
|
14
|
+
];
|
|
15
|
+
/**
|
|
16
|
+
* Полускриптовое интервью. Гайд отвечает за покрытие и вайтлист ключей
|
|
17
|
+
* преференсов; модель — за формулировки и лёгкие уточнения. Домен-нейтрально.
|
|
18
|
+
* Тело промпта — на английском: уходит модели как есть.
|
|
19
|
+
*/
|
|
20
|
+
export const MEET_SYSTEM_PROMPT = `You are getting acquainted with the user. This is a short interview, not a task.
|
|
21
|
+
Rules:
|
|
22
|
+
- Ask 1-3 short questions per turn, in the user's language.
|
|
23
|
+
- For closed / multiple-choice questions (e.g. response style, autonomy), use the "question" tool and provide explicit options. For open-ended questions, ask in plain text.
|
|
24
|
+
- START by asking what the user will mainly use the agent for (their domain / usage profile): e.g. software development, working with APIs, smart home, automation, personal assistant, web search, computer setup — or anything else. Never assume their use case is software development.
|
|
25
|
+
- Then cover: name; reply language; response style (concise | balanced | detailed); tools & experience; working habits; hard "do not do without asking" rules; goals.
|
|
26
|
+
- Only if the user named software development as a use case may you ask about code / commit language.
|
|
27
|
+
- Save each answer with the "remember" tool. Use category=preferences with these keys ONLY: domain, name, language, response_style, autonomy, code_language. Use category=facts (free text, user's language) for experience, habits, goals and any concrete "do not" rule (preserve it verbatim).
|
|
28
|
+
- Leave code_language out entirely when development is not a use case.
|
|
29
|
+
- Keep preference values as canonical English tokens: domain=development,api; response_style=concise|balanced|detailed; autonomy=ask|act. Record language as the token the user chose (e.g. language=ru) and name exactly as the user wrote it.
|
|
30
|
+
- Never touch the file system, run commands, or inspect the repository.
|
|
31
|
+
- When every topic is covered (or the user wants to stop), give a one-line summary of what you remembered, then call the "meet_done" tool.`;
|
|
32
|
+
/**
|
|
33
|
+
* Гайд автора AGENTS.md. Домен-нейтрален: код, доки, заметки или конфиги;
|
|
34
|
+
* код — лишь частный случай. Тело промпта — на английском: уходит модели как есть.
|
|
35
|
+
*/
|
|
36
|
+
export const INIT_SYSTEM_PROMPT = `You create or improve an AGENTS.md file for the current workspace.
|
|
37
|
+
Rules:
|
|
38
|
+
- First read what is here: use project_map, read_file, list_dir, glob, grep. The workspace may be code, docs, notes, configs or mixed — never assume a programming project.
|
|
39
|
+
- If AGENTS.md already exists, IMPROVE it in place: produce a proposed full version, show it, and let the user confirm before writing. Never silently overwrite.
|
|
40
|
+
- Capture: purpose & usage profile; key structure; how to run/use things (only if applicable); conventions; setup quirks/gotchas; references to existing instruction sources (e.g. Cursor/Copilot rules).
|
|
41
|
+
- Ask targeted questions only when the files cannot answer.
|
|
42
|
+
- Keep it concise and within the instructions budget.
|
|
43
|
+
- Write with write_file or edit_file; do not run shell commands.`;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { t } from "../../i18n/index";
|
|
2
|
+
/** Движок пайплайна: порядок обхода зависимостей и учёт статусов шагов. */
|
|
2
3
|
export class PipelineEngine {
|
|
3
4
|
stepStatus = new Map();
|
|
5
|
+
/**
|
|
6
|
+
* Топологически сортирует шаги по `depends_on`. Бросает при цикле.
|
|
7
|
+
* Возвращает id в порядке выполнения.
|
|
8
|
+
*/
|
|
4
9
|
resolveDependencies(steps) {
|
|
5
10
|
const visited = new Set();
|
|
6
11
|
const inStack = new Set();
|
|
@@ -29,6 +34,7 @@ export class PipelineEngine {
|
|
|
29
34
|
}
|
|
30
35
|
return order;
|
|
31
36
|
}
|
|
37
|
+
/** Шаги, готовые к запуску: не завершены, не в работе/провале, зависимости закрыты. */
|
|
32
38
|
getReadySteps(steps, completed) {
|
|
33
39
|
return steps.filter((s) => {
|
|
34
40
|
if (completed.has(s.id))
|
|
@@ -42,18 +48,22 @@ export class PipelineEngine {
|
|
|
42
48
|
return s.depends_on.every((d) => completed.has(d));
|
|
43
49
|
});
|
|
44
50
|
}
|
|
51
|
+
/** Ставит статус шага. */
|
|
45
52
|
setStepStatus(stepId, status) {
|
|
46
53
|
this.stepStatus.set(stepId, status);
|
|
47
54
|
}
|
|
55
|
+
/** Статус шага; неизвестному — `pending`. */
|
|
48
56
|
getStepStatus(stepId) {
|
|
49
57
|
return this.stepStatus.get(stepId) || "pending";
|
|
50
58
|
}
|
|
59
|
+
/** True, когда все шаги `done` или `skipped`. */
|
|
51
60
|
isComplete(stepIds) {
|
|
52
61
|
return stepIds.every((id) => {
|
|
53
62
|
const s = this.stepStatus.get(id);
|
|
54
63
|
return s === "done" || s === "skipped";
|
|
55
64
|
});
|
|
56
65
|
}
|
|
66
|
+
/** Сбрасывает все статусы (перезапуск пайплайна). */
|
|
57
67
|
reset() {
|
|
58
68
|
this.stepStatus.clear();
|
|
59
69
|
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
// Минималистичный парсер YAML-описаний пайплайнов (без внешних зависимостей).
|
|
1
2
|
import { t } from "../../i18n/index";
|
|
3
|
+
/** Парсер описания пайплайна. Бросает при невалидном YAML/полях. */
|
|
2
4
|
export class PipelineParser {
|
|
5
|
+
/** Разбирает YAML в `Pipeline`; бросает с локализованной ошибкой. */
|
|
3
6
|
static parse(yaml) {
|
|
4
7
|
const lines = yaml.split("\n").filter((l) => l.trim());
|
|
5
8
|
const result = {};
|
|
6
9
|
let currentSection = null;
|
|
7
|
-
|
|
10
|
+
const currentSteps = [];
|
|
8
11
|
for (const line of lines) {
|
|
9
12
|
if (line.match(/^\w+:/) && !line.startsWith(" ") && !line.startsWith(" -")) {
|
|
10
13
|
const [key, ...valParts] = line.split(":");
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
// Подстановка в шаблоны: `{param}` из params и `{{steps.<id>.output}}` из выходов шагов.
|
|
1
2
|
export class TemplateEngine {
|
|
3
|
+
/**
|
|
4
|
+
* Рендерит шаблон. Неизвестный выход шага остаётся плейсхолдером как есть.
|
|
5
|
+
*/
|
|
2
6
|
static render(template, params, stepOutputs) {
|
|
3
7
|
let result = template;
|
|
4
8
|
for (const [key, val] of Object.entries(params)) {
|