File size: 9,192 Bytes
feb8f14 |
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 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
import gradio as gr
import os
import logging
from typing import List, Dict, Tuple
from analyzer import combine_repo_files_for_llm, handle_load_repository
from hf_utils import download_filtered_space_files
# Setup logger
logger = logging.getLogger(__name__)
def create_repo_explorer_tab() -> Tuple[Dict[str, gr.components.Component], Dict[str, gr.State]]:
"""
Creates the Repo Explorer tab content and returns the component references and state variables.
"""
# State variables for repo explorer
states = {
"repo_context_summary": gr.State(""),
"current_repo_id": gr.State("")
}
gr.Markdown("### ποΈ Deep Dive into a Specific Repository")
with gr.Row():
with gr.Column(scale=2):
repo_explorer_input = gr.Textbox(
label="π Repository ID",
placeholder="microsoft/DialoGPT-medium",
info="Enter a Hugging Face repository ID to explore"
)
with gr.Column(scale=1):
load_repo_btn = gr.Button("π Load Repository", variant="primary", size="lg")
with gr.Row():
repo_status_display = gr.Textbox(
label="π Repository Status",
interactive=False,
lines=3,
info="Current repository loading status and basic info"
)
with gr.Row():
with gr.Column(scale=2):
repo_chatbot = gr.Chatbot(
label="π€ Repository Assistant",
height=400,
type="messages",
avatar_images=(
"https://cdn-icons-png.flaticon.com/512/149/149071.png",
"https://huggingface.co/datasets/huggingface/brand-assets/resolve/main/hf-logo.png"
),
show_copy_button=True,
value=[] # Start empty - welcome message will appear only after repo is loaded
)
with gr.Row():
repo_msg_input = gr.Textbox(
label="π Ask about this repository",
placeholder="What does this repository do? How do I use it?",
lines=1,
scale=4,
info="Ask anything about the loaded repository"
)
repo_send_btn = gr.Button("π€ Send", variant="primary", scale=1)
# with gr.Column(scale=1):
# # Repository content preview
# repo_content_display = gr.Textbox(
# label="π Repository Content Preview",
# lines=20,
# show_copy_button=True,
# interactive=False,
# info="Overview of the loaded repository structure and content"
# )
# Component references
components = {
"repo_explorer_input": repo_explorer_input,
"load_repo_btn": load_repo_btn,
"repo_status_display": repo_status_display,
"repo_chatbot": repo_chatbot,
"repo_msg_input": repo_msg_input,
"repo_send_btn": repo_send_btn,
# "repo_content_display": repo_content_display
}
return components, states
def handle_repo_user_message(user_message: str, history: List[Dict[str, str]], repo_context_summary: str, repo_id: str) -> Tuple[List[Dict[str, str]], str]:
"""Handle user messages in the repo-specific chatbot."""
if not repo_context_summary.strip():
return history, ""
# Initialize with repository-specific welcome message if empty
if not history:
welcome_msg = f"Hello! I'm your assistant for the '{repo_id}' repository. I have analyzed all the files and created a comprehensive understanding of this repository. I'm ready to answer any questions about its functionality, usage, architecture, and more. What would you like to know?"
history = [{"role": "assistant", "content": welcome_msg}]
if user_message:
history.append({"role": "user", "content": user_message})
return history, ""
def handle_repo_bot_response(history: List[Dict[str, str]], repo_context_summary: str, repo_id: str) -> List[Dict[str, str]]:
"""Generate bot response for repo-specific questions using comprehensive context."""
if not history or history[-1]["role"] != "user" or not repo_context_summary.strip():
return history
user_message = history[-1]["content"]
# Create a specialized prompt using the comprehensive context summary
repo_system_prompt = f"""You are an expert assistant for the Hugging Face repository '{repo_id}'.
You have comprehensive knowledge about this repository based on detailed analysis of all its files and components.
Use the following comprehensive analysis to answer user questions accurately and helpfully:
{repo_context_summary}
Instructions:
- Answer questions clearly and conversationally about this specific repository
- Reference specific components, functions, or features when relevant
- Provide practical guidance on installation, usage, and implementation
- If asked about code details, refer to the analysis above
- Be helpful and informative while staying focused on this repository
- If something isn't covered in the analysis, acknowledge the limitation
Answer the user's question based on your comprehensive knowledge of this repository."""
try:
from openai import OpenAI
client = OpenAI(api_key=os.getenv("modal_api"))
client.base_url = os.getenv("base_url")
response = client.chat.completions.create(
model="Orion-zhen/Qwen2.5-Coder-7B-Instruct-AWQ",
messages=[
{"role": "system", "content": repo_system_prompt},
{"role": "user", "content": user_message}
],
max_tokens=1024,
temperature=0.7
)
bot_response = response.choices[0].message.content
history.append({"role": "assistant", "content": bot_response})
except Exception as e:
logger.error(f"Error generating repo bot response: {e}")
error_response = f"I apologize, but I encountered an error while processing your question: {e}"
history.append({"role": "assistant", "content": error_response})
return history
def initialize_repo_chatbot(repo_status: str, repo_id: str, repo_context_summary: str) -> List[Dict[str, str]]:
"""Initialize the repository chatbot with a welcome message after successful repo loading."""
# Only initialize if repository was loaded successfully
if repo_context_summary.strip() and "successfully" in repo_status.lower():
welcome_msg = f"π Welcome! I've successfully analyzed the **{repo_id}** repository.\n\nπ§ **I now have comprehensive knowledge of:**\nβ’ All files and code structure\nβ’ Key features and capabilities\nβ’ Installation and usage instructions\nβ’ Architecture and implementation details\nβ’ Dependencies and requirements\n\nπ¬ **Ask me anything about this repository!** \nFor example:\nβ’ \"What does this repository do?\"\nβ’ \"How do I install and use it?\"\nβ’ \"What are the main components?\"\nβ’ \"Show me usage examples\"\n\nWhat would you like to know? π€"
return [{"role": "assistant", "content": welcome_msg}]
else:
# Keep chatbot empty if loading failed
return []
def setup_repo_explorer_events(components: Dict[str, gr.components.Component], states: Dict[str, gr.State]):
"""Setup event handlers for the repo explorer components."""
# Load repository event
components["load_repo_btn"].click(
fn=handle_load_repository,
inputs=[components["repo_explorer_input"]],
outputs=[components["repo_status_display"], states["repo_context_summary"]]
).then(
fn=lambda repo_id: repo_id,
inputs=[components["repo_explorer_input"]],
outputs=[states["current_repo_id"]]
).then(
fn=initialize_repo_chatbot,
inputs=[components["repo_status_display"], states["current_repo_id"], states["repo_context_summary"]],
outputs=[components["repo_chatbot"]]
)
# Chat message submission events
components["repo_msg_input"].submit(
fn=handle_repo_user_message,
inputs=[components["repo_msg_input"], components["repo_chatbot"], states["repo_context_summary"], states["current_repo_id"]],
outputs=[components["repo_chatbot"], components["repo_msg_input"]]
).then(
fn=handle_repo_bot_response,
inputs=[components["repo_chatbot"], states["repo_context_summary"], states["current_repo_id"]],
outputs=[components["repo_chatbot"]]
)
components["repo_send_btn"].click(
fn=handle_repo_user_message,
inputs=[components["repo_msg_input"], components["repo_chatbot"], states["repo_context_summary"], states["current_repo_id"]],
outputs=[components["repo_chatbot"], components["repo_msg_input"]]
).then(
fn=handle_repo_bot_response,
inputs=[components["repo_chatbot"], states["repo_context_summary"], states["current_repo_id"]],
outputs=[components["repo_chatbot"]]
) |