|
import openai |
|
import os |
|
import json |
|
|
|
def analyze_code(code: str) -> str: |
|
""" |
|
Uses OpenAI's GPT-4.1 mini model to analyze the given code. |
|
Returns the analysis as a string. |
|
""" |
|
from openai import OpenAI |
|
client = OpenAI(api_key=os.getenv("modal_api")) |
|
client.base_url = os.getenv("base_url") |
|
system_prompt = ( |
|
"You are a helpful assistant. Analyze the code given to you. " |
|
"Return your response strictly in JSON format with the following keys: " |
|
"'strength', 'weaknesses', 'speciality', 'relevance rating'. " |
|
"Do not include any other text outside the JSON." |
|
"the reply should just be the following format:" |
|
"{" |
|
" 'strength': '...', " |
|
" 'weaknesses': '...', " |
|
" 'speciality': '...', " |
|
" 'relevance rating': '...'" |
|
"}" |
|
) |
|
response = client.chat.completions.create( |
|
model="neuralmagic/Meta-Llama-3.1-8B-Instruct-quantized.w4a16", |
|
messages=[ |
|
{"role": "system", "content": system_prompt}, |
|
{"role": "user", "content": code} |
|
], |
|
max_tokens=512, |
|
temperature=0.7 |
|
) |
|
return response.choices[0].message.content |
|
|
|
def parse_llm_json_response(response: str): |
|
try: |
|
return json.loads(response) |
|
except Exception as e: |
|
return {"error": f"Failed to parse JSON: {e}", "raw": response} |
|
|
|
def combine_repo_files_for_llm(repo_dir="repo_files", output_file="combined_repo.txt"): |
|
""" |
|
Combines all .py and .md files in the given directory (recursively) into a single text file. |
|
Returns the path to the combined file. |
|
""" |
|
combined_content = [] |
|
seen_files = set() |
|
|
|
priority_files = ["app.py", "README.md"] |
|
for pf in priority_files: |
|
pf_path = os.path.join(repo_dir, pf) |
|
if os.path.isfile(pf_path): |
|
try: |
|
with open(pf_path, "r", encoding="utf-8") as f: |
|
combined_content.append(f"\n# ===== File: {pf} =====\n") |
|
combined_content.append(f.read()) |
|
seen_files.add(os.path.abspath(pf_path)) |
|
except Exception as e: |
|
combined_content.append(f"\n# Could not read {pf_path}: {e}\n") |
|
|
|
for root, _, files in os.walk(repo_dir): |
|
for file in files: |
|
if file.endswith(".py") or file.endswith(".md"): |
|
file_path = os.path.join(root, file) |
|
abs_path = os.path.abspath(file_path) |
|
if abs_path in seen_files: |
|
continue |
|
try: |
|
with open(file_path, "r", encoding="utf-8") as f: |
|
combined_content.append(f"\n# ===== File: {file} =====\n") |
|
combined_content.append(f.read()) |
|
seen_files.add(abs_path) |
|
except Exception as e: |
|
combined_content.append(f"\n# Could not read {file_path}: {e}\n") |
|
with open(output_file, "w", encoding="utf-8") as out_f: |
|
out_f.write("\n".join(combined_content)) |
|
return output_file |
|
|
|
def analyze_combined_file(output_file="combined_repo.txt"): |
|
""" |
|
Reads the combined file and passes its contents to analyze_code, returning the LLM's output. |
|
""" |
|
try: |
|
with open(output_file, "r", encoding="utf-8") as f: |
|
lines = f.readlines() |
|
code = "".join(lines[:500]) |
|
return analyze_code(code) |
|
except Exception as e: |
|
return f"Error analyzing combined file: {e}" |
|
|