| 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): |
| |
| 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() |
| 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: |
| |
| Repo.clone_from(req.repo_url, temp_dir, branch='main', depth=1) |
| |
| |
| repo_analysis = analyze_repo(temp_dir) |
|
|
| |
| 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. |
| |
| ... |
| """ |
|
|
| |
| 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 |