micro-models-agent 0.16.2 → 0.16.3
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/dist/modules/execution/stuck-detector.js +6 -4
- package/dist/tools/bash.js +1 -1
- package/dist/tools/glob-tool.js +1 -1
- package/dist/tools/grep-tool.js +1 -1
- package/dist/tools/list-dir.js +1 -1
- package/dist/tools/preview.js +2 -0
- package/dist/tools/process-log.js +2 -1
- package/dist/tools/read-file.js +2 -2
- package/dist/tools/web-browse.js +9 -3
- package/dist/tools/web-fetch.js +12 -2
- package/package.json +1 -1
|
@@ -97,16 +97,18 @@ export class StuckDetector {
|
|
|
97
97
|
if (this.isStuck()) {
|
|
98
98
|
return t('exec.stuck_recovery', { iterations: this.iterationsOnCurrentStep });
|
|
99
99
|
}
|
|
100
|
+
// Per-tool error recovery (more specific — e.g., "bash failed 3 times")
|
|
101
|
+
const errorTool = Array.from(this.toolErrors.entries()).find(([_, c]) => c >= this.errorThreshold);
|
|
102
|
+
if (errorTool) {
|
|
103
|
+
return t('exec.tool_errors_recovery', { tool: errorTool[0], count: errorTool[1] });
|
|
104
|
+
}
|
|
105
|
+
// Consecutive failures from different tools (generic — e.g., "5 consecutive failures")
|
|
100
106
|
if (this.hasConsecutiveFailures()) {
|
|
101
107
|
return t('exec.consecutive_failures_recovery', { count: this.consecutiveFailures });
|
|
102
108
|
}
|
|
103
109
|
if (this.hasRepetitiveToolCalls()) {
|
|
104
110
|
return this.getRepetitiveToolMessage();
|
|
105
111
|
}
|
|
106
|
-
const errorTool = Array.from(this.toolErrors.entries()).find(([_, c]) => c >= this.errorThreshold);
|
|
107
|
-
if (errorTool) {
|
|
108
|
-
return t('exec.tool_errors_recovery', { tool: errorTool[0], count: errorTool[1] });
|
|
109
|
-
}
|
|
110
112
|
return '';
|
|
111
113
|
}
|
|
112
114
|
checkOffTrack(toolName, call) {
|
package/dist/tools/bash.js
CHANGED
|
@@ -5,8 +5,8 @@ import { DEFAULT_SECURITY_CONFIG } from '../config/security';
|
|
|
5
5
|
import { runCommand, processRegistry, isLongRunningCommand } from '../modules/processes';
|
|
6
6
|
import { t } from '../i18n/index';
|
|
7
7
|
import { platform } from 'os';
|
|
8
|
+
import { MAX_PREVIEW_LINES } from './preview';
|
|
8
9
|
const BASH_TIMEOUT_MS = 120_000;
|
|
9
|
-
const MAX_PREVIEW_LINES = 25;
|
|
10
10
|
function adaptCommandForWindows(command) {
|
|
11
11
|
if (platform() !== 'win32')
|
|
12
12
|
return command;
|
package/dist/tools/glob-tool.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { globSync } from 'fs';
|
|
2
2
|
import { t } from '../i18n/index';
|
|
3
|
-
|
|
3
|
+
import { MAX_PREVIEW_LINES } from './preview';
|
|
4
4
|
export const globTool = {
|
|
5
5
|
name: 'glob',
|
|
6
6
|
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).`,
|
package/dist/tools/grep-tool.js
CHANGED
|
@@ -2,7 +2,7 @@ import { execFileSync, execSync } from 'child_process';
|
|
|
2
2
|
import { resolve } from 'path';
|
|
3
3
|
import { t } from '../i18n/index';
|
|
4
4
|
import { logBashCommand } from '../modules/security/audit-log';
|
|
5
|
-
|
|
5
|
+
import { MAX_PREVIEW_LINES } from './preview';
|
|
6
6
|
function truncateLines(output) {
|
|
7
7
|
const lines = output.split('\n');
|
|
8
8
|
if (lines.length <= MAX_PREVIEW_LINES)
|
package/dist/tools/list-dir.js
CHANGED
|
@@ -3,7 +3,7 @@ import { resolve } from 'path';
|
|
|
3
3
|
import { t } from '../i18n/index';
|
|
4
4
|
import { isPathInScope } from '../modules/security/path-validator';
|
|
5
5
|
import { safeResolvePath } from './path-utils';
|
|
6
|
-
|
|
6
|
+
import { MAX_PREVIEW_LINES } from './preview';
|
|
7
7
|
export const listDirTool = {
|
|
8
8
|
name: 'list_dir',
|
|
9
9
|
description: `List files and directories in a given path. Shows up to ${MAX_PREVIEW_LINES} entries by default.`,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { processRegistry } from '../modules/processes';
|
|
2
2
|
import { t } from '../i18n/index';
|
|
3
|
-
|
|
3
|
+
import { MAX_PREVIEW_LINES } from './preview';
|
|
4
|
+
const DEFAULT_TAIL = MAX_PREVIEW_LINES;
|
|
4
5
|
export const processLogTool = {
|
|
5
6
|
name: 'process_log',
|
|
6
7
|
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.`,
|
package/dist/tools/read-file.js
CHANGED
|
@@ -5,8 +5,8 @@ import { isPathInScope } from "../modules/security/path-validator";
|
|
|
5
5
|
import { DEFAULT_SECURITY_CONFIG } from "../config/security";
|
|
6
6
|
import { logSecurityBlock } from "../modules/security/audit-log";
|
|
7
7
|
import { safeResolvePath } from "./path-utils";
|
|
8
|
-
|
|
9
|
-
const DEFAULT_LIMIT =
|
|
8
|
+
import { MAX_PREVIEW_LINES } from "./preview";
|
|
9
|
+
const DEFAULT_LIMIT = MAX_PREVIEW_LINES;
|
|
10
10
|
export const readFileTool = {
|
|
11
11
|
name: "read_file",
|
|
12
12
|
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.`,
|
package/dist/tools/web-browse.js
CHANGED
|
@@ -2,9 +2,11 @@ import { t } from '../i18n/index';
|
|
|
2
2
|
import { isUrlAllowed, sanitizeUrl } from '../modules/security/network-validator';
|
|
3
3
|
import { logNetworkRequest, logSecurityBlock } from '../modules/security/audit-log';
|
|
4
4
|
import { getSessionSecurityConfig } from '../modules/security/session-isolation';
|
|
5
|
+
import { MAX_PREVIEW_LINES } from './preview';
|
|
6
|
+
const MAX_CHARS = 3000;
|
|
5
7
|
export const webBrowseTool = {
|
|
6
8
|
name: 'web_browse',
|
|
7
|
-
description:
|
|
9
|
+
description: `Fetch and read a web page. Returns the page content as plain text (max ${MAX_PREVIEW_LINES} lines / ${MAX_CHARS} chars).`,
|
|
8
10
|
tags: ['research'],
|
|
9
11
|
parameters: {
|
|
10
12
|
type: 'object',
|
|
@@ -39,8 +41,12 @@ export const webBrowseTool = {
|
|
|
39
41
|
.trim();
|
|
40
42
|
// Log successful network request
|
|
41
43
|
logNetworkRequest(ctx.sessionId, sanitizeUrl(url), true, `Status: ${response.status}`);
|
|
42
|
-
const maxLen = securityConfig?.maxResponseSize ||
|
|
43
|
-
|
|
44
|
+
const maxLen = securityConfig?.maxResponseSize || MAX_CHARS;
|
|
45
|
+
let content = stripped.length > maxLen ? stripped.slice(0, maxLen) + t('file.truncated') : stripped;
|
|
46
|
+
const lines = content.split('\n');
|
|
47
|
+
if (lines.length > MAX_PREVIEW_LINES) {
|
|
48
|
+
content = lines.slice(0, MAX_PREVIEW_LINES).join('\n') + `\n... (${lines.length - MAX_PREVIEW_LINES} more lines)`;
|
|
49
|
+
}
|
|
44
50
|
return { success: true, output: content || t('file.empty_page') };
|
|
45
51
|
}
|
|
46
52
|
catch (err) {
|
package/dist/tools/web-fetch.js
CHANGED
|
@@ -3,7 +3,8 @@ import { isUrlAllowed, sanitizeUrl } from '../modules/security/network-validator
|
|
|
3
3
|
import { logNetworkRequest, logSecurityBlock } from '../modules/security/audit-log';
|
|
4
4
|
import { getSessionSecurityConfig } from '../modules/security/session-isolation';
|
|
5
5
|
import { DEFAULT_SECURITY_CONFIG } from '../config/security';
|
|
6
|
-
|
|
6
|
+
import { MAX_PREVIEW_LINES } from './preview';
|
|
7
|
+
const MAX_CHARS = 5000;
|
|
7
8
|
function stripHtml(html) {
|
|
8
9
|
return html
|
|
9
10
|
.replace(/<script[\s\S]*?<\/script>/gi, '')
|
|
@@ -50,7 +51,16 @@ export const webFetchTool = {
|
|
|
50
51
|
// Log successful network request
|
|
51
52
|
logNetworkRequest(ctx.sessionId, sanitizeUrl(url), true, `Status: ${response.status}`);
|
|
52
53
|
if (cleaned.length > (securityConfig?.maxResponseSize || MAX_CHARS)) {
|
|
53
|
-
|
|
54
|
+
let content = cleaned.slice(0, securityConfig?.maxResponseSize || MAX_CHARS) + t('file.truncated');
|
|
55
|
+
const lines = content.split('\n');
|
|
56
|
+
if (lines.length > MAX_PREVIEW_LINES) {
|
|
57
|
+
content = lines.slice(0, MAX_PREVIEW_LINES).join('\n') + `\n... (${lines.length - MAX_PREVIEW_LINES} more lines)`;
|
|
58
|
+
}
|
|
59
|
+
return { success: true, output: content };
|
|
60
|
+
}
|
|
61
|
+
const lines = cleaned.split('\n');
|
|
62
|
+
if (lines.length > MAX_PREVIEW_LINES) {
|
|
63
|
+
return { success: true, output: lines.slice(0, MAX_PREVIEW_LINES).join('\n') + `\n... (${lines.length - MAX_PREVIEW_LINES} more lines)` };
|
|
54
64
|
}
|
|
55
65
|
return { success: true, output: cleaned || t('file.empty_page') };
|
|
56
66
|
}
|