Skip to main content

Overview

Splat is an AI-powered debugging CLI tool that automatically analyzes runtime errors, builds context from your codebase, and provides intelligent fixes. The system combines error parsing, dependency analysis, and LLM-powered code understanding to deliver actionable debugging insights.

Architecture

Splat’s architecture consists of three core components working together:
1

Error Capture & Parsing

Intercepts runtime errors and extracts file paths, line numbers, and stack traces
2

Context Collection

Builds a dependency graph and gathers relevant source code context
3

AI Analysis

Sends context to LLM for structured error analysis and solution generation

Workflow Diagram

Core Pipeline

1. Command Execution

Splat wraps your application’s entrypoint using subprocess execution:
relational.py
def relational_error_parsing_function(entrypoint, flag: str = "") -> Tuple[str, str, str]:
  try:
    subprocess.run(entrypoint, capture_output=True, check=True, text=True)
    return "", "", ""  # Return empty strings if no error occurs
  except subprocess.CalledProcessError as error:
    # Capture the error output to simulate the error stack
    traceback: str = error.stderr if error.stderr else str(error)
    error_information: str = str(error)
    collected_traceback_files = parse_error_stack(traceback)
The capture_output=True flag ensures both stdout and stderr are captured for analysis.

2. Error Stack Parsing

When an error occurs, Splat extracts all file paths mentioned in the traceback:
utils/utils.py
def parse_error_stack(error_info: str) -> List[str]:
  files = []
  # This regex looks for file paths in various formats
  file_pattern = re.compile(r'(?:File "([^"]+)"|\b(\S+\.py)\b)')

  for line in error_info.split('\n'):
    matches = file_pattern.findall(line)
    for match in matches:
      file_path = next((m for m in match if m), None)
      if file_path:
        file_path = file_path.strip().strip('\'\'"')
        if os.path.exists(file_path):
          files.append(file_path)

  return list(dict.fromkeys(files))
The regex pattern handles both quoted paths (File "path.py") and unquoted paths (path.py) commonly found in error tracebacks.

3. Context Packaging

Depending on the flag provided, Splat collects different levels of context:
# Only files directly mentioned in error stack
return traceback, error_information, run_mock_repopack(collected_traceback_files)

4. LLM Processing

The collected context is sent to an LLM with structured prompts:
process/process.py
def process(traceback_message: str, original_error_information: str, context: str) -> object:
  client = Groq(api_key=os.getenv("API"))

  chat_completion = client.chat.completions.create(
    messages=[
      {
        "role": "system",
        "content": "You are an expert software debugging assistant..."
      },
      {
        "role": "user",
        "content": f"Context: {context}\n\nTraceback: {traceback_message}"
      }
    ],
    model="llama3-70b-8192",
    response_format={"type": "json_object"}
  )
  return chat_completion.choices[0].message.content
Splat uses structured JSON output to ensure consistent, parseable responses from the LLM.

Response Structure

The LLM returns a structured JSON response with three key sections:
{
  "where": {
    "repository_path": "/absolute/path/to/repo",
    "file_name": "error_file.py",
    "line_number": "42"
  },
  "what": {
    "error_type": "SyntaxError",
    "description": "Unclosed parenthesis in print statement"
  },
  "how": {
    "error_origination": "42",
    "suggested_code_solution": "print(hello)"
  }
}

Interactive Terminal Display

Results are displayed using an interactive prompt:
terminalout/terminal.py
def terminalstep1(json_object):
    data = json.loads(json_object)
    print_formatted_text(HTML("🔎 <u><b>Details about error</b></u>"))
    print_formatted_text(HTML(f"✅ Error at line {data['where']['line_number']}"))
    print_formatted_text(HTML(f"✅ File: {data['where']['file_name']}"))
    print_formatted_text(HTML(f"✅ Type: {data['what']['error_type']}"))
Users can navigate with arrow keys to accept or reject the suggested fix.

Key Design Decisions

Running commands via subprocess allows Splat to intercept stderr/stdout without modifying the target application’s code.
Errors often stem from imported modules. The graph ensures the LLM sees all relevant context, not just the file where the error surfaced.
JSON output from the LLM enables programmatic parsing and consistent UI rendering, unlike free-form text responses.

Next Steps

Error Analysis

Deep dive into how Splat parses and understands errors

Dependency Graphs

Learn how Splat maps your codebase relationships

Build docs developers (and LLMs) love