File size: 10,412 Bytes
3d5faef
87ce049
65f9a95
3d5faef
87ce049
3d5faef
 
65f9a95
 
3d5faef
65f9a95
3d5faef
65f9a95
 
3d5faef
 
 
65f9a95
3d5faef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87ce049
 
3d5faef
 
65f9a95
3d5faef
87ce049
 
65f9a95
3d5faef
65f9a95
3d5faef
 
 
 
65f9a95
3d5faef
87ce049
3d5faef
65f9a95
 
 
3d5faef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87ce049
3d5faef
65f9a95
3d5faef
 
 
 
 
 
65f9a95
 
3d5faef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65f9a95
3d5faef
 
 
65f9a95
3d5faef
 
 
 
 
 
 
 
65f9a95
3d5faef
65f9a95
3d5faef
65f9a95
 
 
 
 
3d5faef
 
 
65f9a95
3d5faef
 
 
 
 
 
 
 
 
 
 
65f9a95
 
3d5faef
 
 
 
 
 
 
 
 
 
65f9a95
 
3d5faef
 
 
 
 
65f9a95
 
 
3d5faef
65f9a95
3d5faef
 
 
 
 
 
 
65f9a95
3d5faef
65f9a95
3d5faef
 
 
 
 
 
 
65f9a95
3d5faef
 
65f9a95
3d5faef
 
65f9a95
3d5faef
 
65f9a95
87ce049
3d5faef
 
 
 
65f9a95
 
 
3d5faef
65f9a95
3d5faef
65f9a95
 
 
 
 
 
 
 
 
3d5faef
 
 
 
 
 
65f9a95
 
3d5faef
65f9a95
 
 
3d5faef
 
 
 
 
 
 
 
 
65f9a95
 
87ce049
 
3d5faef
 
 
 
 
 
8afa1cf
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# app.py - Robust version with fallback
import gradio as gr
import logging
import traceback

# Set up logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# Global debugger instance
debugger = None
debugger_status = "πŸ”„ Initializing..."

def initialize_debugger():
    """Initialize the debugger with comprehensive error handling."""
    global debugger, debugger_status
    
    try:
        logger.info("πŸš€ Starting debugger initialization...")
        debugger_status = "πŸ”„ Loading AI model..."
        
        # First, try the main model wrapper
        try:
            from model_wrapper import CodeDebuggerWrapper
            logger.info("Attempting to load main model wrapper...")
            debugger = CodeDebuggerWrapper()
            debugger_status = "βœ… AI model loaded successfully!"
            logger.info("βœ… Main model wrapper loaded successfully")
            return debugger_status
            
        except Exception as main_error:
            logger.warning(f"Main model wrapper failed: {str(main_error)[:200]}...")
            logger.debug(f"Full error: {traceback.format_exc()}")
            
            # Try fallback debugger
            try:
                from model_wrapper import FallbackDebugger
                logger.info("Falling back to rule-based debugger...")
                debugger = FallbackDebugger()
                debugger_status = "⚠️ Using fallback debugger (AI model unavailable)"
                logger.info("βœ… Fallback debugger loaded")
                return debugger_status
                
            except Exception as fallback_error:
                logger.error(f"Fallback debugger also failed: {fallback_error}")
                debugger_status = "❌ Both AI and fallback debuggers failed"
                return debugger_status
    
    except Exception as critical_error:
        logger.error(f"Critical initialization error: {critical_error}")
        logger.error(f"Full traceback: {traceback.format_exc()}")
        debugger_status = f"❌ Critical error: {str(critical_error)[:100]}..."
        return debugger_status

def debug_code(code: str):
    """Debug code with comprehensive error handling."""
    global debugger, debugger_status
    
    # Input validation
    if not code or not code.strip():
        return "❌ Please paste some code to debug."
    
    # Initialize debugger if needed
    if debugger is None:
        logger.info("Debugger not initialized, initializing now...")
        status = initialize_debugger()
        if "❌" in status:
            return f"{status}\n\nπŸ”§ **Manual Analysis:**\n{manual_debug_fallback(code)}"
    
    # Try to debug with loaded debugger
    try:
        logger.info("🐞 Processing debug request...")
        result = debugger.debug(code)
        logger.info("βœ… Debug request completed")
        return result
        
    except Exception as debug_error:
        logger.error(f"Debug processing failed: {debug_error}")
        logger.error(f"Full traceback: {traceback.format_exc()}")
        
        # Ultimate fallback
        return f"❌ Debug processing failed: {str(debug_error)[:100]}...\n\nπŸ”§ **Manual Analysis:**\n{manual_debug_fallback(code)}"

