micro-models-agent 0.43.3 → 0.44.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 +92 -10
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -6292,6 +6292,7 @@ var init_read_file = __esm(() => {
6292
6292
  init_path_utils();
6293
6293
  readFileTool = {
6294
6294
  name: "read_file",
6295
+ icon: "\uD83D\uDC40",
6295
6296
  description: `Read a file from the filesystem. Reads up to ${DEFAULT_LIMIT} lines at a time by default; use offset to page through large files.`,
6296
6297
  tags: ["file", "code"],
6297
6298
  boundedOutput: true,
@@ -6661,6 +6662,7 @@ var init_write_file = __esm(() => {
6661
6662
  init_path_utils();
6662
6663
  writeFileTool = {
6663
6664
  name: "write_file",
6665
+ icon: "\uD83D\uDCDD",
6664
6666
  description: "Create or overwrite a file with given content. Creates intermediate directories if needed.",
6665
6667
  tags: ["file", "code"],
6666
6668
  parameters: {
@@ -6736,6 +6738,7 @@ var init_edit_file = __esm(() => {
6736
6738
  init_path_utils();
6737
6739
  editFileTool = {
6738
6740
  name: "edit_file",
6741
+ icon: "✏️",
6739
6742
  description: "Find and replace text in an existing file. Uses exact string match (not regex).",
6740
6743
  tags: ["file", "code"],
6741
6744
  parameters: {
@@ -6809,6 +6812,7 @@ var init_glob_tool = __esm(() => {
6809
6812
  init_i18n();
6810
6813
  globTool = {
6811
6814
  name: "glob",
6815
+ icon: "\uD83D\uDD0E",
6812
6816
  description: `Search for files matching a glob pattern. Shows up to ${MAX_PREVIEW_LINES} results by default. Uses standard glob syntax (e.g., **/*.ts, src/**/*.test.ts).`,
6813
6817
  tags: ["file", "code", "research"],
6814
6818
  parameters: {
@@ -6850,6 +6854,7 @@ var init_grep_tool = __esm(() => {
6850
6854
  init_audit_log();
6851
6855
  grepTool = {
6852
6856
  name: "grep",
6857
+ icon: "\uD83D\uDD0D",
6853
6858
  description: `Search file contents using a regular expression. Shows up to ${MAX_PREVIEW_LINES} matching lines by default. Uses ripgrep (rg) if available, otherwise falls back to grep -r.`,
6854
6859
  tags: ["file", "code", "research"],
6855
6860
  parameters: {
@@ -6925,6 +6930,7 @@ var init_list_dir = __esm(() => {
6925
6930
  init_path_utils();
6926
6931
  listDirTool = {
6927
6932
  name: "list_dir",
6933
+ icon: "\uD83D\uDCC2",
6928
6934
  description: `List files and directories in a given path. Shows up to ${MAX_PREVIEW_LINES} entries by default.`,
6929
6935
  tags: ["file"],
6930
6936
  boundedOutput: true,
@@ -6977,6 +6983,7 @@ var init_create_dir = __esm(() => {
6977
6983
  init_path_utils();
6978
6984
  createDirTool = {
6979
6985
  name: "create_dir",
6986
+ icon: "\uD83D\uDCC1",
6980
6987
  description: "Create a directory (and any intermediate directories).",
6981
6988
  tags: ["file"],
6982
6989
  parameters: {
@@ -7031,6 +7038,7 @@ var init_delete_file = __esm(() => {
7031
7038
  init_path_utils();
7032
7039
  deleteFileTool = {
7033
7040
  name: "delete_file",
7041
+ icon: "\uD83D\uDDD1️",
7034
7042
  description: "Delete a file from the filesystem.",
7035
7043
  tags: ["file"],
7036
7044
  parameters: {
@@ -7092,6 +7100,7 @@ var init_move_file = __esm(() => {
7092
7100
  init_path_utils();
7093
7101
  moveFileTool = {
7094
7102
  name: "move_file",
7103
+ icon: "\uD83D\uDCE6",
7095
7104
  description: "Move or rename a file or directory.",
7096
7105
  tags: ["file"],
7097
7106
  parameters: {
@@ -7170,6 +7179,7 @@ var init_file_info = __esm(() => {
7170
7179
  init_path_utils();
7171
7180
  fileInfoTool = {
7172
7181
  name: "file_info",
7182
+ icon: "ℹ️",
7173
7183
  description: "Get metadata about a file or directory (size, creation date, modification date).",
7174
7184
  tags: ["file"],
7175
7185
  boundedOutput: true,
@@ -7844,6 +7854,7 @@ var init_bash = __esm(() => {
7844
7854
  NPM_EXEC_RE = /could not determine executable to run/i;
7845
7855
  bashTool = {
7846
7856
  name: "bash",
7857
+ icon: "\uD83D\uDCBB",
7847
7858
  description: `Execute a shell command and return its output. Use for running tests, build, git, and shell operations. Commands that are still running after a few seconds are automatically moved to the background and return a process id — manage them with process_list, process_log, process_kill. Set background=true to return a process id immediately for commands you know are long-running (dev servers, watchers).
7848
7859
 
7849
7860
  Windows notes: the shell is cmd.exe — PowerShell cmdlets (Write-Host, Get-Content, Select-String, Out-File) and bash heredocs (cat << EOF) do NOT work there. Use the read_file/write_file tools instead of cat/echo redirection. Sequential commands: use && (a leading ; is auto-converted to &).`,
@@ -8012,6 +8023,7 @@ var init_process_list = __esm(() => {
8012
8023
  init_i18n();
8013
8024
  processListTool = {
8014
8025
  name: "process_list",
8026
+ icon: "\uD83D\uDCCA",
8015
8027
  description: "List background processes started via the bash tool (dev servers, watchers, long-running commands). Shows id, pid, command, status, and recent output. Use with process_log and process_kill to inspect or stop them.",
8016
8028
  tags: ["shell"],
8017
8029
  parameters: {
@@ -8056,6 +8068,7 @@ var init_process_log = __esm(() => {
8056
8068
  DEFAULT_TAIL = MAX_PREVIEW_LINES;
8057
8069
  processLogTool = {
8058
8070
  name: "process_log",
8071
+ icon: "\uD83D\uDCDC",
8059
8072
  description: `Show the buffered output of a background process started via bash. Shows the last ${DEFAULT_TAIL} lines by default. Use after starting a dev server to verify it came up without errors, and while it runs to check its state.`,
8060
8073
  tags: ["shell"],
8061
8074
  boundedOutput: true,
@@ -8101,6 +8114,7 @@ var init_process_kill = __esm(() => {
8101
8114
  init_i18n();
8102
8115
  processKillTool = {
8103
8116
  name: "process_kill",
8117
+ icon: "⛔",
8104
8118
  description: "Stop a background process started via bash (dev server, watcher). Kills the whole process tree (children included). Use the id returned by bash or process_list.",
8105
8119
  tags: ["shell"],
8106
8120
  parameters: {
@@ -11536,6 +11550,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
11536
11550
  if (result) {
11537
11551
  logger.debug("Context compacted");
11538
11552
  slog.logCompaction({ reason: "interval", iteration, ...result });
11553
+ hallucinationDetector.addKnownFiles(contextManager.getKnownFiles());
11539
11554
  }
11540
11555
  }
11541
11556
  const currentTokens = contextManager.getEstimatedTokens();
@@ -11551,6 +11566,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
11551
11566
  iteration,
11552
11567
  ...result
11553
11568
  });
11569
+ hallucinationDetector.addKnownFiles(contextManager.getKnownFiles());
11554
11570
  }
11555
11571
  }
11556
11572
  if (currentTokens > budget2.history) {
@@ -11562,6 +11578,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
11562
11578
  iteration,
11563
11579
  ...result
11564
11580
  });
11581
+ hallucinationDetector.addKnownFiles(contextManager.getKnownFiles());
11565
11582
  }
11566
11583
  }
11567
11584
  this.refreshSystemPrompt();
@@ -11713,6 +11730,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
11713
11730
  });
11714
11731
  const summaries = [];
11715
11732
  let anyToolFailed = false;
11733
+ const infoTools = new Set(["file_info"]);
11716
11734
  for (const call of toolCalls) {
11717
11735
  this.setScope();
11718
11736
  const startTime = Date.now();
@@ -11721,14 +11739,15 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
11721
11739
  args: call.arguments
11722
11740
  });
11723
11741
  pluginManager.runOnToolStart({ iteration, logger, contextManager }, { id: call.id, name: call.name, arguments: call.arguments });
11724
- onTool?.({ type: "start", tool: call.name, args: call.arguments });
11742
+ const toolIcon = this.deps.toolExecutor.getRegistry().get(call.name)?.icon;
11743
+ onTool?.({ type: "start", tool: call.name, args: call.arguments, icon: toolIcon });
11725
11744
  slog.logToolCall(call, iteration);
11726
11745
  const tokensBeforeTool = contextManager.getEstimatedTokens();
11727
11746
  const result = await toolExecutor.execute(call, this.abortController?.signal);
11728
11747
  if (this.shutdownRequested)
11729
11748
  break;
11730
11749
  const duration = Date.now() - startTime;
11731
- if (!result.success)
11750
+ if (!result.success && !infoTools.has(call.name))
11732
11751
  anyToolFailed = true;
11733
11752
  if (result.success && call.arguments.path) {
11734
11753
  const filePath = String(call.arguments.path);
@@ -11787,9 +11806,10 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
11787
11806
  iteration,
11788
11807
  ...result2
11789
11808
  });
11809
+ hallucinationDetector.addKnownFiles(contextManager.getKnownFiles());
11790
11810
  }
11791
11811
  }
11792
- if (!result.success) {
11812
+ if (!result.success && !infoTools.has(call.name)) {
11793
11813
  const key = call.name;
11794
11814
  const prev = toolFailureCounts.get(key) ?? { count: 0, error: "" };
11795
11815
  prev.count++;
@@ -12184,6 +12204,10 @@ class FactExtractor {
12184
12204
  return null;
12185
12205
  return `[Files: ${liveFiles.slice(-15).join("; ")}]`;
12186
12206
  }
12207
+ getKnownFiles() {
12208
+ const deletedSet = new Set(this.deletedFacts);
12209
+ return this.fileFacts.filter((p) => !deletedSet.has(p));
12210
+ }
12187
12211
  deletedLine() {
12188
12212
  if (this.deletedFacts.length === 0)
12189
12213
  return null;
@@ -12308,6 +12332,9 @@ class ContextManager {
12308
12332
  getIterationsSinceCompaction() {
12309
12333
  return this.iterationsSinceCompaction;
12310
12334
  }
12335
+ getKnownFiles() {
12336
+ return this.facts.getKnownFiles();
12337
+ }
12311
12338
  noteIteration() {
12312
12339
  this.iterationsSinceCompaction++;
12313
12340
  }
@@ -12647,9 +12674,14 @@ class FactualCheck {
12647
12674
  static NAME_CACHE_TTL_MS = 5000;
12648
12675
  static RESCAN_COOLDOWN_MS = 2000;
12649
12676
  static MAX_INDEXED_FILES = 20000;
12677
+ knownFiles = new Set;
12650
12678
  constructor(baseDir) {
12651
12679
  this.baseDir = baseDir;
12652
12680
  }
12681
+ addKnownFiles(files) {
12682
+ for (const f of files)
12683
+ this.knownFiles.add(f);
12684
+ }
12653
12685
  validate(response) {
12654
12686
  const filePaths = this.extractFilePaths(response);
12655
12687
  if (filePaths.length === 0)
@@ -12673,6 +12705,8 @@ class FactualCheck {
12673
12705
  pathExists(fp) {
12674
12706
  if (isAbsolute2(fp))
12675
12707
  return existsSync23(fp);
12708
+ if (this.knownFiles.has(fp))
12709
+ return true;
12676
12710
  if (!fp.includes("/") && !fp.includes("\\")) {
12677
12711
  return this.bareNameExists(fp);
12678
12712
  }
@@ -12683,6 +12717,11 @@ class FactualCheck {
12683
12717
  return true;
12684
12718
  if (this.indexHas(name))
12685
12719
  return true;
12720
+ for (const known of this.knownFiles) {
12721
+ if (known.endsWith(`/${name}`) || known.endsWith(`\\${name}`) || known === name) {
12722
+ return true;
12723
+ }
12724
+ }
12686
12725
  const now = Date.now();
12687
12726
  if (now - this.lastRescan < FactualCheck.RESCAN_COOLDOWN_MS)
12688
12727
  return false;
@@ -12862,6 +12901,9 @@ class HallucinationDetector {
12862
12901
  getConfidenceCheck() {
12863
12902
  return this.confidence;
12864
12903
  }
12904
+ addKnownFiles(files) {
12905
+ this.factual?.addKnownFiles(files);
12906
+ }
12865
12907
  async validate(response) {
12866
12908
  const confidenceResult = this.confidence.validate(response);
12867
12909
  if (confidenceResult.status === "retry" || confidenceResult.status === "block") {
@@ -13208,6 +13250,7 @@ var init_subagent = __esm(() => {
13208
13250
  init_store();
13209
13251
  subagentTool = {
13210
13252
  name: "subagent",
13253
+ icon: "\uD83E\uDD16",
13211
13254
  description: "Spawn an isolated sub-agent to work on a task independently. The sub-agent has its own context and executes autonomously. Use for parallel work or complex sub-tasks.",
13212
13255
  tags: ["code"],
13213
13256
  parameters: {
@@ -13506,6 +13549,7 @@ var init_chunk_query = __esm(() => {
13506
13549
  init_scope_check();
13507
13550
  chunkQueryTool = {
13508
13551
  name: "chunk_query",
13552
+ icon: "\uD83E\uDDE9",
13509
13553
  description: "Answer a query over a large text (file or inline) by splitting it into chunks and querying the model per chunk in parallel, then optionally synthesizing a final answer. Use when the input is too large for the context window.",
13510
13554
  tags: ["research", "code"],
13511
13555
  timeoutMs: 300000,
@@ -13705,6 +13749,7 @@ var init_web_search = __esm(() => {
13705
13749
  init_session_isolation();
13706
13750
  webSearchTool = {
13707
13751
  name: "web_search",
13752
+ icon: "\uD83C\uDF0D",
13708
13753
  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.",
13709
13754
  tags: ["research"],
13710
13755
  parameters: {
@@ -13772,6 +13817,7 @@ var init_web_fetch = __esm(() => {
13772
13817
  init_security();
13773
13818
  webFetchTool = {
13774
13819
  name: "web_fetch",
13820
+ icon: "⬇️",
13775
13821
  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.',
13776
13822
  tags: ["research"],
13777
13823
  parameters: {
@@ -13858,6 +13904,7 @@ var init_web_browse = __esm(() => {
13858
13904
  init_session_isolation();
13859
13905
  webBrowseTool = {
13860
13906
  name: "web_browse",
13907
+ icon: "\uD83C\uDF10",
13861
13908
  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.`,
13862
13909
  tags: ["research"],
13863
13910
  parameters: {
@@ -13942,6 +13989,7 @@ var init_download_file = __esm(() => {
13942
13989
  MAX_DOWNLOAD_BYTES = 100 * 1024 * 1024;
13943
13990
  downloadFileTool = {
13944
13991
  name: "download_file",
13992
+ icon: "⬇️",
13945
13993
  description: "Download a file (image, archive, binary, font, etc.) from a URL and save it to disk. Returns only the path, size and content type — read the saved file with read_file/attach_image afterwards. Use this for binary files; web_fetch/web_browse return text only and cannot save bytes.",
13946
13994
  tags: ["file", "research"],
13947
13995
  parameters: {
@@ -14045,6 +14093,7 @@ var init_download_file = __esm(() => {
14045
14093
  function createLoadSkillTool(skillsModule) {
14046
14094
  return {
14047
14095
  name: "load_skill",
14096
+ icon: "\uD83C\uDFAF",
14048
14097
  tags: ["core"],
14049
14098
  description: "Load a skill by name. Skills provide specialized instructions and workflows. When loaded, the skill content is injected into the system prompt (not conversation history) so it persists through context compaction. Only use when the task clearly requires domain-specific knowledge.",
14050
14099
  parameters: {
@@ -14276,6 +14325,7 @@ var init_pipeline_run = __esm(() => {
14276
14325
  engine = new PipelineEngine;
14277
14326
  pipelineRunTool = {
14278
14327
  name: "pipeline_run",
14328
+ icon: "▶️",
14279
14329
  description: "Run a named pipeline with YAML definition. Creates a DAG of sub-agents that execute in dependency order.",
14280
14330
  tags: ["shell", "code"],
14281
14331
  parameters: {
@@ -14807,6 +14857,7 @@ var init_mcp_call = __esm(() => {
14807
14857
  registry = new MCPRegistry;
14808
14858
  mcpCallTool = {
14809
14859
  name: "mcp_call",
14860
+ icon: "\uD83D\uDD17",
14810
14861
  description: "Call a tool on an MCP (Model Context Protocol) server. MCP servers provide external capabilities like databases, APIs, or specialized tools.",
14811
14862
  tags: ["code", "research"],
14812
14863
  parameters: {
@@ -14876,6 +14927,7 @@ var init_search_history = __esm(() => {
14876
14927
  init_i18n();
14877
14928
  searchHistoryTool = {
14878
14929
  name: "search_history",
14930
+ icon: "\uD83D\uDD75️",
14879
14931
  description: "Search through session history for past interactions across all sessions.",
14880
14932
  tags: ["research"],
14881
14933
  parameters: {
@@ -15072,6 +15124,7 @@ var init_remember = __esm(() => {
15072
15124
  CATEGORIES = ["preferences", "conventions", "decisions", "errors", "facts"];
15073
15125
  rememberTool = {
15074
15126
  name: "remember",
15127
+ icon: "\uD83E\uDDE0",
15075
15128
  description: "Remember information across sessions. Use for user preferences, facts, conventions, decisions, or errors.",
15076
15129
  tags: ["memory"],
15077
15130
  parameters: {
@@ -15199,6 +15252,7 @@ var init_recall = __esm(() => {
15199
15252
  CATEGORIES2 = ["preferences", "conventions", "decisions", "errors", "facts"];
15200
15253
  recallTool = {
15201
15254
  name: "recall",
15255
+ icon: "\uD83D\uDCBE",
15202
15256
  description: "Recall stored information from memory. Search across preferences, facts, conventions, decisions, errors.",
15203
15257
  tags: ["memory"],
15204
15258
  parameters: {
@@ -16228,6 +16282,7 @@ function formatScreenshotResult(snapshot, screenshot, supportsVision) {
16228
16282
  function createBrowserTool() {
16229
16283
  return {
16230
16284
  name: "browser",
16285
+ icon: "\uD83C\uDF10",
16231
16286
  tags: ["browser", "vision"],
16232
16287
  description: [
16233
16288
  "Control a headless browser. Navigate pages, click elements, type text, scroll, take screenshots.",
@@ -16432,6 +16487,7 @@ var init_attach_image = __esm(() => {
16432
16487
  init_audit_log();
16433
16488
  attachImageTool = {
16434
16489
  name: "attach_image",
16490
+ icon: "\uD83D\uDDBC️",
16435
16491
  description: "Attach an image to the conversation from a file path, URL, or clipboard. The image will be included in the next message sent to the model. Supports PNG, JPEG, GIF, WebP.",
16436
16492
  tags: ["vision", "image"],
16437
16493
  parameters: {
@@ -16517,6 +16573,7 @@ var init_enable_tools = __esm(() => {
16517
16573
  init_i18n();
16518
16574
  enableToolsTool = {
16519
16575
  name: "enable_tools",
16576
+ icon: "\uD83D\uDD0C",
16520
16577
  description: "Enable hidden tool categories for the current session. Only the essential tools (file/code/shell) are active by default. Call this with the tags you need and they become available from the next turn. Available tags: file, code, shell, research, browser, vision, image, memory, core. Returns the newly available tools. To run a task in a separate context instead, use subagent with tool_tags.",
16521
16578
  alwaysOn: true,
16522
16579
  parameters: {
@@ -17741,6 +17798,7 @@ function createPlanToolDefinitions(deps) {
17741
17798
  return [
17742
17799
  {
17743
17800
  name: "plan",
17801
+ icon: "\uD83D\uDCCB",
17744
17802
  alwaysOn: true,
17745
17803
  description: `Create, update, show, abort, list, switch, delete, purge, or re-plan multi-step plans.
17746
17804
 
@@ -18017,6 +18075,20 @@ ${progress2}`,
18017
18075
  };
18018
18076
  }
18019
18077
  }
18078
+ if (status === "done" && target.kind !== "delete") {
18079
+ const missing = deps.missingStepDeliverables(target);
18080
+ if (missing.length > 0) {
18081
+ const existing = deps.stillExistingDeliverables(target);
18082
+ const allGone = deps.hasStepDeliverables(target) && existing.length === 0;
18083
+ if (allGone) {
18084
+ const wasDeleted = deps.wasFileDeleted ? missing.every((f) => deps.wasFileDeleted(f)) : false;
18085
+ if (wasDeleted) {
18086
+ target.kind = "delete";
18087
+ deps.store.saveActive(tracker.getPlan());
18088
+ }
18089
+ }
18090
+ }
18091
+ }
18020
18092
  if (status === "done") {
18021
18093
  if (target.kind === "delete") {
18022
18094
  const leftovers = deps.stillExistingDeliverables(target);
@@ -18186,6 +18258,7 @@ ${progress}${vacuousNote}`,
18186
18258
  },
18187
18259
  {
18188
18260
  name: "todo",
18261
+ icon: "☑️",
18189
18262
  alwaysOn: true,
18190
18263
  description: "Manage sub-tasks within current plan step. Use to break down complex steps into smaller tasks.",
18191
18264
  parameters: {
@@ -18282,6 +18355,7 @@ ${lines.join(`
18282
18355
  },
18283
18356
  {
18284
18357
  name: "verify",
18358
+ icon: "✅",
18285
18359
  alwaysOn: true,
18286
18360
  description: "Run verification for the current step. Checks files mentioned in the step description.",
18287
18361
  parameters: {
@@ -18342,6 +18416,7 @@ class ExecutionModule {
18342
18416
  retryWebSearchSignatures = new Set;
18343
18417
  lastErrorSearchAt = 0;
18344
18418
  errorSearchCooldownMs;
18419
+ hallucinationDetector = null;
18345
18420
  state = {
18346
18421
  lastRecoveryIteration: -STUCK_RECOVERY_COOLDOWN,
18347
18422
  consecutivePlanWarnings: 0,
@@ -18380,6 +18455,9 @@ class ExecutionModule {
18380
18455
  this.completedPlan = null;
18381
18456
  this._auditSkipsRemaining = 0;
18382
18457
  }
18458
+ setHallucinationDetector(detector) {
18459
+ this.hallucinationDetector = detector;
18460
+ }
18383
18461
  recordCompleted(plan) {
18384
18462
  this.completedPlan = plan;
18385
18463
  }
@@ -18534,7 +18612,8 @@ class ExecutionModule {
18534
18612
  parseKinds: (a, st) => this.parseKinds(a, st),
18535
18613
  getTaskText: (c) => this.getTaskText(c),
18536
18614
  typecheckFailures: this.state.typecheckFailures,
18537
- baseDir: this.baseDir
18615
+ baseDir: this.baseDir,
18616
+ wasFileDeleted: this.hallucinationDetector ? (path) => this.hallucinationDetector.getConsistencyCheck().getDeletedFiles().includes(path) : undefined
18538
18617
  });
18539
18618
  }
18540
18619
  getPlugin() {
@@ -20067,6 +20146,7 @@ ${items}`;
20067
20146
  return [
20068
20147
  {
20069
20148
  name: "lsp_check",
20149
+ icon: "\uD83E\uDE7A",
20070
20150
  description: 'Run static checks (LSP diagnostics) on a file or directory. For "check for errors" tasks: pass a file to check it, or a directory to check its source files (capped at 15). Returns [LSP errors] / [LSP warnings] for files with a configured LSP server.',
20071
20151
  tags: ["code", "check"],
20072
20152
  alwaysOn: true,
@@ -20801,6 +20881,7 @@ ${t("indexer.and_more", { count: result.files.length - 100 })}` : "";
20801
20881
  createProjectMapTool() {
20802
20882
  return {
20803
20883
  name: "project_map",
20884
+ icon: "\uD83D\uDDFA️",
20804
20885
  alwaysOn: true,
20805
20886
  description: t("indexer.project_map_desc"),
20806
20887
  parameters: {
@@ -21327,6 +21408,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
21327
21408
  execModule.restorePlan();
21328
21409
  }
21329
21410
  moduleRegistry.register(execModule);
21411
+ execModule.setHallucinationDetector(hallucinationDetector);
21330
21412
  const sessionModule = new SessionModule(sessionManager);
21331
21413
  moduleRegistry.register(sessionModule);
21332
21414
  moduleRegistry.register(indexerModule);
@@ -32686,20 +32768,20 @@ class Renderer {
32686
32768
  thinkingEnd() {
32687
32769
  this.spinner.stop();
32688
32770
  }
32689
- toolStart(tool, args, stepContext) {
32771
+ toolStart(tool, args, stepContext, icon) {
32690
32772
  this.endCard();
32691
32773
  this.spinner.stop();
32692
32774
  const summary = summarizeArgs2(args);
32693
32775
  const step = stepContext ? ` ${pc2.cyan(`← ${stepContext}`)}` : "";
32776
+ const marker = icon || toolMarker(tool);
32694
32777
  if (!this.rich) {
32695
32778
  this.out.write(`
32696
- ${pc2.dim("⚙")} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}${step}
32779
+ ${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}${step}
32697
32780
  `);
32698
32781
  return;
32699
32782
  }
32700
32783
  this.card = { tool, args, body: [], start: Date.now() };
32701
32784
  if (this.toolStyle === "inline") {
32702
- const marker = toolMarker(tool);
32703
32785
  this.out.write(`
32704
32786
  ${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}${step}
32705
32787
  `);
@@ -32708,7 +32790,7 @@ ${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
32708
32790
  }
32709
32791
  return;
32710
32792
  }
32711
- this.spinner.start(`${pc2.dim("⚙")} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}${step}`);
32793
+ this.spinner.start(`${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}${step}`);
32712
32794
  }
32713
32795
  planBlock(lines) {
32714
32796
  this.endCard();
@@ -33268,7 +33350,7 @@ ${t("image.clipboard_empty")}`));
33268
33350
  this.refreshActivePlan(renderer);
33269
33351
  const result = await this.agent.run(input, (c) => renderer.text(c), (m) => renderer.meta(m), (ev) => {
33270
33352
  if (ev.type === "start") {
33271
- renderer.toolStart(ev.tool, ev.args, stepContextForTool(this.activePlan, ev.tool, ev.args));
33353
+ renderer.toolStart(ev.tool, ev.args, stepContextForTool(this.activePlan, ev.tool, ev.args), ev.icon);
33272
33354
  } else {
33273
33355
  renderer.toolEnd(ev.tool, ev.duration ?? 0, ev.error, ev.ctxDelta);
33274
33356
  if (ev.tool === "plan" || ev.tool === "todo") {
@@ -33714,7 +33796,7 @@ async function main() {
33714
33796
  });
33715
33797
  const result = await agent.run(prompt, (chunk) => renderer.text(chunk), (meta) => renderer.meta(meta), (ev) => {
33716
33798
  if (ev.type === "start") {
33717
- renderer.toolStart(ev.tool, ev.args);
33799
+ renderer.toolStart(ev.tool, ev.args, undefined, ev.icon);
33718
33800
  } else {
33719
33801
  renderer.toolEnd(ev.tool, ev.duration ?? 0, ev.error, ev.ctxDelta);
33720
33802
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "micro-models-agent",
3
- "version": "0.43.3",
3
+ "version": "0.44.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": {