|  | import os | 
					
						
						|  | import time | 
					
						
						|  | import requests | 
					
						
						|  | import gradio as gr | 
					
						
						|  | import pandas as pd | 
					
						
						|  | import random | 
					
						
						|  | import re | 
					
						
						|  | from datetime import datetime | 
					
						
						|  | from dotenv import load_dotenv | 
					
						
						|  | from together import Together | 
					
						
						|  | import openai | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | load_dotenv() | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | def process_retrieval_text(retrieval_text, user_input): | 
					
						
						|  | """ | 
					
						
						|  | Process the retrieval text by identifying proper document boundaries | 
					
						
						|  | and highlighting relevant keywords. | 
					
						
						|  | """ | 
					
						
						|  | if not retrieval_text or retrieval_text.strip() == "No retrieval text found.": | 
					
						
						|  | return retrieval_text | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | if retrieval_text.count("Doc:") > 0 and retrieval_text.count("Content:") > 0: | 
					
						
						|  |  | 
					
						
						|  | chunks = [] | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | doc_sections = re.split(r'\n\n(?=Doc:)', retrieval_text) | 
					
						
						|  |  | 
					
						
						|  | for i, section in enumerate(doc_sections): | 
					
						
						|  | if section.strip(): | 
					
						
						|  |  | 
					
						
						|  | chunks.append(f"<strong>Evidence Document {i+1}</strong><br>{section.strip()}") | 
					
						
						|  | else: | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | raw_chunks = retrieval_text.strip().split("\n\n") | 
					
						
						|  | chunks = [] | 
					
						
						|  | current_chunk = "" | 
					
						
						|  |  | 
					
						
						|  | for chunk in raw_chunks: | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | if (len(chunk) < 50 and not re.search(r'doc|document|evidence', chunk.lower())) or \ | 
					
						
						|  | not chunk.strip().startswith(("Doc", "Document", "Evidence", "Source", "Content")): | 
					
						
						|  | if current_chunk: | 
					
						
						|  | current_chunk += "\n\n" + chunk | 
					
						
						|  | else: | 
					
						
						|  | current_chunk = chunk | 
					
						
						|  | else: | 
					
						
						|  |  | 
					
						
						|  | if current_chunk: | 
					
						
						|  | chunks.append(current_chunk) | 
					
						
						|  | current_chunk = chunk | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | if current_chunk: | 
					
						
						|  | chunks.append(current_chunk) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | chunks = [f"<strong>Evidence Document {i+1}</strong><br>{chunk.strip()}" | 
					
						
						|  | for i, chunk in enumerate(chunks)] | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | keywords = re.findall(r'\b\w{4,}\b', user_input.lower()) | 
					
						
						|  | keywords = [k for k in keywords if k not in ['what', 'when', 'where', 'which', 'would', 'could', | 
					
						
						|  | 'should', 'there', 'their', 'about', 'these', 'those', | 
					
						
						|  | 'them', 'from', 'have', 'this', 'that', 'will', 'with']] | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | highlighted_chunks = [] | 
					
						
						|  | for chunk in chunks: | 
					
						
						|  | highlighted_chunk = chunk | 
					
						
						|  | for keyword in keywords: | 
					
						
						|  |  | 
					
						
						|  | pattern = r'\b(' + re.escape(keyword) + r')\b' | 
					
						
						|  | highlighted_chunk = re.sub(pattern, r'<span class="highlight-match">\1</span>', highlighted_chunk, flags=re.IGNORECASE) | 
					
						
						|  |  | 
					
						
						|  | highlighted_chunks.append(highlighted_chunk) | 
					
						
						|  |  | 
					
						
						|  | return "<br><br>".join(highlighted_chunks) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | ORACLE_API_KEY = "key-HgVH3QX0GkyPKZhS3l3QrnLAqvjR2shrPPb_WK3lmrWHPzeKU" | 
					
						
						|  | TOGETHER_API_KEY = "25e1acc0998143afee6b7cb3cb4a9447d39166be767a13a36a22da64234343de" | 
					
						
						|  | OPENAI_API_KEY = "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" | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | CUSTOM_CSS = """ | 
					
						
						|  | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap'); | 
					
						
						|  |  | 
					
						
						|  | body, .gradio-container { | 
					
						
						|  | font-family: 'All Round Gothic Demi', 'Poppins', sans-serif !important; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | .rating-box { | 
					
						
						|  | border-radius: 8px; | 
					
						
						|  | box-shadow: 0 2px 5px rgba(0,0,0,0.1); | 
					
						
						|  | padding: 15px; | 
					
						
						|  | margin-bottom: 10px; | 
					
						
						|  | transition: all 0.3s ease; | 
					
						
						|  | background-color: #ffffff; | 
					
						
						|  | position: relative; | 
					
						
						|  | overflow-y: auto; | 
					
						
						|  | white-space: pre-line; | 
					
						
						|  | font-family: 'All Round Gothic Demi', 'Poppins', sans-serif !important; | 
					
						
						|  | } | 
					
						
						|  | .rating-box:hover { | 
					
						
						|  | box-shadow: 0 5px 15px rgba(0,0,0,0.1); | 
					
						
						|  | } | 
					
						
						|  | .safe-rating { | 
					
						
						|  | border-left: 5px solid #4CAF50; | 
					
						
						|  | } | 
					
						
						|  | .warning-rating { | 
					
						
						|  | border-left: 5px solid #FCA539; | 
					
						
						|  | } | 
					
						
						|  | .unsafe-rating { | 
					
						
						|  | border-left: 5px solid #F44336; | 
					
						
						|  | } | 
					
						
						|  | .empty-rating { | 
					
						
						|  | border-left: 5px solid #FCA539; | 
					
						
						|  | display: flex; | 
					
						
						|  | align-items: center; | 
					
						
						|  | justify-content: center; | 
					
						
						|  | font-style: italic; | 
					
						
						|  | color: #999; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | /* Different heights for different rating boxes */ | 
					
						
						|  | .contextual-box { | 
					
						
						|  | min-height: 150px; | 
					
						
						|  | } | 
					
						
						|  | .secondary-box { | 
					
						
						|  | min-height: 80px; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | .result-header { | 
					
						
						|  | font-size: 18px; | 
					
						
						|  | font-weight: bold; | 
					
						
						|  | margin-bottom: 10px; | 
					
						
						|  | padding-bottom: 5px; | 
					
						
						|  | border-bottom: 1px solid #eee; | 
					
						
						|  | font-family: 'All Round Gothic Demi', 'Poppins', sans-serif !important; | 
					
						
						|  | } | 
					
						
						|  | .copy-button { | 
					
						
						|  | position: absolute; | 
					
						
						|  | top: 10px; | 
					
						
						|  | right: 10px; | 
					
						
						|  | padding: 5px 10px; | 
					
						
						|  | background: #f0f0f0; | 
					
						
						|  | border: none; | 
					
						
						|  | border-radius: 4px; | 
					
						
						|  | cursor: pointer; | 
					
						
						|  | font-size: 12px; | 
					
						
						|  | font-family: 'All Round Gothic Demi', 'Poppins', sans-serif !important; | 
					
						
						|  | } | 
					
						
						|  | .copy-button:hover { | 
					
						
						|  | background: #e0e0e0; | 
					
						
						|  | } | 
					
						
						|  | .orange-button { | 
					
						
						|  | background: #FCA539 !important; | 
					
						
						|  | color: #000000 !important; | 
					
						
						|  | font-weight: bold; | 
					
						
						|  | border-radius: 5px; | 
					
						
						|  | padding: 10px 15px; | 
					
						
						|  | box-shadow: 0 2px 5px rgba(0,0,0,0.1); | 
					
						
						|  | transition: all 0.3s ease; | 
					
						
						|  | font-family: 'All Round Gothic Demi', 'Poppins', sans-serif !important; | 
					
						
						|  | } | 
					
						
						|  | .orange-button:hover { | 
					
						
						|  | box-shadow: 0 5px 15px rgba(0,0,0,0.2); | 
					
						
						|  | transform: translateY(-2px); | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | /* Input box styling with orange border */ | 
					
						
						|  | textarea.svelte-1pie7s6 { | 
					
						
						|  | border-left: 5px solid #FCA539 !important; | 
					
						
						|  | border-radius: 8px !important; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | #loading-spinner { | 
					
						
						|  | display: none; | 
					
						
						|  | margin: 10px auto; | 
					
						
						|  | width: 100%; | 
					
						
						|  | height: 4px; | 
					
						
						|  | position: relative; | 
					
						
						|  | overflow: hidden; | 
					
						
						|  | background-color: #ddd; | 
					
						
						|  | } | 
					
						
						|  | #loading-spinner:before { | 
					
						
						|  | content: ''; | 
					
						
						|  | display: block; | 
					
						
						|  | position: absolute; | 
					
						
						|  | left: -50%; | 
					
						
						|  | width: 50%; | 
					
						
						|  | height: 100%; | 
					
						
						|  | background-color: #FCA539; | 
					
						
						|  | animation: loading 1s linear infinite; | 
					
						
						|  | } | 
					
						
						|  | @keyframes loading { | 
					
						
						|  | from {left: -50%;} | 
					
						
						|  | to {left: 100%;} | 
					
						
						|  | } | 
					
						
						|  | .loading-active { | 
					
						
						|  | display: block !important; | 
					
						
						|  | } | 
					
						
						|  | .empty-box-message { | 
					
						
						|  | color: #999; | 
					
						
						|  | font-style: italic; | 
					
						
						|  | text-align: center; | 
					
						
						|  | margin-top: 30px; | 
					
						
						|  | font-family: 'All Round Gothic Demi', 'Poppins', sans-serif !important; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | /* Knowledge Button Styling */ | 
					
						
						|  | .knowledge-button { | 
					
						
						|  | padding: 5px 10px; | 
					
						
						|  | background-color: #222222; | 
					
						
						|  | color: #ffffff !important; | 
					
						
						|  | border: none; | 
					
						
						|  | border-radius: 4px; | 
					
						
						|  | cursor: pointer; | 
					
						
						|  | font-weight: 500; | 
					
						
						|  | font-size: 12px; | 
					
						
						|  | margin-bottom: 10px; | 
					
						
						|  | display: inline-block; | 
					
						
						|  | box-shadow: 0 1px 3px rgba(0,0,0,0.1); | 
					
						
						|  | transition: all 0.2s ease; | 
					
						
						|  | text-decoration: none !important; | 
					
						
						|  | } | 
					
						
						|  | .knowledge-button:hover { | 
					
						
						|  | background-color: #000000; | 
					
						
						|  | box-shadow: 0 2px 4px rgba(0,0,0,0.15); | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | /* Knowledge popup styles - IMPROVED */ | 
					
						
						|  | .knowledge-popup { | 
					
						
						|  | display: block; | 
					
						
						|  | padding: 20px; | 
					
						
						|  | border: 2px solid #FCA539; | 
					
						
						|  | background-color: white; | 
					
						
						|  | border-radius: 8px; | 
					
						
						|  | box-shadow: 0 5px 20px rgba(0,0,0,0.15); | 
					
						
						|  | margin: 15px 0; | 
					
						
						|  | position: relative; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | .knowledge-popup-header { | 
					
						
						|  | font-weight: bold; | 
					
						
						|  | border-bottom: 1px solid #eee; | 
					
						
						|  | padding-bottom: 10px; | 
					
						
						|  | margin-bottom: 15px; | 
					
						
						|  | color: #222; | 
					
						
						|  | font-size: 16px; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | .knowledge-popup-content { | 
					
						
						|  | max-height: 400px; | 
					
						
						|  | overflow-y: auto; | 
					
						
						|  | line-height: 1.6; | 
					
						
						|  | white-space: normal; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | .knowledge-popup-content p { | 
					
						
						|  | margin-bottom: 12px; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | /* Document section formatting */ | 
					
						
						|  | .doc-section { | 
					
						
						|  | margin-bottom: 15px; | 
					
						
						|  | padding-bottom: 15px; | 
					
						
						|  | border-bottom: 1px solid #eee; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | .doc-title { | 
					
						
						|  | font-weight: bold; | 
					
						
						|  | margin-bottom: 5px; | 
					
						
						|  | color: #444; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | .doc-content { | 
					
						
						|  | padding-left: 10px; | 
					
						
						|  | border-left: 3px solid #f0f0f0; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | /* Matching text highlighting */ | 
					
						
						|  | .highlight-match { | 
					
						
						|  | background-color: #FCA539; | 
					
						
						|  | color: black; | 
					
						
						|  | font-weight: bold; | 
					
						
						|  | padding: 0 2px; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | /* Updated close button to match knowledge button */ | 
					
						
						|  | .knowledge-popup-close { | 
					
						
						|  | position: absolute; | 
					
						
						|  | top: 15px; | 
					
						
						|  | right: 15px; | 
					
						
						|  | background-color: #222222; | 
					
						
						|  | color: #ffffff !important; | 
					
						
						|  | border: none; | 
					
						
						|  | border-radius: 4px; | 
					
						
						|  | padding: 5px 10px; | 
					
						
						|  | cursor: pointer; | 
					
						
						|  | font-size: 12px; | 
					
						
						|  | font-weight: 500; | 
					
						
						|  | box-shadow: 0 1px 3px rgba(0,0,0,0.1); | 
					
						
						|  | } | 
					
						
						|  | .knowledge-popup-close:hover { | 
					
						
						|  | background-color: #000000; | 
					
						
						|  | box-shadow: 0 2px 4px rgba(0,0,0,0.15); | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | h1, h2, h3, h4, h5, h6, p, span, div, button, input, textarea, label { | 
					
						
						|  | font-family: 'All Round Gothic Demi', 'Poppins', sans-serif !important; | 
					
						
						|  | } | 
					
						
						|  | """ | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | class ContextualAPIUtils: | 
					
						
						|  | def __init__(self, api_key): | 
					
						
						|  | self.api_key = api_key | 
					
						
						|  |  | 
					
						
						|  | self.model_id = "92ab273b-378f-4b52-812b-7ec21506e49b" | 
					
						
						|  | self.endpoint_url = f"https://api.contextual.ai/v1/agents/{self.model_id}/query" | 
					
						
						|  |  | 
					
						
						|  | def chat(self, prompt): | 
					
						
						|  | url = f"{self.endpoint_url}?retrievals_only=false&include_retrieval_content_text=true" | 
					
						
						|  | headers = { | 
					
						
						|  | "accept": "application/json", | 
					
						
						|  | "content-type": "application/json", | 
					
						
						|  | "authorization": f"Bearer {self.api_key}", | 
					
						
						|  | } | 
					
						
						|  | body = { | 
					
						
						|  | "stream": False, | 
					
						
						|  | "messages": [{"role": "user", "content": prompt}], | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | start_time = time.time() | 
					
						
						|  | try: | 
					
						
						|  | response = requests.post(url, headers=headers, json=body) | 
					
						
						|  | response.raise_for_status() | 
					
						
						|  | response_json = response.json() | 
					
						
						|  |  | 
					
						
						|  | response_content = response_json.get("message", {}).get("content", "No content received.") | 
					
						
						|  | retrieved_texts = [ | 
					
						
						|  | f"Doc: {item.get('doc_name', 'Unknown')}, Page: {item.get('page', 'N/A')}\n" | 
					
						
						|  | f"Content: {item.get('content_text', 'No Content')}" | 
					
						
						|  | for item in response_json.get("retrieval_contents", []) | 
					
						
						|  | ] | 
					
						
						|  | retrieval_text = "\n\n".join(retrieved_texts) if retrieved_texts else "No retrieval text found." | 
					
						
						|  | error_message = "" | 
					
						
						|  |  | 
					
						
						|  | except requests.exceptions.RequestException as e: | 
					
						
						|  | response_content = "API Request Failed" | 
					
						
						|  | retrieval_text = "" | 
					
						
						|  | error_message = str(e) | 
					
						
						|  |  | 
					
						
						|  | response_time = round(time.time() - start_time, 4) | 
					
						
						|  | return response_content, response_time, retrieval_text, error_message | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | def get_contextual_rating(contextual_api, user_input): | 
					
						
						|  | rating_prompt = f"Content to rate: {user_input}" | 
					
						
						|  | response_text, response_time, retrieval_text, error = contextual_api.chat(rating_prompt) | 
					
						
						|  | if error: | 
					
						
						|  | return f"Error: {error}", "", "unsafe" | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | safety_level = "safe" | 
					
						
						|  | if "out of policy" in response_text.lower() or "unsafe" in response_text.lower(): | 
					
						
						|  | safety_level = "unsafe" | 
					
						
						|  | elif "caution" in response_text.lower() or "warning" in response_text.lower(): | 
					
						
						|  | safety_level = "warning" | 
					
						
						|  |  | 
					
						
						|  | return response_text, retrieval_text, safety_level | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | LLAMA_HARM_CATEGORIES = { | 
					
						
						|  | "S1": "Hate Speech", "S2": "Harassment", "S3": "Violence & Threats", | 
					
						
						|  | "S4": "Sexual Content", "S5": "Self-Harm & Suicide", "S6": "Child Sexual Exploitation", | 
					
						
						|  | "S7": "Dangerous & Illegal Activities", "S8": "Misinformation", "S9": "Political Content", | 
					
						
						|  | "S10": "Spam & Scams", "S11": "Privacy Violations", "S12": "Defamation", "S13": "Other Unsafe Content" | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | def get_llama_guard_rating(together_client, user_input): | 
					
						
						|  | chat_input = [{"role": "user", "content": user_input}] | 
					
						
						|  | try: | 
					
						
						|  | response = together_client.chat.completions.create( | 
					
						
						|  | model="meta-llama/Meta-Llama-Guard-3-8B", messages=chat_input | 
					
						
						|  | ) | 
					
						
						|  | raw_output = response.choices[0].message.content.strip() | 
					
						
						|  | for code, full_name in LLAMA_HARM_CATEGORIES.items(): | 
					
						
						|  | raw_output = raw_output.replace(code, full_name) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | safety_level = "safe" | 
					
						
						|  | if "unsafe" in raw_output.lower(): | 
					
						
						|  | safety_level = "unsafe" | 
					
						
						|  | elif "caution" in raw_output.lower() or "warning" in raw_output.lower(): | 
					
						
						|  | safety_level = "warning" | 
					
						
						|  |  | 
					
						
						|  | return raw_output, safety_level | 
					
						
						|  | except Exception as e: | 
					
						
						|  | return f"Error: {str(e)}", "unsafe" | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | def get_openai_moderation(openai_client, user_input): | 
					
						
						|  | try: | 
					
						
						|  | start_time = time.time() | 
					
						
						|  | response = openai_client.moderations.create(input=user_input, model="omni-moderation-latest") | 
					
						
						|  | end_time = time.time() | 
					
						
						|  |  | 
					
						
						|  | moderation_result = response.results[0] | 
					
						
						|  | flagged = moderation_result.flagged | 
					
						
						|  | safety_status = "Unsafe" if flagged else "Safe" | 
					
						
						|  | safety_level = "unsafe" if flagged else "safe" | 
					
						
						|  |  | 
					
						
						|  | categories = moderation_result.categories | 
					
						
						|  | high_risk_categories = { | 
					
						
						|  | category: score | 
					
						
						|  | for category, score in vars(categories).items() | 
					
						
						|  | if isinstance(score, (int, float)) and score > 0.5 | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | if not flagged and any(score > 0.3 for score in vars(categories).values() if isinstance(score, (int, float))): | 
					
						
						|  | safety_level = "warning" | 
					
						
						|  |  | 
					
						
						|  | formatted_result = f"Safety Status: {safety_status}\n" | 
					
						
						|  | if high_risk_categories: | 
					
						
						|  | formatted_result += "Flagged Categories (Confidence > 0.5):\n" | 
					
						
						|  | for category, score in high_risk_categories.items(): | 
					
						
						|  | formatted_result += f"  - {category}: {score:.2f}\n" | 
					
						
						|  | else: | 
					
						
						|  | formatted_result += "Flagged Categories: None\n" | 
					
						
						|  |  | 
					
						
						|  | return formatted_result, safety_level | 
					
						
						|  | except Exception as e: | 
					
						
						|  | return f"Safety Status: Error\nError: {str(e)}", "unsafe" | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | def get_perspective_rating(user_input): | 
					
						
						|  | """ | 
					
						
						|  | Get content rating from Google's Perspective API. | 
					
						
						|  | Returns formatted results and safety level. | 
					
						
						|  | """ | 
					
						
						|  | import json | 
					
						
						|  | import requests | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | API_KEY = "AIzaSyDK8R5gn-Gm42dSyexhThbnBuzcglD6rgY" | 
					
						
						|  |  | 
					
						
						|  | url = 'https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze' | 
					
						
						|  | params = { | 
					
						
						|  | 'key': API_KEY | 
					
						
						|  | } | 
					
						
						|  | data = { | 
					
						
						|  | 'comment': {'text': user_input}, | 
					
						
						|  | 'requestedAttributes': { | 
					
						
						|  | 'TOXICITY': {}, | 
					
						
						|  | 'SEVERE_TOXICITY': {}, | 
					
						
						|  | 'IDENTITY_ATTACK': {}, | 
					
						
						|  | 'INSULT': {}, | 
					
						
						|  | 'PROFANITY': {}, | 
					
						
						|  | 'THREAT': {}, | 
					
						
						|  | 'SEXUALLY_EXPLICIT': {} | 
					
						
						|  | } | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | try: | 
					
						
						|  | start_time = time.time() | 
					
						
						|  | response = requests.post(url, params=params, data=json.dumps(data)) | 
					
						
						|  | end_time = time.time() | 
					
						
						|  | response_time = round(end_time - start_time, 4) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | if response.status_code != 200: | 
					
						
						|  | return f"Error: API returned status code {response.status_code}", "unsafe" | 
					
						
						|  |  | 
					
						
						|  | response_json = response.json() | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | if 'attributeScores' not in response_json: | 
					
						
						|  | return f"Error in API response: {response_json}", "unsafe" | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | scores = {} | 
					
						
						|  | flagged_attributes = [] | 
					
						
						|  |  | 
					
						
						|  | for attr, data in response_json['attributeScores'].items(): | 
					
						
						|  | score = data['summaryScore']['value'] | 
					
						
						|  | scores[attr] = score | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | if score > 0.5: | 
					
						
						|  | flagged_attributes.append(attr) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | if flagged_attributes: | 
					
						
						|  | safety_level = "unsafe" | 
					
						
						|  | elif any(score > 0.3 for score in scores.values()): | 
					
						
						|  | safety_level = "warning" | 
					
						
						|  | else: | 
					
						
						|  | safety_level = "safe" | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | if flagged_attributes: | 
					
						
						|  | flagged_str = ", ".join(flagged_attributes) | 
					
						
						|  | formatted_result = f"Safety Status: Unsafe\nFlagged Attributes: {flagged_str}\n\n" | 
					
						
						|  | else: | 
					
						
						|  | formatted_result = "Safety Status: Safe\n\n" | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | formatted_result += "Attribute Scores:\n" | 
					
						
						|  | for attr, score in scores.items(): | 
					
						
						|  | formatted_result += f"β’ {attr}: {score:.2f}\n" | 
					
						
						|  |  | 
					
						
						|  | return formatted_result, safety_level | 
					
						
						|  |  | 
					
						
						|  | except Exception as e: | 
					
						
						|  | return f"Error: {str(e)}", "unsafe" | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | def rate_user_input(user_input): | 
					
						
						|  | """ | 
					
						
						|  | Function to rate a single user input using all four rating services: | 
					
						
						|  | - Contextual Safety Oracle | 
					
						
						|  | - LlamaGuard | 
					
						
						|  | - OpenAI Moderation | 
					
						
						|  | - Google Perspective API | 
					
						
						|  | """ | 
					
						
						|  |  | 
					
						
						|  | contextual_api = ContextualAPIUtils(api_key=ORACLE_API_KEY) | 
					
						
						|  | together_client = Together(api_key=TOGETHER_API_KEY) | 
					
						
						|  | openai_client = openai.OpenAI(api_key=OPENAI_API_KEY) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | llama_rating, llama_safety = get_llama_guard_rating(together_client, user_input, user_input) | 
					
						
						|  | contextual_rating, contextual_retrieval, contextual_safety = get_contextual_rating(contextual_api, user_input, user_input) | 
					
						
						|  | openai_rating, openai_safety = get_openai_moderation(openai_client, user_input, user_input) | 
					
						
						|  | perspective_rating, perspective_safety = get_perspective_rating(user_input) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | llama_rating = re.sub(r'\.(?=\s+[A-Z])', '.\n', llama_rating) | 
					
						
						|  | contextual_rating = re.sub(r'\.(?=\s+[A-Z])', '.\n', contextual_rating) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | processed_retrieval = process_retrieval_text(contextual_retrieval, user_input) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | llama_html = f"""<div class="rating-box secondary-box {llama_safety}-rating">{llama_rating}</div>""" | 
					
						
						|  | openai_html = f"""<div class="rating-box secondary-box {openai_safety}-rating">{openai_rating}</div>""" | 
					
						
						|  | perspective_html = f"""<div class="rating-box secondary-box {perspective_safety}-rating">{perspective_rating}</div>""" | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | knowledge_html = "" | 
					
						
						|  | knowledge_button = "" | 
					
						
						|  |  | 
					
						
						|  | if processed_retrieval and processed_retrieval != "No retrieval text found.": | 
					
						
						|  |  | 
					
						
						|  | import uuid | 
					
						
						|  | popup_id = f"knowledge-popup-{uuid.uuid4().hex[:8]}" | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | knowledge_html = f""" | 
					
						
						|  | <div id="{popup_id}" class="knowledge-popup" style="display: none;"> | 
					
						
						|  | <div class="knowledge-popup-header">Retrieved Knowledge</div> | 
					
						
						|  | <button class="knowledge-popup-close" | 
					
						
						|  | onclick="this.parentElement.style.display='none'; | 
					
						
						|  | document.getElementById('btn-{popup_id}').style.display='inline-block'; | 
					
						
						|  | return false;"> | 
					
						
						|  | Close | 
					
						
						|  | </button> | 
					
						
						|  | <div class="knowledge-popup-content"> | 
					
						
						|  | {processed_retrieval} | 
					
						
						|  | </div> | 
					
						
						|  | </div> | 
					
						
						|  | """ | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | knowledge_button = f""" | 
					
						
						|  | <div style="margin-top: 10px; margin-bottom: 5px;"> | 
					
						
						|  | <a href="#" id="btn-{popup_id}" class="knowledge-button" | 
					
						
						|  | onclick="document.getElementById('{popup_id}').style.display='block'; this.style.display='none'; return false;"> | 
					
						
						|  | Show Retrieved Knowledge | 
					
						
						|  | </a> | 
					
						
						|  | </div> | 
					
						
						|  | """ | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | contextual_html = f""" | 
					
						
						|  | <div class="rating-box contextual-box {contextual_safety}-rating"> | 
					
						
						|  | <button class="copy-button" onclick="navigator.clipboard.writeText(this.parentElement.innerText.replace('Copy', ''))">Copy</button> | 
					
						
						|  | {contextual_rating} | 
					
						
						|  | </div> | 
					
						
						|  | {knowledge_button} | 
					
						
						|  | {knowledge_html} | 
					
						
						|  | """ | 
					
						
						|  |  | 
					
						
						|  | return contextual_html, llama_html, openai_html, perspective_html, "" | 
					
						
						|  |  | 
					
						
						|  | def random_test_case(): | 
					
						
						|  | try: | 
					
						
						|  | df = pd.read_csv("hate_speech_test_cases.csv") | 
					
						
						|  | sample = df.sample(1).iloc[0]["user input"] | 
					
						
						|  | return sample | 
					
						
						|  | except Exception as e: | 
					
						
						|  | return f"Error: {e}" | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | def create_gradio_app(): | 
					
						
						|  |  | 
					
						
						|  | theme = gr.themes.Default().set( | 
					
						
						|  | body_text_size="16px", | 
					
						
						|  | body_text_color="#333333", | 
					
						
						|  | button_primary_background_fill="#FCA539", | 
					
						
						|  | button_primary_text_color="#000000", | 
					
						
						|  | button_secondary_background_fill="#FCA539", | 
					
						
						|  | button_secondary_text_color="#000000", | 
					
						
						|  | background_fill_primary="#FFFFFF", | 
					
						
						|  | background_fill_secondary="#F8F9FA", | 
					
						
						|  | block_title_text_weight="600", | 
					
						
						|  | block_border_width="1px", | 
					
						
						|  | block_shadow="0 1px 3px rgba(0,0,0,0.1)", | 
					
						
						|  | border_color_primary="#E0E0E0" | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | custom_css = CUSTOM_CSS + """ | 
					
						
						|  | /* Policy preview popup styles */ | 
					
						
						|  | .policy-popup { | 
					
						
						|  | display: none; | 
					
						
						|  | position: fixed; | 
					
						
						|  | top: 0; | 
					
						
						|  | left: 0; | 
					
						
						|  | width: 100%; | 
					
						
						|  | height: 100%; | 
					
						
						|  | background-color: rgba(0,0,0,0.7); | 
					
						
						|  | z-index: 1000; | 
					
						
						|  | justify-content: center; | 
					
						
						|  | align-items: center; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | .policy-popup-content { | 
					
						
						|  | background-color: white; | 
					
						
						|  | width: 80%; | 
					
						
						|  | height: 80%; | 
					
						
						|  | border-radius: 8px; | 
					
						
						|  | padding: 20px; | 
					
						
						|  | position: relative; | 
					
						
						|  | box-shadow: 0 5px 20px rgba(0,0,0,0.3); | 
					
						
						|  | display: flex; | 
					
						
						|  | flex-direction: column; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | .policy-popup-header { | 
					
						
						|  | display: flex; | 
					
						
						|  | justify-content: space-between; | 
					
						
						|  | align-items: center; | 
					
						
						|  | margin-bottom: 15px; | 
					
						
						|  | border-bottom: 1px solid #eee; | 
					
						
						|  | padding-bottom: 10px; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | .policy-popup-title { | 
					
						
						|  | font-weight: bold; | 
					
						
						|  | font-size: 18px; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | .policy-popup-close { | 
					
						
						|  | background-color: #222222; | 
					
						
						|  | color: white; | 
					
						
						|  | border: none; | 
					
						
						|  | border-radius: 4px; | 
					
						
						|  | padding: 5px 10px; | 
					
						
						|  | cursor: pointer; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | .policy-popup-close:hover { | 
					
						
						|  | background-color: #000000; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | .policy-iframe-container { | 
					
						
						|  | flex: 1; | 
					
						
						|  | overflow: hidden; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | .policy-iframe { | 
					
						
						|  | width: 100%; | 
					
						
						|  | height: 100%; | 
					
						
						|  | border: 1px solid #eee; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | /* Fallback for when PDF can't be displayed in iframe */ | 
					
						
						|  | .policy-fallback { | 
					
						
						|  | padding: 20px; | 
					
						
						|  | text-align: center; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | .policy-fallback a { | 
					
						
						|  | display: inline-block; | 
					
						
						|  | margin-top: 15px; | 
					
						
						|  | padding: 10px 15px; | 
					
						
						|  | background-color: #FCA539; | 
					
						
						|  | color: #000000; | 
					
						
						|  | text-decoration: none; | 
					
						
						|  | border-radius: 4px; | 
					
						
						|  | font-weight: bold; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | /* Custom gray button style */ | 
					
						
						|  | .gray-button { | 
					
						
						|  | background-color: #c4c4c3 !important; | 
					
						
						|  | color: #000000 !important; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | /* Perspective API styling */ | 
					
						
						|  | .perspective-icon { | 
					
						
						|  | vertical-align: middle; | 
					
						
						|  | margin-right: 5px; | 
					
						
						|  | } | 
					
						
						|  | """ | 
					
						
						|  |  | 
					
						
						|  | with gr.Blocks(title="Hate Speech Policy Rating Oracle", theme=theme, css=custom_css) as app: | 
					
						
						|  |  | 
					
						
						|  | loading_spinner = gr.HTML('<div id="loading-spinner"></div>') | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | pdf_file = gr.File("Hate Speech Policy.pdf", visible=False, label="Policy PDF") | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | policy_popup_html = """ | 
					
						
						|  | <div id="policy-popup" class="policy-popup"> | 
					
						
						|  | <div class="policy-popup-content"> | 
					
						
						|  | <div class="policy-popup-header"> | 
					
						
						|  | <div class="policy-popup-title">Hate Speech Policy</div> | 
					
						
						|  | <button class="policy-popup-close" onclick="document.getElementById('policy-popup').style.display='none';">Close</button> | 
					
						
						|  | </div> | 
					
						
						|  | <div class="policy-iframe-container"> | 
					
						
						|  | <!-- Primary method: Try Google PDF Viewer --> | 
					
						
						|  | <iframe class="policy-iframe" id="policy-iframe"></iframe> | 
					
						
						|  |  | 
					
						
						|  | <!-- Fallback content if iframe fails --> | 
					
						
						|  | <div class="policy-fallback" id="policy-fallback" style="display:none;"> | 
					
						
						|  | <p>The policy document couldn't be displayed in the preview.</p> | 
					
						
						|  | <a href="#" id="policy-download-link" target="_blank">Download Policy PDF</a> | 
					
						
						|  | </div> | 
					
						
						|  | </div> | 
					
						
						|  | </div> | 
					
						
						|  | </div> | 
					
						
						|  |  | 
					
						
						|  | <script> | 
					
						
						|  | // Function to handle opening the policy popup | 
					
						
						|  | function openPolicyPopup() { | 
					
						
						|  | // Set PDF URL - this approach is more reliable with Gradio | 
					
						
						|  | const pdfFileName = "Hate Speech Policy.pdf"; | 
					
						
						|  |  | 
					
						
						|  | // Try multiple approaches to display the PDF | 
					
						
						|  | // 1. Google PDF viewer (works in most cases) | 
					
						
						|  | const googleViewerUrl = "https://docs.google.com/viewer?embedded=true&url="; | 
					
						
						|  |  | 
					
						
						|  | // 2. Direct link as fallback | 
					
						
						|  | let directPdfUrl = ""; | 
					
						
						|  |  | 
					
						
						|  | // Find the PDF link by looking for file links in the DOM | 
					
						
						|  | const links = document.querySelectorAll("a"); | 
					
						
						|  | for (const link of links) { | 
					
						
						|  | if (link.href && link.href.includes(encodeURIComponent(pdfFileName))) { | 
					
						
						|  | directPdfUrl = link.href; | 
					
						
						|  | break; | 
					
						
						|  | } | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | // Set the iframe source if we found a link | 
					
						
						|  | const iframe = document.getElementById("policy-iframe"); | 
					
						
						|  | const fallback = document.getElementById("policy-fallback"); | 
					
						
						|  | const downloadLink = document.getElementById("policy-download-link"); | 
					
						
						|  |  | 
					
						
						|  | if (directPdfUrl) { | 
					
						
						|  | // Try Google Viewer first | 
					
						
						|  | iframe.src = googleViewerUrl + encodeURIComponent(directPdfUrl); | 
					
						
						|  | iframe.style.display = "block"; | 
					
						
						|  | fallback.style.display = "none"; | 
					
						
						|  |  | 
					
						
						|  | // Set the download link | 
					
						
						|  | downloadLink.href = directPdfUrl; | 
					
						
						|  |  | 
					
						
						|  | // Provide fallback in case Google Viewer fails | 
					
						
						|  | iframe.onerror = function() { | 
					
						
						|  | iframe.style.display = "none"; | 
					
						
						|  | fallback.style.display = "block"; | 
					
						
						|  | }; | 
					
						
						|  | } else { | 
					
						
						|  | // No direct URL found, show fallback | 
					
						
						|  | iframe.style.display = "none"; | 
					
						
						|  | fallback.style.display = "block"; | 
					
						
						|  | downloadLink.href = "#"; | 
					
						
						|  | downloadLink.textContent = "PDF not available"; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | // Display the popup | 
					
						
						|  | document.getElementById('policy-popup').style.display = 'flex'; | 
					
						
						|  | } | 
					
						
						|  | </script> | 
					
						
						|  | """ | 
					
						
						|  |  | 
					
						
						|  | gr.HTML(policy_popup_html) | 
					
						
						|  |  | 
					
						
						|  | gr.Markdown("# Hate Speech Policy Rating Oracle") | 
					
						
						|  | gr.Markdown( | 
					
						
						|  | "Assess whether user-generated social content contains hate speech using Contextual AI's State-of-the-Art Agentic RAG system. Classifications are steerable and explainable as they are based on a policy document rather than parametric knowledge! This app also returns ratings from LlamaGuard 3.0, the OpenAI Moderation API, and Google's Perspective API for you to compare. This is a demo from Contextual AI researchers. Feedback is welcome as we work with design partners to bring this to production.  \n" | 
					
						
						|  | "## Instructions \n" | 
					
						
						|  | "Enter user-generated content to receive an assessment from all four models. Or use our random test case generator to have it pre-filled.  \n" | 
					
						
						|  | "## How it works\n" | 
					
						
						|  | "* **Document-Grounded Evaluations**: Every rating is directly tied to our <a href='#' onclick='openPolicyPopup(); return false;'>hate speech policy document</a>, which makes our system far superior to other solutions that lack transparent decision criteria.\n" | 
					
						
						|  | "* **Adaptable Policies**: The policy document serves as a starting point and can be easily adjusted to meet your specific requirements. As policies evolve, the system immediately adapts without requiring retraining.\n" | 
					
						
						|  | "* **Clear Rationales**: Each evaluation includes a detailed explanation referencing specific policy sections, allowing users to understand exactly why content was flagged or approved.\n" | 
					
						
						|  | "* **Continuous Improvement**: The system learns from feedback, addressing any misclassifications by improving retrieval accuracy over time.\n\n" | 
					
						
						|  | "Our approach combines Contextual's state-of-the-art <a href='https://contextual.ai/blog/introducing-instruction-following-reranker/' target='_blank'>steerable reranker</a>, <a href='https://contextual.ai/blog/introducing-grounded-language-model/' target='_blank'>world's most grounded language model</a>, and <a href='https://contextual.ai/blog/combining-rag-and-specialization/' target='_blank'>tuning for agent specialization</a> to achieve superhuman performance in content evaluation tasks. This technology enables consistent, fine-grained assessments across any content type and format.\n\n" | 
					
						
						|  |  | 
					
						
						|  | "<h3 style='color:red; font-weight:bold;'>SAFETY WARNING</h3>" | 
					
						
						|  | "Some of the randomly generated test cases contain hateful language that you might find offensive or upsetting." | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  | with gr.Row(): | 
					
						
						|  | with gr.Column(scale=1): | 
					
						
						|  |  | 
					
						
						|  | random_test_btn = gr.Button("π² Random Test Case", elem_classes=["orange-button"]) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | rate_btn = gr.Button("Rate Content", variant="primary", size="lg", elem_classes=["gray-button"]) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | user_input = gr.Textbox(label="Input content to rate:", placeholder="Type content to evaluate here...", lines=6) | 
					
						
						|  |  | 
					
						
						|  | with gr.Column(scale=2): | 
					
						
						|  |  | 
					
						
						|  | gr.HTML(""" | 
					
						
						|  | <div> | 
					
						
						|  | <h3 class="result-header">π Contextual Safety Oracle</h3> | 
					
						
						|  | <div style="margin-top: -10px; margin-bottom: 10px;"> | 
					
						
						|  | <a href="#" class="knowledge-button" onclick="openPolicyPopup(); return false;">View policy</a> | 
					
						
						|  | </div> | 
					
						
						|  | </div> | 
					
						
						|  | """) | 
					
						
						|  | contextual_results = gr.HTML('<div class="rating-box contextual-box empty-rating">Rating will appear here</div>') | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | retrieved_knowledge = gr.HTML('', visible=False) | 
					
						
						|  |  | 
					
						
						|  | with gr.Row(): | 
					
						
						|  | with gr.Column(): | 
					
						
						|  |  | 
					
						
						|  | gr.HTML(""" | 
					
						
						|  | <div> | 
					
						
						|  | <h3 class="result-header">π¦ LlamaGuard Rating</h3> | 
					
						
						|  | <div style="margin-top: -10px; margin-bottom: 10px;"> | 
					
						
						|  | <a href="https://github.com/meta-llama/PurpleLlama/blob/main/Llama-Guard3/8B/MODEL_CARD.md" | 
					
						
						|  | target="_blank" class="knowledge-button">View model card</a> | 
					
						
						|  | </div> | 
					
						
						|  | </div> | 
					
						
						|  | """) | 
					
						
						|  | llama_results = gr.HTML('<div class="rating-box secondary-box empty-rating">Rating will appear here</div>') | 
					
						
						|  | with gr.Column(): | 
					
						
						|  |  | 
					
						
						|  | gr.HTML(""" | 
					
						
						|  | <div> | 
					
						
						|  | <h3 class="result-header">π§· OpenAI Moderation</h3> | 
					
						
						|  | <div style="margin-top: -10px; margin-bottom: 10px;"> | 
					
						
						|  | <a href="https://platform.openai.com/docs/guides/moderation" | 
					
						
						|  | target="_blank" class="knowledge-button">View model card</a> | 
					
						
						|  | </div> | 
					
						
						|  | </div> | 
					
						
						|  | """) | 
					
						
						|  | openai_results = gr.HTML('<div class="rating-box secondary-box empty-rating">Rating will appear here</div>') | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | with gr.Row(): | 
					
						
						|  | with gr.Column(): | 
					
						
						|  |  | 
					
						
						|  | gr.HTML(""" | 
					
						
						|  | <div> | 
					
						
						|  | <h3 class="result-header">π Google Perspective API</h3> | 
					
						
						|  | <div style="margin-top: -10px; margin-bottom: 10px;"> | 
					
						
						|  | <a href="https://developers.perspectiveapi.com/s/about-the-api" | 
					
						
						|  | target="_blank" class="knowledge-button">View API info</a> | 
					
						
						|  | </div> | 
					
						
						|  | </div> | 
					
						
						|  | """) | 
					
						
						|  | perspective_results = gr.HTML('<div class="rating-box secondary-box empty-rating">Rating will appear here</div>') | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | def show_loading(): | 
					
						
						|  | return """<script> | 
					
						
						|  | const spinner = document.getElementById('loading-spinner'); | 
					
						
						|  | if (spinner) spinner.style.display = 'block'; | 
					
						
						|  | </script>""" | 
					
						
						|  |  | 
					
						
						|  | def hide_loading(): | 
					
						
						|  | return """<script> | 
					
						
						|  | const spinner = document.getElementById('loading-spinner'); | 
					
						
						|  | if (spinner) spinner.style.display = 'none'; | 
					
						
						|  | </script>""" | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | random_test_btn.click( | 
					
						
						|  | show_loading, | 
					
						
						|  | inputs=None, | 
					
						
						|  | outputs=loading_spinner | 
					
						
						|  | ).then( | 
					
						
						|  | random_test_case, | 
					
						
						|  | inputs=[], | 
					
						
						|  | outputs=[user_input] | 
					
						
						|  | ).then( | 
					
						
						|  | hide_loading, | 
					
						
						|  | inputs=None, | 
					
						
						|  | outputs=loading_spinner | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | rate_btn.click( | 
					
						
						|  | show_loading, | 
					
						
						|  | inputs=None, | 
					
						
						|  | outputs=loading_spinner | 
					
						
						|  | ).then( | 
					
						
						|  | rate_user_input, | 
					
						
						|  | inputs=[user_input], | 
					
						
						|  | outputs=[contextual_results, llama_results, openai_results, perspective_results, retrieved_knowledge] | 
					
						
						|  | ).then( | 
					
						
						|  | hide_loading, | 
					
						
						|  | inputs=None, | 
					
						
						|  | outputs=loading_spinner | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  | return app | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | if __name__ == "__main__": | 
					
						
						|  | app = create_gradio_app() | 
					
						
						|  | app.launch(share=True) |