|
|
|
|
|
import os |
|
from dotenv import load_dotenv |
|
from github import Github, Auth |
|
|
|
|
|
from langchain_groq import ChatGroq |
|
from langchain_core.tools import tool |
|
from langchain.agents import create_tool_calling_agent, AgentExecutor |
|
|
|
|
|
load_dotenv() |
|
GROQ_API_KEY = os.getenv("GROQ_API_KEY") |
|
GITHUB_PAT = os.getenv("GITHUB_API_KEY") |
|
|
|
if not (GROQ_API_KEY and GITHUB_PAT): |
|
raise ValueError("Please set GROQ_API_KEY and GITHUB_API_KEY in your .env") |
|
|
|
|
|
_auth = Auth.Token(GITHUB_PAT) |
|
_gh = Github(auth=_auth) |
|
|
|
|
|
@tool |
|
def get_repo_info(repo_name: str) -> str: |
|
"""Fetch and summarize metadata about a GitHub repository.""" |
|
try: |
|
repo = _gh.get_repo(repo_name) |
|
except Exception as e: |
|
return f" Error fetching '{repo_name}': {e}" |
|
|
|
name = repo.full_name |
|
desc = repo.description or "No description" |
|
url = repo.html_url |
|
owner = repo.owner.login |
|
stars = repo.stargazers_count |
|
forks = repo.forks_count |
|
issues = repo.open_issues_count |
|
created = repo.created_at.isoformat() |
|
updated = repo.updated_at.isoformat() |
|
watchers = repo.watchers_count |
|
default_br = repo.default_branch |
|
language = repo.language or "None" |
|
|
|
try: |
|
license_name = repo.get_license().license.name |
|
except: |
|
license_name = "None" |
|
|
|
topics = repo.get_topics() |
|
try: |
|
raw_md = repo.get_readme().decoded_content.decode("utf-8") |
|
snippet = raw_md[:300].replace("\n", " ") + "..." |
|
except: |
|
snippet = "No README found" |
|
|
|
contribs = repo.get_contributors()[:5] |
|
contrib_list = ", ".join(f"{c.login}({c.contributions})" for c in contribs) |
|
|
|
commits = repo.get_commits()[:3] |
|
commit_list = "; ".join(c.commit.message.split("\n")[0] for c in commits) |
|
|
|
return f""" |
|
Repository: {name} |
|
Description: {desc} |
|
URL: {url} |
|
Owner: {owner} |
|
β Stars: {stars} π΄ Forks: {forks} π Open Issues: {issues} |
|
ποΈ Watchers: {watchers} Default branch: {default_br} |
|
βοΈ Language: {language} License: {license_name} |
|
π Topics: {topics} |
|
|
|
README Snippet: {snippet} |
|
|
|
π₯ Top Contributors: {contrib_list} |
|
π§Ύ Latest Commits: {commit_list} |
|
""" |
|
|
|
|
|
llm = ChatGroq( |
|
model="llama-3.1-8b-instant", |
|
temperature=0.3, |
|
max_tokens=1024, |
|
api_key=GROQ_API_KEY, |
|
) |
|
|
|
|
|
tools = [get_repo_info] |
|
|
|
|
|
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder |
|
|
|
prompt = ChatPromptTemplate.from_messages([ |
|
("system", |
|
"You are GitHub Agent, an expert at analyzing repositories.\n" |
|
"When a user asks about a repo, call the tool and return a clear, concise summary of the repository based on the tool result.\n" |
|
"Avoid repeating raw tool output or adding unnecessary disclaimers.\n" |
|
"Respond in complete sentences, in natural language." |
|
), |
|
MessagesPlaceholder(variable_name="chat_history", optional=True), |
|
("human", "{input}"), |
|
MessagesPlaceholder(variable_name="agent_scratchpad"), |
|
]) |
|
|
|
|
|
agent = create_tool_calling_agent(llm, tools, prompt) |
|
|
|
|
|
|
|
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, max_iterations=2) |
|
|
|
|
|
__all__ = ["agent_executor"] |
|
|
|
|
|
if __name__ == "__main__": |
|
import time |
|
user_input = "Give me details about the repo zamalali/deepgit" |
|
start_time = time.time() |
|
result = agent_executor.invoke({"input": user_input}) |
|
end_time = time.time() |
|
print("\n Final Answer:\n", result["output"]) |
|
print(f"\n Took {end_time - start_time:.2f} seconds") |