micro-models-agent 0.33.0 → 0.33.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.
Files changed (2) hide show
  1. package/dist/main.js +159 -38
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -2634,6 +2634,7 @@ Available commands:`,
2634
2634
  "repl.skill_unknown_sub": "Unknown skill subcommand: {subcmd}",
2635
2635
  "repl.skill_usage": "Usage: /skill [list|loaded|load|unload|search]",
2636
2636
  "repl.agent": "Agent: ",
2637
+ "repl.you": "You: ",
2637
2638
  "repl.interrupt": "Interrupted (Esc)",
2638
2639
  "repl.title": "MMA REPL v{version}",
2639
2640
  "repl.model": "Model:",
@@ -3207,6 +3208,7 @@ var init_ru = __esm(() => {
3207
3208
  "repl.skill_unknown_sub": "Неизвестная подкоманда скилла: {subcmd}",
3208
3209
  "repl.skill_usage": "Использование: /skill [list|loaded|load|unload|search]",
3209
3210
  "repl.agent": "Агент: ",
3211
+ "repl.you": "Вы: ",
3210
3212
  "repl.interrupt": "Прервано (Esc)",
3211
3213
  "repl.title": "MMA REPL v{version}",
3212
3214
  "repl.model": "Модель:",
@@ -11382,12 +11384,15 @@ function isFilePathLike(s) {
11382
11384
  const lower = s.toLowerCase();
11383
11385
  if (TECH_NAMES.has(lower))
11384
11386
  return false;
11385
- if (!s.includes("/") && !s.includes("\\") && !/^\w+\.[a-z]{2,4}$/i.test(s))
11386
- return false;
11387
11387
  if (isJsMemberAccess(s))
11388
11388
  return false;
11389
11389
  const ext = s.split(".").pop()?.toLowerCase() || "";
11390
- return !NON_FILE_EXTENSIONS.has(ext);
11390
+ if (!s.includes("/") && !s.includes("\\")) {
11391
+ if (!/^\w+\.[a-z]{1,6}$/i.test(s))
11392
+ return false;
11393
+ return FILE_EXTENSIONS.has(ext);
11394
+ }
11395
+ return true;
11391
11396
  }
11392
11397
  function extractFileLikeTokens(text) {
11393
11398
  const matches = text.match(FILE_TOKEN_RE) || [];
@@ -11396,7 +11401,7 @@ function extractFileLikeTokens(text) {
11396
11401
  function stripUrls(text) {
11397
11402
  return text.replace(/\bhttps?:\/\/[^\s"'<>]+/gi, " ");
11398
11403
  }
11399
- var JS_GLOBALS, NON_FILE_EXTENSIONS, TECH_NAMES, FILE_TOKEN_RE;
11404
+ var JS_GLOBALS, FILE_EXTENSIONS, TECH_NAMES, FILE_TOKEN_RE;
11400
11405
  var init_js_identifiers = __esm(() => {
11401
11406
  JS_GLOBALS = new Set([
11402
11407
  "process",
@@ -11454,27 +11459,110 @@ var init_js_identifiers = __esm(() => {
11454
11459
  "deno",
11455
11460
  "node"
11456
11461
  ]);
11457
- NON_FILE_EXTENSIONS = new Set([
11458
- "com",
11459
- "org",
11460
- "net",
11461
- "gov",
11462
- "edu",
11463
- "io",
11464
- "dev",
11465
- "app",
11466
- "co",
11467
- "ai",
11468
- "ru",
11469
- "de",
11470
- "fr",
11471
- "uk",
11472
- "us",
11473
- "es",
11474
- "it",
11475
- "jp",
11476
- "cn",
11477
- "br"
11462
+ FILE_EXTENSIONS = new Set([
11463
+ "ts",
11464
+ "tsx",
11465
+ "js",
11466
+ "jsx",
11467
+ "mjs",
11468
+ "cjs",
11469
+ "py",
11470
+ "pyc",
11471
+ "rb",
11472
+ "go",
11473
+ "rs",
11474
+ "java",
11475
+ "jar",
11476
+ "kt",
11477
+ "kts",
11478
+ "c",
11479
+ "h",
11480
+ "cc",
11481
+ "cpp",
11482
+ "cxx",
11483
+ "hpp",
11484
+ "hh",
11485
+ "cs",
11486
+ "php",
11487
+ "swift",
11488
+ "m",
11489
+ "mm",
11490
+ "lua",
11491
+ "pl",
11492
+ "sh",
11493
+ "bash",
11494
+ "zsh",
11495
+ "fish",
11496
+ "bat",
11497
+ "cmd",
11498
+ "ps1",
11499
+ "vue",
11500
+ "svelte",
11501
+ "dart",
11502
+ "json",
11503
+ "jsonc",
11504
+ "json5",
11505
+ "yaml",
11506
+ "yml",
11507
+ "toml",
11508
+ "ini",
11509
+ "cfg",
11510
+ "conf",
11511
+ "env",
11512
+ "xml",
11513
+ "html",
11514
+ "htm",
11515
+ "md",
11516
+ "markdown",
11517
+ "rst",
11518
+ "txt",
11519
+ "log",
11520
+ "csv",
11521
+ "tsv",
11522
+ "lock",
11523
+ "sql",
11524
+ "sqlite",
11525
+ "db",
11526
+ "wasm",
11527
+ "map",
11528
+ "css",
11529
+ "scss",
11530
+ "sass",
11531
+ "less",
11532
+ "svg",
11533
+ "png",
11534
+ "jpg",
11535
+ "jpeg",
11536
+ "gif",
11537
+ "webp",
11538
+ "bmp",
11539
+ "ico",
11540
+ "avif",
11541
+ "tiff",
11542
+ "pdf",
11543
+ "doc",
11544
+ "docx",
11545
+ "xls",
11546
+ "xlsx",
11547
+ "ppt",
11548
+ "pptx",
11549
+ "odt",
11550
+ "ods",
11551
+ "zip",
11552
+ "gz",
11553
+ "tar",
11554
+ "tgz",
11555
+ "bz2",
11556
+ "xz",
11557
+ "7z",
11558
+ "rar",
11559
+ "bin",
11560
+ "exe",
11561
+ "dll",
11562
+ "so",
11563
+ "o",
11564
+ "a",
11565
+ "dylib"
11478
11566
  ]);
11479
11567
  TECH_NAMES = new Set([
11480
11568
  "node.js",
@@ -11488,7 +11576,7 @@ var init_js_identifiers = __esm(() => {
11488
11576
  "svelte.js",
11489
11577
  "jquery.js"
11490
11578
  ]);
11491
- FILE_TOKEN_RE = /\b(?:[a-zA-Z]:[\\/])?[\w./\\-]+\.[a-z]{2,6}\b/gi;
11579
+ FILE_TOKEN_RE = /\b(?:[a-zA-Z]:[\\/])?[\w./\\-]+\.[a-z]{1,6}\b/gi;
11492
11580
  });
11493
11581
 
11494
11582
  // src/modules/hallucination/factual.ts
@@ -12383,7 +12471,7 @@ var init_web_search = __esm(() => {
12383
12471
  init_session_isolation();
12384
12472
  webSearchTool = {
12385
12473
  name: "web_search",
12386
- description: "Search the web for information. Returns search results with titles and snippets.",
12474
+ description: "Search the web for information. Returns search results with titles and snippets. Use this for search queries instead of opening search engines (Google/Yandex/Bing) in the browser — they block headless browsers.",
12387
12475
  tags: ["research"],
12388
12476
  parameters: {
12389
12477
  type: "object",
@@ -12467,7 +12555,7 @@ var init_web_fetch = __esm(() => {
12467
12555
  init_security();
12468
12556
  webFetchTool = {
12469
12557
  name: "web_fetch",
12470
- description: "Fetch a URL and convert its content to markdown. Use for reading documentation, APIs, web pages.",
12558
+ description: 'Fetch a URL and convert its content to markdown. Use for reading documentation, APIs, web pages. This is a plain HTTP request without a browser engine — it does NOT run JavaScript, so JS-rendered single-page apps (weather sites, dashboards, modern SPAs) return empty or near-empty content; use the "browser" tool for those.',
12471
12559
  tags: ["research"],
12472
12560
  parameters: {
12473
12561
  type: "object",
@@ -12553,7 +12641,7 @@ var init_web_browse = __esm(() => {
12553
12641
  init_session_isolation();
12554
12642
  webBrowseTool = {
12555
12643
  name: "web_browse",
12556
- description: `Fetch and read a web page. Returns the page content as plain text (max ${MAX_PREVIEW_LINES} lines / ${MAX_CHARS2} chars).`,
12644
+ description: `Fetch and read a web page. Returns the page content as plain text (max ${MAX_PREVIEW_LINES} lines / ${MAX_CHARS2} chars). This is a plain HTTP request — it does NOT execute JavaScript, so JS-rendered single-page apps (weather sites, dashboards, modern SPAs) return empty or near-empty content. For such pages use the "browser" tool instead.`,
12557
12645
  tags: ["research"],
12558
12646
  parameters: {
12559
12647
  type: "object",
@@ -14653,6 +14741,8 @@ function createBrowserTool() {
14653
14741
  tags: ["browser", "vision"],
14654
14742
  description: [
14655
14743
  "Control a headless browser. Navigate pages, click elements, type text, scroll, take screenshots.",
14744
+ "Runs a real browser with JavaScript enabled — use it for JS-rendered sites (weather, dashboards, SPAs) where web_fetch/web_browse return empty content.",
14745
+ "Do NOT use it for search queries: search engines (Google, Yandex, Bing) block headless browsers with CAPTCHA/429/redirect pages — use the web_search tool for searching.",
14656
14746
  "Each snapshot returns: a numbered list of interactive elements, the visible page text (Content section), browser console messages, and network errors.",
14657
14747
  "Use the Content section to understand what the page says; use element numbers as targets for click/type.",
14658
14748
  "Actions: open (url), click (target), type (target, text), scroll (direction), back, forward, screenshot, snapshot, close, wait (ms)."
@@ -28715,6 +28805,7 @@ class LineEditor {
28715
28805
  questionCb = null;
28716
28806
  rawMode = false;
28717
28807
  listeners = {};
28808
+ prevCursorRow = 0;
28718
28809
  constructor(opts) {
28719
28810
  this.input = opts.input;
28720
28811
  this.output = opts.output;
@@ -28772,6 +28863,7 @@ class LineEditor {
28772
28863
  this.col = 0;
28773
28864
  this.historyIndex = -1;
28774
28865
  this.stash = null;
28866
+ this.prevCursorRow = 0;
28775
28867
  if (this.input.isTTY)
28776
28868
  this.render();
28777
28869
  }
@@ -28781,6 +28873,7 @@ class LineEditor {
28781
28873
  this.lines = [""];
28782
28874
  this.row = 0;
28783
28875
  this.col = 0;
28876
+ this.prevCursorRow = 0;
28784
28877
  if (this.input.isTTY)
28785
28878
  this.render();
28786
28879
  }
@@ -28981,10 +29074,13 @@ class LineEditor {
28981
29074
  this.questionCb = null;
28982
29075
  const answer = this.lines.join(`
