dpml-prompt
Version:
DPML-powered AI prompt framework - Revolutionary AI-First CLI system based on Deepractice Prompt Markup Language. Build sophisticated AI agents with structured prompts, memory systems, and execution frameworks.
285 lines (244 loc) • 9.22 kB
JavaScript
/**
* SandboxErrorManager - ToolSandbox智能错误管理器
*
* 设计原则:
* - 与现有ToolCommand错误体系兼容
* - 提供Agent友好的错误信息和自动恢复建议
* - 支持MCP协议的结构化错误响应
* - 遵循奥卡姆剃刀原则,最简化错误处理流程
*/
class SandboxErrorManager {
constructor() {
this.version = '1.0.0';
}
/**
* 分析原始错误并生成智能错误信息
* @param {Error} originalError - 原始错误对象
* @param {Object} context - 错误上下文信息
* @param {string} context.toolId - 工具ID
* @param {Array} context.dependencies - 声明的依赖列表
* @param {string} context.sandboxPath - 沙箱路径
* @param {string} context.phase - 执行阶段 (analyze|prepare|execute)
* @returns {Object} 增强的错误信息
*/
analyzeError(originalError, context = {}) {
const errorType = this.classifyError(originalError, context);
const agentInstructions = this.generateAgentInstructions(errorType, originalError, context);
return {
// 保持与ToolCommand兼容的原始信息
originalError,
message: originalError.message,
// 增强的智能信息
type: errorType,
agentInstructions,
context,
// MCP友好的格式化消息
formattedMessage: this.formatForMCP(errorType, originalError, agentInstructions, context)
};
}
/**
* 错误分类逻辑
* @param {Error} error - 错误对象
* @param {Object} context - 上下文信息
* @returns {string} 错误类型
*/
classifyError(error, context) {
const message = error.message.toLowerCase();
// 依赖缺失错误 - 最常见的问题
if (message.includes('cannot find module')) {
const missingModule = this.extractModuleName(error.message);
const isDeclaredDependency = context.dependencies?.some(dep =>
dep.split('@')[0] === missingModule
);
if (isDeclaredDependency) {
return 'DEPENDENCY_MISSING';
} else {
return 'UNDECLARED_DEPENDENCY';
}
}
// 依赖安装失败
if (message.includes('pnpm install failed') ||
message.includes('dependency installation') ||
message.includes('npm err')) {
return 'DEPENDENCY_INSTALL_FAILED';
}
// 工具文件问题
if (message.includes('failed to load tool') ||
message.includes('tool does not export') ||
message.includes('invalid tool export format')) {
return 'TOOL_LOADING_ERROR';
}
// 参数验证错误
if (message.includes('parameter validation failed') ||
message.includes('missing required parameter')) {
return 'PARAMETER_VALIDATION_ERROR';
}
// 沙箱环境错误
if (message.includes('sandbox') || message.includes('vm')) {
return 'SANDBOX_ENVIRONMENT_ERROR';
}
// 网络超时
if (message.includes('timeout') || message.includes('etimedout')) {
return 'NETWORK_TIMEOUT';
}
return 'UNKNOWN_ERROR';
}
/**
* 为Agent生成智能指令
* @param {string} errorType - 错误类型
* @param {Error} originalError - 原始错误
* @param {Object} context - 上下文
* @returns {Object} Agent指令对象
*/
generateAgentInstructions(errorType, originalError, context) {
switch (errorType) {
case 'DEPENDENCY_MISSING':
return {
action: 'AUTO_RETRY_WITH_FORCE_REINSTALL',
autoRetryable: true,
command: '自动重试,添加 forceReinstall: true 参数',
explanation: '依赖已声明但未正确安装,通过强制重装可解决',
userMessage: `检测到依赖 ${this.extractModuleName(originalError.message)} 安装不完整,正在自动重新安装...`,
retryParameters: { forceReinstall: true }
};
case 'UNDECLARED_DEPENDENCY':
const missingModule = this.extractModuleName(originalError.message);
return {
action: 'REPORT_MISSING_DEPENDENCY',
autoRetryable: false,
command: '提示工具开发者添加依赖声明',
explanation: `工具代码使用了未声明的依赖: ${missingModule}`,
userMessage: `❌ 工具缺少依赖声明
🔧 需要在工具的 getDependencies() 方法中添加:
"${missingModule}@latest"
📝 完整示例:
getDependencies() {
return [${context.dependencies?.map(d => `"${d}"`).join(', ')}, "${missingModule}@latest"];
}`,
developerAction: `在 ${context.toolId}.tool.js 中添加 ${missingModule} 到依赖列表`
};
case 'DEPENDENCY_INSTALL_FAILED':
return {
action: 'CHECK_NETWORK_AND_RETRY',
autoRetryable: false,
command: '检查网络连接,建议用户稍后重试',
explanation: '依赖安装过程失败,可能是网络问题或包源问题',
userMessage: `❌ 依赖安装失败
🌐 可能原因:
• 网络连接不稳定
• npm/pnpm 镜像源问题
• 依赖包版本不存在
💡 建议解决方案:
1. 检查网络连接
2. 稍后重试(使用 forceReinstall: true)
3. 如果持续失败,请联系开发者`,
retryDelay: 5000
};
case 'TOOL_LOADING_ERROR':
return {
action: 'REPORT_TOOL_ERROR',
autoRetryable: false,
command: '报告工具文件问题',
explanation: '工具代码本身存在问题,需要开发者修复',
userMessage: `❌ 工具加载失败
🔧 工具代码问题:${originalError.message}
💡 这是工具开发问题,请联系工具作者修复`,
developerAction: '检查工具的 module.exports 和基本语法'
};
case 'NETWORK_TIMEOUT':
return {
action: 'RETRY_WITH_EXTENDED_TIMEOUT',
autoRetryable: true,
command: '自动重试,使用更长的超时时间',
explanation: '网络超时,使用更长超时时间重试',
userMessage: '⏰ 网络超时,正在使用更长超时时间重试...',
retryParameters: { timeout: 60000 } // 60秒
};
default:
return {
action: 'REPORT_UNKNOWN_ERROR',
autoRetryable: false,
command: '报告未知错误给用户',
explanation: '未知错误类型,需要人工分析',
userMessage: `❌ 执行失败:${originalError.message}
🤖 这是一个未分类的错误,请将此信息反馈给开发者以改进错误处理`,
debugInfo: {
stack: originalError.stack,
context
}
};
}
}
/**
* 为MCP协议格式化错误消息
* @param {string} errorType - 错误类型
* @param {Error} originalError - 原始错误
* @param {Object} agentInstructions - Agent指令
* @param {Object} context - 上下文
* @returns {string} MCP友好的错误消息
*/
formatForMCP(errorType, originalError, agentInstructions, context) {
const emoji = this.getErrorEmoji(errorType);
const timestamp = new Date().toISOString();
let message = `${emoji} ToolSandbox执行失败
🏷️ 错误类型: ${errorType}
⏰ 时间: ${timestamp}
🔧 工具: ${context.toolId || 'unknown'}
📁 阶段: ${context.phase || 'unknown'}
📋 详细信息:
${originalError.message}
🤖 AI处理建议:
${agentInstructions.userMessage || agentInstructions.explanation}`;
// 如果可以自动重试,添加重试信息
if (agentInstructions.autoRetryable) {
message += `
🔄 自动恢复: ${agentInstructions.action}
⚡ 操作: ${agentInstructions.command}`;
}
return message;
}
/**
* 从错误消息中提取模块名
* @param {string} errorMessage - 错误消息
* @returns {string} 模块名
*/
extractModuleName(errorMessage) {
const match = errorMessage.match(/Cannot (?:find|resolve) module ['\"]([^'\"]+)['\"]/);
return match ? match[1] : 'unknown';
}
/**
* 根据错误类型获取对应emoji
* @param {string} errorType - 错误类型
* @returns {string} emoji
*/
getErrorEmoji(errorType) {
const emojiMap = {
'DEPENDENCY_MISSING': '📦',
'UNDECLARED_DEPENDENCY': '🔍',
'DEPENDENCY_INSTALL_FAILED': '🌐',
'TOOL_LOADING_ERROR': '🔧',
'PARAMETER_VALIDATION_ERROR': '📝',
'SANDBOX_ENVIRONMENT_ERROR': '🏗️',
'NETWORK_TIMEOUT': '⏰',
'UNKNOWN_ERROR': '❓'
};
return emojiMap[errorType] || '❌';
}
/**
* 检查错误是否可以自动恢复
* @param {Object} intelligentError - 智能错误对象
* @returns {boolean} 是否可自动恢复
*/
isAutoRecoverable(intelligentError) {
return intelligentError.agentInstructions.autoRetryable === true;
}
/**
* 获取自动恢复的重试参数
* @param {Object} intelligentError - 智能错误对象
* @returns {Object|null} 重试参数
*/
getRetryParameters(intelligentError) {
return intelligentError.agentInstructions.retryParameters || null;
}
}
module.exports = SandboxErrorManager;