dbgagent 0.1.0__tar.gz

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.
@@ -0,0 +1,83 @@
1
+ Metadata-Version: 2.4
2
+ Name: dbgagent
3
+ Version: 0.1.0
4
+ Summary: AI-powered Python debugger — run a broken script, get root cause, explanation, and fix
5
+ Author: Aryan Tyagi
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/aryantyagi2211/Debug_agent
8
+ Project-URL: Issues, https://github.com/aryantyagi2211/Debug_agent/issues
9
+ Keywords: debugger,python,ai,llm,groq
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Operating System :: OS Independent
13
+ Requires-Python: >=3.10
14
+ Description-Content-Type: text/markdown
15
+ Requires-Dist: groq
16
+ Requires-Dist: python-dotenv
17
+ Requires-Dist: rich
18
+
19
+ # Debug_agent
20
+
21
+ AI-powered Python debugger. Run a broken script, get a structured diagnosis with root cause, explanation, and proposed fix.
22
+
23
+ ## Install
24
+
25
+ ```bash
26
+ pip install debugagent
27
+ ```
28
+
29
+ ## Setup
30
+
31
+ Create a `.env` file in your project folder:
32
+
33
+ ```
34
+ GROQ_API_KEY=your_groq_api_key_here
35
+ ```
36
+
37
+ Get a free API key at [console.groq.com](https://console.groq.com).
38
+
39
+ ## Usage
40
+
41
+ ```bash
42
+ debugagent run brokenscript.py
43
+ ```
44
+
45
+ That's it. It will:
46
+ 1. Run your script and capture the error
47
+ 2. Read the source code around the error
48
+ 3. Check requirements.txt and git diff
49
+ 4. Send everything to an LLM and return a structured diagnosis
50
+
51
+ ## Example
52
+
53
+ ```
54
+ $ debugagent run brokenscript.py
55
+
56
+ Running: brokenscript.py
57
+
58
+ Script failed (exit 1)
59
+
60
+ ╭─────────────── Traceback ───────────────╮
61
+ │ Traceback (most recent call last): │
62
+ │ File "brokenscript.py", line 1 │
63
+ │ import nonexistent_module │
64
+ │ ModuleNotFoundError: ... │
65
+ ╰─────────────────────────────────────────╯
66
+
67
+ Analyzing with LLM...
68
+
69
+ ╭─────────────── Root Cause ──────────────╮
70
+ │ The module does not exist │
71
+ ╰─────────────────────────────────────────╯
72
+ ╭─────────────── Explanation ─────────────╮
73
+ │ The import statement references a │
74
+ │ module that is not installed... │
75
+ ╰─────────────────────────────────────────╯
76
+ ╭─────────────── Proposed Fix ────────────╮
77
+ │ Install the module or remove the import │
78
+ ╰─────────────────────────────────────────╯
79
+ ```
80
+
81
+ ## License
82
+
83
+ MIT
@@ -0,0 +1,65 @@
1
+ # Debug_agent
2
+
3
+ AI-powered Python debugger. Run a broken script, get a structured diagnosis with root cause, explanation, and proposed fix.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install debugagent
9
+ ```
10
+
11
+ ## Setup
12
+
13
+ Create a `.env` file in your project folder:
14
+
15
+ ```
16
+ GROQ_API_KEY=your_groq_api_key_here
17
+ ```
18
+
19
+ Get a free API key at [console.groq.com](https://console.groq.com).
20
+
21
+ ## Usage
22
+
23
+ ```bash
24
+ debugagent run brokenscript.py
25
+ ```
26
+
27
+ That's it. It will:
28
+ 1. Run your script and capture the error
29
+ 2. Read the source code around the error
30
+ 3. Check requirements.txt and git diff
31
+ 4. Send everything to an LLM and return a structured diagnosis
32
+
33
+ ## Example
34
+
35
+ ```
36
+ $ debugagent run brokenscript.py
37
+
38
+ Running: brokenscript.py
39
+
40
+ Script failed (exit 1)
41
+
42
+ ╭─────────────── Traceback ───────────────╮
43
+ │ Traceback (most recent call last): │
44
+ │ File "brokenscript.py", line 1 │
45
+ │ import nonexistent_module │
46
+ │ ModuleNotFoundError: ... │
47
+ ╰─────────────────────────────────────────╯
48
+
49
+ Analyzing with LLM...
50
+
51
+ ╭─────────────── Root Cause ──────────────╮
52
+ │ The module does not exist │
53
+ ╰─────────────────────────────────────────╯
54
+ ╭─────────────── Explanation ─────────────╮
55
+ │ The import statement references a │
56
+ │ module that is not installed... │
57
+ ╰─────────────────────────────────────────╯
58
+ ╭─────────────── Proposed Fix ────────────╮
59
+ │ Install the module or remove the import │
60
+ ╰─────────────────────────────────────────╯
61
+ ```
62
+
63
+ ## License
64
+
65
+ MIT
@@ -0,0 +1,83 @@
1
+ Metadata-Version: 2.4
2
+ Name: dbgagent
3
+ Version: 0.1.0
4
+ Summary: AI-powered Python debugger — run a broken script, get root cause, explanation, and fix
5
+ Author: Aryan Tyagi
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/aryantyagi2211/Debug_agent
8
+ Project-URL: Issues, https://github.com/aryantyagi2211/Debug_agent/issues
9
+ Keywords: debugger,python,ai,llm,groq
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Operating System :: OS Independent
13
+ Requires-Python: >=3.10
14
+ Description-Content-Type: text/markdown
15
+ Requires-Dist: groq
16
+ Requires-Dist: python-dotenv
17
+ Requires-Dist: rich
18
+
19
+ # Debug_agent
20
+
21
+ AI-powered Python debugger. Run a broken script, get a structured diagnosis with root cause, explanation, and proposed fix.
22
+
23
+ ## Install
24
+
25
+ ```bash
26
+ pip install debugagent
27
+ ```
28
+
29
+ ## Setup
30
+
31
+ Create a `.env` file in your project folder:
32
+
33
+ ```
34
+ GROQ_API_KEY=your_groq_api_key_here
35
+ ```
36
+
37
+ Get a free API key at [console.groq.com](https://console.groq.com).
38
+
39
+ ## Usage
40
+
41
+ ```bash
42
+ debugagent run brokenscript.py
43
+ ```
44
+
45
+ That's it. It will:
46
+ 1. Run your script and capture the error
47
+ 2. Read the source code around the error
48
+ 3. Check requirements.txt and git diff
49
+ 4. Send everything to an LLM and return a structured diagnosis
50
+
51
+ ## Example
52
+
53
+ ```
54
+ $ debugagent run brokenscript.py
55
+
56
+ Running: brokenscript.py
57
+
58
+ Script failed (exit 1)
59
+
60
+ ╭─────────────── Traceback ───────────────╮
61
+ │ Traceback (most recent call last): │
62
+ │ File "brokenscript.py", line 1 │
63
+ │ import nonexistent_module │
64
+ │ ModuleNotFoundError: ... │
65
+ ╰─────────────────────────────────────────╯
66
+
67
+ Analyzing with LLM...
68
+
69
+ ╭─────────────── Root Cause ──────────────╮
70
+ │ The module does not exist │
71
+ ╰─────────────────────────────────────────╯
72
+ ╭─────────────── Explanation ─────────────╮
73
+ │ The import statement references a │
74
+ │ module that is not installed... │
75
+ ╰─────────────────────────────────────────╯
76
+ ╭─────────────── Proposed Fix ────────────╮
77
+ │ Install the module or remove the import │
78
+ ╰─────────────────────────────────────────╯
79
+ ```
80
+
81
+ ## License
82
+
83
+ MIT
@@ -0,0 +1,13 @@
1
+ README.md
2
+ pyproject.toml
3
+ dbgagent.egg-info/PKG-INFO
4
+ dbgagent.egg-info/SOURCES.txt
5
+ dbgagent.egg-info/dependency_links.txt
6
+ dbgagent.egg-info/entry_points.txt
7
+ dbgagent.egg-info/requires.txt
8
+ dbgagent.egg-info/top_level.txt
9
+ debug_agent/__init__.py
10
+ debug_agent/agent.py
11
+ debug_agent/cli.py
12
+ debug_agent/context.py
13
+ debug_agent/runner.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ debugagent = debug_agent.cli:main
@@ -0,0 +1,3 @@
1
+ groq
2
+ python-dotenv
3
+ rich
@@ -0,0 +1 @@
1
+ debug_agent
File without changes
@@ -0,0 +1,62 @@
1
+ import json
2
+ import os
3
+ from groq import Groq
4
+
5
+ from .runner import RunResult
6
+ from .context import gather_context
7
+
8
+ SYSTEM_PROMPT = """\
9
+ You are a Python debugging assistant. Given a traceback, source code context, \
10
+ and project info, produce a JSON object with exactly these fields:
11
+
12
+ {
13
+ "root_cause": "concise description of the root cause",
14
+ "explanation": "detailed explanation of why the error occurs",
15
+ "proposed_fix": "specific code or steps to fix the issue"
16
+ }
17
+
18
+ Respond ONLY with valid JSON. No markdown, no extra text.
19
+ """
20
+
21
+
22
+ def _parse_response(raw: str) -> dict:
23
+ text = raw.strip()
24
+ if text.startswith("```"):
25
+ text = text.split("\n", 1)[1]
26
+ if text.endswith("```"):
27
+ text = text[: -3].rstrip()
28
+ return json.loads(text)
29
+
30
+
31
+ def analyze(result: RunResult) -> dict:
32
+ api_key = os.environ.get("GROQ_API_KEY")
33
+ if not api_key:
34
+ raise RuntimeError("GROQ_API_KEY not set. Add it to .env or export it.")
35
+
36
+ ctx = gather_context(result.error_file or "", result.error_line)
37
+ prompt = (
38
+ f"## Traceback\n```\n{result.traceback}\n```\n\n"
39
+ f"## Error\nType: {result.error_type}\nMessage: {result.error_message}\n\n"
40
+ f"## Source around error line\n```\n{ctx['source_snippet']}\n```\n\n"
41
+ f"## Project context\n{ctx['requirements']}\n\n"
42
+ f"## Recent changes\n{ctx['git_diff']}\n"
43
+ )
44
+
45
+ client = Groq(api_key=api_key)
46
+ last_error = None
47
+ for _ in range(2):
48
+ try:
49
+ resp = client.chat.completions.create(
50
+ model="llama-3.3-70b-versatile",
51
+ messages=[
52
+ {"role": "system", "content": SYSTEM_PROMPT},
53
+ {"role": "user", "content": prompt},
54
+ ],
55
+ temperature=0.1,
56
+ max_tokens=1024,
57
+ )
58
+ return _parse_response(resp.choices[0].message.content)
59
+ except Exception as e:
60
+ last_error = e
61
+
62
+ raise RuntimeError(f"Failed to parse LLM response after 2 attempts.\nLast error: {last_error}")
@@ -0,0 +1,55 @@
1
+ import argparse
2
+ import sys
3
+
4
+ from dotenv import load_dotenv
5
+ from rich.console import Console
6
+ from rich.panel import Panel
7
+
8
+ from .runner import run_script
9
+ from .agent import analyze
10
+
11
+
12
+ def main():
13
+ load_dotenv()
14
+ console = Console()
15
+
16
+ parser = argparse.ArgumentParser(prog="debugagent", description="Run a Python script, capture errors, and get AI-powered debugging help.")
17
+ sub = parser.add_subparsers(dest="command")
18
+ run_parser = sub.add_parser("run", help="Run and debug a Python script")
19
+ run_parser.add_argument("script", help="Path to the Python script to debug")
20
+
21
+ args = parser.parse_args()
22
+ if args.command != "run":
23
+ parser.print_help()
24
+ sys.exit(1)
25
+
26
+ console.print(f"[bold cyan]Running:[/] {args.script}\n")
27
+
28
+ try:
29
+ result = run_script(args.script)
30
+ except (FileNotFoundError, PermissionError, ValueError) as e:
31
+ console.print(f"[bold red]Error:[/] {e}")
32
+ sys.exit(1)
33
+
34
+ if result.returncode == 0:
35
+ console.print("[bold green]Script ran successfully.[/] No errors to debug.")
36
+ if result.stdout:
37
+ console.print(f"\n[dim]stdout:[/]\n{result.stdout}")
38
+ sys.exit(0)
39
+
40
+ console.print(f"[bold red]Script failed (exit {result.returncode})[/]\n")
41
+ console.print(Panel(result.traceback, title="Traceback", border_style="red"))
42
+
43
+ console.print("[bold yellow]Analyzing with LLM...[/]\n")
44
+ try:
45
+ analysis = analyze(result)
46
+ except RuntimeError as e:
47
+ console.print(f"[bold red]Agent error:[/] {e}")
48
+ sys.exit(1)
49
+
50
+ for key, title, color in [("root_cause", "Root Cause", "red"), ("explanation", "Explanation", "yellow"), ("proposed_fix", "Proposed Fix", "green")]:
51
+ console.print(Panel(analysis[key], title=title, border_style=color))
52
+
53
+
54
+ if __name__ == "__main__":
55
+ main()
@@ -0,0 +1,40 @@
1
+ import subprocess
2
+ from pathlib import Path
3
+
4
+
5
+ def read_file_around_error(file_path: str, line_number: int, radius: int = 15) -> str:
6
+ path = Path(file_path)
7
+ if not path.exists():
8
+ return f"[File not found: {file_path}]"
9
+ try:
10
+ lines = path.read_text(encoding="utf-8", errors="replace").splitlines()
11
+ except Exception as e:
12
+ return f"[Error reading file: {e}]"
13
+
14
+ start, end = max(0, line_number - radius - 1), min(len(lines), line_number + radius)
15
+ return "\n".join(
16
+ ("%s %4d | %s" % (">>>" if i == line_number - 1 else " ", i + 1, lines[i]))
17
+ for i in range(start, end)
18
+ )
19
+
20
+
21
+ def gather_context(error_file: str, error_line: int | None) -> dict:
22
+ source = read_file_around_error(error_file, error_line) if error_line else "No error line."
23
+
24
+ req_path = Path(error_file).parent / "requirements.txt"
25
+ requirements = f"requirements.txt:\n{req_path.read_text('utf-8', errors='replace')}" if req_path.exists() else "No requirements.txt."
26
+
27
+ try:
28
+ diff = subprocess.run(
29
+ ["git", "diff", "HEAD"], capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=10,
30
+ )
31
+ git_diff = f"git diff HEAD:\n{diff.stdout}" if diff.returncode == 0 and diff.stdout.strip() else "No uncommitted changes."
32
+ except (FileNotFoundError, Exception):
33
+ git_diff = "Git not available."
34
+
35
+ # ponytail: hard truncation keeps prompt under Groq free-tier 12k TPM limit
36
+ return {
37
+ "source_snippet": source[:2000],
38
+ "requirements": requirements[:1000],
39
+ "git_diff": git_diff[:2000],
40
+ }
@@ -0,0 +1,69 @@
1
+ import re
2
+ import subprocess
3
+ import sys
4
+ from dataclasses import dataclass
5
+ from pathlib import Path
6
+
7
+
8
+ @dataclass
9
+ class RunResult:
10
+ stdout: str
11
+ stderr: str
12
+ traceback: str
13
+ returncode: int
14
+ error_type: str | None
15
+ error_message: str | None
16
+ error_line: int | None
17
+ error_file: str | None
18
+
19
+
20
+ def run_script(script_path: str) -> RunResult:
21
+ path = Path(script_path)
22
+
23
+ if not path.exists():
24
+ raise FileNotFoundError(f"Script not found: {script_path}")
25
+ if path.suffix != ".py":
26
+ raise ValueError(f"Not a Python file: {script_path}")
27
+
28
+ try:
29
+ proc = subprocess.run(
30
+ [sys.executable, str(path.resolve())],
31
+ capture_output=True,
32
+ text=True,
33
+ encoding="utf-8",
34
+ errors="replace",
35
+ timeout=30,
36
+ )
37
+ except PermissionError as e:
38
+ raise PermissionError(f"Permission denied executing {script_path}: {e}")
39
+
40
+ tb_lines = proc.stderr.strip().splitlines() if proc.returncode != 0 else []
41
+ error_type = error_message = error_file = error_line = None
42
+
43
+ for i, line in enumerate(tb_lines):
44
+ if line.startswith(" File ") and "line " in line:
45
+ m = re.search(r'File "(.+?)", line (\d+)', line)
46
+ if m:
47
+ error_file, error_line = m.group(1), int(m.group(2))
48
+ # skip indented lines and nested File entries to reach error message
49
+ for tail in tb_lines[i + 1 :]:
50
+ if tail.startswith(" File ") and "line " in tail:
51
+ continue
52
+ if tail.startswith(" "):
53
+ continue
54
+ if ":" in tail:
55
+ error_type, error_message = tail.split(":", 1)
56
+ error_type, error_message = error_type.strip(), error_message.strip()
57
+ break
58
+ break
59
+
60
+ return RunResult(
61
+ stdout=proc.stdout,
62
+ stderr=proc.stderr,
63
+ traceback="\n".join(tb_lines),
64
+ returncode=proc.returncode,
65
+ error_type=error_type,
66
+ error_message=error_message,
67
+ error_line=error_line,
68
+ error_file=error_file,
69
+ )
@@ -0,0 +1,33 @@
1
+ [build-system]
2
+ requires = ["setuptools>=64", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "dbgagent"
7
+ version = "0.1.0"
8
+ description = "AI-powered Python debugger — run a broken script, get root cause, explanation, and fix"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.10"
12
+ authors = [{ name = "Aryan Tyagi" }]
13
+ keywords = ["debugger", "python", "ai", "llm", "groq"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Programming Language :: Python :: 3",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+ dependencies = [
20
+ "groq",
21
+ "python-dotenv",
22
+ "rich",
23
+ ]
24
+
25
+ [project.urls]
26
+ Homepage = "https://github.com/aryantyagi2211/Debug_agent"
27
+ Issues = "https://github.com/aryantyagi2211/Debug_agent/issues"
28
+
29
+ [tool.setuptools.packages.find]
30
+ include = ["debug_agent*"]
31
+
32
+ [project.scripts]
33
+ debugagent = "debug_agent.cli:main"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+