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/core/bootstrap.js
CHANGED
|
@@ -3,6 +3,7 @@ import { Logger } from "../logger/app-logger";
|
|
|
3
3
|
import { OpenAICompatProvider } from "../llm/openai-compat";
|
|
4
4
|
import { ModelLoader } from "../llm/model-loader";
|
|
5
5
|
import { ToolRegistry, registerAllTools } from "../tools/index";
|
|
6
|
+
import { buildHiddenToolsBlock } from "../tools/hidden-tools-block";
|
|
6
7
|
import { ToolExecutor } from "../tools/executor";
|
|
7
8
|
import { ModuleRegistry } from "../modules/registry";
|
|
8
9
|
import { PluginManager } from "../modules/plugins/manager";
|
|
@@ -13,19 +14,22 @@ import { ContextManager } from "../modules/context/manager";
|
|
|
13
14
|
import { TokenCounter } from "../llm/token-counter";
|
|
14
15
|
import { HallucinationDetector } from "../modules/hallucination/detector";
|
|
15
16
|
import { ExecutionModule } from "../modules/execution/module";
|
|
16
|
-
import { SessionStore, SessionManager, SessionModule
|
|
17
|
+
import { SessionStore, SessionManager, SessionModule } from "../modules/session/index";
|
|
17
18
|
import { UserProfile } from "../modules/user-profile/profile";
|
|
18
19
|
import { SkillsLoader, SkillsModule } from "../modules/skills/index";
|
|
19
20
|
import { BrowserModule } from "../modules/browser/index";
|
|
20
|
-
import { LspModule } from "../modules/lsp/index";
|
|
21
|
+
import { LspModule, DEFAULT_LSP_CONFIG } from "../modules/lsp/index";
|
|
22
|
+
import { runStartupHealthCheck } from "../modules/lsp/startup-check";
|
|
21
23
|
import { IndexerModule } from "../modules/indexer/index";
|
|
22
24
|
import { MCPModule } from "../modules/mcp/index";
|
|
23
25
|
import { MemoryModule } from "../modules/memory/module";
|
|
26
|
+
import { MemoryStore } from "../modules/memory/store";
|
|
24
27
|
import { setLocale } from "../i18n/index";
|
|
25
28
|
import { Agent } from "./agent";
|
|
26
29
|
import { homedir } from "os";
|
|
27
30
|
import { join, resolve } from "path";
|
|
28
31
|
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
32
|
+
import { readMmaVersion } from "./version";
|
|
29
33
|
export function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
30
34
|
const now = new Date().toISOString().replace("T", " ").slice(0, 19);
|
|
31
35
|
const isWin = profileCompressed.toLowerCase().includes("win32");
|
|
@@ -42,12 +46,20 @@ export function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
|
42
46
|
// files and tests (observed: model wasted 10+ iterations installing tsx
|
|
43
47
|
// instead of running `bun file.ts`).
|
|
44
48
|
lines.push(`Runtime: Bun is available — run TypeScript directly with "bun <file.ts>" and tests with "bun test" (no tsx/ts-node/npm install needed for that).`);
|
|
45
|
-
lines.push(`Bash: use "workdir" param instead of "cd dir && cmd". One command per call. Long-running processes: pass "background: true" (id immediately), otherwise auto-backgrounded after a few seconds — check with process_log.`, `DEVELOPMENT RULES (strict): 1) install deps BEFORE writing source (npm/pip/cargo, verify lockfile exists; never import uninstalled packages); 2) framework/toolkit init BEFORE app code; 3) follow plan sequentially, after each step verify deliverables exist with real content, then "plan update step=N status=done"; 4) verify work on disk + command output — don't assume success; 5) no premature work (no files/imports for future steps); 6) stuck after 2+ failures: STOP, try a different approach, write files directly, ask the user.`, `PLAN QUALITY: each step = CONCRETE deliverables (exact file paths with extensions, exact packages, exact commands). Vague steps ("Setup the project") forbidden. Cover init → deps → framework → code → verification. 5-8 steps.`);
|
|
49
|
+
lines.push(`Bash: use "workdir" param instead of "cd dir && cmd". One command per call. Long-running processes: pass "background: true" (id immediately), otherwise auto-backgrounded after a few seconds — check with process_log.`, `DEVELOPMENT RULES (strict): 1) install deps BEFORE writing source (npm/pip/cargo, verify lockfile exists; never import uninstalled packages); 2) framework/toolkit init BEFORE app code; 3) follow plan sequentially, after each step verify deliverables exist with real content, then "plan update step=N status=done"; 4) verify work on disk + command output — don't assume success; 5) no premature work (no files/imports for future steps); 6) stuck after 2+ failures: STOP, try a different approach, write files directly, ask the user.`, `VERIFY EVERY WRITE: after write_file or edit_file, if the tool result contains NO [LSP errors], [LSP warnings], [Syntax check failed], or [Project typecheck failed] feedback, call the "lsp_check" tool on the file you just wrote BEFORE marking the step done. Never assume a written file is valid — prove it.`, `PLAN QUALITY: each step = CONCRETE deliverables (exact file paths with extensions, exact packages, exact commands). Vague steps ("Setup the project") forbidden. Cover init → deps → framework → code → verification. 5-8 steps.`, `For "check/fix errors" tasks, each verification step must name the exact command that proves the errors are gone — "bun run build", "bun test", or the "lsp_check" tool — and the step is done only after that check reports clean.`);
|
|
46
50
|
if (config.autoPlan) {
|
|
47
51
|
lines.push(`Plan rule (MANDATORY): any task creating files, installing packages, or requiring multiple actions MUST create a plan with the "plan" tool BEFORE starting. Each step = a concrete deliverable.`);
|
|
48
52
|
}
|
|
49
|
-
|
|
50
|
-
|
|
53
|
+
// When a bug is described in terms of runtime behavior (what happens when
|
|
54
|
+
// the app runs), the fix is only provable by REPRODUCING it — running the
|
|
55
|
+
// app/build/browser and comparing against actual output. The model decides
|
|
56
|
+
// when this applies (no keyword classification). Stale dev servers started
|
|
57
|
+
// before a config/deps change keep the OLD pipeline in memory and still
|
|
58
|
+
// throw the original error (observed: old vite on 5173-5176 kept failing
|
|
59
|
+
// postcss after the fix was on disk, while a fresh server on 5177 was
|
|
60
|
+
// clean) — the fix is only real when the USER's running server is clean.
|
|
61
|
+
lines.push(`Runtime verification: when a bug is described in terms of runtime behavior (what happens when the app runs), reproduce it — run the app / build / browser tool — and confirm the fix against actual runtime output before calling "plan update step=N status=done". Check existing servers first with process_list/process_log: a stale dev server started BEFORE your change still runs the old pipeline and keeps failing even after the files on disk are fixed. Restart or kill it (process_kill) and verify the exact endpoint/port the user reported — a fresh server on a new port does NOT prove the user's error is gone.`);
|
|
62
|
+
const hasMCP = config.mcpServers && Object.values(config.mcpServers).some((s) => s.enabled !== false);
|
|
51
63
|
if (hasMCP) {
|
|
52
64
|
lines.push(`MCP servers are available — use the named MCP tools (prefixed mcp__) to query external services.`);
|
|
53
65
|
}
|
|
@@ -55,9 +67,7 @@ export function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
|
55
67
|
}
|
|
56
68
|
export async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
57
69
|
const dir = configDir || join(homedir(), ".mma");
|
|
58
|
-
const projectConfigPath = projectDir
|
|
59
|
-
? join(projectDir, ".mmrc")
|
|
60
|
-
: join(process.cwd(), ".mmrc");
|
|
70
|
+
const projectConfigPath = projectDir ? join(projectDir, ".mmrc") : join(process.cwd(), ".mmrc");
|
|
61
71
|
const config = loadConfig({ configDir: dir, projectConfigPath });
|
|
62
72
|
setLocale(config.locale);
|
|
63
73
|
// Update global audit notifier with config
|
|
@@ -126,7 +136,9 @@ export async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplet
|
|
|
126
136
|
const skillsBudget = Math.floor(config.contextWindow * config.skills.budget);
|
|
127
137
|
const skillsModule = new SkillsModule(availableSkills, skillsBudget);
|
|
128
138
|
const toolRegistry = new ToolRegistry();
|
|
129
|
-
registerAllTools(toolRegistry, skillsModule
|
|
139
|
+
registerAllTools(toolRegistry, skillsModule, {
|
|
140
|
+
enableOnDemand: config.tools?.enableOnDemand,
|
|
141
|
+
});
|
|
130
142
|
const pluginManager = new PluginManager();
|
|
131
143
|
const systemInfoContent = buildSystemInfo(config, baseDir, profile.compress());
|
|
132
144
|
const systemInfoPrompt = {
|
|
@@ -153,6 +165,17 @@ export async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplet
|
|
|
153
165
|
sessionManager.create();
|
|
154
166
|
}
|
|
155
167
|
const tokenCounter = new TokenCounter(config.model);
|
|
168
|
+
// Mutable set of active tool tags, shared between the agent loop and the
|
|
169
|
+
// `enable_tools` tool. The loop re-reads it every iteration to recompute the
|
|
170
|
+
// LLM-visible tool set; enable_tools pushes tags into it. When on-demand
|
|
171
|
+
// enabling is disabled the tag set stays empty, which restores the legacy
|
|
172
|
+
// all-tools behavior (getAllForLLM returns everything for empty tags).
|
|
173
|
+
const enableOnDemand = config.tools?.enableOnDemand !== false;
|
|
174
|
+
const activeToolTags = enableOnDemand
|
|
175
|
+
? config.tools?.defaultTags
|
|
176
|
+
? [...config.tools.defaultTags]
|
|
177
|
+
: []
|
|
178
|
+
: [];
|
|
156
179
|
const contextManager = new ContextManager(config.contextWindow, config.contextBudget, tokenCounter);
|
|
157
180
|
const toolCtx = {
|
|
158
181
|
config,
|
|
@@ -160,6 +183,7 @@ export async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplet
|
|
|
160
183
|
logger,
|
|
161
184
|
exitOnComplete,
|
|
162
185
|
contextManager,
|
|
186
|
+
activeToolTags,
|
|
163
187
|
sessionId: sessionManager.getActiveMeta()?.id,
|
|
164
188
|
sessionContext: sessionManager.getSessionContext() ?? undefined,
|
|
165
189
|
recursionDepth: 0,
|
|
@@ -206,7 +230,8 @@ export async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplet
|
|
|
206
230
|
const mcpModule = new MCPModule(config);
|
|
207
231
|
await mcpModule.initialize();
|
|
208
232
|
moduleRegistry.register(mcpModule);
|
|
209
|
-
const
|
|
233
|
+
const memoryStore = new MemoryStore(join(dir, "memory"));
|
|
234
|
+
const memoryModule = new MemoryModule(memoryStore);
|
|
210
235
|
moduleRegistry.register(memoryModule);
|
|
211
236
|
if (config.browser.enabled) {
|
|
212
237
|
const browserModule = new BrowserModule();
|
|
@@ -224,6 +249,16 @@ export async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplet
|
|
|
224
249
|
lspPlugin.isBuiltin = true;
|
|
225
250
|
pluginManager.register(lspPlugin);
|
|
226
251
|
}
|
|
252
|
+
// Startup health check: scan project for existing errors so the model
|
|
253
|
+
// knows the baseline before it starts working. Skip for one-shot runs and
|
|
254
|
+
// test environments. Started in the background (never awaited) so the REPL
|
|
255
|
+
// banner is not blocked by `npx tsc` on the whole project; the Agent awaits
|
|
256
|
+
// it before the first LLM call via `lazyPromptBlocks` (already resolved by
|
|
257
|
+
// the time the user types in the interactive REPL).
|
|
258
|
+
let startupCheckBlock = null;
|
|
259
|
+
const startupCheckPromise = !exitOnComplete && process.env.NODE_ENV !== "test"
|
|
260
|
+
? runStartupHealthCheck(config.lsp ?? DEFAULT_LSP_CONFIG, baseDir)
|
|
261
|
+
: Promise.resolve(null);
|
|
227
262
|
const moduleTools = moduleRegistry.collectToolDefinitions();
|
|
228
263
|
for (const tool of moduleTools) {
|
|
229
264
|
toolRegistry.register(tool);
|
|
@@ -258,8 +293,15 @@ export async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplet
|
|
|
258
293
|
const pluginLoader = new PluginLoader();
|
|
259
294
|
const globalPluginsDir = join(homedir(), ".mma", "plugins");
|
|
260
295
|
const projectPluginsDir = join(baseDir, ".mma", "plugins");
|
|
261
|
-
|
|
262
|
-
pluginLoader.loadFromDir(
|
|
296
|
+
const mmaVersion = readMmaVersion();
|
|
297
|
+
pluginLoader.loadFromDir(globalPluginsDir, pluginManager, logger, {
|
|
298
|
+
source: "global",
|
|
299
|
+
mmaVersion,
|
|
300
|
+
});
|
|
301
|
+
pluginLoader.loadFromDir(projectPluginsDir, pluginManager, logger, {
|
|
302
|
+
source: "project",
|
|
303
|
+
mmaVersion,
|
|
304
|
+
});
|
|
263
305
|
contextManager.onCompact = (summary) => {
|
|
264
306
|
const meta = sessionManager.getActiveMeta();
|
|
265
307
|
if (!meta || !config.session.autoSave)
|
|
@@ -271,6 +313,11 @@ export async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplet
|
|
|
271
313
|
timestamp: new Date().toISOString(),
|
|
272
314
|
});
|
|
273
315
|
};
|
|
316
|
+
// Carry the active plan (id, progress, current step) into the compaction
|
|
317
|
+
// summary so a 9B model doesn't re-create the plan from scratch right after
|
|
318
|
+
// compaction (observed: ses_msvuao0h — plan_e07pb2 (1/6) discarded for a
|
|
319
|
+
// fresh plan_xzq9xe the same iteration the old plan was still visible).
|
|
320
|
+
contextManager.setPlanSummaryProvider(() => execModule.getPlanSummary());
|
|
274
321
|
const agentsMdBlocks = [];
|
|
275
322
|
const skipAgentsMd = noAgentsMd === true;
|
|
276
323
|
if (!skipAgentsMd) {
|
|
@@ -295,7 +342,7 @@ export async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplet
|
|
|
295
342
|
}
|
|
296
343
|
const promptBlocks = [
|
|
297
344
|
systemInfoPrompt,
|
|
298
|
-
...moduleRegistry.collectPromptBlocks(),
|
|
345
|
+
...moduleRegistry.collectPromptBlocks(["indexer"]),
|
|
299
346
|
...agentsMdBlocks,
|
|
300
347
|
];
|
|
301
348
|
const agentDeps = {
|
|
@@ -307,6 +354,7 @@ export async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplet
|
|
|
307
354
|
hallucinationDetector,
|
|
308
355
|
logger,
|
|
309
356
|
baseDir,
|
|
357
|
+
toolTags: activeToolTags,
|
|
310
358
|
promptBlocks,
|
|
311
359
|
getDynamicPromptBlocks: () => {
|
|
312
360
|
const blocks = [];
|
|
@@ -316,10 +364,29 @@ export async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplet
|
|
|
316
364
|
const skillsBlock = skillsModule.getSystemPromptBlock();
|
|
317
365
|
if (skillsBlock)
|
|
318
366
|
blocks.push(skillsBlock);
|
|
367
|
+
const mapBlock = indexerModule.getSystemPromptBlock();
|
|
368
|
+
if (mapBlock)
|
|
369
|
+
blocks.push(mapBlock);
|
|
370
|
+
const hiddenToolsBlock = buildHiddenToolsBlock(toolRegistry.getAll(), activeToolTags);
|
|
371
|
+
if (hiddenToolsBlock) {
|
|
372
|
+
blocks.push({
|
|
373
|
+
content: hiddenToolsBlock,
|
|
374
|
+
priority: "low",
|
|
375
|
+
essential: false,
|
|
376
|
+
estimatedTokens: Math.ceil(hiddenToolsBlock.length / 4),
|
|
377
|
+
});
|
|
378
|
+
}
|
|
319
379
|
return blocks;
|
|
320
380
|
},
|
|
321
381
|
finalAudit: () => execModule.runFinalAudit(),
|
|
382
|
+
lazyPromptBlocks: async () => {
|
|
383
|
+
if (startupCheckBlock)
|
|
384
|
+
return [startupCheckBlock];
|
|
385
|
+
startupCheckBlock = (await startupCheckPromise) ?? null;
|
|
386
|
+
return startupCheckBlock ? [startupCheckBlock] : [];
|
|
387
|
+
},
|
|
322
388
|
sessionManager,
|
|
389
|
+
memoryStore,
|
|
323
390
|
exitOnComplete,
|
|
324
391
|
};
|
|
325
392
|
const agent = new Agent(agentDeps);
|
package/dist/core/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { PromptBuilder } from
|
|
2
|
-
export { Agent } from
|
|
1
|
+
export { PromptBuilder } from "./prompt-builder";
|
|
2
|
+
export { Agent } from "./agent";
|
|
@@ -4,6 +4,10 @@ const PRIORITY_ORDER = {
|
|
|
4
4
|
normal: 2,
|
|
5
5
|
low: 3,
|
|
6
6
|
};
|
|
7
|
+
function blockLabel(content) {
|
|
8
|
+
const firstLine = content.split("\n")[0].trim();
|
|
9
|
+
return firstLine.length > 70 ? firstLine.slice(0, 67) + "..." : firstLine;
|
|
10
|
+
}
|
|
7
11
|
export class PromptBuilder {
|
|
8
12
|
blocks = [];
|
|
9
13
|
budget;
|
|
@@ -33,23 +37,40 @@ export class PromptBuilder {
|
|
|
33
37
|
let usedTokens = 0;
|
|
34
38
|
const included = [];
|
|
35
39
|
const excluded = [];
|
|
40
|
+
const blocks = [];
|
|
36
41
|
for (const block of essential) {
|
|
37
42
|
included.push(block.content);
|
|
38
43
|
usedTokens += block.estimatedTokens;
|
|
44
|
+
blocks.push({
|
|
45
|
+
label: blockLabel(block.content),
|
|
46
|
+
priority: block.priority,
|
|
47
|
+
essential: true,
|
|
48
|
+
tokens: block.estimatedTokens,
|
|
49
|
+
included: true,
|
|
50
|
+
});
|
|
39
51
|
}
|
|
40
52
|
for (const block of nonEssential) {
|
|
41
53
|
const tokens = block.estimatedTokens;
|
|
42
|
-
|
|
54
|
+
const fits = usedTokens + tokens <= this.budget;
|
|
55
|
+
if (fits) {
|
|
43
56
|
included.push(block.content);
|
|
44
57
|
usedTokens += tokens;
|
|
45
58
|
}
|
|
46
59
|
else {
|
|
47
60
|
excluded.push(block.content);
|
|
48
61
|
}
|
|
62
|
+
blocks.push({
|
|
63
|
+
label: blockLabel(block.content),
|
|
64
|
+
priority: block.priority,
|
|
65
|
+
essential: false,
|
|
66
|
+
tokens,
|
|
67
|
+
included: fits,
|
|
68
|
+
});
|
|
49
69
|
}
|
|
50
70
|
return {
|
|
51
|
-
prompt: included.join(
|
|
71
|
+
prompt: included.join("\n\n"),
|
|
52
72
|
excluded,
|
|
73
|
+
blocks,
|
|
53
74
|
};
|
|
54
75
|
}
|
|
55
76
|
}
|
|
@@ -118,14 +118,56 @@ export class SessionLogger {
|
|
|
118
118
|
iteration,
|
|
119
119
|
});
|
|
120
120
|
}
|
|
121
|
-
logCompaction(
|
|
121
|
+
logCompaction(info) {
|
|
122
122
|
this.session?.appendLog({
|
|
123
123
|
ts: new Date().toISOString(),
|
|
124
124
|
type: "compaction",
|
|
125
|
-
content,
|
|
125
|
+
content: `${info.reason}, iteration ${info.iteration}`,
|
|
126
|
+
iteration: info.iteration,
|
|
127
|
+
reason: info.reason,
|
|
128
|
+
tokensBefore: info.tokensBefore,
|
|
129
|
+
tokensAfter: info.tokensAfter,
|
|
130
|
+
qualityBefore: info.qualityBefore,
|
|
131
|
+
qualityAfter: info.qualityAfter,
|
|
132
|
+
messagesBefore: info.messagesBefore,
|
|
133
|
+
messagesAfter: info.messagesAfter,
|
|
134
|
+
removedTurns: info.removedTurns,
|
|
135
|
+
keptTurns: info.keptTurns,
|
|
136
|
+
summary: info.summary,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
logContext(info) {
|
|
140
|
+
this.session?.appendLog({
|
|
141
|
+
ts: new Date().toISOString(),
|
|
142
|
+
type: "context",
|
|
143
|
+
content: info.kind === "start"
|
|
144
|
+
? "context snapshot at session start"
|
|
145
|
+
: `context at iteration ${info.iteration}`,
|
|
146
|
+
iteration: info.iteration,
|
|
147
|
+
window: info.window,
|
|
148
|
+
systemBudget: info.systemBudget,
|
|
149
|
+
reserveBudget: info.reserveBudget,
|
|
150
|
+
historyBudget: info.historyBudget,
|
|
151
|
+
systemTokens: info.systemTokens,
|
|
152
|
+
toolTokens: info.toolTokens,
|
|
153
|
+
contextTokens: info.tokens,
|
|
154
|
+
quality: info.quality,
|
|
155
|
+
messageCount: info.messageCount,
|
|
156
|
+
compactionCount: info.compactionCount,
|
|
157
|
+
iterationsSinceCompaction: info.iterationsSinceCompaction,
|
|
158
|
+
blocks: info.blocks,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
logLlmUsage(iteration, usage) {
|
|
162
|
+
this.session?.appendLog({
|
|
163
|
+
ts: new Date().toISOString(),
|
|
164
|
+
type: "llm_usage",
|
|
126
165
|
iteration,
|
|
127
|
-
|
|
128
|
-
|
|
166
|
+
promptTokens: usage.promptTokens,
|
|
167
|
+
completionTokens: usage.completionTokens,
|
|
168
|
+
totalTokens: usage.totalTokens,
|
|
169
|
+
source: usage.source,
|
|
170
|
+
durationMs: usage.durationMs,
|
|
129
171
|
});
|
|
130
172
|
}
|
|
131
173
|
logError(message) {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "fs";
|
|
2
|
+
import { join, dirname } from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
/**
|
|
5
|
+
* Read the MMA version from package.json at runtime (never a static import —
|
|
6
|
+
* bundlers inline a stale value at build time, see design rule #12).
|
|
7
|
+
*/
|
|
8
|
+
export function readMmaVersion() {
|
|
9
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const candidates = [join(here, "..", "..", "package.json"), join(here, "..", "package.json")];
|
|
11
|
+
for (const p of candidates) {
|
|
12
|
+
if (existsSync(p)) {
|
|
13
|
+
try {
|
|
14
|
+
const raw = JSON.parse(readFileSync(p, "utf8"));
|
|
15
|
+
if (raw.version)
|
|
16
|
+
return raw.version;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
// Broken package.json — fall through to the next candidate
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return "0.0.0";
|
|
24
|
+
}
|
package/dist/i18n/en.json
CHANGED
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"error.response_blocked": "Response blocked: {reason}",
|
|
29
29
|
"error.max_iters": "Max iterations ({max}) reached",
|
|
30
30
|
"error.empty_response": "Model returned an empty response after retries",
|
|
31
|
+
"error.audit_failed": "Task could not be verified as complete: {summary}",
|
|
31
32
|
"error.grep_failed": "Grep failed: {message}",
|
|
32
33
|
"error.search_failed": "Search failed: {message}",
|
|
33
34
|
"error.fetch_failed": "Fetch failed: {message}",
|
|
@@ -86,9 +87,12 @@
|
|
|
86
87
|
"tool.friendly.web_search": "Web search",
|
|
87
88
|
"tool.friendly.web_fetch": "Fetching page",
|
|
88
89
|
"tool.friendly.web_browse": "Browsing page",
|
|
90
|
+
"tool.friendly.download_file": "Downloading file",
|
|
89
91
|
"tool.web_fetch_result": "Fetched page: {url} — {chars} chars, {lines} lines{truncated}",
|
|
90
92
|
"tool.web_browse_result": "Browsed page: {url} — {chars} chars, {lines} lines{truncated}",
|
|
91
93
|
"tool.web_search_result": "Search results for \"{query}\" — {count} results",
|
|
94
|
+
"tool.downloaded": "Downloaded {url} \u2192 {path} ({size} bytes, {type})",
|
|
95
|
+
"tool.download_too_large": "Download blocked: file exceeds the {max} bytes limit",
|
|
92
96
|
"tool.friendly.browser": "Browser",
|
|
93
97
|
"tool.friendly.subagent": "Sub-agent task",
|
|
94
98
|
"tool.friendly.question": "Question to user",
|
|
@@ -96,8 +100,10 @@
|
|
|
96
100
|
"tool.friendly.search_history": "Searching history",
|
|
97
101
|
"tool.friendly.pipeline_run": "Running pipeline",
|
|
98
102
|
"tool.friendly.mcp_call": "MCP call",
|
|
103
|
+
"tool.friendly.lsp_check": "Checking code",
|
|
99
104
|
"tool.truncated": "[Truncated: {tokens} tokens removed]",
|
|
100
105
|
"tool.subagent_queued": "Sub-agent task queued: {task}",
|
|
106
|
+
"tool.subagent_artifact": "Sub-agent completed. Full result saved to artifact: {path}\nIterations: {iterations}\nSummary:\n{summary}",
|
|
101
107
|
"tool.pipeline_started": "Pipeline \"{name}\" execution started. Pipeline engine is a stub \u2014 run dispatched.",
|
|
102
108
|
"tool.mcp_call": "MCP call: {server}/{tool} with {args}",
|
|
103
109
|
"tool.action_required": "Action is required.",
|
|
@@ -118,6 +124,8 @@
|
|
|
118
124
|
"tool.question.unanswered": "Unanswered",
|
|
119
125
|
"tool.question.answered": "User has answered your questions: {formatted}. You can now continue with the user's answers in mind.",
|
|
120
126
|
"tool.name_or_task": "Provide either \"name\" or \"task\" parameter",
|
|
127
|
+
"tool.chunk_query_no_query": "chunk_query: a query string is required.",
|
|
128
|
+
"tool.chunk_query_no_input": "chunk_query: provide input_path or text.",
|
|
121
129
|
"tool.invalid_params": "Invalid parameters",
|
|
122
130
|
"tool.skill_budget": "Skill \"{name}\" loaded ({tokens} tokens, {remaining} remaining in skills budget). Skill content is now in system prompt — no need to reload after context compaction.",
|
|
123
131
|
"tool.skill_available_hint": "Available skills",
|
|
@@ -135,6 +143,7 @@
|
|
|
135
143
|
"proc.started": "Started background process {id} (PID {pid}).\nCommand: {command}",
|
|
136
144
|
"proc.promoted_hint": "Command still running after {ms} ms — moved to the background",
|
|
137
145
|
"proc.manage_hint": "Check output: process_log id={id}. Stop it: process_kill id={id}. List all: process_list.",
|
|
146
|
+
"proc.output_preview": "First output:\n{lines}",
|
|
138
147
|
"proc.none": "No background processes running.",
|
|
139
148
|
"proc.not_found": "Process not found: {id}",
|
|
140
149
|
"proc.killed": "Process {id} (PID {pid}) killed.",
|
|
@@ -157,12 +166,20 @@
|
|
|
157
166
|
"plan.title_steps": "Plan \"{title}\" created with {count} steps",
|
|
158
167
|
"plan.step_marked": "Step {step} marked as {status}",
|
|
159
168
|
"plan.aborted": "Plan aborted",
|
|
169
|
+
"plan.completed_archived": "Plan {id} is complete ({done}/{total} steps) — archived. You may create a new plan for new work (plan create), or reply with your final answer.",
|
|
160
170
|
"plan.unknown_action": "Unknown plan action: {action}",
|
|
161
171
|
"plan.updated": "Plan updated: {title} ({steps} steps)",
|
|
162
172
|
"plan.acknowledged": "Plan {action}: acknowledged",
|
|
163
173
|
"plan.step_status": "Step {step}: {status}",
|
|
164
174
|
"plan.no_active": "No active plan",
|
|
165
175
|
"plan.step_not_found": "Step not found",
|
|
176
|
+
"plan.step_already_done": "Step {step} is already done — nothing to do. Plan progress:",
|
|
177
|
+
"plan.order_blocked": "Cannot mark step {step} done: step {first} (\"{desc}\") is not finished yet. Complete earlier steps first, or mark step {first} status=skipped if it is not needed.",
|
|
178
|
+
"plan.deliverables_missing": "Cannot mark step {step} done: the files it names do not exist yet: {files}. Create these files first (or mark the step status=skipped if they are not actually needed).",
|
|
179
|
+
"plan.kinds_mismatch": "kinds array length must match steps",
|
|
180
|
+
"plan.kinds_invalid": "Invalid step kind(s): {kinds}. Use \"create\" or \"delete\".",
|
|
181
|
+
"plan.kinds_not_array": "kinds must be an array of \"create\" or \"delete\"",
|
|
182
|
+
"plan.deliverables_remain": "Cannot mark step {step} done: the files it names still exist: {files}. This step is kind=delete — delete these files first (or set status=skipped if they should stay).",
|
|
166
183
|
"plan.show_header": "Plan status:",
|
|
167
184
|
"plan.show_empty": "(plan has no steps)",
|
|
168
185
|
"plan.list_header": "Plans:",
|
|
@@ -172,9 +189,14 @@
|
|
|
172
189
|
"plan.switched": "Switched to plan {id}: {title}",
|
|
173
190
|
"plan.replanned": "Plan re-planned: {kept} completed steps kept, {steps} new steps added",
|
|
174
191
|
"plan.replan_no_steps": "Provide new steps for re-planning",
|
|
192
|
+
"plan.active_in_progress": "Cannot create a new plan: active plan {id} already has progress ({done}/{total} done, current: step {current}). Resume it — use \"plan show\" to view, then continue working. To replace it, call \"plan abort\" first, then \"plan create\" again.",
|
|
193
|
+
"plan.id_ignored": "note: plan ids are auto-generated; use \"plan switch\" to activate an existing plan by id.",
|
|
194
|
+
"plan.existing_fresh": "note: the previous active plan had no progress and was preserved as a draft.",
|
|
175
195
|
"todo.added": "Added {count} todo(s): {items}",
|
|
176
196
|
"todo.marked_done": "Marked {count} item(s) as done",
|
|
177
197
|
"todo.no_active": "No active todos",
|
|
198
|
+
"todo.no_items": "No todo items specified — provide items to mark done",
|
|
199
|
+
"todo.subtask_not_found": "No matching sub-task(s) found for: {items}",
|
|
178
200
|
"todo.unknown_action": "Unknown todo action: {action}",
|
|
179
201
|
"todo.acknowledged": "Todo acknowledged",
|
|
180
202
|
"verify.passed": "Verification passed",
|
|
@@ -184,6 +206,14 @@
|
|
|
184
206
|
"verify.script_passed": "Script '{script}' passed",
|
|
185
207
|
"verify.script_failed": "Script '{script}' failed: {message}",
|
|
186
208
|
"verify.syntax_error": "Syntax error in: {path}",
|
|
209
|
+
"verify.no_files": "Step {step} has no named files to verify — run a real check instead (bash: bun run build / bun test / lsp_check) and confirm the result.",
|
|
210
|
+
"lsp.unavailable": "static checks are unavailable (server not found). Verify via the project's own build/test instead.",
|
|
211
|
+
"lsp.check_disabled": "LSP checks are disabled in the config.",
|
|
212
|
+
"lsp.check_no_path": "Provide a path (file or directory) to check.",
|
|
213
|
+
"lsp.check_notfound": "Path not found: {path}",
|
|
214
|
+
"lsp.check_unsupported": "No LSP server configured for: {path}",
|
|
215
|
+
"lsp.check_clean": "No errors or warnings detected ({count} file(s) checked).",
|
|
216
|
+
"lsp.startup_header": "[Existing project errors (checked at session start) — fix these before continuing]:",
|
|
187
217
|
"cli.description": "Micro Models Agent \u2014 AI coding agent for small models",
|
|
188
218
|
"cli.init": "Run interactive setup wizard",
|
|
189
219
|
"cli.config_saved": "Configuration saved to ~/.mma/config.json",
|
|
@@ -296,6 +326,13 @@
|
|
|
296
326
|
"cli.security.recommended_for": "Recommended for",
|
|
297
327
|
"cli.yes": "Yes",
|
|
298
328
|
"cli.no": "No",
|
|
329
|
+
"cli.plugins.description": "Manage plugins",
|
|
330
|
+
"cli.plugins.list": "List loaded plugins (name, version, source)",
|
|
331
|
+
"cli.plugins.all": "Include builtin plugins",
|
|
332
|
+
"cli.plugins.only_external": "(builtin plugins omitted — use --all to show them)",
|
|
333
|
+
"cli.plugins.none": "No plugins loaded",
|
|
334
|
+
"cli.plugins.header": "Plugins: {count} loaded (MMA v{mma})",
|
|
335
|
+
"cli.plugins.builtin_mark": "●",
|
|
299
336
|
"repl.help": "Show available commands",
|
|
300
337
|
"repl.help_usage": "Usage: /help",
|
|
301
338
|
"repl.exit": "Exit the REPL",
|
|
@@ -310,6 +347,8 @@
|
|
|
310
347
|
"repl.reasoning_usage": "Usage: /reasoning",
|
|
311
348
|
"repl.status": "Show agent status",
|
|
312
349
|
"repl.status_usage": "Usage: /status",
|
|
350
|
+
"repl.plugins": "List loaded plugins",
|
|
351
|
+
"repl.plugins_usage": "Usage: /plugins [--all]",
|
|
313
352
|
"repl.sessions": "List all sessions (* active)",
|
|
314
353
|
"repl.sessions_usage": "Usage: /sessions",
|
|
315
354
|
"repl.new": "Create a new session",
|
|
@@ -336,6 +375,7 @@
|
|
|
336
375
|
"repl.skill_unknown_sub": "Unknown skill subcommand: {subcmd}",
|
|
337
376
|
"repl.skill_usage": "Usage: /skill [list|loaded|load|unload|search]",
|
|
338
377
|
"repl.agent": "Agent: ",
|
|
378
|
+
"repl.you": "You: ",
|
|
339
379
|
"repl.interrupt": "Interrupted (Esc)",
|
|
340
380
|
"repl.title": "MMA REPL v{version}",
|
|
341
381
|
"repl.model": "Model:",
|
|
@@ -353,6 +393,10 @@
|
|
|
353
393
|
"repl.skills_label": "Skills:",
|
|
354
394
|
"repl.plugins_label": "Plugins:",
|
|
355
395
|
"repl.mcp_label": "MCP:",
|
|
396
|
+
"repl.lsp_label": "LSP:",
|
|
397
|
+
"repl.lsp_timeout": "timeout",
|
|
398
|
+
"repl.lsp_failed": "did not start",
|
|
399
|
+
"repl.lsp_unknown": "unknown",
|
|
356
400
|
"repl.work_dir": "Dir:",
|
|
357
401
|
"repl.agents_label": "Instructions:",
|
|
358
402
|
"repl.not_found": "not found",
|
|
@@ -427,6 +471,8 @@
|
|
|
427
471
|
"exec.tool_errors_recovery": "Tool {tool} has failed {count} times in a row. Try an alternative: create files directly via write_file, use a different command, or if nothing works — skip this step via plan update step=N status=skipped with a note explaining why.",
|
|
428
472
|
"exec.repetitive_tool": "Called {tool} {count} times with identical arguments and result. Try a different approach — create files directly, change arguments, or check process status via process_log.",
|
|
429
473
|
"exec.consecutive_failures_recovery": "{count} consecutive tool failures. Create files directly via write_file instead of terminal commands. Check that dependencies are installed (npm install). Do not run build/tests until all files are created.",
|
|
474
|
+
"exec.read_only_loop": "No write/exec for {count} tool calls — the agent is only reading/exploring.",
|
|
475
|
+
"exec.read_only_loop_recovery": "{count} consecutive read-only tool calls (read_file/glob/grep/browser) with no writes. STOP exploring and make the edit the task requires: read the file, then call write_file or edit_file. If you cannot finish the task, ask the user instead of re-reading the same files.",
|
|
430
476
|
"exec.plan_warning": "Current plan step {step} is \"{description}\", but {tool} is being called for files outside this step. Complete the current step first, then call plan update step={step} status=done before moving to the next step.",
|
|
431
477
|
"exec.plan_blocked": "{max} consecutive calls outside the current step. Finish step {step} before proceeding — other steps should wait until this one is complete.",
|
|
432
478
|
"exec.off_track": "Step {stepId} — \"{description}\" — but you are using {tool} on a different path. Return to the current step.",
|
|
@@ -436,13 +482,18 @@
|
|
|
436
482
|
"exec.step_gate_ok": "[\u2713] Step {step} completed and verified. MOVING to step {nextStep}: \"{nextDesc}\". Work ONLY on this step.",
|
|
437
483
|
"exec.step_gate_last": "[\u2713] Step {step} completed — that was the final step. Verify everything together and provide the final answer.]",
|
|
438
484
|
"exec.audit_pass": "[\u2713] Task complete: {done}/{total} steps done, {files} files verified",
|
|
485
|
+
"exec.audit_pending": "[\u2717] Task incomplete: {done}/{total} steps done — remaining steps are not marked done",
|
|
439
486
|
"exec.audit_fail": "[\u2717] Task incomplete: {done}/{total} steps done, {files} files missing",
|
|
487
|
+
"exec.audit_leftovers": "[\u2717] Task incomplete: {done}/{total} steps done, {files} files from delete-steps still exist",
|
|
488
|
+
"exec.audit_fail_tests": "[\u2717] Task incomplete: {done}/{total} steps done, tests FAILING: {failed} failed / {passed} passed — {detail}",
|
|
440
489
|
"exec.audit_fail_typecheck": "[\u2717] Task incomplete: {done}/{total} steps done, {missing} files missing, typecheck error: {typeError}",
|
|
441
490
|
"exec.audit_incomplete": "[\u26a0 Final audit incomplete: {summary}. Task is NOT finished \u2014 continue working. Remaining steps: {steps}]",
|
|
442
491
|
"exec.mass_edit_warning": "\u26a0\ufe0f Plan affects {count} files \u2014 review the full list before proceeding.",
|
|
443
492
|
"exec.escalation": "\n\n\u26a0\ufe0f Agent stuck on step {stepId} ({description}). Escalating to user \u2014 please provide guidance.",
|
|
444
493
|
"exec.hints": "\n[Hints]\n{hints}",
|
|
445
494
|
"exec.file_rewrite_warning": "\u26a0\ufe0f File {file} has been rewritten {count} times. Consider a different approach \u2014 the current fix strategy is not working.",
|
|
495
|
+
"exec.forbidden_cmd": "STOP using \"{cmd}\" via the bash tool \u2014 it is not a native Windows cmd.exe command and has failed repeatedly this session. Use the dedicated tool instead: grep \u2192 the grep tool, ls/dir \u2192 list_dir, find \u2192 glob, rm \u2192 delete_file, sed \u2192 edit_file, touch \u2192 write_file, which \u2192 `where`, cp/mv \u2192 move_file, diff \u2192 read_file. Do NOT call bash for this purpose again.",
|
|
496
|
+
"exec.npm_exec_hint": "\"could not determine executable to run\" \u2014 no \"bin\" for that package/script. Use \"npm run <script>\" (script must exist in package.json) or \"bunx <pkg>\" for a package that declares a bin.",
|
|
446
497
|
"hall.max_retries_exhausted": "Model returned empty or insufficient responses after multiple retries",
|
|
447
498
|
"hall.short_response": "Response too short or empty",
|
|
448
499
|
"hall.repetitive": "Response too repetitive ({pct}% overlap)",
|
|
@@ -468,11 +519,17 @@
|
|
|
468
519
|
"browser.no_page_short": "No page",
|
|
469
520
|
"browser.no_elements": "(no interactive elements on page)",
|
|
470
521
|
"browser.more_elements": "... and more elements not shown. Use scroll or search to find others.",
|
|
522
|
+
"browser.content_header": "Content:",
|
|
523
|
+
"browser.console_header": "Console:",
|
|
524
|
+
"browser.network_errors_header": "Network errors:",
|
|
525
|
+
"browser.truncated": "... (truncated)",
|
|
471
526
|
"pipeline.invalid": "Invalid pipeline: name and steps required",
|
|
472
527
|
"pipeline.step_missing_fields": "Step missing required fields (id, agent, prompt): {step}",
|
|
473
528
|
"pipeline.circular": "Circular dependency: {stepId}",
|
|
474
529
|
"plugin.loaded": "Loaded plugin: {name}",
|
|
475
530
|
"plugin.skipped": "Skipped incompatible plugin: {entry} ({message})",
|
|
531
|
+
"plugin.incompatible": "Skipped plugin {name}: requires MMA v{min}, current is v{current}",
|
|
532
|
+
"plugin.dedup_older": "Plugin {name} v{version} skipped: a newer version is already loaded",
|
|
476
533
|
"migration.detected": "[MMA] Detected old config. {summary}",
|
|
477
534
|
"migration.summary": "[MMA] {summary}",
|
|
478
535
|
"migration.config_bak": "- config \u2192 config.json.bak",
|
|
@@ -483,6 +540,7 @@
|
|
|
483
540
|
"ui.success_prefix": "\u2713 ",
|
|
484
541
|
"ui.warning_prefix": "\u26a0 ",
|
|
485
542
|
"ui.thinking": "Thinking…",
|
|
543
|
+
"ui.step_context": "step {id}: {desc}",
|
|
486
544
|
"indexer.map_header": "Project map",
|
|
487
545
|
"indexer.top_directories": "Top directories",
|
|
488
546
|
"indexer.files": "Files",
|
|
@@ -496,6 +554,10 @@
|
|
|
496
554
|
"indexer.not_indexed": "Project has not been indexed yet",
|
|
497
555
|
"indexer.find_results": "Found {count} matching files:\n{results}",
|
|
498
556
|
"indexer.no_matches": "No matching files for \"{query}\"",
|
|
557
|
+
"indexer.duplicates": "Duplicate basenames (verify which file is the real source): {names}",
|
|
558
|
+
"indexer.stack_deps": "deps",
|
|
559
|
+
"indexer.stack_dev": "dev",
|
|
560
|
+
"indexer.stack_scripts": "scripts",
|
|
499
561
|
"tool.friendly.project_map": "Project map",
|
|
500
562
|
"config.decryption_warning": "Warning: Failed to decrypt config: {error}",
|
|
501
563
|
"config.encryption_warning": "Warning: Failed to encrypt config: {error}",
|
|
@@ -520,6 +582,17 @@
|
|
|
520
582
|
"ctx.compactions": "compactions: {count}",
|
|
521
583
|
"ctx.quality": "quality: {percent}%",
|
|
522
584
|
"ctx.delta_pos": "ctx +{tokens}",
|
|
523
|
-
"ctx.delta_neg": "ctx -{tokens}
|
|
524
|
-
"ctx.delta_zero": "ctx
|
|
585
|
+
"ctx.delta_neg": "ctx -{tokens} ",
|
|
586
|
+
"ctx.delta_zero": "ctx +0",
|
|
587
|
+
"updater.check_error": "[updater] update check failed: {error}",
|
|
588
|
+
"updater.available": "[updater] Update available: {current} → {latest}. Run `npm install -g micro-models-agent` to upgrade.",
|
|
589
|
+
"updater.installing": "[updater] Installing {latest} globally (current: {current})…",
|
|
590
|
+
"updater.installed": "[updater] Installed {latest}. Restart MMA to use it (was {current}).",
|
|
591
|
+
"updater.install_failed": "[updater] Failed to install {latest}: {error}. Update manually with `npm install -g micro-models-agent`.",
|
|
592
|
+
"tools.enable_no_tags": "enable_tools requires at least one tag in the \"tags\" array.",
|
|
593
|
+
"tools.enable_no_executor": "Tool executor is not available — cannot enumerate enabled tools.",
|
|
594
|
+
"tools.enable_already_active": "Tool tags already active: {tags}.",
|
|
595
|
+
"tools.enable_added": "Enabled tool tags: {tags}. Available tools now: {tools}",
|
|
596
|
+
"tools.hidden_header": "Additional tools (enable on demand via enable_tools or route to subagent tool_tags):",
|
|
597
|
+
"tool.friendly.enable_tools": "Enable tools"
|
|
525
598
|
}
|