@blockrun/runcode 2.5.4 → 2.5.6
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/agent/optimize.js +3 -3
- package/dist/tools/bash.js +17 -2
- package/dist/tools/glob.js +19 -2
- package/dist/tools/grep.js +11 -3
- package/package.json +1 -1
package/dist/agent/optimize.js
CHANGED
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
* 5. Pre-compact stripping — remove images/docs before summarization
|
|
10
10
|
*/
|
|
11
11
|
// ─── Constants ─────────────────────────────────────────────────────────────
|
|
12
|
-
/** Max chars per individual tool result before truncation */
|
|
13
|
-
const MAX_TOOL_RESULT_CHARS =
|
|
12
|
+
/** Max chars per individual tool result before truncation (history-level safety net) */
|
|
13
|
+
const MAX_TOOL_RESULT_CHARS = 32_000;
|
|
14
14
|
/** Max aggregate tool result chars per user message */
|
|
15
|
-
const MAX_TOOL_RESULTS_PER_MESSAGE_CHARS =
|
|
15
|
+
const MAX_TOOL_RESULTS_PER_MESSAGE_CHARS = 100_000;
|
|
16
16
|
/** Preview size when truncating */
|
|
17
17
|
const PREVIEW_CHARS = 2_000;
|
|
18
18
|
/** Default max_tokens (low to save output slot reservation) */
|
package/dist/tools/bash.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* Bash capability — execute shell commands with timeout and output capture.
|
|
3
3
|
*/
|
|
4
4
|
import { spawn } from 'node:child_process';
|
|
5
|
-
const MAX_OUTPUT_BYTES = 512 * 1024; // 512KB
|
|
5
|
+
const MAX_OUTPUT_BYTES = 512 * 1024; // 512KB capture buffer (prevents OOM)
|
|
6
|
+
const MAX_RETURN_CHARS = 32_000; // 32KB return cap (~8,000 tokens) — prevents context bloat
|
|
6
7
|
const DEFAULT_TIMEOUT_MS = 120_000; // 2 minutes
|
|
7
8
|
async function execute(input, ctx) {
|
|
8
9
|
const { command, timeout } = input;
|
|
@@ -99,7 +100,21 @@ async function execute(input, ctx) {
|
|
|
99
100
|
result += stderr;
|
|
100
101
|
}
|
|
101
102
|
if (truncated) {
|
|
102
|
-
result += '\n\n... (output truncated
|
|
103
|
+
result += '\n\n... (output truncated — command produced >512KB)';
|
|
104
|
+
}
|
|
105
|
+
// Cap returned output to prevent context bloat.
|
|
106
|
+
// Keep the LAST part (most relevant for errors/test failures/build output).
|
|
107
|
+
if (result.length > MAX_RETURN_CHARS) {
|
|
108
|
+
const lines = result.split('\n');
|
|
109
|
+
let trimmed = '';
|
|
110
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
111
|
+
const candidate = lines[i] + '\n' + trimmed;
|
|
112
|
+
if (candidate.length > MAX_RETURN_CHARS)
|
|
113
|
+
break;
|
|
114
|
+
trimmed = candidate;
|
|
115
|
+
}
|
|
116
|
+
const omitted = result.length - trimmed.length;
|
|
117
|
+
result = `... (${omitted.toLocaleString()} chars omitted from start)\n${trimmed}`;
|
|
103
118
|
}
|
|
104
119
|
if (killed) {
|
|
105
120
|
resolve({
|
package/dist/tools/glob.js
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import fs from 'node:fs';
|
|
5
5
|
import path from 'node:path';
|
|
6
|
-
const MAX_RESULTS =
|
|
6
|
+
const MAX_RESULTS = 200;
|
|
7
|
+
const MAX_OUTPUT_CHARS = 12_000; // ~3,000 tokens — prevents huge glob results from blowing up context
|
|
7
8
|
/**
|
|
8
9
|
* Simple glob matcher supporting *, **, and ? wildcards.
|
|
9
10
|
* No external dependencies.
|
|
@@ -115,7 +116,23 @@ async function execute(input, ctx) {
|
|
|
115
116
|
}
|
|
116
117
|
let output = sorted.join('\n');
|
|
117
118
|
if (sorted.length >= MAX_RESULTS) {
|
|
118
|
-
output += `\n\n... (limited to ${MAX_RESULTS} results)`;
|
|
119
|
+
output += `\n\n... (limited to ${MAX_RESULTS} results. Use a more specific pattern to narrow results.)`;
|
|
120
|
+
}
|
|
121
|
+
// Cap total output length to prevent context bloat
|
|
122
|
+
if (output.length > MAX_OUTPUT_CHARS) {
|
|
123
|
+
const lines = output.split('\n');
|
|
124
|
+
let trimmed = '';
|
|
125
|
+
let count = 0;
|
|
126
|
+
for (const line of lines) {
|
|
127
|
+
if ((trimmed + line).length > MAX_OUTPUT_CHARS)
|
|
128
|
+
break;
|
|
129
|
+
trimmed += (trimmed ? '\n' : '') + line;
|
|
130
|
+
count++;
|
|
131
|
+
}
|
|
132
|
+
const remaining = lines.length - count;
|
|
133
|
+
if (remaining > 0) {
|
|
134
|
+
output = `${trimmed}\n... (${remaining} more paths not shown — use a more specific pattern)`;
|
|
135
|
+
}
|
|
119
136
|
}
|
|
120
137
|
return { output };
|
|
121
138
|
}
|
package/dist/tools/grep.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { execSync, execFileSync } from 'node:child_process';
|
|
5
5
|
import fs from 'node:fs';
|
|
6
6
|
import path from 'node:path';
|
|
7
|
+
const MAX_GREP_OUTPUT_CHARS = 16_000; // ~4,000 tokens — prevents huge grep results
|
|
7
8
|
let _hasRipgrep = null;
|
|
8
9
|
function hasRipgrep() {
|
|
9
10
|
if (_hasRipgrep !== null)
|
|
@@ -63,8 +64,8 @@ function runRipgrep(opts, searchPath, mode, limit) {
|
|
|
63
64
|
args.push('-U', '--multiline-dotall');
|
|
64
65
|
if (opts.glob)
|
|
65
66
|
args.push(`--glob=${opts.glob}`);
|
|
66
|
-
// Always exclude common noise
|
|
67
|
-
args.push('--glob=!node_modules', '--glob=!.git', '--glob=!dist');
|
|
67
|
+
// Always exclude common noise + lock files (huge, rarely useful)
|
|
68
|
+
args.push('--glob=!node_modules', '--glob=!.git', '--glob=!dist', '--glob=!*.lock', '--glob=!package-lock.json', '--glob=!pnpm-lock.yaml');
|
|
68
69
|
args.push('--', opts.pattern);
|
|
69
70
|
args.push(searchPath);
|
|
70
71
|
try {
|
|
@@ -79,6 +80,10 @@ function runRipgrep(opts, searchPath, mode, limit) {
|
|
|
79
80
|
if (lines.length > limited.length) {
|
|
80
81
|
output += `\n\n... (${lines.length - limited.length} more results, use head_limit to see more)`;
|
|
81
82
|
}
|
|
83
|
+
// Cap total output to prevent context bloat
|
|
84
|
+
if (output.length > MAX_GREP_OUTPUT_CHARS) {
|
|
85
|
+
output = output.slice(0, MAX_GREP_OUTPUT_CHARS) + `\n... (output capped at ${MAX_GREP_OUTPUT_CHARS / 1000}KB — use more specific pattern or head_limit)`;
|
|
86
|
+
}
|
|
82
87
|
return { output: output || 'No matches found' };
|
|
83
88
|
}
|
|
84
89
|
catch (err) {
|
|
@@ -113,7 +118,7 @@ function runNativeGrep(opts, searchPath, mode, limit) {
|
|
|
113
118
|
.replace(/\*\*/, '*'); // Convert ** to * for flat matching
|
|
114
119
|
args.push(`--include=${nativeGlob}`);
|
|
115
120
|
}
|
|
116
|
-
args.push('--exclude-dir=node_modules', '--exclude-dir=.git', '--exclude-dir=dist');
|
|
121
|
+
args.push('--exclude-dir=node_modules', '--exclude-dir=.git', '--exclude-dir=dist', '--exclude=*.lock', '--exclude=package-lock.json', '--exclude=pnpm-lock.yaml');
|
|
117
122
|
args.push('-e', opts.pattern, searchPath);
|
|
118
123
|
try {
|
|
119
124
|
const result = execFileSync('grep', args, {
|
|
@@ -127,6 +132,9 @@ function runNativeGrep(opts, searchPath, mode, limit) {
|
|
|
127
132
|
if (lines.length > limited.length) {
|
|
128
133
|
output += `\n\n... (${lines.length - limited.length} more results)`;
|
|
129
134
|
}
|
|
135
|
+
if (output.length > MAX_GREP_OUTPUT_CHARS) {
|
|
136
|
+
output = output.slice(0, MAX_GREP_OUTPUT_CHARS) + `\n... (output capped at ${MAX_GREP_OUTPUT_CHARS / 1000}KB)`;
|
|
137
|
+
}
|
|
130
138
|
return { output: output || 'No matches found' };
|
|
131
139
|
}
|
|
132
140
|
catch (err) {
|