diff --git a/backend/config.py b/backend/config.py index d173231..05592b0 100644 --- a/backend/config.py +++ b/backend/config.py @@ -5,7 +5,11 @@ import os ANTHROPIC_API_KEY = os.environ.get("ANTHROPIC_API_KEY", None) +# Debugging-related + SHOULD_MOCK_AI_RESPONSE = bool(os.environ.get("MOCK", False)) +IS_DEBUG_ENABLED = bool(os.environ.get("IS_DEBUG_ENABLED", False)) +DEBUG_DIR = os.environ.get("DEBUG_DIR", "") # Set to True when running in production (on the hosted version) # Used as a feature flag to enable or disable certain features diff --git a/backend/debug/DebugFileWriter.py b/backend/debug/DebugFileWriter.py new file mode 100644 index 0000000..bbcd77b --- /dev/null +++ b/backend/debug/DebugFileWriter.py @@ -0,0 +1,30 @@ +import os +import logging +import uuid + +from config import DEBUG_DIR, IS_DEBUG_ENABLED + + +class DebugFileWriter: + def __init__(self): + if not IS_DEBUG_ENABLED: + return + + try: + self.debug_artifacts_path = os.path.expanduser( + f"{DEBUG_DIR}/{str(uuid.uuid4())}" + ) + os.makedirs(self.debug_artifacts_path, exist_ok=True) + print(f"Debugging artifacts will be stored in: {self.debug_artifacts_path}") + except: + logging.error("Failed to create debug directory") + + def write_to_file(self, filename: str, content: str) -> None: + try: + with open(os.path.join(self.debug_artifacts_path, filename), "w") as file: + file.write(content) + except Exception as e: + logging.error(f"Failed to write to file: {e}") + + def extract_html_content(self, text: str) -> str: + return str(text.split("")[-1].rsplit("", 1)[0] + "") diff --git a/backend/debug/__init__.py b/backend/debug/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/llm.py b/backend/llm.py index e6e628c..3c2c853 100644 --- a/backend/llm.py +++ b/backend/llm.py @@ -3,6 +3,8 @@ from typing import Any, Awaitable, Callable, List, cast from anthropic import AsyncAnthropic from openai import AsyncOpenAI from openai.types.chat import ChatCompletionMessageParam, ChatCompletionChunk +from config import IS_DEBUG_ENABLED +from debug.DebugFileWriter import DebugFileWriter from utils import pprint_prompt @@ -142,6 +144,10 @@ async def stream_claude_response_native( prefix = "" response = None + # For debugging + full_stream = "" + debug_file_writer = DebugFileWriter() + while current_pass_num <= max_passes: current_pass_num += 1 @@ -163,10 +169,22 @@ async def stream_claude_response_native( ) as stream: async for text in stream.text_stream: print(text, end="", flush=True) + full_stream += text await callback(text) - # Return final message response = await stream.get_final_message() + response_text = response.content[0].text + + # Write each pass's code to .html file and thinking to .txt file + if IS_DEBUG_ENABLED: + debug_file_writer.write_to_file( + f"pass_{current_pass_num - 1}.html", + debug_file_writer.extract_html_content(response_text), + ) + debug_file_writer.write_to_file( + f"thinking_pass_{current_pass_num - 1}.txt", + response_text.split("")[0], + ) # Set up messages array for next pass messages += [ @@ -184,6 +202,9 @@ async def stream_claude_response_native( # Close the Anthropic client await client.close() + if IS_DEBUG_ENABLED: + debug_file_writer.write_to_file("full_stream.txt", full_stream) + if not response: raise Exception("No HTML response found in AI response") else: diff --git a/frontend/src/components/recording/ScreenRecorder.tsx b/frontend/src/components/recording/ScreenRecorder.tsx index fa1d3db..a031888 100644 --- a/frontend/src/components/recording/ScreenRecorder.tsx +++ b/frontend/src/components/recording/ScreenRecorder.tsx @@ -58,8 +58,6 @@ function ScreenRecorder({ const dataUrl = await blobToBase64DataUrl(completeBlob); - // downloadBlob(completeBlob); - setScreenRecordingDataUrl(dataUrl); setScreenRecorderState(ScreenRecorderState.FINISHED); };