How Debugging Mode Captures and Logs Prompts and Completions in screenshot-to-code

When the IS_DEBUG_ENABLED environment flag is set, the screenshot-to-code backend automatically records every LLM prompt and the HTML portion of the first successful completion to a timestamped JSON file for later analysis.

The abi/screenshot-to-code repository provides a built-in debugging mechanism that helps developers audit exactly what data flows between the application and large language models. By toggling a single configuration flag, the system persists full prompt histories, model selections, and completion outputs to disk, enabling precise replay and troubleshooting of code generation requests.

Enabling the Debug Flag

Debugging functionality is controlled by the IS_DEBUG_ENABLED environment variable defined in backend/config.py (lines 15–18). When this flag evaluates to truthy, the backend activates additional logging throughout the request pipeline.


# backend/config.py

IS_DEBUG_ENABLED = bool(os.environ.get("IS_DEBUG_ENABLED", False))
DEBUG_DIR = os.environ.get("DEBUG_DIR", "")

Upon startup, backend/main.py (lines 16–18) prints the debug status to the console, providing immediate confirmation that the mode is active.


# backend/main.py

debug_status = "ENABLED" if IS_DEBUG_ENABLED else "DISABLED"
print(f"Backend startup complete. Debug mode is {debug_status}.")

Capturing Prompt Metadata and Model Selection

Once debugging is enabled, the system augments WebSocket communications with extra diagnostic information. In backend/routes/generate_code.py (lines 48–55), the CodeGenerationMiddleware emits a special variantModels message containing the list of model identifiers used for the request, but only when IS_DEBUG_ENABLED is true.


# backend/routes/generate_code.py

if IS_DEBUG_ENABLED:
    await context.send_message(
        "variantModels",
        None,
        0,
        {"models": [model.value for model in context.variant_models]},
        None,
    )

Additionally, the WebSocketCommunicator prints every message type—including errors, status updates, and variant progress—to the server console (lines 77–86), providing real-time visibility into the generation pipeline when debugging is active.

Extracting and Persisting Completions

After all variant generations finish, the PostProcessingStage.process_completions method in backend/routes/generate_code.py (lines 99–104) filters for valid completions, extracts the <html> fragment from the first non-empty result, and triggers the logging mechanism.


# backend/routes/generate_code.py

valid_completions = [comp for comp in completions if comp]
if valid_completions:
    html_content = extract_html_content(valid_completions[0])
    write_logs(prompt_messages, html_content)

The write_logs function in backend/fs_logging/core.py (lines 7–24) handles the actual persistence. It creates a run_logs directory under the path specified by the LOGS_PATH environment variable (defaulting to the current working directory), then writes a JSON file named messages_YYYYMMDD_HHMMSS.json containing two keys: prompt (the list of messages sent to the LLM) and completion (the extracted HTML string).


# backend/fs_logging/core.py

logs_path = os.environ.get("LOGS_PATH", os.getcwd())
logs_directory = os.path.join(logs_path, "run_logs")
os.makedirs(logs_directory, exist_ok=True)

filename = datetime.now().strftime(
    f"{logs_directory}/messages_%Y%m%d_%H%M%S.json"
)
with open(filename, "w") as f:
    f.write(json.dumps({"prompt": prompt_messages, "completion": completion}))

Optional Artifact Storage Infrastructure

For future extensibility, the repository includes a DebugFileWriter class in backend/debug/DebugFileWriter.py (lines 10–18). When instantiated, this class creates a unique per-run directory under DEBUG_DIR to store auxiliary debug artifacts, though the current implementation primarily relies on the fs_logging module for prompt and completion persistence.


# backend/debug/DebugFileWriter.py

if not IS_DEBUG_ENABLED:
    return
self.debug_artifacts_path = os.path.expanduser(
    f"{DEBUG_DIR}/{str(uuid.uuid4())}"
)
os.makedirs(self.debug_artifacts_path, exist_ok=True)

Practical Implementation Example

To activate debugging for a local development session, export the environment flag before starting the backend:

export IS_DEBUG_ENABLED=1
export LOGS_PATH=/var/log/screenshot-to-code

After running a generation request, inspect the captured data using standard file operations:

import json
from pathlib import Path

log_file = Path("/var/log/screenshot-to-code/run_logs/messages_20241012_153045.json")
data = json.loads(log_file.read_text())

# Inspect the exact prompt sent to the LLM

for message in data["prompt"]:
    print(message)

# View the extracted HTML completion

print(data["completion"])

Summary

  • Activation: Set the IS_DEBUG_ENABLED environment variable in backend/config.py to enable the debugging pipeline.
  • Metadata Capture: The backend emits a variantModels WebSocket message and prints communication logs only when debugging is active.
  • Data Extraction: The PostProcessingStage.process_completions method extracts the HTML fragment from the first valid completion and passes it to the logger.
  • Persistence: The write_logs function in backend/fs_logging/core.py writes timestamped JSON files to the run_logs directory, preserving both the full prompt array and the resulting HTML.
  • Configuration: Use LOGS_PATH to customize the output directory; use DEBUG_DIR for future artifact storage via DebugFileWriter.

Frequently Asked Questions

How do I enable debugging mode in screenshot-to-code?

Set the IS_DEBUG_ENABLED environment variable to 1 or true before starting the backend server. The startup sequence in backend/main.py will confirm the mode is active via console output.

What file format does the debugging system use to store logs?

The system writes standard JSON files named messages_YYYYMMDD_HHMMS.json containing two top-level keys: prompt (an array of message objects sent to the LLM) and completion (the extracted HTML string from the first successful response).

Where are the debug logs stored by default?

By default, logs are written to a run_logs subdirectory within the current working directory. You can override this location by setting the LOGS_PATH environment variable to an absolute path before launching the application.

Does debugging mode capture all completion variants or just the first one?

The current implementation extracts and logs the HTML content from only the first non-empty completion in the variants list, as implemented in PostProcessingStage.process_completions at lines 99–104 of backend/routes/generate_code.py.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →