import gradio as gr import requests import re import os API_ENDPOINT = os.getenv("API_ENDPOINT", "none") API_TOKEN = os.getenv("API_TOKEN") def get_ai_response(message, history): """Fetch AI response from the API using the modern messages format.""" messages = [ {"role": "system", "content": "You are a helpful assistant."} ] + history + [{"role": "user", "content": message}] payload = { "model": "RekaAI/reka-flash-3", "messages": messages, "stream": False, "max_tokens": 1024, "temperature": 0.7 } headers = { "Authorization": f"Bearer {API_TOKEN}", "Content-Type": "application/json" } try: response = requests.post(API_ENDPOINT, headers=headers, json=payload) response.raise_for_status() raw_response = response.json()["choices"][0]["message"]["content"] # Convert reasoning tags to collapsible HTML html_response = convert_reasoning_to_collapsible(raw_response) return html_response except Exception as e: return f"Error: {str(e)}" def convert_reasoning_to_collapsible(text): """Convert reasoning tags to collapsible HTML sections.""" # Find all reasoning sections reasoning_pattern = re.compile(r'(.*?)', re.DOTALL) # Function to replace each reasoning section with collapsible HTML def replace_with_collapsible(match): reasoning_content = match.group(1).strip() return f'
See reasoning
{reasoning_content}
' # Replace reasoning tags with collapsible sections html_response = reasoning_pattern.sub(replace_with_collapsible, text) # Remove tags html_response = re.sub(r'.*?', '', html_response, flags=re.DOTALL) html_response = html_response.replace('', '').replace('', '') return html_response def chat_interface(message, history): """Handle chat interactions and update history.""" if not history: history = [] # Convert history to the format expected by the API api_history = [] for user_msg, ai_msg in history: # Remove HTML tags for API history clean_ai_msg = re.sub(r'
.*?
', '', ai_msg, flags=re.DOTALL) clean_ai_msg = re.sub(r'<[^>]*>', '', clean_ai_msg) api_history.append({"role": "user", "content": user_msg}) api_history.append({"role": "assistant", "content": clean_ai_msg}) ai_response = get_ai_response(message, api_history) # Update history in the format expected by Gradio chatbot history.append((message, ai_response)) return history # Modern CSS for a clean UI custom_css = """ body { background-color: #1a1a1a; color: #ffffff; font-family: 'Arial', sans-serif; } #chatbot { height: 80vh; background-color: #2d2d2d; border: 1px solid #404040; border-radius: 8px; } input, button { background-color: #333333; color: #ffffff; border: 1px solid #404040; border-radius: 5px; } button:hover { background-color: #404040; } details { background-color: #333333; padding: 10px; margin: 5px 0; border-radius: 5px; } summary { cursor: pointer; color: #70a9e6; } .reasoning-content { padding: 10px; margin-top: 5px; background-color: #404040; border-radius: 5px; } """ # Build the Gradio app with gr.Blocks(css=custom_css, title="Reka Flash 3") as demo: with gr.Column(): gr.Markdown("## Reka Flash 3") gr.Markdown("This assistant shows reasoning in collapsible sections.") chatbot = gr.Chatbot(elem_id="chatbot", render_markdown=False, bubble_full_width=True) with gr.Row(): message = gr.Textbox(placeholder="Type your message...", show_label=False, container=False) submit_btn = gr.Button("Send", size="sm") clear_chat_btn = gr.Button("Clear Chat") # State management chat_state = gr.State([]) # Current chat history # JavaScript for enabling HTML in chatbot js = """ function() { // Add event listener for when new messages are added const observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.addedNodes.length) { document.querySelectorAll('#chatbot .message:not(.processed)').forEach(msg => { msg.classList.add('processed'); // Replace content with innerHTML to render HTML const content = msg.querySelector('.content'); if (content) { content.innerHTML = content.textContent; } }); } }); }); // Start observing chatbot for changes const chatbot = document.getElementById('chatbot'); if (chatbot) { observer.observe(chatbot, { childList: true, subtree: true }); } return []; } """ # Event handlers submit_btn.click( chat_interface, [message, chat_state], [chat_state] ).then( lambda history: history, chat_state, chatbot ).then( lambda: "", # Clear the input box None, message ) # Message submit via Enter key message.submit( chat_interface, [message, chat_state], [chat_state] ).then( lambda history: history, chat_state, chatbot ).then( lambda: "", # Clear the input box None, message ) clear_chat_btn.click( lambda: [], None, [chat_state, chatbot] ) # Load JavaScript for HTML rendering demo.load( fn=lambda: None, inputs=None, outputs=None, js=js ) demo.launch()