Merge pull request #119 from Deepractice/feature/toolsandbox-unified-refactor

🔧 ToolSandbox统一重构:修复process API缺失和代码重复问题
This commit is contained in:
Sean
2025-07-05 14:57:50 +08:00
committed by GitHub

View File

@ -207,9 +207,12 @@ class ToolSandbox {
* 在基础沙箱中分析工具 * 在基础沙箱中分析工具
*/ */
async analyzeToolInSandbox() { async analyzeToolInSandbox() {
const basicSandbox = this.createBasicSandbox(); const sandbox = this.createSandbox({
supportDependencies: false,
sandboxPath: process.cwd()
});
const script = new vm.Script(this.toolContent, { filename: `${this.toolId}.js` }); const script = new vm.Script(this.toolContent, { filename: `${this.toolId}.js` });
const context = vm.createContext(basicSandbox); const context = vm.createContext(sandbox);
try { try {
script.runInContext(context); script.runInContext(context);
@ -442,7 +445,10 @@ class ToolSandbox {
* 创建执行沙箱环境 * 创建执行沙箱环境
*/ */
async createExecutionSandbox() { async createExecutionSandbox() {
this.sandboxContext = this.createSmartSandbox(); this.sandboxContext = this.createSandbox({
supportDependencies: true,
sandboxPath: this.sandboxPath
});
// 在智能沙箱中重新加载工具 // 在智能沙箱中重新加载工具
const script = new vm.Script(this.toolContent, { filename: `${this.toolId}.js` }); const script = new vm.Script(this.toolContent, { filename: `${this.toolId}.js` });
@ -459,19 +465,27 @@ class ToolSandbox {
} }
/** /**
* 创建基础沙箱 * 创建统一沙箱环境
* @param {Object} options - 沙箱配置
* @param {boolean} options.supportDependencies - 是否支持依赖解析
* @param {string} options.sandboxPath - 沙箱工作目录
* @returns {Object} 沙箱环境对象
*/ */
createBasicSandbox() { createSandbox(options = {}) {
const {
supportDependencies = false,
sandboxPath = process.cwd()
} = options;
return { return {
require: require, require: supportDependencies ?
this.createSmartRequire(sandboxPath) :
this.createAnalysisRequire(),
module: { exports: {} }, module: { exports: {} },
exports: {}, exports: {},
console: console, console: console,
Buffer: Buffer, Buffer: Buffer,
process: { process: this.createProcessMock(sandboxPath),
env: process.env,
hrtime: process.hrtime
},
setTimeout: setTimeout, setTimeout: setTimeout,
clearTimeout: clearTimeout, clearTimeout: clearTimeout,
setInterval: setInterval, setInterval: setInterval,
@ -491,48 +505,70 @@ class ToolSandbox {
} }
/** /**
* 创建智能沙箱(支持依赖) * 创建完整的process对象mock
* @param {string} sandboxPath - 沙箱工作目录
* @returns {Object} mock的process对象
*/ */
createSmartSandbox() { createProcessMock(sandboxPath) {
return { return {
require: (moduleName) => { env: process.env,
try { version: process.version,
// 优先从沙箱目录查找依赖 platform: process.platform,
return require(require.resolve(moduleName, { arch: process.arch,
paths: [ hrtime: process.hrtime,
path.join(this.sandboxPath, 'node_modules'), cwd: () => sandboxPath,
this.sandboxPath, pid: process.pid,
process.cwd() + '/node_modules' uptime: process.uptime
] };
})); }
} catch (error) {
// 回退到默认require /**
* 创建分析阶段的mock require
* 让所有require调用都成功脚本能完整执行到module.exports
* @returns {Function} mock require函数
*/
createAnalysisRequire() {
return (moduleName) => {
// Node.js内置模块使用真实require
const builtinModules = ['path', 'fs', 'url', 'crypto', 'util', 'os', 'events', 'stream'];
try {
// 检查是否是内置模块
if (builtinModules.includes(moduleName) || moduleName.startsWith('node:')) {
return require(moduleName); return require(moduleName);
} }
}, } catch (e) {
module: { exports: {} }, // 内置模块加载失败继续mock处理
exports: {}, }
console: console,
Buffer: Buffer, // 第三方模块返回通用mock对象
process: { console.log(`[ToolSandbox] 分析阶段mock模块: ${moduleName}`);
env: process.env, return new Proxy({}, {
hrtime: process.hrtime get: () => () => ({}), // 所有属性和方法都返回空函数/对象
}, apply: () => ({}), // 如果被当作函数调用
setTimeout: setTimeout, construct: () => ({}) // 如果被当作构造函数
clearTimeout: clearTimeout, });
setInterval: setInterval, };
clearInterval: clearInterval, }
Object: Object,
Array: Array, /**
String: String, * 创建支持依赖解析的require函数
Number: Number, * @param {string} sandboxPath - 沙箱路径
Boolean: Boolean, * @returns {Function} 智能require函数
Date: Date, */
JSON: JSON, createSmartRequire(sandboxPath) {
Math: Math, return (moduleName) => {
RegExp: RegExp, try {
Error: Error, return require(require.resolve(moduleName, {
URL: URL paths: [
path.join(sandboxPath, 'node_modules'),
sandboxPath,
process.cwd() + '/node_modules'
]
}));
} catch (error) {
return require(moduleName);
}
}; };
} }