micro-models-agent 0.20.2 → 0.21.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.
Files changed (2) hide show
  1. package/dist/main.js +75 -11
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -2303,6 +2303,8 @@ Command: {command}`,
2303
2303
  "tool.friendly.process_list": "Listing background processes",
2304
2304
  "tool.friendly.process_log": "Process output",
2305
2305
  "tool.friendly.process_kill": "Stopping process",
2306
+ "plan.no_steps": "No plan steps specified. Provide concrete steps with files and commands.",
2307
+ "plan.bad_steps": "Plan step quality unacceptable. Each step must describe concrete deliverables (files, packages, commands). Minimum 20 chars per step. Errors: {errors}",
2306
2308
  "plan.created": "Plan created: {title} ({steps} steps)",
2307
2309
  "plan.step_done": "Step {n}/{total}: {description} ✓",
2308
2310
  "plan.complete": "Task complete: {summary}",
@@ -2800,6 +2802,8 @@ var init_ru = __esm(() => {
2800
2802
  "tool.friendly.process_list": "Список фоновых процессов",
2801
2803
  "tool.friendly.process_log": "Вывод процесса",
2802
2804
  "tool.friendly.process_kill": "Остановка процесса",
2805
+ "plan.no_steps": "Не указаны шаги плана. Укажите конкретные шаги с файлами и командами.",
2806
+ "plan.bad_steps": "Качество шагов плана неприемлемо. Каждый шаг должен описывать конкретные deliverables (файлы, пакеты, команды). Минимум 20 символов на шаг. Ошибки: {errors}",
2803
2807
  "plan.created": "План создан: {title} ({steps} шагов)",
2804
2808
  "plan.step_done": "Шаг {n}/{total}: {description} ✓",
2805
2809
  "plan.complete": "Задача выполнена: {summary}",
@@ -12381,29 +12385,67 @@ var init_notify = __esm(() => {
12381
12385
  });
12382
12386
 
12383
12387
  // src/modules/execution/planner.ts
12388
+ function generatePlanId() {
12389
+ const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
12390
+ let id = "";
12391
+ for (let i = 0;i < 6; i++) {
12392
+ id += chars[Math.floor(Math.random() * chars.length)];
12393
+ }
12394
+ return `plan_${id}`;
12395
+ }
12396
+
12384
12397
  class PlanCreator {
12385
12398
  static isMultiStep(task) {
12386
12399
  const fileCount = (task.match(/\b[\w./-]+\.[a-z]+\b/gi) || []).length;
12387
12400
  if (fileCount > 1)
12388
12401
  return true;
12389
- const actionWords = ["implement", "create", "add", "build", "setup", "configure", "write", "make", "develop"];
12402
+ const actionWords = [
12403
+ "implement",
12404
+ "create",
12405
+ "add",
12406
+ "build",
12407
+ "setup",
12408
+ "configure",
12409
+ "write",
12410
+ "make",
12411
+ "develop"
12412
+ ];
12390
12413
  const words = task.split(/\s+/);
12391
12414
  const hasActionWord = actionWords.some((w) => task.toLowerCase().includes(w));
12392
12415
  return hasActionWord && words.length > 8;
12393
12416
  }
12394
- static createPlan(title, stepDescriptions) {
12417
+ static createPlan(title, stepDescriptions, baseDir) {
12418
+ const stepCount = stepDescriptions.length;
12395
12419
  return {
12396
- title,
12420
+ id: generatePlanId(),
12421
+ title: `[${stepCount} ст.] ${title}`,
12397
12422
  steps: stepDescriptions.map((desc, i) => ({
12398
12423
  id: i + 1,
12399
12424
  description: desc,
12400
12425
  status: "pending"
12401
12426
  })),
12402
- createdAt: new Date().toISOString()
12427
+ createdAt: new Date().toISOString(),
12428
+ baseDir
12403
12429
  };
12404
12430
  }
12431
+ static validateSteps(steps) {
12432
+ const errors = [];
12433
+ for (let i = 0;i < steps.length; i++) {
12434
+ const s = steps[i].trim();
12435
+ if (s.length < MIN_STEP_DESC_LENGTH) {
12436
+ errors.push(`Step ${i + 1} too short (${s.length} chars). Describe WHAT files to create, WHICH packages to install, WHICH commands to run. Minimum ${MIN_STEP_DESC_LENGTH} chars.`);
12437
+ }
12438
+ }
12439
+ return { valid: errors.length === 0, errors };
12440
+ }
12405
12441
  static toPromptBlock(plan, currentStepIndex) {
12406
- const lines = [`[Plan: ${plan.title}] (steps: ${plan.steps.filter((s) => s.status === "done").length}/${plan.steps.length} done, current: step ${currentStepIndex + 1})`];
12442
+ const date = plan.createdAt.slice(0, 10);
12443
+ const lines = [
12444
+ `[${plan.id}] ${plan.title}`,
12445
+ `Dir: ${plan.baseDir}`,
12446
+ `Created: ${date} | Progress: ${plan.steps.filter((s) => s.status === "done").length}/${plan.steps.length} done, current: step ${currentStepIndex + 1}`,
12447
+ ``
12448
+ ];
12407
12449
  for (const step of plan.steps) {
12408
12450
  const icon = step.status === "done" ? "[x]" : step.status === "in_progress" ? "[*]" : step.status === "failed" ? "[!]" : step.status === "skipped" ? "[-]" : "[ ]";
12409
12451
  const note = step.note ? ` — ${step.note}` : "";
@@ -12413,6 +12455,7 @@ class PlanCreator {
12413
12455
  `);
