v0.1.2: 全项目代码审查修复 + 子代理编排器 + 上下文压缩 + 并行工具执行
后端修复: Ollama adapter 移除死代码/修复超时硬编码/iteration硬编码/pullModel无超时/流异常断开补发DONE; SSE解析器支持非字符串arguments; Sandbox fail-closed安全加固; IPC移除未使用变量 新增功能: TaskOrchestrator子任务编排器; DelegateTaskTool委派工具; Agent Loop并行工具执行; 上下文自动压缩; 记忆检索注入System Prompt 前端修复: useAgentStream text_delta thought累积bug; 工具调用状态正确流转; 修复重复stateChange事件; TraceStep.thought正确填充
This commit is contained in:
@@ -9,10 +9,11 @@
|
||||
|
||||
import { exec } from 'child_process';
|
||||
import { promisify } from 'util';
|
||||
import { resolve } from 'path';
|
||||
import type { IMetonaTool, ToolExecutionContext } from '../../types/metona-tool';
|
||||
import type { MetonaToolDef } from '../../../harness/types';
|
||||
import { MetonaToolCategory, MetonaRiskLevel } from '../../../harness/types';
|
||||
import { commandTouchesProtectedFile } from './file-guard';
|
||||
import { commandTouchesProtectedFile, isPathWithinWorkspace } from './file-guard';
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
@@ -42,7 +43,13 @@ export class RunCommandTool implements IMetonaTool {
|
||||
const workdir = (args.workdir as string) ?? context.workspacePath;
|
||||
const timeout = Math.min(300_000, Math.max(1_000, (args.timeout as number) ?? 120_000));
|
||||
|
||||
// 安全校验
|
||||
// 安全校验:workdir 必须在工作空间内
|
||||
const resolvedWorkdir = resolve(context.workspacePath, workdir);
|
||||
if (!isPathWithinWorkspace(workdir, context.workspacePath)) {
|
||||
return { success: false, error: `Working directory must be within workspace: ${workdir}`, command };
|
||||
}
|
||||
|
||||
// 命令安全校验
|
||||
const validation = this.validateCommand(command);
|
||||
if (!validation.allowed) {
|
||||
return { success: false, error: validation.reason, command };
|
||||
@@ -50,7 +57,7 @@ export class RunCommandTool implements IMetonaTool {
|
||||
|
||||
try {
|
||||
const { stdout, stderr } = await execAsync(command, {
|
||||
cwd: workdir,
|
||||
cwd: resolvedWorkdir,
|
||||
timeout,
|
||||
maxBuffer: 1024 * 1024, // 1MB
|
||||
env: { ...process.env, NODE_ENV: 'production' },
|
||||
@@ -99,6 +106,14 @@ export class RunCommandTool implements IMetonaTool {
|
||||
{ pattern: /\bdd\b.*of=\/dev\//, reason: 'Writing to device files is forbidden' },
|
||||
{ pattern: /\b(mkfs|fdisk)\b/, reason: 'Disk formatting commands are forbidden' },
|
||||
{ pattern: /\bchmod\s+777\b/, reason: 'chmod 777 is forbidden' },
|
||||
// Windows 危险命令
|
||||
{ pattern: /\b(format|diskpart)\b/i, reason: 'Disk formatting commands are forbidden' },
|
||||
{ pattern: /\bshutdown\s*\//i, reason: 'System shutdown commands are forbidden' },
|
||||
{ pattern: /\breg\s+(add|delete|import|restore)/i, reason: 'Registry modification commands are forbidden' },
|
||||
{ pattern: /\b(taskkill|kill)\s*\//i, reason: 'Process termination with system flags is forbidden' },
|
||||
// 后台进程与管道炸弹
|
||||
{ pattern: /&\s*\(/, reason: 'Background subshell execution is forbidden' },
|
||||
{ pattern: /\|\s*&/, reason: 'Pipe to background process is forbidden' },
|
||||
];
|
||||
|
||||
for (const block of hardBlocks) {
|
||||
|
||||
Reference in New Issue
Block a user