Spaces:
Runtime error
Runtime error
ToolStore Agent
fix: proper code bindings for debug, webapp-testing, doc-coauthoring, internal-comms toolsets
fe204a0 | """debug‑toolkit — Parse and analyze error messages and stack traces. | |
| ===============================================================""" | |
| import re | |
| from pathlib import Path | |
| try: | |
| from toolstore.toolset import tool | |
| except ImportError: | |
| def tool(fn): | |
| return fn | |
| def analyze_error(*, error_text: str) -> dict: | |
| """Parse an error message or stack trace into structured parts. | |
| Handles Python tracebacks, generic error messages, and multi-line logs. | |
| Args: | |
| error_text: The full error/stack trace text. | |
| Returns: | |
| dict with: error_type, message, file, line, traceback_frames | |
| """ | |
| result = {"error_type": "", "message": "", "file": "", "line": None, "frames": []} | |
| # Python traceback | |
| tb_match = re.search(r'Traceback \(most recent call last\):', error_text) | |
| if tb_match: | |
| frames = re.findall(r'File "(.+?)", line (\d+), in (\w+)', error_text) | |
| for fpath, lineno, func in frames: | |
| result["frames"].append({"file": fpath, "line": int(lineno), "function": func}) | |
| err_match = re.search(r'(\w+(?:Error|Exception|Warning)): (.+)', error_text) | |
| if err_match: | |
| result["error_type"] = err_match.group(1) | |
| result["message"] = err_match.group(2) | |
| if result["frames"]: | |
| result["file"] = result["frames"][-1]["file"] | |
| result["line"] = result["frames"][-1]["line"] | |
| return result | |
| # Generic error | |
| err_match = re.search(r'(\w+(?:Error|Exception|Warning)):?\s*(.+)', error_text) | |
| if err_match: | |
| result["error_type"] = err_match.group(1) | |
| result["message"] = err_match.group(2).strip() | |
| elif error_text.strip(): | |
| result["message"] = error_text.strip().split("\n")[0] | |
| return result | |
| def extract_log_patterns(*, log_text: str, pattern: str = "") -> dict: | |
| """Extract common log patterns: timestamps, IPs, error levels, URLs. | |
| Args: | |
| log_text: The log content to scan. | |
| pattern: One of "timestamps", "ips", "errors", "urls", "all". | |
| Defaults to "all". | |
| Returns: | |
| dict with found patterns grouped by type. | |
| """ | |
| patterns = {} | |
| if pattern in ("all", "timestamps"): | |
| ts = re.findall(r'\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?', log_text) | |
| if ts: | |
| patterns["timestamps"] = ts | |
| if pattern in ("all", "ips"): | |
| ips = re.findall(r'\b(?:\d{1,3}\.){3}\d{1,3}\b', log_text) | |
| if ips: | |
| # Filter valid IPs only | |
| valid = [ip for ip in ips if all(0 <= int(o) <= 255 for o in ip.split("."))] | |
| if valid: | |
| patterns["ips"] = valid[:50] | |
| if pattern in ("all", "errors"): | |
| errs = re.findall(r'(ERROR|WARN|WARNING|CRITICAL|FATAL|DEBUG|INFO|TRACE)', log_text) | |
| if errs: | |
| from collections import Counter | |
| patterns["log_levels"] = dict(Counter(errs)) | |
| if pattern in ("all", "urls"): | |
| urls = re.findall(r'https?://[^\s<>"\'\)]+', log_text) | |
| if urls: | |
| patterns["urls"] = urls[:50] | |
| patterns["total_chars"] = len(log_text) | |
| patterns["total_lines"] = log_text.count("\n") + 1 | |
| return patterns | |