import os import gradio as gr from openai import OpenAI from typing import List, Tuple CLIENTS = { "perplexity": {"key": os.getenv('PX_KEY'), "endpoint": "https://api.perplexity.ai"}, "hyperbolic": {"key": os.getenv('HYPERBOLIC_XYZ_KEY'), "endpoint": "https://api.hyperbolic.xyz/v1"}, "huggingface": {"key": os.getenv('HF_KEY'), "endpoint": "https://huggingface.co/api/inference-proxy/together"}, } for client_type in CLIENTS: CLIENTS[client_type]["client"] = OpenAI( base_url=CLIENTS[client_type]["endpoint"], api_key=CLIENTS[client_type]["key"] ) PASSWORD = os.getenv("PASSWD") # Define available models AVAILABLE_MODELS = { "Llama3.3-70b-Instruct (Hyperbolic.xyz)": { "model_name": "meta-llama/Llama-3.3-70B-Instruct", "type": "hyperbolic" }, "Llama3.1-8b-Instruct (Hyperbolic.xyz)": { "model_name": "meta-llama/Meta-Llama-3.1-8B-Instruct", "type": "hyperbolic" }, "DeepSeek V3 (Hyperbolic.xyz)": { "model_name": "deepseek-ai/DeepSeek-V3", "type": "hyperbolic" }, "DeepSeek V3 (HuggingFace.co)": { "model_name": "deepseek-ai/DeepSeek-V3", "type": "huggingface" }, "Sonar Pro (Perplexity.ai)": { "model_name": "sonar-pro", "type": "perplexity" }, "Sonar (Perplexity.ai)": { "model_name": "sonar", "type": "perplexity" }, } def respond( message: str, history: List[Tuple[str, str]], session_password: str, # added parameter from session state system_message: str, model_choice: str, max_tokens: int, temperature: float, top_p: float, ): """Handles chatbot responses with password re-checking.""" # Re-check the session password on every message if session_password != PASSWORD: yield "Error: Invalid session password. Please refresh the page and enter the correct password." return if model_choice not in AVAILABLE_MODELS: yield "Error: Invalid model selection." return messages = [{"role": "system", "content": system_message}] for user_msg, assistant_msg in history: if user_msg: messages.append({"role": "user", "content": user_msg}) if assistant_msg: messages.append({"role": "assistant", "content": assistant_msg}) messages.append({"role": "user", "content": message}) response = "" citations = [] selected_client = CLIENTS[AVAILABLE_MODELS[model_choice]["type"]]["client"] try: stream = selected_client.chat.completions.create( model=AVAILABLE_MODELS[model_choice]["model_name"], messages=messages, max_tokens=max_tokens, temperature=temperature, top_p=top_p, stream=True, ) for chunk in stream: if hasattr(chunk, "choices") and chunk.choices: token = chunk.choices[0].delta.content or "" response += token yield response # Stream response as it arrives if hasattr(chunk, "citations") and chunk.citations: citations = chunk.citations # Append citations as clickable links, if any if citations: citation_text = "\n\nSources:\n" + "\n".join( [f"[{i+1}] [{url}]({url})" for i, url in enumerate(citations)] ) response += citation_text yield response except Exception as e: yield f"Error: {str(e)}" def check_password(input_password): """Validates the password and, if valid, stores it in session state.""" if input_password == PASSWORD: # Return the password to store in the session state. return gr.update(visible=False), gr.update(visible=True), input_password else: return gr.update(value="", interactive=True), gr.update(visible=False), "" with gr.Blocks() as demo: # A hidden state component to store the session password session_password = gr.State("") with gr.Column(): password_input = gr.Textbox( type="password", label="Enter Password", interactive=True ) submit_button = gr.Button("Submit") error_message = gr.Textbox( label="Error", visible=False, interactive=False ) with gr.Column(visible=False) as chat_interface: system_prompt = gr.Textbox( value="You are a helpful assistant.", label="System message" ) model_choice = gr.Dropdown( choices=list(AVAILABLE_MODELS.keys()), value=list(AVAILABLE_MODELS.keys())[0], label="Select Model" ) max_tokens = gr.Slider( minimum=1, maximum=30000, value=2048, step=100, label="Max new tokens" ) temperature = gr.Slider( minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature" ) top_p = gr.Slider( minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p (nucleus sampling)" ) # Note: The session_password is now passed as an additional input to the chat function. chat = gr.ChatInterface( fn=respond, api_name=False, chatbot=gr.Chatbot(height=400), # Set desired height here additional_inputs=[session_password, system_prompt, model_choice, max_tokens, temperature, top_p] ) # Now, the submit_button click updates three outputs: the password_input, chat_interface visibility, and session_password state. submit_button.click( fn=check_password, inputs=password_input, outputs=[password_input, chat_interface, session_password] ) if __name__ == "__main__": demo.launch()