|
|
import gradio as gr |
|
|
import os |
|
|
from huggingface_hub import InferenceClient |
|
|
from utils.retriever import KnowledgeRetriever |
|
|
import json |
|
|
|
|
|
class AccessibilityChatbot: |
|
|
def __init__(self): |
|
|
|
|
|
self.client = InferenceClient( |
|
|
model="deepseek-ai/DeepSeek-R1", |
|
|
token=os.getenv("HF_TOKEN") |
|
|
) |
|
|
|
|
|
|
|
|
self.retriever = KnowledgeRetriever() |
|
|
|
|
|
|
|
|
self.system_prompt = """You are an expert web accessibility instructor helping university students learn about web accessibility. |
|
|
|
|
|
Your knowledge comes from WebAIM resources, which are authoritative sources for web accessibility information. |
|
|
|
|
|
Guidelines for responses: |
|
|
1. Provide clear, student-friendly explanations |
|
|
2. Use the provided WebAIM context to answer questions accurately |
|
|
3. Always cite your sources by mentioning the WebAIM document and page number |
|
|
4. Include practical examples and code snippets when relevant |
|
|
5. Break down complex concepts into digestible parts |
|
|
6. Encourage best practices and standards compliance |
|
|
7. If asked about assignments, provide actionable guidance |
|
|
|
|
|
Remember: You're teaching students, so be encouraging and educational while maintaining accuracy.""" |
|
|
|
|
|
def generate_response(self, message, history): |
|
|
"""Generate response using DeepSeek-R1 with WebAIM context""" |
|
|
|
|
|
|
|
|
relevant_content = self.retriever.retrieve_relevant_content(message) |
|
|
context = self.retriever.format_context_for_llm(relevant_content) |
|
|
|
|
|
|
|
|
messages = [ |
|
|
{"role": "system", "content": f"{self.system_prompt}\n\nContext from WebAIM resources:\n{context}"} |
|
|
] |
|
|
|
|
|
|
|
|
for human, assistant in history: |
|
|
messages.append({"role": "user", "content": human}) |
|
|
messages.append({"role": "assistant", "content": assistant}) |
|
|
|
|
|
|
|
|
messages.append({"role": "user", "content": message}) |
|
|
|
|
|
try: |
|
|
response = self.client.chat_completion( |
|
|
messages=messages, |
|
|
max_tokens=1500, |
|
|
temperature=0.7, |
|
|
top_p=0.9 |
|
|
) |
|
|
|
|
|
assistant_response = response.choices[0].message.content |
|
|
|
|
|
|
|
|
if relevant_content: |
|
|
sources = self.format_sources(relevant_content) |
|
|
assistant_response += f"\n\n**Sources:**\n{sources}" |
|
|
|
|
|
return assistant_response |
|
|
|
|
|
except Exception as e: |
|
|
return f"I apologize, but I'm experiencing technical difficulties. Please try again. Error: {str(e)}" |
|
|
|
|
|
def format_sources(self, content_list): |
|
|
"""Format source citations for display""" |
|
|
sources = [] |
|
|
seen_sources = set() |
|
|
|
|
|
for item in content_list: |
|
|
source_key = f"{item['source_file']}_{item['page_number']}" |
|
|
if source_key not in seen_sources: |
|
|
sources.append(f"β’ {item['source_file']} (Page {item['page_number']})") |
|
|
seen_sources.add(source_key) |
|
|
|
|
|
return "\n".join(sources) |
|
|
|
|
|
|
|
|
chatbot = AccessibilityChatbot() |
|
|
|
|
|
|
|
|
def create_interface(): |
|
|
with gr.Blocks( |
|
|
title="Web Accessibility Learning Assistant", |
|
|
theme=gr.themes.Soft(), |
|
|
css=""" |
|
|
.gradio-container { |
|
|
max-width: 1000px !important; |
|
|
} |
|
|
""" |
|
|
) as demo: |
|
|
|
|
|
gr.Markdown(""" |
|
|
# π Web Accessibility Learning Assistant |
|
|
|
|
|
Welcome to your personal web accessibility tutor! I'm here to help you learn about web accessibility using **WebAIM resources** - the gold standard for accessibility guidance. |
|
|
|
|
|
## What I can help you with: |
|
|
- **WCAG Guidelines**: Understanding success criteria and implementation |
|
|
- **Screen Reader Testing**: How to test with assistive technologies |
|
|
- **Code Examples**: Accessible HTML, CSS, and JavaScript patterns |
|
|
- **Best Practices**: Real-world accessibility solutions |
|
|
- **Assignment Help**: Guidance for your accessibility projects |
|
|
|
|
|
*All answers are based on authoritative WebAIM documentation with proper citations.* |
|
|
""") |
|
|
|
|
|
|
|
|
chatbot_interface = gr.Chatbot( |
|
|
height=500, |
|
|
placeholder="π Ask me anything about web accessibility!", |
|
|
show_label=False, |
|
|
container=True, |
|
|
bubble_full_width=False |
|
|
) |
|
|
|
|
|
msg = gr.Textbox( |
|
|
placeholder="Type your question here... (e.g., 'How do I write good alt text?')", |
|
|
label="Your Question", |
|
|
lines=2, |
|
|
max_lines=4 |
|
|
) |
|
|
|
|
|
|
|
|
gr.Markdown("### π Quick Start Examples:") |
|
|
gr.Examples( |
|
|
examples=[ |
|
|
"What are the WCAG 2.1 AA requirements for color contrast?", |
|
|
"How do I make forms accessible to screen readers?", |
|
|
"What's the difference between aria-label and aria-labelledby?", |
|
|
"How can I test my website with a screen reader?", |
|
|
"What are the most common accessibility mistakes students make?", |
|
|
"How do I write effective alt text for complex images?", |
|
|
"What ARIA roles should I use for a navigation menu?", |
|
|
"How do I make data tables accessible?", |
|
|
"What are the keyboard navigation requirements?", |
|
|
"How do I ensure my site works without JavaScript?" |
|
|
], |
|
|
inputs=msg, |
|
|
examples_per_page=5 |
|
|
) |
|
|
|
|
|
|
|
|
with gr.Accordion("π Additional Learning Resources", open=False): |
|
|
gr.Markdown(""" |
|
|
### Recommended Tools: |
|
|
- **WAVE**: Web accessibility evaluation tool |
|
|
- **axe DevTools**: Browser extension for accessibility testing |
|
|
- **Lighthouse**: Built-in accessibility audit in Chrome |
|
|
- **NVDA/JAWS**: Screen readers for testing |
|
|
|
|
|
### Key Standards: |
|
|
- **WCAG 2.1**: Current web accessibility guidelines |
|
|
- **Section 508**: US federal accessibility requirements |
|
|
- **ADA**: Americans with Disabilities Act considerations |
|
|
""") |
|
|
|
|
|
|
|
|
def respond(message, history): |
|
|
if not message.strip(): |
|
|
return history, "" |
|
|
|
|
|
response = chatbot.generate_response(message, history) |
|
|
history.append((message, response)) |
|
|
return history, "" |
|
|
|
|
|
msg.submit(respond, [msg, chatbot_interface], [chatbot_interface, msg]) |
|
|
|
|
|
|
|
|
gr.Markdown(""" |
|
|
--- |
|
|
*This chatbot uses WebAIM resources and is powered by DeepSeek-R1. |
|
|
For the most up-to-date information, always refer to the original WebAIM documentation.* |
|
|
""") |
|
|
|
|
|
return demo |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
demo = create_interface() |
|
|
demo.launch() |