def manual_debug_fallback(code: str) -> str:
    """Ultimate fallback - basic syntax checking."""
    try:
        issues = []
        lines = code.split('\n')
        
        for i, line in enumerate(lines, 1):
            stripped = line.strip()
            if not stripped or stripped.startswith('#'):
                continue
            
            # Check for missing colons
            control_keywords = ['if ', 'elif ', 'else:', 'for ', 'while ', 'def ', 'class ', 'try:', 'except', 'finally:']
            if any(keyword in stripped for keyword in control_keywords):
                if not stripped.endswith(':') and 'else:' not in stripped and 'try:' not in stripped and 'finally:' not in stripped:
                    issues.append(f"Line {i}: Possible missing colon (:)")
            
            # Check for unbalanced parentheses
            if stripped.count('(') != stripped.count(')'):
                issues.append(f"Line {i}: Unbalanced parentheses")
            
            # Check for unbalanced quotes
            single_quotes = stripped.count("'")
            double_quotes = stripped.count('"')
            if single_quotes % 2 != 0:
                issues.append(f"Line {i}: Unbalanced single quotes")
            if double_quotes % 2 != 0:
                issues.append(f"Line {i}: Unbalanced double quotes")
        
        # Generate response
        result = f"**Your Code:**\n```python\n{code}\n```\n\n"
        
        if issues:
            result += "**Potential Issues Found:**\n"
            for issue in issues:
                result += f"β€’ {issue}\n"
        else:
            result += "**No obvious syntax errors detected.**\n"
        
        result += "\n**Debugging Checklist:**\n"
        result += "β€’ βœ“ Check for missing colons after if/for/def statements\n"
        result += "β€’ βœ“ Verify proper indentation (4 spaces per level)\n"
        result += "β€’ βœ“ Ensure parentheses and quotes are balanced\n"
        result += "β€’ βœ“ Check for typos in variable names\n"
        result += "β€’ βœ“ Verify all imports are included\n"
        result += "β€’ βœ“ Look for logic errors in conditions\n"
        
        return result
        
    except Exception as e:
        return f"Even manual analysis failed: {e}\n\nOriginal code:\n{code}"

def get_status():
    """Get current system status."""
    global debugger_status
    return debugger_status

def create_app():
    """Create the Gradio interface."""
    
    with gr.Blocks(
        title="🐞 AI Code Debugger",
        theme=gr.themes.Soft(),
        css="""
        .status-box { 
            background: linear-gradient(45deg, #f0f0f0, #e0e0e0); 
            border-radius: 10px; 
            padding: 10px; 
        }
        .code-box {
            font-family: 'Consolas', 'Monaco', monospace;
            font-size: 14px;
        }
        """
    ) as demo:
        
        # Header
        gr.Markdown("""
        # 🐞 AI Code Debugger
        ### Fine-tuned AI model for debugging Python code
        
        **How to use:**
        1. Paste your Python code in the left box
        2. Click "πŸ”§ Debug Code" 
        3. Get AI-powered suggestions and fixes
        """)
        
        # Status display
        status_display = gr.Textbox(
            label="πŸ“Š System Status",
            value="πŸ”„ Loading...",
            interactive=False,
            elem_classes=["status-box"]
        )
        
        # Main interface
        with gr.Row():
            with gr.Column(scale=1):
                code_input = gr.Textbox(
                    lines=16,
                    placeholder="Paste your Python code here...",
                    label="πŸ” Input Code",
                    elem_classes=["code-box"],
                    value="""# Example: Function with syntax error
def calculate_average(numbers):
    total = 0
    for num in numbers
        total += num
    return total / len(numbers)

# Test with empty list (will cause error)
result = calculate_average([])
print(result)"""
                )
                
                with gr.Row():
                    debug_btn = gr.Button(
                        "πŸ”§ Debug Code", 
                        variant="primary", 
                        size="lg"
                    )
                    clear_btn = gr.Button(
                        "πŸ—‘οΈ Clear", 
                        variant="secondary"
                    )
            
            with gr.Column(scale=1):
                output = gr.Textbox(
                    lines=16,
                    label="✨ Debug Results",
                    placeholder="Debug results will appear here...",
                    elem_classes=["code-box"]
                )
        
        # Examples section
        gr.Markdown("### πŸ“š Example Problems:")
        
        example_codes = [
            # Syntax error example
            ["""def greet(name):
    if name
        print(f"Hello, {name}!")
    else:
        print("Hello, stranger!")

greet("Alice")"""],
            
            # Logic error example  
            ["""def find_maximum(numbers):
    max_num = 0  # Bug: assumes all numbers are positive
    for num in numbers:
        if num > max_num:
            max_num = num
    return max_num

result = find_maximum([-5, -2, -8, -1])
print(f"Maximum: {result}")"""],
            
            # Runtime error example
            ["""def divide_list(numbers, divisor):
    result = []
    for num in numbers:
        result.append(num / divisor)
    return result

# This will cause division by zero
data = [10, 20, 30]
divided = divide_list(data, 0)
print(divided)"""],
        ]
        
        gr.Examples(
            examples=example_codes,
            inputs=code_input,
            label="Click any example to load:"
        )
        
        # Event handlers
        debug_btn.click(
            fn=debug_code,
            inputs=code_input,
            outputs=output
        )
        
        clear_btn.click(
            lambda: ("", ""),
            outputs=[code_input, output]
        )
        
        # Initialize status on load
        demo.load(
            fn=initialize_debugger,
            outputs=status_display
        )
        
        # Footer
        gr.Markdown("""
        ---
        **Model:** `Girinath11/aiml_code_debug_model` | **Fallback:** Rule-based analysis
        
        **Tips for better results:**
        β€’ Include complete, runnable code snippets
        β€’ Add comments explaining expected behavior  
        β€’ Include any error messages you're seeing
        """)
    
    return demo

if __name__ == "__main__":
    try:
        logger.info("πŸš€ Starting Code Debugger application...")
        demo = create_app()
        
        # Launch the app
        demo.launch(
            share=True,
            server_name="0.0.0.0",
            server_port=7860,
            show_error=True
        )
        
    except Exception as e:
        logger.error(f"Failed to start application: {e}")
        logger.error(f"Full traceback: {traceback.format_exc()}")
        raise