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