micro-models-agent 0.28.2 → 0.28.4

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 +82 -30
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -2231,7 +2231,9 @@ var init_defaults = __esm(() => {
2231
2231
  ui: {
2232
2232
  spinner: true,
2233
2233
  toolStyle: "inline",
2234
- toolComments: true
2234
+ toolComments: true,
2235
+ showContextStats: false,
2236
+ showCompaction: true
2235
2237
  },
2236
2238
  mcpServers: {
2237
2239
  context7: {
@@ -6896,16 +6898,16 @@ class ProcessRegistry {
6896
6898
  const decoder = platform() === "win32" ? (() => {
6897
6899
  try {
6898
6900
  const cpOut = __require("child_process").execSync("chcp.com", {
6899
- encoding: "utf-8",
6901
+ encoding: "buffer",
6900
6902
  timeout: 2000,
6901
6903
  windowsHide: true
6902
- }).toString();
6904
+ }).toString("latin1");
6903
6905
  const m = cpOut.match(/(\d+)/);
6904
6906
  if (m)
6905
6907
  return new TextDecoder("ibm" + m[1]);
6906
6908
  } catch {}
6907
- return null;
6908
- })() : null;
6909
+ return new TextDecoder("ibm866");
6910
+ })() : new TextDecoder("utf-8");
6909
6911
  let buf = "";
6910
6912
  const pushLine = (line) => {
6911
6913
  if (entry.log.length >= MAX_LOG_LINES) {
@@ -6914,7 +6916,7 @@ class ProcessRegistry {
6914
6916
  entry.log.push(line);
6915
6917
  };
6916
6918
  const append = (chunk) => {
6917
- const decoded = decoder ? decoder.decode(chunk, { stream: true }) : chunk.toString();
6919
+ const decoded = decoder.decode(chunk, { stream: true });
6918
6920
  buf += decoded;
6919
6921
  const lines = buf.split(/\r?\n/);
6920
6922
  buf = lines.pop() ?? "";
@@ -6923,9 +6925,7 @@ class ProcessRegistry {
6923
6925
  }
6924
6926
  };
6925
6927
  const flush = () => {
6926
- if (decoder) {
6927
- buf += decoder.decode();
6928
- }
6928
+ buf += decoder.decode();
6929
6929
  if (buf) {
6930
6930
  pushLine(buf);
6931
6931
  buf = "";
@@ -7053,6 +7053,9 @@ import { platform as platform2 } from "os";
7053
7053
  function adaptCommandForWindows(command) {
7054
7054
  if (platform2() !== "win32")
7055
7055
  return command;
7056
+ if (/\|\|\s*true\b/.test(command)) {
7057
+ command = command.replace(/\s*\|\|\s*true\b/g, "; exit 0");
7058
+ }
7056
7059
  const trimmed = command.trim();
7057
7060
  if (trimmed.startsWith("mkdir -p ")) {
7058
7061
  return trimmed.replace(/^mkdir -p /, "mkdir ");
@@ -9702,6 +9705,7 @@ class Agent {
9702
9705
  systemPromptAdded = false;
9703
9706
  shutdownRequested = false;
9704
9707
  abortController = null;
9708
+ lastCompactionShown = 0;
9705
9709
  constructor(deps) {
9706
9710
  this.deps = deps;
9707
9711
  }
@@ -10086,19 +10090,30 @@ ${taskReminder}</system-summary>`
10086
10090
  content: `<system-summary>${summaries.join(`
10087
10091
  `)}</system-summary>`
10088
10092
  });
10089
- const ctxTokens = contextManager.getEstimatedTokens();
10090
- const ctxBudget = contextManager.getBudget();
10091
- const ctxPct = Math.min(100, Math.round(ctxTokens / ctxBudget.history * 100));
10092
- const barLen = 10;
10093
- const filled = Math.round(ctxPct / 100 * barLen);
10094
- const ctxBar = pc2.green("█".repeat(filled)) + pc2.dim("░".repeat(barLen - filled));
10095
- const pctColor = ctxPct >= 75 ? pc2.yellow : pc2.dim;
10096
- const compCount = contextManager.getCompactionCount();
10097
- const quality2 = contextManager.getQuality();
10098
- const qualityColor = quality2 >= 70 ? pc2.green : quality2 >= 40 ? pc2.yellow : pc2.red;
10099
- onMeta?.(`
10093
+ const ui = this.deps.config.ui;
10094
+ if (ui?.showContextStats) {
10095
+ const ctxTokens = contextManager.getEstimatedTokens();
10096
+ const ctxBudget = contextManager.getBudget();
10097
+ const ctxPct = Math.min(100, Math.round(ctxTokens / ctxBudget.history * 100));
10098
+ const barLen = 10;
10099
+ const filled = Math.round(ctxPct / 100 * barLen);
10100
+ const ctxBar = pc2.green("█".repeat(filled)) + pc2.dim("░".repeat(barLen - filled));
10101
+ const pctColor = ctxPct >= 75 ? pc2.yellow : pc2.dim;
10102
+ const compCount = contextManager.getCompactionCount();
10103
+ const quality2 = contextManager.getQuality();
10104
+ const qualityColor = quality2 >= 70 ? pc2.green : quality2 >= 40 ? pc2.yellow : pc2.red;
10105
+ onMeta?.(`
10100
10106
  ${ctxBar} ${pctColor(`${ctxPct}%`)} ${pc2.dim(`ctx: ${ctxTokens}/${ctxBudget.history}`)} ${pc2.dim(`compactions: ${compCount}`)} ${qualityColor(`quality: ${quality2}%`)}
10101
10107
  `);
10108
+ } else if (ui?.showCompaction) {
10109
+ const compCount = contextManager.getCompactionCount();
10110
+ if (compCount > this.lastCompactionShown) {
10111
+ this.lastCompactionShown = compCount;
10112
+ onMeta?.(pc2.dim(`
10113
+ ⟳ Context compacted (${compCount})
10114
+ `));
10115
+ }
10116
+ }
10102
10117
  continue;
10103
10118
  }
10104
10119
  hallucinationDetector.getConfidenceCheck().setPreviousResponse(lastText);
@@ -13465,9 +13480,30 @@ var init_loader = __esm(() => {
13465
13480
  });
13466
13481
 
13467
13482
  // src/modules/plugins/builtin/lint-on-write.ts
13468
- import { spawn as spawn4 } from "child_process";
13483
+ import { spawn as spawn4, execSync } from "child_process";
13469
13484
  import { existsSync as existsSync24, readFileSync as readFileSync13 } from "fs";
13470
13485
  import { resolve as resolve13, extname as extname4, join as join18 } from "path";
13486
+ import { platform as platform3 } from "os";
13487
+ function getWinDecoder() {
13488
+ if (_winDecoder === undefined) {
13489
+ if (platform3() !== "win32") {
13490
+ _winDecoder = null;
13491
+ } else {
13492
+ try {
13493
+ const cpOut = execSync("chcp.com", {
13494
+ encoding: "buffer",
13495
+ timeout: 2000,
13496
+ windowsHide: true
13497
+ }).toString("latin1");
13498
+ const m = cpOut.match(/(\d+)/);
13499
+ _winDecoder = m ? new TextDecoder("ibm" + m[1]) : null;
13500
+ } catch {
13501
+ _winDecoder = null;
13502
+ }
13503
+ }
13504
+ }
13505
+ return _winDecoder ?? new TextDecoder("utf-8");
13506
+ }
13471
13507
 
13472
13508
  class LintOnWritePlugin {
13473
13509
  name = "lint-on-write";
@@ -13602,11 +13638,12 @@ function runAsync(command, cwd, timeoutMs) {
13602
13638
  });
13603
13639
  let stdout = "";
13604
13640
  let stderr = "";
13641
+ const decoder = getWinDecoder();
13605
13642
  child.stdout?.on("data", (d) => {
13606
- stdout += d.toString();
13643
+ stdout += decoder.decode(d, { stream: true });
13607
13644
  });
13608
13645
  child.stderr?.on("data", (d) => {
13609
- stderr += d.toString();
13646
+ stderr += decoder.decode(d, { stream: true });
13610
13647
  });
13611
13648
  const timer = setTimeout(() => {
13612
13649
  child.kill();
@@ -13618,6 +13655,8 @@ function runAsync(command, cwd, timeoutMs) {
13618
13655
  });
13619
13656
  child.on("close", (code) => {
13620
13657
  clearTimeout(timer);
13658
+ stdout += decoder.decode();
13659
+ stderr += decoder.decode();
13621
13660
  if (code === 0) {
13622
13661
  resolve14({ stdout, stderr });
13623
13662
  } else {
@@ -13630,7 +13669,7 @@ function runAsync(command, cwd, timeoutMs) {
13630
13669
  });
13631
13670
  });
13632
13671
  }
13633
- var TYPE_CHECK_DEBOUNCE_MS = 2000, plugin;
13672
+ var TYPE_CHECK_DEBOUNCE_MS = 2000, _winDecoder, plugin;
13634
13673
  var init_lint_on_write = __esm(() => {
13635
13674
  plugin = new LintOnWritePlugin;
13636
13675
  });
@@ -14232,6 +14271,19 @@ Sub-tasks: ${note}`
14232
14271
  this.stuckDetector.reset();
14233
14272
  this.consecutivePlanWarnings = 0;
14234
14273
  this.lastStepId = -1;
14274
+ const iter = typeof ctx.iteration === "number" ? ctx.iteration : 0;
14275
+ if (iter === 3 && !this.tracker && ctx.contextManager) {
14276
+ ctx.contextManager.addMessage({
14277
+ role: "user",
14278
+ content: `<system-summary>You have made 3 tool calls without creating a plan. For any task that involves creating files, installing packages, or multiple steps — you MUST use plan create BEFORE continuing. Use the plan tool now with concrete steps (exact filenames, commands, deliverables). Do NOT make any more write/edit/bash calls until you have a plan.</system-summary>`
14279
+ });
14280
+ }
14281
+ if (iter >= 6 && !this.tracker && ctx.contextManager) {
14282
+ ctx.contextManager.addMessage({
14283
+ role: "user",
14284
+ content: `<system-summary>STOP. ${iter} iterations without a plan. You MUST call plan create RIGHT NOW. No more tool calls until you create a plan.</system-summary>`
14285
+ });
14286
+ }
14235
14287
  }
14236
14288
  const stuckReason = this.stuckDetector.getStuckReason();
14237
14289
  if (stuckReason) {
@@ -15031,7 +15083,7 @@ class ProfileCompressor {
15031
15083
  // src/modules/user-profile/profile.ts
15032
15084
  import { readFileSync as readFileSync18, writeFileSync as writeFileSync11, existsSync as existsSync30, mkdirSync as mkdirSync13 } from "fs";
15033
15085
  import { join as join22 } from "path";
15034
- import { homedir as homedir9, hostname, platform as platform3, type } from "os";
15086
+ import { homedir as homedir9, hostname, platform as platform4, type } from "os";
15035
15087
  import { env } from "process";
15036
15088
 
15037
15089
  class UserProfile {
@@ -15043,7 +15095,7 @@ class UserProfile {
15043
15095
  }
15044
15096
  collect() {
15045
15097
  this.info = {
15046
- platform: platform3(),
15098
+ platform: platform4(),
15047
15099
  os: `${type()} ${hostname()}`,
15048
15100
  hostname: hostname(),
15049
15101
  shell: env.SHELL || env.ComSpec || "unknown",
@@ -15393,7 +15445,7 @@ var init_browser2 = __esm(() => {
15393
15445
  });
15394
15446
 
15395
15447
  // src/modules/lsp/client.ts
15396
- import { spawn as spawn5, execSync } from "child_process";
15448
+ import { spawn as spawn5, execSync as execSync2 } from "child_process";
15397
15449
  import { resolve as resolve16 } from "path";
15398
15450
 
15399
15451
  class LspClient {
@@ -15450,7 +15502,7 @@ class LspClient {
15450
15502
  async startServer(config, baseDir) {
15451
15503
  if (config.autoInstall === false) {
15452
15504
  try {
15453
- execSync(`where ${config.command}`, { stdio: "pipe", timeout: 3000 });
15505
+ execSync2(`where ${config.command}`, { stdio: "pipe", timeout: 3000 });
15454
15506
  } catch {
15455
15507
  throw new Error(`${config.command} not found in PATH`);
15456
15508
  }
@@ -24643,7 +24695,7 @@ var init_fact_checker = () => {};
24643
24695
  // src/modules/certification/runner.ts
24644
24696
  import { spawn as spawn6 } from "child_process";
24645
24697
  import { existsSync as existsSync39, mkdirSync as mkdirSync16, rmSync as rmSync3, cpSync as cpSync2 } from "fs";
24646
- import { platform as platform4 } from "os";
24698
+ import { platform as platform5 } from "os";
24647
24699
  import { join as join32, resolve as resolve19, dirname as dirname9 } from "path";
24648
24700
  async function runScenario(scenario, opts) {
24649
24701
  if (scenario.mode === "skip") {
@@ -24754,7 +24806,7 @@ function killTree2(child) {
24754
24806
  const pid = child.pid;
24755
24807
  if (!pid)
24756
24808
  return;
24757
- if (platform4() === "win32") {
24809
+ if (platform5() === "win32") {
24758
24810
  spawn6("taskkill", ["/pid", String(pid), "/T", "/F"], {
24759
24811
  windowsHide: true,
24760
24812
  stdio: "ignore"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "micro-models-agent",
3
- "version": "0.28.2",
3
+ "version": "0.28.4",
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": {