import os import requests from datetime import datetime import gradio as gr from gradio import components import openai from langchain_openai import ChatOpenAI from langchain.chains.summarize import load_summarize_chain from langchain.docstore.document import Document def comment_datetime(comment_json): dt = datetime.fromisoformat(comment_json["created_at"][:-1]) return comment_json["user"]["login"] + " commented on " + dt.strftime("%b %d, %Y") + ":" str_format = """ {author}\n {comment} """.strip() def get_comments(url): response = requests.get(url, headers=None) json_content = response.json() comments = "<|endoftext|>".join([str_format.format(author=comment_datetime(x).strip(), comment=x["body"].strip()) for x in json_content]) return comments template = """ ### ISSUE #{issue_num}\n ### TITLE: {title}\n ### URL: {html_url}\n ### LABELS: {labels}\n ### BODY:\n {body}\n ### COMMENTS:\n {comments}\n """.strip() def get_full_context(row): labels = row["labels"].split("<|endoftext|>") comments = row["comments"].replace("<|endoftext|>", "\n\n") context = template.format( issue_num=row["issue_num"], url=row["url"], comments_url=row["comments_url"], html_url=row["html_url"], title=row["title"], labels=labels, body=row["body"], comments=comments ) return context def get_issue_info(url): url_items = url.split("/") url_api = "https://api.github.com/repos/{}/{}/issues/{}".format(url_items[-4], url_items[-3], url_items[-1]) headers = {"Authorization": f"token {os.getenv('GITHUB_TOKEN')}"} response = requests.get(url_api, headers=None) issue = response.json() issue_short = {k: v for k, v in issue.items() if k in ["id", "url", "comments_url", "html_url", "title", "body"]} issue_short["labels"] = "<|endoftext|>".join([x["name"] for x in issue["labels"]]) issue_short["issue_num"] = issue["number"] issue_short["comment_count"] = issue["comments"] # get comments issue_short["comments"] = get_comments(issue_short["comments_url"]) # get context context = get_full_context(issue_short) return context def init_chain(openai_api_key): llm = ChatOpenAI( model_name="gpt-4o", temperature=0.0, openai_api_key=openai_api_key ) chain = load_summarize_chain(llm, chain_type="stuff") return chain def get_summary(text, chain): doc = Document(page_content=text) summary = chain.invoke([doc])["output_text"].strip() return summary template_output = """ ## SUMMARY 📝 ### {summary} *** ## Source 👾 {context} """.strip() def run_all(openai_api_key, url): try: context = get_issue_info(url) except (IndexError, KeyError) as error: return "## Invalid Github Issue URL.\n ## See examples below for reference." try: chain = init_chain(openai_api_key) summary = get_summary(context, chain) print(summary) return template_output.format(summary=summary, context=context) except (ValueError, openai.AuthenticationError) as error: return "## Invalid OpenAI API key provided." html = """

GitHub Issue Summarizer

""".strip() examples = [ [None, "https://github.com/rust-lang/rust/issues/97362"], [None, "https://github.com/rust-lang/rust/issues/83788"], [None, "https://github.com/langchain-ai/langchain/issues/9733"], [None, "https://github.com/huggingface/transformers/issues/25720"] ] with gr.Blocks() as demo: with gr.Row(): gr.HTML(html) with gr.Row(): with gr.Column(): with gr.Row(): textbox_api_key = components.Textbox(placeholder="sk-...", label="OpenAI API Key", value=None, type="password") with gr.Row(): textbox = gr.Textbox(label="Type a GitHub Issue URL:", placeholder="https://github.com/rust-lang/rust/issues/97362", lines=1) with gr.Row(): summarize = gr.Button("Summarize", variant="primary") clear_button = gr.ClearButton() with gr.Row(): gr.Examples(examples=examples, inputs=[textbox_api_key, textbox]) with gr.Column(scale=1, min_width=1000): summary = gr.Markdown(value="Summary") summarize.click(run_all, [textbox_api_key, textbox], outputs=summary) clear_button.click(fn=lambda: [None, None, "Summary"], outputs=[textbox_api_key, textbox, summary]) demo.launch()