algospaced-dsa / llm_reviewer.py
iamfebin's picture
feat: implement sandbox mode
a95fdd1
Raw
History Blame Contribute Delete
9.56 kB
import json
import streamlit as st
from google import genai
from google.genai import types
from gdrive_sync import get_secret
def generate_content_with_fallback(client, system_instruction, user_prompt, is_json=False):
models = [
'gemini-2.5-flash',
'gemini-3.5-flash',
'gemini-3-flash-preview',
'gemini-3.1-flash-lite'
]
last_err = None
for model_name in models:
try:
if is_json:
response = client.models.generate_content(
model=model_name,
contents=user_prompt,
config=types.GenerateContentConfig(
system_instruction=system_instruction,
response_mime_type="application/json",
)
)
else:
response = client.models.generate_content(
model=model_name,
contents=user_prompt,
config=types.GenerateContentConfig(
system_instruction=system_instruction,
)
)
return response
except Exception as e:
last_err = e
continue
raise last_err if last_err else Exception("No Gemini models succeeded")
def evaluate_code(problem_name, pattern_name, expected_time, expected_space, candidate_code, custom_api_key=None):
api_key = custom_api_key or get_secret("GEMINI_API_KEY")
if not api_key:
return {"error": "GEMINI_API_KEY not found in secrets. Please configure your API key in the System Control Panel."}
client = genai.Client(api_key=api_key)
system_instruction = """
You are an expert technical interviewer evaluating a candidate's LeetCode code written from memory.
Your primary objective is to review code correctness, algorithmic efficiency, and potential edge-case failures.
Be highly forgiving of minor visual/syntax typos (e.g., off-by-one indentation, minor spelling mistakes in variables, or missing colons)
which would be caught in 1 second by a standard IDE. Focus on raw algorithmic correctness.
Return ONLY a JSON response matching the required schema. No markdown formatting blocks around the JSON.
"""
user_prompt_template = f"""
Problem Name: {problem_name}
Target Pattern: {pattern_name}
Expected Complexity: Time: {expected_time}, Space: {expected_space}
Candidate's Code Submission:
{candidate_code}
Evaluate the code logic and return the structured JSON output with the exact schema:
{{
"is_correct": boolean,
"detected_complexity": {{"time": string, "space": string}},
"bugs": [string, string, ...],
"key_suggestion": string
}}
"""
try:
response = generate_content_with_fallback(client, system_instruction, user_prompt_template, is_json=True)
# Parse the JSON output
result = json.loads(response.text)
return result
except Exception as e:
return {"error": str(e)}
def explain_code(problem_name, code, optimal_time, optimal_space, custom_api_key=None):
api_key = custom_api_key or get_secret("GEMINI_API_KEY")
if not api_key:
return {"error": "GEMINI_API_KEY not found in secrets. Please configure your API key in the System Control Panel."}
client = genai.Client(api_key=api_key)
system_instruction = """
You are an expert technical interviewer and computer science educator.
Your objective is to provide a clean, comprehensive line-by-line explanation of a LeetCode reference solution.
Analyze only the provided code block text. Do NOT suggest or write an alternative code solution.
Break down the line-by-line logic, explain the state tracking variables, and explicitly match the code to the time and space complexities saved next to it.
Format your response in beautiful, clear Markdown.
"""
user_prompt = f"""
Problem Name: {problem_name}
Expected Complexity: Time: {optimal_time}, Space: {optimal_space}
Reference Code to Explain:
```python
{code}
```
Provide the explanation satisfying the constraints:
1. Break down the line-by-line logic of the code.
2. Explain any state tracking variables (what they hold and how they evolve).
3. Explicitly explain and match why the time complexity is {optimal_time} and the space complexity is {optimal_space}.
4. Do not write any alternative code solution.
"""
try:
response = generate_content_with_fallback(client, system_instruction, user_prompt, is_json=False)
return {"explanation": response.text}
except Exception as e:
return {"error": str(e)}
def generate_daily_python_challenge(custom_api_key=None):
api_key = custom_api_key or get_secret("GEMINI_API_KEY")
if not api_key:
return {"error": "GEMINI_API_KEY not found in secrets. Please configure your API key in the System Control Panel."}
client = genai.Client(api_key=api_key)
system_instruction = """
You are an expert curriculum designer for a retro-arcade coding platform called AlgoSpaced.
Your task is to generate a new, daily python programming challenge.
The challenge should test standard core DSA concepts or standard coding tasks.
Provide test cases that check edge cases.
Return ONLY a JSON response matching the required schema. No markdown formatting blocks around the JSON.
"""
import random
concepts = [
"arrays and hashing", "two pointers", "sliding window", "stack",
"binary search", "linked lists", "trees and graphs", "heap / priority queue",
"backtracking", "dynamic programming", "greedy algorithms", "string manipulation",
"math & geometry", "bit manipulation"
]
concept = random.choice(concepts)
user_prompt = f"""
Generate a daily coding challenge on the topic: "{concept}".
Return the structured JSON output with the exact schema:
{{
"title": "string (Short creative title, max 50 chars)",
"description": "string (Markdown description of the problem, input format, output format)",
"difficulty": "string (Easy, Medium, or Hard)",
"points": number (100 for Easy, 200 for Medium, 300 for Hard),
"starter_code": "string (Python starter code ending with 'pass')",
"test_cases": [
{{
"input": [any] (list of args to pass to the function),
"expected": any (expected return value)
}},
...
]
}}
Ensure the test cases are completely valid JSON and mathematically correct.
Ensure the starter_code defines a function (e.g., 'def solve(arr):\\n pass').
"""
try:
response = generate_content_with_fallback(client, system_instruction, user_prompt, is_json=True)
result = json.loads(response.text)
return result
except Exception as e:
return {"error": str(e)}
def generate_sql_challenge(custom_api_key=None):
api_key = custom_api_key or get_secret("GEMINI_API_KEY")
if not api_key:
return {"error": "GEMINI_API_KEY not found in secrets. Please configure your API key in the System Control Panel."}
client = genai.Client(api_key=api_key)
system_instruction = """
You are an expert SQL instructor for a retro-arcade coding platform called AlgoSpaced.
Your task is to generate an interactive SQL challenge.
The challenge must test standard SQL capabilities (SELECT, JOIN, GROUP BY, Window Functions, or simple mutations like UPDATE/DELETE).
Return ONLY a JSON response matching the required schema. No markdown formatting blocks around the JSON.
"""
import random
topics = [
"Window Functions (DENSE_RANK, ROW_NUMBER, PARTITION BY)",
"Aggregations & Grouping (SUM, AVG, HAVING)",
"Subqueries & CTEs (WITH clause)",
"Table Joins & Filtering (LEFT/INNER JOIN, NULL handling)",
"Data Mutations (UPDATE balances, DELETE inactive users)"
]
topic = random.choice(topics)
user_prompt = f"""
Generate an interactive SQL challenge on the topic: "{topic}".
Return the structured JSON output with the exact schema:
{{
"title": "string (Short creative title, max 50 chars)",
"objective": "string (Describe the SQL query the user needs to write. E.g., 'Write a query using DENSE_RANK() to rank employee salaries within each department.')",
"ddl": "string (DDL statements to create 2-3 tables. Use standard SQL types compatible with SQLite/MySQL. Ensure syntax is correct.)",
"inserts": "string (INSERT statements to populate the tables with 5-10 realistic mock rows.)",
"validation_query": "string (The correct reference SQL query that fulfills the objective.)",
"challenge_type": "string ('SELECT' or 'DML' (for UPDATE/DELETE challenges))",
"points": number (e.g., 150)
}}
Ensure that the DDL and INSERT statements are correct and run sequentially without errors.
Do not use complex MySQL-specific engines or custom functions. Keep it standard SQL.
"""
try:
response = generate_content_with_fallback(client, system_instruction, user_prompt, is_json=True)
result = json.loads(response.text)
return result
except Exception as e:
return {"error": str(e)}