File size: 3,915 Bytes
b90747c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
import modal
HF_SECRET_NAME = "hf-secret"
MODEL_ID = "mistralai/Mistral-7B-Instruct-v0.2"
image = (
modal.Image.debian_slim(python_version="3.12")
.pip_install(
"smolagents[toolkit]",
"huggingface_hub",
"transformers",
"duckduckgo-search",
"fastapi",
"uvicorn"
)
)
app = modal.App("auto-readme-agent")
@app.function(
image=image,
gpu="A10G",
secrets=[modal.Secret.from_name("hf-secret")],
timeout=180,
)
# @modal.asgi_app()
# def fastapi_app():
# from fastapi import FastAPI, HTTPException
# from pydantic import BaseModel
# from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel
# class AgentRequest(BaseModel):
# query: str
# # Use DuckDuckGoSearchTool as an example tool
# agent = CodeAgent(
# tools=[DuckDuckGoSearchTool()],
# model=HfApiModel(
# model_id=MODEL_ID
# ), # Uses Hugging Face Inference API with your token
# stream_outputs=True
# )
# app = FastAPI()
# @app.post("/")
# async def run_agent(req: AgentRequest):
# try:
# result = agent.run(req.query)
# return {"result": result}
# except Exception as e:
# raise HTTPException(status_code=500, detail=str(e))
# return app
@modal.asgi_app()
def fastapi_app():
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from smolagents import CodeAgent, HfApiModel
import os
import tempfile
import shutil
import subprocess
from git import Repo
class RepoRequest(BaseModel):
repo_url: str
agent = CodeAgent(
model=HfApiModel(),
stream_outputs=True
)
app = FastAPI()
def analyze_repo(repo_path):
repo_summary = []
for root, dirs, files in os.walk(repo_path):
# Skip hidden directories
dirs[:] = [d for d in dirs if not d.startswith('.')]
rel_path = os.path.relpath(root, repo_path)
repo_summary.append(f"Directory: {rel_path}")
for file in files:
if file.endswith(('.py', '.md', '.txt', '.json', '.yaml')):
file_path = os.path.join(root, file)
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read(1000) # Read first 1000 characters
repo_summary.append(f" File: {file}\n Content: {content[:500]}...")
except Exception as e:
repo_summary.append(f" File: {file} [Error reading file]")
return "\n".join(repo_summary)
@app.post("/")
async def generate_readme(req: RepoRequest):
temp_dir = tempfile.mkdtemp()
try:
# Clone repository
Repo.clone_from(req.repo_url, temp_dir, branch='main', depth=1)
# Analyze repository
repo_analysis = analyze_repo(temp_dir)
# Create prompt
prompt = f"""Create a comprehensive README.md for this GitHub repository based on its structure and contents:
Repository Structure:
{repo_analysis}
The README should include:
- Project description
- Installation instructions
- Usage examples
- Contributing guidelines
- License information if available
Format using markdown with proper sections."""
# Generate README
result = agent.run(prompt)
return {"readme": result}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
finally:
shutil.rmtree(temp_dir, ignore_errors=True)
return app |