@claude-vector/claude-tools
Version:
Claude integration tools for AI-powered development assistance
508 lines (460 loc) • 16.2 kB
JavaScript
/**
* Error Assistant for Claude Vector Search
* Analyzes errors and provides intelligent solutions
*
* Responsibilities:
* - Parse and categorize error messages
* - Search for related code patterns and solutions
* - Provide actionable debugging steps
* - Integrate with context management for error tracking
*/
import { VectorSearchEngine } from '@claude-vector/core';
export class ErrorAssistant {
constructor(config = {}) {
this.searchEngine = null;
this.contextManager = null;
this.sessionManager = null;
// Error categorization patterns
this.errorPatterns = {
'syntax': {
patterns: [
/SyntaxError/i,
/Unexpected token/i,
/Missing semicolon/i,
/Unterminated string/i,
/Unexpected end of input/i
],
severity: 'high',
category: 'syntax',
urgency: 'immediate'
},
'reference': {
patterns: [
/ReferenceError/i,
/is not defined/i,
/Cannot access before initialization/i,
/Undeclared variable/i
],
severity: 'high',
category: 'reference',
urgency: 'immediate'
},
'type': {
patterns: [
/TypeError/i,
/Cannot read propert(y|ies) of/i,
/is not a function/i,
/Cannot call method/i,
/null is not an object/i,
/undefined is not an object/i
],
severity: 'high',
category: 'type',
urgency: 'high'
},
'module': {
patterns: [
/Module not found/i,
/Cannot resolve module/i,
/Error: Cannot find module/i,
/ENOENT.*no such file/i,
/Failed to import/i
],
severity: 'medium',
category: 'module',
urgency: 'high'
},
'network': {
patterns: [
/ECONNREFUSED/i,
/ENOTFOUND/i,
/ETIMEDOUT/i,
/Network error/i,
/Fetch failed/i,
/CORS error/i
],
severity: 'medium',
category: 'network',
urgency: 'medium'
},
'runtime': {
patterns: [
/RangeError/i,
/Stack overflow/i,
/Out of memory/i,
/Maximum call stack/i
],
severity: 'high',
category: 'runtime',
urgency: 'high'
},
'permission': {
patterns: [
/EACCES/i,
/Permission denied/i,
/EPERM/i,
/Access denied/i
],
severity: 'medium',
category: 'permission',
urgency: 'medium'
}
};
// Solution templates for common error patterns
this.solutionTemplates = {
'syntax': [
'Check for missing brackets, braces, or parentheses',
'Verify proper quotation mark matching',
'Look for trailing commas in object literals',
'Ensure proper function declaration syntax'
],
'reference': [
'Check if the variable is declared before use',
'Verify import statements and module paths',
'Look for typos in variable names',
'Ensure proper scope and hoisting rules'
],
'type': [
'Add null/undefined checks before property access',
'Verify the object/variable type before calling methods',
'Check for proper initialization of variables',
'Use optional chaining (?.) for safer property access'
],
'module': [
'Check if the module is installed: npm install [module-name]',
'Verify the file path and extension',
'Check for typos in the import/require statement',
'Ensure the module exists in node_modules or is a valid relative path'
],
'network': [
'Check network connectivity',
'Verify the URL and endpoint availability',
'Check firewall and proxy settings',
'Verify API keys and authentication'
],
'runtime': [
'Check for infinite loops or recursive calls',
'Optimize memory usage and data structures',
'Review algorithm complexity',
'Add proper base cases for recursive functions'
],
'permission': [
'Check file/directory permissions',
'Run with appropriate user privileges',
'Verify access to required resources',
'Check environment variables and configuration'
]
};
// Debug step templates
this.debugSteps = {
'syntax': [
'Use your editor\'s syntax highlighting to spot errors',
'Run a linter (ESLint, JSHint) to identify syntax issues',
'Check the console for the exact line number of the error',
'Use a code formatter to identify mismatched brackets'
],
'reference': [
'Check the declaration order of variables and functions',
'Use console.log to verify variable values at runtime',
'Check the import/export statements',
'Use your IDE\'s "Go to Definition" feature'
],
'type': [
'Add console.log statements to check variable types',
'Use typeof operator to verify data types',
'Check the return values of functions',
'Use browser developer tools or Node.js debugger'
],
'module': [
'Check if node_modules directory exists',
'Verify package.json dependencies',
'Try reinstalling node_modules: rm -rf node_modules && npm install',
'Check for case-sensitive file system issues'
],
'network': [
'Test the endpoint with curl or Postman',
'Check browser developer tools Network tab',
'Verify environment variables for API endpoints',
'Test with different network conditions'
],
'runtime': [
'Use profiling tools to identify performance bottlenecks',
'Add logging to trace execution flow',
'Set breakpoints to examine variable states',
'Monitor memory usage during execution'
],
'permission': [
'Check file permissions with ls -la',
'Try running with sudo (if appropriate)',
'Verify the user has access to required directories',
'Check environment variables for paths and credentials'
]
};
}
/**
* Set module dependencies
*/
setModules({ searchEngine, contextManager, sessionManager }) {
this.searchEngine = searchEngine;
this.contextManager = contextManager;
this.sessionManager = sessionManager;
}
/**
* Analyze an error message and provide solutions
*/
async analyzeError(errorMessage, options = {}) {
try {
// Parse and categorize the error
const errorInfo = this.parseError(errorMessage);
// Search for related solutions if search engine is available
const relatedSolutions = await this.searchForSolutions(errorMessage, errorInfo);
// Generate specific solutions
const solutions = this.generateSolutions(errorInfo, relatedSolutions);
// Generate debug steps
const debugSteps = this.generateDebugSteps(errorInfo);
// Add to context if context manager is available
if (this.contextManager && options.addToContext !== false) {
await this.addErrorToContext(errorMessage, errorInfo, solutions);
}
// Log activity if session manager is available
if (this.sessionManager) {
await this.logErrorActivity(errorMessage, errorInfo);
}
return {
originalError: errorMessage,
category: errorInfo.category,
severity: errorInfo.severity,
urgency: errorInfo.urgency,
type: errorInfo.type,
component: errorInfo.component,
lineNumber: errorInfo.lineNumber,
solutions,
debugSteps,
relatedSolutions: relatedSolutions.slice(0, 3), // Top 3 most relevant
suggestions: this.generateSuggestions(errorInfo)
};
} catch (error) {
console.error('Error during error analysis:', error);
// Fallback analysis
return {
originalError: errorMessage,
category: 'unknown',
severity: 'medium',
urgency: 'medium',
type: 'unknown',
component: 'unknown',
solutions: [
'Search for the error message in your codebase',
'Check recent changes that might have caused this error',
'Look for similar error patterns in documentation'
],
debugSteps: [
'Check the full error stack trace',
'Verify recent code changes',
'Search online for the specific error message'
],
relatedSolutions: [],
suggestions: [
'Try breaking down the problem into smaller parts',
'Check if the error is reproducible',
'Look for error handling patterns in the codebase'
]
};
}
}
/**
* Parse error message and extract information
*/
parseError(errorMessage) {
let bestMatch = null;
let bestCategory = 'unknown';
// Find the best matching error pattern
for (const [category, config] of Object.entries(this.errorPatterns)) {
for (const pattern of config.patterns) {
if (pattern.test(errorMessage)) {
if (!bestMatch) {
bestMatch = config;
bestCategory = category;
}
}
}
}
// Extract additional information
const lineNumberMatch = errorMessage.match(/line (\d+)/i) ||
errorMessage.match(/:(\d+):/);
const lineNumber = lineNumberMatch ? parseInt(lineNumberMatch[1]) : null;
// Extract component/file information
const fileMatch = errorMessage.match(/at (.+?):/i) ||
errorMessage.match(/in (.+?\.js)/i) ||
errorMessage.match(/from (.+?\.js)/i);
const component = fileMatch ? fileMatch[1].split('/').pop() : 'unknown';
return {
category: bestCategory,
severity: bestMatch?.severity || 'medium',
urgency: bestMatch?.urgency || 'medium',
type: bestCategory,
component,
lineNumber,
fullMessage: errorMessage
};
}
/**
* Search for solutions using vector search
*/
async searchForSolutions(errorMessage, errorInfo) {
if (!this.searchEngine) {
return [];
}
try {
// Create search queries based on error information
const queries = [
`error ${errorInfo.category} ${errorInfo.component}`,
`fix ${errorMessage.split('\n')[0]}`, // First line of error
`solution ${errorInfo.type} error`,
`handle ${errorInfo.category} exception`
];
const solutions = [];
for (const query of queries) {
try {
const results = await this.searchEngine.search(query, {
maxResults: 3,
threshold: 0.6
});
if (results && results.results) {
solutions.push(...results.results.map(result => ({
content: result.chunk?.content || result.content,
score: result.score,
file: result.chunk?.file,
query,
type: 'code_solution'
})));
}
} catch (error) {
console.warn(`Search failed for query "${query}":`, error.message);
}
}
// Remove duplicates and sort by score
const uniqueSolutions = solutions
.filter((solution, index, array) =>
array.findIndex(s => s.content === solution.content) === index
)
.sort((a, b) => b.score - a.score);
return uniqueSolutions;
} catch (error) {
console.warn('Search for solutions failed:', error.message);
return [];
}
}
/**
* Generate specific solutions based on error type
*/
generateSolutions(errorInfo, relatedSolutions = []) {
const templateSolutions = this.solutionTemplates[errorInfo.category] ||
this.solutionTemplates['syntax'];
const solutions = [...templateSolutions];
// Add solutions from search results
relatedSolutions.slice(0, 2).forEach(solution => {
if (solution.content && solution.content.length > 20) {
solutions.push(`Based on similar code: ${solution.content.substring(0, 100)}...`);
}
});
// Add component-specific solutions
if (errorInfo.component && errorInfo.component !== 'unknown') {
solutions.push(`Check the ${errorInfo.component} component for recent changes`);
solutions.push(`Look for similar patterns in other parts of ${errorInfo.component}`);
}
// Add line-specific solutions
if (errorInfo.lineNumber) {
solutions.push(`Focus on line ${errorInfo.lineNumber} and surrounding context`);
solutions.push(`Check if line ${errorInfo.lineNumber} has proper syntax and dependencies`);
}
return solutions.slice(0, 8); // Limit to 8 solutions
}
/**
* Generate debug steps based on error type
*/
generateDebugSteps(errorInfo) {
const templateSteps = this.debugSteps[errorInfo.category] ||
this.debugSteps['syntax'];
const steps = [...templateSteps];
// Add context-specific debug steps
if (errorInfo.lineNumber) {
steps.unshift(`Examine line ${errorInfo.lineNumber} and the lines immediately before and after`);
}
if (errorInfo.component && errorInfo.component !== 'unknown') {
steps.push(`Test the ${errorInfo.component} component in isolation`);
}
return steps.slice(0, 6); // Limit to 6 steps
}
/**
* Generate suggestions for next actions
*/
generateSuggestions(errorInfo) {
const suggestions = [
`Search for more examples: claude-search search "${errorInfo.category} error solution"`,
`Look for related issues: claude-search search "${errorInfo.component} ${errorInfo.type}"`
];
if (errorInfo.category === 'module') {
suggestions.push('Check package.json dependencies and run npm install');
}
if (errorInfo.category === 'type') {
suggestions.push('Add TypeScript for better type checking');
}
if (errorInfo.category === 'syntax') {
suggestions.push('Use a linter like ESLint to catch syntax errors early');
}
return suggestions;
}
/**
* Add error information to context
*/
async addErrorToContext(errorMessage, errorInfo, solutions) {
if (!this.contextManager) return;
try {
await this.contextManager.addItem({
type: 'error_solution',
content: `Error: ${errorMessage}\nCategory: ${errorInfo.category}\nSolutions: ${solutions.slice(0, 3).join('; ')}`,
metadata: {
errorCategory: errorInfo.category,
severity: errorInfo.severity,
component: errorInfo.component,
lineNumber: errorInfo.lineNumber,
timestamp: Date.now()
},
source: 'error-analysis'
}, 'high'); // High priority for error solutions
} catch (error) {
console.warn('Failed to add error to context:', error.message);
}
}
/**
* Log error analysis activity
*/
async logErrorActivity(errorMessage, errorInfo) {
// This would need to be implemented in SessionManager
// For now, we'll just log the activity
console.log(`Error analysis: ${errorInfo.category} error in ${errorInfo.component}`);
}
/**
* Get error statistics from current session
*/
getErrorStatistics() {
// This would analyze errors from the current session
// Implementation would depend on SessionManager integration
return {
totalErrors: 0,
errorsByCategory: {},
commonPatterns: [],
resolutionRate: 0
};
}
/**
* Learn from error resolution
*/
async learnFromResolution(errorMessage, solution, wasHelpful = true) {
// This would implement learning from user feedback
// Could update solution rankings or add custom patterns
console.log(`Learning from resolution: ${wasHelpful ? 'helpful' : 'not helpful'}`);
}
}
export default ErrorAssistant;