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