roma-debug 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
roma_debug/prompts.py ADDED
@@ -0,0 +1,153 @@
1
+ """System prompts for ROMA Debug."""
2
+
3
+ SYSTEM_PROMPT = """You are a code repair engine. Analyze the error and context provided.
4
+
5
+ CRITICAL RULES:
6
+ 1. Return ONLY valid JSON. No markdown. No explanations outside JSON.
7
+ 2. The "full_code_block" must contain the COMPLETE corrected code for the function, class, or file segment.
8
+ 3. Do not include line numbers or markers (like ">>") in the code.
9
+ 4. Preserve all imports and dependencies that were in the original context.
10
+
11
+ OUTPUT FORMAT (strict JSON):
12
+ {
13
+ "filepath": "path/to/file.py",
14
+ "full_code_block": "def fixed_function():\\n # complete corrected code here\\n pass",
15
+ "explanation": "Brief explanation of what was fixed and why."
16
+ }
17
+
18
+ FILEPATH RULES:
19
+ - Extract the filepath from the traceback (e.g., File "/app/src/main.py", line 10).
20
+ - If the error is a GENERAL SYSTEM ERROR (API errors, network errors, configuration issues, authentication failures, etc.) where no specific source file is mentioned, set "filepath" to null.
21
+ - If the error log does not contain a clear file path, set "filepath" to null.
22
+ - DO NOT INVENT or GUESS file paths. Only use paths explicitly shown in the error traceback.
23
+ - When filepath is null, provide general advice in the explanation and example fix code in full_code_block.
24
+
25
+ Examples of when filepath should be null:
26
+ - "400 API key not valid" (configuration error)
27
+ - "Connection refused" (network error)
28
+ - "ModuleNotFoundError: No module named 'xyz'" (environment error)
29
+ - Any error without a File "..." traceback line
30
+ """
31
+
32
+ SYSTEM_PROMPT_SIMPLE = """You are a code correction engine. Do not explain the plan. Do not ask for clarification. Receive error -> Output Code Fix only."""
33
+
34
+
35
+ # V2 System Prompt for Deep Debugging
36
+ SYSTEM_PROMPT_V2 = """You are a code repair engine with deep project understanding and multi-language support.
37
+
38
+ You analyze errors across Python, JavaScript, TypeScript, Go, Rust, Java, and other languages.
39
+ You receive comprehensive context including:
40
+ - PROJECT INFORMATION: Project type, frameworks, and entry points
41
+ - ERROR ANALYSIS: Analyzed error type, category, and relevant files
42
+ - PRIMARY ERROR LOCATION: The file/function where the error occurred or relevant files
43
+ - TRACEBACK/STACK TRACE: Full call stack showing execution flow (when available)
44
+ - UPSTREAM CONTEXT: Code from imported modules that may be relevant
45
+ - KEY PROJECT FILES: Entry point code for context
46
+
47
+ Your task is to:
48
+ 1. Identify the root cause of the error (which may be in a different file than where the error surfaced)
49
+ 2. Provide a complete fix for the code
50
+ 3. Explain the fix and any root cause if it's in a different file
51
+
52
+ CRITICAL RULES:
53
+ 1. Return ONLY valid JSON. No markdown. No explanations outside JSON.
54
+ 2. The "full_code_block" must contain the COMPLETE corrected code for the entire file or function.
55
+ 3. Do not include line numbers or markers (like ">>") in the code.
56
+ 4. Preserve all imports and dependencies from the original context.
57
+ 5. Match the code style and conventions of the existing codebase.
58
+ 6. Be language-aware: use appropriate syntax for the detected language.
59
+
60
+ OUTPUT FORMAT (strict JSON):
61
+ {
62
+ "filepath": "path/to/file.ext",
63
+ "full_code_block": "complete corrected code here",
64
+ "explanation": "What was fixed and why",
65
+ "root_cause_file": "path/to/different/file.ext",
66
+ "root_cause_explanation": "If the bug originates in a different file, explain here",
67
+ "additional_fixes": [
68
+ {
69
+ "filepath": "path/to/another/file.ext",
70
+ "full_code_block": "additional fix code",
71
+ "explanation": "Why this file also needs changes"
72
+ }
73
+ ]
74
+ }
75
+
76
+ FILEPATH RULES (IMPORTANT):
77
+ - Use the exact filepath from the traceback when available.
78
+ - When PROJECT INFORMATION and RELEVANT FILES are provided, USE those file paths for the fix.
79
+ - If ERROR ANALYSIS identifies relevant files (e.g., "Relevant Files: app.py"), USE those paths.
80
+ - If you see "Entry Points: app.py" or similar, and the error relates to that file, USE that path.
81
+ - If the error originates from imported code, set "root_cause_file" to that path.
82
+ - ONLY set "filepath" to null if:
83
+ - The error is purely a configuration/environment issue (API keys, missing packages)
84
+ - No project files are provided in the context
85
+ - The error cannot be fixed by modifying any source code
86
+
87
+ ROOT CAUSE ANALYSIS:
88
+ When analyzing errors, consider:
89
+ - Is the error caused by bad data passed from another module?
90
+ - Is there a type mismatch from an upstream function?
91
+ - Are there missing validations in calling code?
92
+ - Is the error in the code itself, or in how it's being called?
93
+
94
+ If the root cause is in a DIFFERENT file than where the error occurred:
95
+ - Set "filepath" to the file that needs the primary fix
96
+ - Set "root_cause_file" to where the issue originates
97
+ - Provide fixes for both if needed via "additional_fixes"
98
+
99
+ COMMON ERROR PATTERNS:
100
+ - "Cannot GET /path" -> Usually needs route handler added to web server (app.py, server.js, etc.)
101
+ - "404 Not Found" -> Missing route or static file configuration
102
+ - "TypeError: Cannot read property" -> Null/undefined handling issue
103
+ - "AttributeError" -> Object doesn't have expected attribute
104
+
105
+ LANGUAGE-SPECIFIC NOTES:
106
+ - Python/Flask: For static file errors, check static_folder config and add serve routes
107
+ - JavaScript/Express: For routing errors, check app.use() and route handlers
108
+ - Go: Watch for nil pointers, error handling, and goroutine issues
109
+ - Rust: Watch for ownership, borrowing, and Option/Result handling
110
+
111
+ Examples of when filepath should be null:
112
+ - "400 API key not valid" (configuration error - no code fix)
113
+ - "Connection refused to external service" (network error - no code fix)
114
+ - Pure environment setup issues with no project context provided
115
+
116
+ IMPORTANT - BE THOROUGH:
117
+ 1. READ the source files provided CAREFULLY before responding
118
+ 2. UNDERSTAND what the code is doing and what it's trying to achieve
119
+ 3. IDENTIFY the actual root cause - don't assume "no changes needed"
120
+ 4. If a file is missing (like index.html), the FIX might be to:
121
+ - Add code to serve from a different location
122
+ - Add code to generate the missing file
123
+ - Change the static file configuration
124
+ 5. ALWAYS provide a working fix when source code is provided
125
+ 6. The "full_code_block" should be the COMPLETE file content ready to save
126
+
127
+ NEVER respond with "no code changes needed" if source files are provided.
128
+ There is ALWAYS a code fix when the user provides an error with source context.
129
+ """
130
+
131
+
132
+ # Prompt for explaining errors without fixing
133
+ SYSTEM_PROMPT_EXPLAIN = """You are a debugging assistant. Analyze the error and context to explain what went wrong.
134
+
135
+ OUTPUT FORMAT (strict JSON):
136
+ {
137
+ "error_type": "The type/category of error",
138
+ "error_summary": "One sentence summary of the error",
139
+ "root_cause": "Detailed explanation of why this error occurred",
140
+ "call_chain_analysis": "Analysis of how the execution flow led to this error",
141
+ "suggested_fixes": [
142
+ "First suggested approach to fix",
143
+ "Alternative approach if applicable"
144
+ ],
145
+ "related_files": ["file1.py", "file2.py"]
146
+ }
147
+
148
+ Focus on:
149
+ 1. Understanding the full call chain
150
+ 2. Identifying where data flows incorrectly
151
+ 3. Explaining the root cause clearly
152
+ 4. Suggesting practical fixes
153
+ """
roma_debug/server.py ADDED
@@ -0,0 +1,247 @@
1
+ """FastAPI Backend for ROMA Debug.
2
+
3
+ Provides V1 and V2 API endpoints for code debugging.
4
+ """
5
+
6
+ import logging
7
+ import os
8
+ from typing import Optional, List
9
+
10
+ from fastapi import FastAPI, HTTPException
11
+ from fastapi.middleware.cors import CORSMiddleware
12
+ from pydantic import BaseModel
13
+
14
+ from roma_debug import __version__
15
+ from roma_debug.config import GEMINI_API_KEY, get_api_key_status
16
+ from roma_debug.core.engine import analyze_error, analyze_error_v2
17
+ from roma_debug.core.models import Language
18
+
19
+ logger = logging.getLogger("uvicorn.error")
20
+
21
+
22
+ app = FastAPI(
23
+ title="ROMA Debug API",
24
+ description="Code debugging API powered by Gemini. Supports multi-language debugging with V2 deep analysis.",
25
+ version=__version__,
26
+ )
27
+
28
+ # Configure CORS
29
+ app.add_middleware(
30
+ CORSMiddleware,
31
+ allow_origins=["*"],
32
+ allow_credentials=True,
33
+ allow_methods=["*"],
34
+ allow_headers=["*"],
35
+ )
36
+
37
+
38
+ # V1 Models
39
+ class AnalyzeRequest(BaseModel):
40
+ """Request schema for /analyze endpoint."""
41
+ log: str
42
+ context: str = ""
43
+
44
+
45
+ class AnalyzeResponse(BaseModel):
46
+ """Response schema for /analyze endpoint."""
47
+ explanation: str
48
+ code: str
49
+ filepath: Optional[str] = None
50
+
51
+
52
+ # V2 Models
53
+ class AdditionalFixResponse(BaseModel):
54
+ """An additional fix for another file."""
55
+ filepath: str
56
+ code: str
57
+ explanation: str
58
+
59
+
60
+ class AnalyzeRequestV2(BaseModel):
61
+ """Request schema for /analyze/v2 endpoint."""
62
+ log: str
63
+ context: str = ""
64
+ project_root: Optional[str] = None
65
+ language: Optional[str] = None
66
+ include_upstream: bool = True
67
+
68
+
69
+ class AnalyzeResponseV2(BaseModel):
70
+ """Response schema for /analyze/v2 endpoint."""
71
+ explanation: str
72
+ code: str
73
+ filepath: Optional[str] = None
74
+ root_cause_file: Optional[str] = None
75
+ root_cause_explanation: Optional[str] = None
76
+ additional_fixes: List[AdditionalFixResponse] = []
77
+ model_used: str = ""
78
+
79
+
80
+ # V1 Endpoints
81
+ @app.post("/analyze", response_model=AnalyzeResponse)
82
+ async def analyze(request: AnalyzeRequest):
83
+ """Analyze an error log and return a structured code fix.
84
+
85
+ Accepts JSON { "log": "...", "context": "..." }
86
+ Returns structured fix with explanation, code, and filepath.
87
+
88
+ Args:
89
+ request: The analysis request with log and optional context
90
+
91
+ Returns:
92
+ AnalyzeResponse with explanation, code, and optional filepath
93
+
94
+ Raises:
95
+ HTTPException: If analysis fails
96
+ """
97
+ try:
98
+ result = analyze_error(request.log, request.context)
99
+ return AnalyzeResponse(
100
+ explanation=result.explanation,
101
+ code=result.full_code_block,
102
+ filepath=result.filepath,
103
+ )
104
+ except ValueError as e:
105
+ raise HTTPException(status_code=400, detail=str(e))
106
+ except Exception as e:
107
+ raise HTTPException(status_code=500, detail=f"Analysis failed: {str(e)}")
108
+
109
+
110
+ # V2 Endpoints
111
+ @app.post("/analyze/v2", response_model=AnalyzeResponseV2)
112
+ async def analyze_v2(request: AnalyzeRequestV2):
113
+ """Analyze an error with V2 deep debugging.
114
+
115
+ V2 provides:
116
+ - Multi-language support (Python, JavaScript, TypeScript, Go, Rust, Java)
117
+ - Root cause analysis across multiple files
118
+ - Import tracing and call chain analysis
119
+ - Multiple fixes when bugs span files
120
+
121
+ Accepts JSON:
122
+ {
123
+ "log": "error traceback",
124
+ "context": "optional pre-extracted context",
125
+ "project_root": "optional project root path",
126
+ "language": "optional language hint",
127
+ "include_upstream": true
128
+ }
129
+
130
+ Returns structured fix with root cause analysis.
131
+
132
+ Args:
133
+ request: V2 analysis request
134
+
135
+ Returns:
136
+ AnalyzeResponseV2 with root cause analysis and multiple fixes
137
+
138
+ Raises:
139
+ HTTPException: If analysis fails
140
+ """
141
+ try:
142
+ # Build context if not provided
143
+ context = request.context
144
+ if not context and request.project_root:
145
+ try:
146
+ from roma_debug.tracing.context_builder import ContextBuilder
147
+
148
+ language_hint = None
149
+ if request.language:
150
+ language_map = {
151
+ "python": Language.PYTHON,
152
+ "javascript": Language.JAVASCRIPT,
153
+ "typescript": Language.TYPESCRIPT,
154
+ "go": Language.GO,
155
+ "rust": Language.RUST,
156
+ "java": Language.JAVA,
157
+ }
158
+ language_hint = language_map.get(request.language.lower())
159
+
160
+ builder = ContextBuilder(project_root=request.project_root)
161
+ analysis_ctx = builder.build_analysis_context(
162
+ request.log,
163
+ language_hint=language_hint,
164
+ )
165
+ context = builder.get_context_for_prompt(
166
+ analysis_ctx,
167
+ include_upstream=request.include_upstream,
168
+ )
169
+ except Exception as e:
170
+ logger.warning(f"Context building failed, using basic context: {e}")
171
+
172
+ result = analyze_error_v2(
173
+ request.log,
174
+ context,
175
+ include_upstream=request.include_upstream,
176
+ )
177
+
178
+ return AnalyzeResponseV2(
179
+ explanation=result.explanation,
180
+ code=result.full_code_block,
181
+ filepath=result.filepath,
182
+ root_cause_file=result.root_cause_file,
183
+ root_cause_explanation=result.root_cause_explanation,
184
+ additional_fixes=[
185
+ AdditionalFixResponse(
186
+ filepath=fix.filepath,
187
+ code=fix.full_code_block,
188
+ explanation=fix.explanation,
189
+ )
190
+ for fix in result.additional_fixes
191
+ ],
192
+ model_used=result.model_used,
193
+ )
194
+ except ValueError as e:
195
+ raise HTTPException(status_code=400, detail=str(e))
196
+ except Exception as e:
197
+ logger.exception("V2 analysis failed")
198
+ raise HTTPException(status_code=500, detail=f"Analysis failed: {str(e)}")
199
+
200
+
201
+ @app.get("/health")
202
+ async def health():
203
+ """Health check endpoint."""
204
+ return {
205
+ "status": "ok",
206
+ "version": __version__,
207
+ "api_key_configured": bool(GEMINI_API_KEY),
208
+ }
209
+
210
+
211
+ @app.get("/info")
212
+ async def info():
213
+ """Get API information and capabilities."""
214
+ from roma_debug.parsers.treesitter_parser import TreeSitterParser
215
+
216
+ supported_languages = []
217
+ try:
218
+ supported_languages = [lang.value for lang in TreeSitterParser.supported_languages()]
219
+ except Exception:
220
+ supported_languages = ["python"] # Fallback
221
+
222
+ return {
223
+ "version": __version__,
224
+ "api_version": "v2",
225
+ "capabilities": {
226
+ "multi_language": True,
227
+ "deep_debugging": True,
228
+ "root_cause_analysis": True,
229
+ "multiple_fixes": True,
230
+ },
231
+ "supported_languages": supported_languages + ["python"], # Python always supported via AST
232
+ "endpoints": {
233
+ "v1": "/analyze",
234
+ "v2": "/analyze/v2",
235
+ "health": "/health",
236
+ "info": "/info",
237
+ },
238
+ }
239
+
240
+
241
+ @app.on_event("startup")
242
+ async def startup_event():
243
+ """Log startup info."""
244
+ status = get_api_key_status()
245
+ logger.info(f"Server started. Gemini API Key status: [{status}]")
246
+ logger.info(f"ROMA Debug API v{__version__} ready")
247
+ logger.info("Endpoints: /analyze (V1), /analyze/v2 (V2 with deep debugging)")
@@ -0,0 +1,28 @@
1
+ """ROMA Debug Tracing - Import resolution, dependency analysis, and project awareness.
2
+
3
+ This package provides tools for:
4
+ - Tracing imports and building dependency graphs
5
+ - Scanning and understanding project structure
6
+ - Analyzing errors to find relevant files
7
+ - Deep debugging across files
8
+ """
9
+
10
+ from roma_debug.tracing.import_resolver import ImportResolver, resolve_import
11
+ from roma_debug.tracing.dependency_graph import DependencyGraph
12
+ from roma_debug.tracing.call_chain import CallChainAnalyzer
13
+ from roma_debug.tracing.context_builder import ContextBuilder
14
+ from roma_debug.tracing.project_scanner import ProjectScanner, ProjectInfo, ProjectFile
15
+ from roma_debug.tracing.error_analyzer import ErrorAnalyzer, ErrorAnalysis
16
+
17
+ __all__ = [
18
+ "ImportResolver",
19
+ "resolve_import",
20
+ "DependencyGraph",
21
+ "CallChainAnalyzer",
22
+ "ContextBuilder",
23
+ "ProjectScanner",
24
+ "ProjectInfo",
25
+ "ProjectFile",
26
+ "ErrorAnalyzer",
27
+ "ErrorAnalysis",
28
+ ]