28983
29076
  `).trim();
29077
+ this.commitFrame();
29078
+ this.output.write(`\r
29079
+ `);
28984
29080
  this.lines = [""];
28985
29081
  this.row = 0;
28986
29082
  this.col = 0;
28987
- this.render();
29083
+ this.prevCursorRow = 0;
28988
29084
  cb(answer);
28989
29085
  return;
28990
29086
  }
@@ -28998,16 +29094,33 @@ class LineEditor {
28998
29094
  }
28999
29095
  this.historyIndex = -1;
29000
29096
  this.stash = null;
29097
+ this.commitFrame();
29098
+ this.output.write(`\r
29099
+ `);
29001
29100
  this.lines = [""];
29002
29101
  this.row = 0;
29003
29102
  this.col = 0;
29004
- this.render();
29103
+ this.prevCursorRow = 0;
29005
29104
  this.emitLine(text);
29006
29105
  }
29106
+ commitFrame() {
29107
+ const layout = this.layout();
29108
+ const idx = layoutIndexFor(layout, this.row, this.col);
29109
+ const rowsDown = layout.length - 1 - idx;
29110
+ const lastLen = charLen(stripAnsi2(layout[layout.length - 1].text));
29111
+ const out = [];
29112
+ if (rowsDown > 0)
29113
+ out.push(`\x1B[${rowsDown}B`);
29114
+ out.push("\r");
29115
+ if (lastLen > 0)
29116
+ out.push(`\x1B[${lastLen}C`);
29117
+ this.output.write(out.join(""));
29118
+ }
29007
29119
  ctrlC() {
29008
29120
  this.lines = [""];
29009
29121
  this.row = 0;
29010
29122
  this.col = 0;
29123
+ this.prevCursorRow = 0;
29011
29124
  this.render();
29012
29125
  process.emit("SIGINT");
29013
29126
  }
@@ -29257,6 +29370,7 @@ class LineEditor {
29257
29370
  }
29258
29371
  clearScreen() {
29259
29372
  this.output.write("\x1B[2J\x1B[H");
29373
+ this.prevCursorRow = 0;
29260
29374
  this.render();
29261
29375
  }
29262
29376
  columns() {
@@ -29274,7 +29388,10 @@ class LineEditor {
29274
29388
  const vcol = visualColAt(layout, idx, this.col);
29275
29389
  const rowsAfter = layout.length - idx - 1;
29276
29390
  const ccol = (idx === 0 ? promptWidth : 0) + vcol;
29277
- const out = ["\r"];
29391
+ const out = [];
29392
+ if (this.prevCursorRow > 0)
29393
+ out.push(`\x1B[${this.prevCursorRow}A`);
29394
+ out.push("\r");
29278
29395
  for (let i = 0;i < layout.length; i++) {
29279
29396
  out.push("\x1B[2K");
29280
29397
  if (i === 0)
@@ -29290,6 +29407,7 @@ class LineEditor {
29290
29407
  out.push("\r");
29291
29408
  if (ccol > 0)
29292
29409
  out.push(`\x1B[${ccol}C`);
29410
+ this.prevCursorRow = idx;
29293
29411
  this.output.write(out.join(""));
29294
29412
  }
29295
29413
  enableTerminalProtocols() {
@@ -29886,7 +30004,7 @@ class Repl {
29886
30004
  this.rl = process.stdin.isTTY ? new LineEditor({
29887
30005
  input: process.stdin,
29888
30006
  output: process.stdout,
29889
- prompt: pc2.cyan("> "),
30007
+ prompt: pc2.cyan(t("repl.you")),
29890
30008
  history: this.history,
29891
30009
  historySize: this.maxHistory,
29892
30010
  completer: (line) => {
@@ -29898,7 +30016,7 @@ class Repl {
29898
30016
  }) : readline3.createInterface({
29899
30017
  input: process.stdin,
29900
30018
  output: process.stdout,
29901
- prompt: pc2.cyan("> "),
30019
+ prompt: pc2.cyan(t("repl.you")),
29902
30020
  history: this.history,
29903
30021
  historySize: this.maxHistory,
29904
30022
  tabSize: 2,
@@ -29981,11 +30099,11 @@ class Repl {
29981
30099
  }
29982
30100
  }
29983
30101
  if (this.running) {
29984
- this.rl.setPrompt(pc2.cyan("> "));
30102
+ this.rl.setPrompt(pc2.cyan(t("repl.you")));
29985
30103
  this.rl.prompt();
29986
30104
  }
29987
30105
  } else {
29988
- this.rl.setPrompt(pc2.cyan("... "));
30106
+ this.rl.setPrompt(pc2.cyan(t("repl.you") + "… "));
29989
30107
  this.rl.prompt();
29990
30108
  }
29991
30109
  return;
@@ -29993,7 +30111,7 @@ class Repl {
29993
30111
  if (this.isMultiLineInput(trimmed)) {
29994
30112
  inMultiLine = true;
29995
30113
  multiLineBuffer = trimmed;
29996
- this.rl.setPrompt(pc2.cyan("... "));
30114
+ this.rl.setPrompt(pc2.cyan(t("repl.you") + "… "));
29997
30115
  this.rl.prompt();
29998
30116
  return;
29999
30117
  }
@@ -30115,7 +30233,7 @@ ${t("image.clipboard_empty")}`));
30115
30233
  this.logger?.logREPL("user", input);
30116
30234
  if (this.rl instanceof LineEditor)
30117
30235
  this.rl.reset();
30118
- process.stdout.write(`
30236
+ process.stdout.write("\r" + divider() + `
30119
30237
  ` + pc2.green(t("repl.agent")));
30120
30238
  const renderer = new Renderer({
30121
30239
  spinner: this.config.ui?.spinner ?? true,
@@ -30142,6 +30260,9 @@ ${t("image.clipboard_empty")}`));
30142
30260
  console.error(pc2.red(`${t("error.prefix")}${result.error}`));
30143
30261
  }
30144
30262
  this.showContextBar(result);
30263
+ process.stdout.write(`
30264
+ ` + divider() + `
30265
+ `);
30145
30266
  } finally {
30146
30267
  this.agentRunning = false;
30147
30268
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "micro-models-agent",
3
- "version": "0.33.0",
3
+ "version": "0.33.2",
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": {