minimal-agent 0.6.2 → 0.6.4
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/package.json +1 -1
- package/plugins/workflow-runner/src/expressions.js +13 -2
- package/plugins/workflow-runner/src/loader.js +4 -2
- package/src/cli/args.js +27 -0
- package/src/cli/print.js +30 -44
- package/src/cli/streamJson.js +117 -0
- package/src/config/configFile.js +7 -3
- package/src/config.js +19 -0
- package/src/context/compact.js +44 -19
- package/src/context/reactiveCompact.js +40 -19
- package/src/context/recentDirs.js +66 -0
- package/src/context/tokenCounter.js +23 -0
- package/src/llm/client.js +17 -4
- package/src/loop.js +161 -91
- package/src/main.js +31 -4
- package/src/tools/bash/bash.js +34 -4
- package/src/ui/hooks/useTokenUsage.js +3 -2
package/src/tools/bash/bash.js
CHANGED
|
@@ -50,6 +50,12 @@ import { scanDestructiveCommand } from './warnings.js';
|
|
|
50
50
|
// ---------------- 0. 常量 ----------------
|
|
51
51
|
const DEFAULT_TIMEOUT_MS = 120_000; // 2 min
|
|
52
52
|
const MAX_TIMEOUT_MS = 600_000; // 10 min
|
|
53
|
+
/**
|
|
54
|
+
* G1:stdout / stderr 即时缓冲上限(各自)。命令狂输出(如 cat 大文件 / yes)时,
|
|
55
|
+
* 在最终统一截断之前先把内存封顶,防 OOM。取最终展示截断阈值的 2 倍 —— 正常输出不受影响,
|
|
56
|
+
* 超大输出也只占有限内存(最终仍按 DEFAULT_MAX_RESULT_SIZE_CHARS 截断展示)。
|
|
57
|
+
*/
|
|
58
|
+
const MAX_STREAM_BUFFER_CHARS = DEFAULT_MAX_RESULT_SIZE_CHARS * 2;
|
|
53
59
|
/**
|
|
54
60
|
* 灾难性命令黑名单。
|
|
55
61
|
* 命中任意一条就直接拒绝执行 —— 这层是"防猪队友"而不是真沙盒。
|
|
@@ -142,6 +148,27 @@ export function checkForbidden(command) {
|
|
|
142
148
|
}
|
|
143
149
|
return null;
|
|
144
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* 子进程环境变量:从 process.env 复制后**剥离 agent 自己的密钥**
|
|
153
|
+
* (`MINIMAL_AGENT_*` / `TAVILY_*`)。
|
|
154
|
+
*
|
|
155
|
+
* 动机(安全):main.tsx 启动时会把 saved config 里的 key 注入 process.env。
|
|
156
|
+
* 若原样把 process.env 透传给 Bash 子进程,模型只要跑 `echo $MINIMAL_AGENT_API_KEY`
|
|
157
|
+
* 就能把 key(绿色版里是卖家预置的)读进 tool result、回传 LLM、甚至打到 -p stdout。
|
|
158
|
+
* 这些 env 是 agent 自身配置,子进程命令并不需要 —— 直接删掉,最小化泄露面。
|
|
159
|
+
* 其余变量(PATH / HOME / 用户自己 export 的)照常透传。
|
|
160
|
+
*
|
|
161
|
+
* 导出供测试断言。
|
|
162
|
+
*/
|
|
163
|
+
export function sanitizedChildEnv(base = process.env) {
|
|
164
|
+
const env = { ...base };
|
|
165
|
+
for (const key of Object.keys(env)) {
|
|
166
|
+
if (key.startsWith('MINIMAL_AGENT_') || key.startsWith('TAVILY_')) {
|
|
167
|
+
delete env[key];
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return env;
|
|
171
|
+
}
|
|
145
172
|
// ---------------- 1. Zod 输入 schema ----------------
|
|
146
173
|
const inputSchema = z.object({
|
|
147
174
|
command: z
|
|
@@ -256,17 +283,20 @@ async function call(input, signal) {
|
|
|
256
283
|
shell: true,
|
|
257
284
|
cwd: getWorkingDir(),
|
|
258
285
|
signal: ac.signal,
|
|
259
|
-
env:
|
|
286
|
+
env: sanitizedChildEnv(),
|
|
260
287
|
windowsHide: true,
|
|
261
288
|
});
|
|
262
289
|
child.stdout?.setEncoding('utf8');
|
|
263
290
|
child.stderr?.setEncoding('utf8');
|
|
264
291
|
child.stdout?.on('data', (chunk) => {
|
|
265
|
-
|
|
266
|
-
//
|
|
292
|
+
// G1:即时封顶,防止狂输出命令在最终截断前撑爆内存(OOM)。不强行 kill,
|
|
293
|
+
// 让命令自己跑完或被 timeout 收走;超出上限的部分直接丢弃,最终仍按上限截断展示。
|
|
294
|
+
if (stdout.length < MAX_STREAM_BUFFER_CHARS)
|
|
295
|
+
stdout += chunk;
|
|
267
296
|
});
|
|
268
297
|
child.stderr?.on('data', (chunk) => {
|
|
269
|
-
stderr
|
|
298
|
+
if (stderr.length < MAX_STREAM_BUFFER_CHARS)
|
|
299
|
+
stderr += chunk;
|
|
270
300
|
});
|
|
271
301
|
child.on('error', (e) => {
|
|
272
302
|
// signal abort 会先触发 error('AbortError');把这种 case 转成正常分支
|
|
@@ -15,11 +15,12 @@
|
|
|
15
15
|
* 再额外传入版本号 prop 配合依赖即可。
|
|
16
16
|
* ============================================================
|
|
17
17
|
*/
|
|
18
|
-
import {
|
|
18
|
+
import { getCompactThreshold } from '../../context/compact.js';
|
|
19
19
|
import { countMessagesTokens } from '../../context/tokenCounter.js';
|
|
20
20
|
export function useTokenUsage(messages, provider) {
|
|
21
21
|
const tokens = countMessagesTokens(messages);
|
|
22
|
-
|
|
22
|
+
// 与 loop 实际触发同源(getCompactThreshold:按 contextWindow × compactRatio 比例 + 8K 下限)
|
|
23
|
+
const threshold = getCompactThreshold(provider);
|
|
23
24
|
return {
|
|
24
25
|
tokens,
|
|
25
26
|
threshold,
|