12414
12456
  }
12415
12457
  }
12458
+ var MIN_STEP_DESC_LENGTH = 20;
12416
12459
 
12417
12460
  // src/modules/execution/tracker.ts
12418
12461
  class PlanTracker {
@@ -12461,7 +12504,7 @@ class PlanTracker {
12461
12504
  const barWidth = 10;
12462
12505
  const filled = Math.round(done / total * barWidth);
12463
12506
  const bar = "█".repeat(filled) + "░".repeat(barWidth - filled);
12464
- return `[Plan: ${this.plan.title}] ${done}/${total} ${bar} ${pct}%`;
12507
+ return `[${this.plan.id}] ${this.plan.title} ${done}/${total} ${bar} ${pct}%`;
12465
12508
  }
12466
12509
  toPromptBlock() {
12467
12510
  return PlanCreator.toPromptBlock(this.plan, this.currentStepIndex);
@@ -12710,10 +12753,12 @@ class PlanPersister {
12710
12753
  }
12711
12754
  save(plan) {
12712
12755
  const file = {
12756
+ id: plan.id,
12713
12757
  title: plan.title,
12714
12758
  steps: plan.steps,
12715
12759
  createdAt: plan.createdAt,
12716
- updatedAt: new Date().toISOString()
12760
+ updatedAt: new Date().toISOString(),
12761
+ baseDir: plan.baseDir
12717
12762
  };
12718
12763
  writeFileSync9(this.filePath, JSON.stringify(file, null, 2), "utf-8");
12719
12764
  }
@@ -12724,9 +12769,11 @@ class PlanPersister {
12724
12769
  const raw = readFileSync14(this.filePath, "utf-8");
12725
12770
  const file = JSON.parse(raw);
12726
12771
  return {
12772
+ id: file.id || "plan_legacy",
12727
12773
  title: file.title,
12728
12774
  steps: file.steps,
12729
- createdAt: file.createdAt
12775
+ createdAt: file.createdAt,
12776
+ baseDir: file.baseDir || process.cwd()
12730
12777
  };
12731
12778
  } catch {
12732
12779
  return null;
@@ -12814,7 +12861,15 @@ class ExecutionModule {
12814
12861
  return [
12815
12862
  {
12816
12863
  name: "plan",
12817
- description: 'Create, update, show, or abort a multi-step plan. Use "create" at the start of complex tasks. Use "update" after completing each step to track progress. Use "show" to re-print the current plan checklist.',
12864
+ description: `Create, update, show, or abort a multi-step plan. Use "create" at the start of complex tasks. Use "update" after completing each step to track progress. Use "show" to re-print the current plan checklist.
12865
+
12866
+ IMPORTANT — each step MUST be detailed and concrete:
12867
+ - Specify WHICH files to create (filenames with paths, e.g. "create src/components/Header.tsx...")
12868
+ - Specify WHICH packages to install (e.g. "run npm install react react-dom")
12869
+ - Specify WHICH commands to run with exact arguments
12870
+ - Minimum 20 characters per step description
12871
+ - BAD: "Настройка проекта"
12872
+ - GOOD: "Создать package.json с зависимостями react@18, vite@5, установить их через npm install"`,
12818
12873
  parameters: {
12819
12874
  type: "object",
12820
12875
  properties: {
@@ -12838,7 +12893,16 @@ class ExecutionModule {
12838
12893
  if (steps.length === 0) {
12839
12894
  return { success: false, output: t("plan.no_steps") };
12840
12895
  }
12841
- const plan = PlanCreator.createPlan(title, steps);
12896
+ const validation = PlanCreator.validateSteps(steps);
12897
+ if (!validation.valid) {
12898
+ return {
12899
+ success: false,
12900
+ output: t("plan.bad_steps", {
12901
+ errors: validation.errors.join("; ")
12902
+ })
12903
+ };
12904
+ }
12905
+ const plan = PlanCreator.createPlan(title, steps, this.baseDir);
12842
12906
  this.setPlan(plan);
12843
12907
  const display = PlanCreator.toPromptBlock(plan, 0);
12844
12908
  return {
@@ -14583,7 +14647,7 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
14583
14647
  lines.push(``, `Windows environment — use Windows-compatible commands:`, `- Use "dir" instead of "ls". Use "dir /b" for bare listing.`, `- Use "type" or "Get-Content" instead of "cat".`, `- Use "cd" instead of "pwd". Use "echo %cd%" to print working directory.`, `- Use "copy" instead of "cp", "move" instead of "mv", "del" instead of "rm".`, `- Do not use "mkdir -p" — Windows mkdir creates intermediate dirs by default. Use the create_dir tool instead.`, `- Use forward slashes (/) or escaped backslashes (\\\\) in file paths.`, `- Your working directory is: ${baseDir}`);
14584
14648
  }
14585
14649
  lines.push(``, `Bash tool rules:`, `- Use the "workdir" parameter to run commands in a specific directory. Do NOT chain "cd dir && cmd" — the security module blocks the "&&" operator.`, `- Run one command per tool call. Split multi-step shell operations into separate bash calls.`, `- Background processes (dev servers, watchers, long-running npm install): use the "background: true" parameter or the tool will auto-detect and background them. Check output with process_log.`);
14586
- lines.push(``, `=== DEVELOPMENT RULES — follow these strictly ===`, ``, `1. DEPENDENCIES FIRST: Before writing any source code, ALWAYS install project dependencies (e.g., "npm install", "pip install -r requirements.txt", "cargo build", "go mod tidy"). Verify the package manager's lock file or dependency directory exists. Never write code that imports/uses packages that aren't installed yet.`, `2. TOOLKIT/FWK FIRST: If the task specifies a framework or UI library, initialize and configure it BEFORE writing application code. Run its project init command first, then add components/modules. Never write your own version of what the framework already provides.`, `3. ONE STEP AT A TIME: Follow the plan sequentially. Complete step N before starting step N+1. When a step is done: verify the deliverables exist and have real content (not empty), then call "plan update step=N status=done". Do not redo completed work.`, `4. VERIFY YOUR WORK: After creating/modifying files, verify they exist on disk. After installing dependencies, verify the package manager completed successfully. After any command, check its output for errors. Don't assume operations succeeded.`, `5. NO PREMATURE WORK: Do not create files for future steps. Do not add imports/references to packages or modules that haven't been installed yet. Do not reference files or components that don't exist yet. Build incrementally — one layer at a time.`, `6. WHEN STUCK: If a command fails 2+ times, STOP and try a different approach. Write files directly instead of using commands. Ask the user for help. Never repeat the same failing command more than twice.`);
14650
+ lines.push(``, `=== DEVELOPMENT RULES — follow these strictly ===`, ``, `1. DEPENDENCIES FIRST: Before writing any source code, ALWAYS install project dependencies (e.g., "npm install", "pip install -r requirements.txt", "cargo build", "go mod tidy"). Verify the package manager's lock file or dependency directory exists. Never write code that imports/uses packages that aren't installed yet.`, `2. TOOLKIT/FWK FIRST: If the task specifies a framework or UI library, initialize and configure it BEFORE writing application code. Run its project init command first, then add components/modules. Never write your own version of what the framework already provides.`, `3. ONE STEP AT A TIME: Follow the plan sequentially. Complete step N before starting step N+1. When a step is done: verify the deliverables exist and have real content (not empty), then call "plan update step=N status=done". Do not redo completed work.`, `4. VERIFY YOUR WORK: After creating/modifying files, verify they exist on disk. After installing dependencies, verify the package manager completed successfully. After any command, check its output for errors. Don't assume operations succeeded.`, `5. NO PREMATURE WORK: Do not create files for future steps. Do not add imports/references to packages or modules that haven't been installed yet. Do not reference files or components that don't exist yet. Build incrementally — one layer at a time.`, `6. WHEN STUCK: If a command fails 2+ times, STOP and try a different approach. Write files directly instead of using commands. Ask the user for help. Never repeat the same failing command more than twice.`, ``, `=== PLAN QUALITY RULES — your plan MUST follow these ===`, ``, `- Each step must describe CONCRETE deliverables: exact filenames with paths, exact packages to install, exact CLI commands to run.`, `- A step like "Настройка проекта" or "Setup the project" is USELESS and will be REJECTED.`, `- A step like "Создать src/components/Header.tsx с хедером навигации, подключить в App.tsx" is GOOD.`, `- Include file extensions (.tsx, .css, .json) and directory paths. Never write vague steps.`, `- The plan must cover EVERYTHING needed: init → deps → framework setup → code → verification.`, `- Number of steps: 5-8 for a typical task. Too few means you're being vague. Too many means you're over-splitting.`);
14587
14651
  if (config.autoPlan) {
14588
14652
  lines.push(``, `Plan rule (MANDATORY): For ANY task that requires creating files, installing packages, or multiple actions — you MUST create a plan using the "plan" tool BEFORE starting work. Each step must describe a concrete deliverable (specific files to create, packages to install, commands to run). Do not combine unrelated work into one step.`);
14589
14653
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "micro-models-agent",
3
- "version": "0.20.2",
3
+ "version": "0.21.0",
4
4
  "description": "Micro Models Agent (MMA) — LLM agent harness for small models (Qwen3.5-9B, 32K-64K context)",
5
5
  "type": "module",
6
6
  "bin": {