@blockrun/runcode 2.5.4 → 2.5.5
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/tools/bash.js +17 -2
- package/dist/tools/glob.js +19 -2
- package/dist/tools/grep.js +8 -0
- package/package.json +1 -1
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)
|
|
@@ -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) {
|
|
@@ -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) {
|