ai-debug-local-mcp
Version:
🎯 ENHANCED AI GUIDANCE v4.1.2: Dramatically improved tool descriptions help AI users choose the right tools instead of 'close enough' options. Ultra-fast keyboard automation (10x speed), universal recording, multi-ecosystem debugging support, and compreh
326 lines • 17.1 kB
JavaScript
import { BaseToolHandler } from '../base-handler.js';
import { SessionDebugFixes } from '../session-debug-fixes.js';
import * as fmt from './python-formatter-utils.js';
/**
* Handler for Python backend debugging tools (test analysis, Pydantic validation, database debugging)
*/
export class PythonBackendHandler extends BaseToolHandler {
pythonEngine;
constructor(pythonEngine) {
super();
this.pythonEngine = pythonEngine;
}
tools = [
{
name: 'analyze_python_tests',
description: 'Analyze Python test failures, validation errors, and test health status. Handles pytest output, unittest failures, and test structure analysis.',
inputSchema: {
type: 'object',
properties: {
testFilePath: { type: 'string', description: 'Path to Python test file or directory' },
testOutput: { type: 'string', description: 'Test execution output/logs to analyze' },
includeStackTrace: { type: 'boolean', description: 'Include detailed stack trace analysis', default: true }
},
required: ['testFilePath']
}
},
{
name: 'validate_pydantic_models',
description: 'Debug Pydantic model validation errors, field mismatches, and schema conflicts. Analyzes model definitions and validation failures.',
inputSchema: {
type: 'object',
properties: {
modelFilePath: { type: 'string', description: 'Path to Python file containing Pydantic models' },
validationError: { type: 'string', description: 'Pydantic validation error message to debug' },
testData: { type: 'string', description: 'Sample data that failed validation (JSON format)' }
},
required: ['modelFilePath']
}
},
{
name: 'debug_database_schema',
description: 'Analyze database schema issues, migration errors, and model-database mismatches. Supports SQLAlchemy, Django ORM, and raw SQL.',
inputSchema: {
type: 'object',
properties: {
schemaFilePath: { type: 'string', description: 'Path to database schema/model definitions' },
migrationError: { type: 'string', description: 'Database migration error message' },
databaseType: { type: 'string', description: 'Database type (postgresql, mysql, sqlite)', enum: ['postgresql', 'mysql', 'sqlite'] },
includeData: { type: 'boolean', description: 'Include sample data analysis', default: false }
},
required: ['schemaFilePath']
}
},
{
name: 'analyze_backend_logic',
description: 'Debug complex Python backend logic including API endpoints, data processing pipelines, and business logic errors.',
inputSchema: {
type: 'object',
properties: {
codeFilePath: { type: 'string', description: 'Path to Python backend code file' },
errorMessage: { type: 'string', description: 'Runtime error or exception message' },
logContext: { type: 'string', description: 'Application logs around the error' },
analysisType: { type: 'string', description: 'Type of analysis needed', enum: ['api_endpoints', 'data_processing', 'business_logic', 'general'], default: 'general' }
},
required: ['codeFilePath']
}
},
{
name: 'debug_python_imports',
description: 'Analyze Python import errors, module dependencies, and path resolution issues.',
inputSchema: {
type: 'object',
properties: {
projectPath: { type: 'string', description: 'Path to Python project root' },
importError: { type: 'string', description: 'Import error message to debug' },
includeVirtualEnv: { type: 'boolean', description: 'Include virtual environment analysis', default: true }
},
required: ['projectPath']
}
},
{
name: 'analyze_api_integration',
description: 'Debug API integration issues between frontend and Python backend, including request/response validation.',
inputSchema: {
type: 'object',
properties: {
apiEndpointPath: { type: 'string', description: 'Path to API endpoint code' },
requestData: { type: 'string', description: 'Sample request data (JSON format)' },
responseError: { type: 'string', description: 'API response error or validation failure' },
frameworkType: { type: 'string', description: 'API framework type', enum: ['fastapi', 'flask', 'django', 'starlette'], default: 'fastapi' }
},
required: ['apiEndpointPath']
}
}
];
async handle(toolName, args, sessions) {
try {
// Python backend debugging doesn't require browser sessions like web debugging
// Instead, we work directly with file system and code analysis
switch (toolName) {
case 'analyze_python_tests':
return this.analyzePythonTests(args);
case 'validate_pydantic_models':
return this.validatePydanticModels(args);
case 'debug_database_schema':
return this.debugDatabaseSchema(args);
case 'analyze_backend_logic':
return this.analyzeBackendLogic(args);
case 'debug_python_imports':
return this.debugPythonImports(args);
case 'analyze_api_integration':
return this.analyzeApiIntegration(args);
default:
throw new Error(`Unknown Python backend tool: ${toolName}`);
}
}
catch (error) {
return SessionDebugFixes.createDetailedErrorResponse(error, 'Python Backend Debug', 'backend-session');
}
}
async analyzePythonTests(args) {
try {
const analysis = await this.pythonEngine.analyzeTests(args.testFilePath, args.testOutput, args.includeStackTrace);
const sections = [
'🐍 **Python Test Analysis**',
'',
fmt.formatKeyValue('Test File/Directory', args.testFilePath),
''
];
// Test Results Summary
if (analysis.summary) {
sections.push(...fmt.formatSection('**Test Results Summary:**', [
`Total Tests: ${analysis.summary.total || 'Unknown'}`,
`Passed: ${analysis.summary.passed || 0}`,
`Failed: ${analysis.summary.failed || 0}`,
`Skipped: ${analysis.summary.skipped || 0}`,
`Errors: ${analysis.summary.errors || 0}`
]));
}
// Failed Tests Details
if (analysis.failures?.length > 0) {
sections.push(...fmt.formatSection('**Failed Tests:**', analysis.failures.map((failure) => `❌ ${failure.test_name}: ${failure.error_message}`)));
}
// Error Analysis
if (analysis.errorAnalysis?.length > 0) {
sections.push(...fmt.formatSection('**Error Analysis:**', analysis.errorAnalysis.map((error) => `⚠️ ${error.type}: ${error.description}`)));
}
// Recommendations
const recommendations = [];
if (analysis.recommendations?.length > 0) {
recommendations.push(...analysis.recommendations);
}
sections.push(...fmt.formatRecommendations(recommendations));
return this.createTextResponse(sections.join('\n').trim());
}
catch (error) {
throw new Error(`Failed to analyze Python tests: ${error instanceof Error ? error.message : String(error)}`);
}
}
async validatePydanticModels(args) {
try {
const validation = await this.pythonEngine.validatePydanticModels(args.modelFilePath, args.validationError, args.testData);
const sections = [
'📋 **Pydantic Model Validation**',
'',
fmt.formatKeyValue('Model File', args.modelFilePath),
''
];
// Model Analysis
if (validation.models?.length > 0) {
sections.push(...fmt.formatSection('**Models Found:**', validation.models.map((model) => `📄 ${model.name}: ${model.fields.length} fields`)));
}
// Validation Errors
if (validation.errors?.length > 0) {
sections.push(...fmt.formatSection('**Validation Errors:**', validation.errors.map((error) => `❌ ${error.field}: ${error.message}`)));
}
// Field Mismatches
if (validation.fieldMismatches?.length > 0) {
sections.push(...fmt.formatSection('**Field Mismatches:**', validation.fieldMismatches.map((mismatch) => `⚠️ ${mismatch.field}: Expected ${mismatch.expected}, got ${mismatch.actual}`)));
}
// Suggestions
const suggestions = validation.suggestions || [];
sections.push(...fmt.formatRecommendations(suggestions));
return this.createTextResponse(sections.join('\n').trim());
}
catch (error) {
throw new Error(`Failed to validate Pydantic models: ${error instanceof Error ? error.message : String(error)}`);
}
}
async debugDatabaseSchema(args) {
try {
const schemaDebug = await this.pythonEngine.debugDatabaseSchema(args.schemaFilePath, args.migrationError, args.databaseType);
const sections = [
'🗄️ **Database Schema Debug**',
'',
fmt.formatKeyValue('Schema File', args.schemaFilePath),
fmt.formatKeyValue('Database Type', args.databaseType || 'Unknown'),
''
];
// Schema Analysis
if (schemaDebug.tables?.length > 0) {
sections.push(...fmt.formatSection('**Tables Found:**', schemaDebug.tables.map((table) => `📊 ${table.name}: ${table.columns.length} columns`)));
}
// Migration Issues
if (schemaDebug.migrationIssues?.length > 0) {
sections.push(...fmt.formatSection('**Migration Issues:**', schemaDebug.migrationIssues.map((issue) => `⚠️ ${issue.type}: ${issue.description}`)));
}
// Schema Inconsistencies
if (schemaDebug.inconsistencies?.length > 0) {
sections.push(...fmt.formatSection('**Schema Inconsistencies:**', schemaDebug.inconsistencies.map((inconsistency) => `❌ ${inconsistency.table}: ${inconsistency.issue}`)));
}
// Recommendations
const recommendations = schemaDebug.recommendations || [];
sections.push(...fmt.formatRecommendations(recommendations));
return this.createTextResponse(sections.join('\n').trim());
}
catch (error) {
throw new Error(`Failed to debug database schema: ${error instanceof Error ? error.message : String(error)}`);
}
}
async analyzeBackendLogic(args) {
try {
const analysis = await this.pythonEngine.analyzeBackendLogic(args.codeFilePath, args.errorMessage, args.logContext, args.analysisType);
const sections = [
'🔧 **Backend Logic Analysis**',
'',
fmt.formatKeyValue('Code File', args.codeFilePath),
fmt.formatKeyValue('Analysis Type', args.analysisType || 'General'),
''
];
// Code Structure
if (analysis.structure) {
sections.push(...fmt.formatSection('**Code Structure:**', [
`Functions: ${analysis.structure.functions || 0}`,
`Classes: ${analysis.structure.classes || 0}`,
`Lines of Code: ${analysis.structure.lines || 0}`
]));
}
// Error Analysis
if (analysis.errorAnalysis) {
sections.push(...fmt.formatSection('**Error Analysis:**', [
`Error Type: ${analysis.errorAnalysis.type}`,
`Root Cause: ${analysis.errorAnalysis.rootCause}`,
`Location: ${analysis.errorAnalysis.location}`
]));
}
// Logic Issues
if (analysis.logicIssues?.length > 0) {
sections.push(...fmt.formatSection('**Logic Issues:**', analysis.logicIssues.map((issue) => `⚠️ ${issue.type}: ${issue.description}`)));
}
// Suggestions
const suggestions = analysis.suggestions || [];
sections.push(...fmt.formatRecommendations(suggestions));
return this.createTextResponse(sections.join('\n').trim());
}
catch (error) {
throw new Error(`Failed to analyze backend logic: ${error instanceof Error ? error.message : String(error)}`);
}
}
async debugPythonImports(args) {
try {
const importDebug = await this.pythonEngine.debugImports(args.projectPath, args.importError);
const sections = [
'📦 **Python Import Debug**',
'',
fmt.formatKeyValue('Project Path', args.projectPath),
''
];
// Import Analysis
if (importDebug.modules?.length > 0) {
sections.push(...fmt.formatSection('**Modules Found:**', importDebug.modules.map((module) => `📄 ${module.name}: ${module.path}`)));
}
// Import Errors
if (importDebug.errors?.length > 0) {
sections.push(...fmt.formatSection('**Import Errors:**', importDebug.errors.map((error) => `❌ ${error.module}: ${error.message}`)));
}
// Path Issues
if (importDebug.pathIssues?.length > 0) {
sections.push(...fmt.formatSection('**Path Issues:**', importDebug.pathIssues.map((issue) => `⚠️ ${issue.type}: ${issue.description}`)));
}
// Solutions
const solutions = importDebug.solutions || [];
sections.push(...fmt.formatRecommendations(solutions));
return this.createTextResponse(sections.join('\n').trim());
}
catch (error) {
throw new Error(`Failed to debug Python imports: ${error instanceof Error ? error.message : String(error)}`);
}
}
async analyzeApiIntegration(args) {
try {
const apiAnalysis = await this.pythonEngine.analyzeApiIntegration(args.apiEndpointPath, args.requestData, args.responseError, args.frameworkType);
const sections = [
'🔌 **API Integration Analysis**',
'',
fmt.formatKeyValue('Endpoint File', args.apiEndpointPath),
fmt.formatKeyValue('Framework', args.frameworkType || 'Unknown'),
''
];
// Endpoint Analysis
if (apiAnalysis.endpoints?.length > 0) {
sections.push(...fmt.formatSection('**Endpoints Found:**', apiAnalysis.endpoints.map((endpoint) => `🔗 ${endpoint.method} ${endpoint.path}: ${endpoint.status}`)));
}
// Request/Response Issues
if (apiAnalysis.issues?.length > 0) {
sections.push(...fmt.formatSection('**Integration Issues:**', apiAnalysis.issues.map((issue) => `⚠️ ${issue.type}: ${issue.description}`)));
}
// Data Validation
if (apiAnalysis.validation) {
sections.push(...fmt.formatSection('**Data Validation:**', [
`Request Valid: ${apiAnalysis.validation.requestValid ? 'Yes' : 'No'}`,
`Response Valid: ${apiAnalysis.validation.responseValid ? 'Yes' : 'No'}`,
`Schema Matches: ${apiAnalysis.validation.schemaMatches ? 'Yes' : 'No'}`
]));
}
// Recommendations
const recommendations = apiAnalysis.recommendations || [];
sections.push(...fmt.formatRecommendations(recommendations));
return this.createTextResponse(sections.join('\n').trim());
}
catch (error) {
throw new Error(`Failed to analyze API integration: ${error instanceof Error ? error.message : String(error)}`);
}
}
}
//# sourceMappingURL=python-backend-handler.js.map