File size: 3,757 Bytes
b90747c 1eb338d b90747c 1eb338d b90747c 1eb338d b90747c 1eb338d b90747c 1eb338d b90747c 1eb338d b90747c 1eb338d b90747c 1eb338d b90747c 1eb338d b90747c 1eb338d 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 131 132 133 134 135 136 |
import modal
HF_SECRET_NAME = "hf-secret"
MODEL_ID = "google/gemma-3-12b-it"
image = (
modal.Image.debian_slim(python_version="3.12")
.apt_install("git")
.pip_install(
"smolagents[toolkit]",
"huggingface_hub",
"transformers",
"duckduckgo-search",
"fastapi",
"uvicorn",
"GitPython"
)
)
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():
import os
import tempfile
import shutil
from git import Repo
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from smolagents import CodeAgent, HfApiModel, DuckDuckGoSearchTool
class RepoRequest(BaseModel):
repo_url: str
agent = CodeAgent(
model=HfApiModel(),
tools=[],
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')):
file_path = os.path.join(root, file)
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read() # Read first 1000 characters
filtered_lines = [
line for line in content.splitlines()
if not (
line.strip().startswith('#')
or line.strip().startswith('import')
or line.strip().startswith('from')
)
]
filtered_content = "\n".join(filtered_lines)
repo_summary.append(f"File: {file}\n Content: {filtered_content}...")
except Exception:
raise f"File: {file} [Error reading file]"
return "\n".join(repo_summary)[:500]
@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}
It would be good if the README.md includes the following contents:
- Repository name
- Project description
- Contributing guidelines
Format using markdown with proper sections.
Here is an example of the style and detail you should provide:
---
# ExampleProject
A Python package for advanced data analysis and visualization.
## Installation
```
pip install exampleproject
```
## Usage
```
from exampleproject import analyze
analyze('data.csv')
```
## Contribution
Contributions are welcome! Please open an issue or submit a pull request.
...
"""
# 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 |