Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import openai | |
| from openai import OpenAI | |
| import os | |
| from typing import List, Tuple | |
| # Initialize OpenAI with environment variable | |
| # Set OPENAI_API_KEY in Hugging Face secrets | |
| client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) | |
| # Global session state | |
| chat_history = [] | |
| def respond_to_message(message: str, history: List[List[str]]) -> Tuple[str, List[List[str]]]: | |
| """Handle user message and return response with updated history""" | |
| if not message.strip(): | |
| return "", history | |
| # Add user message to history | |
| history.append([message, ""]) | |
| # Add to global chat history for sidebar | |
| global chat_history | |
| chat_history.append(message) | |
| try: | |
| # Prepare messages for OpenAI API | |
| messages = [{"role": "system", "content": "You are a helpful assistant."}] | |
| # Add conversation history | |
| for user_msg, assistant_msg in history[:-1]: # Exclude the current message | |
| if user_msg and assistant_msg: | |
| messages.append({"role": "user", "content": user_msg}) | |
| messages.append({"role": "assistant", "content": assistant_msg}) | |
| # Add current user message | |
| messages.append({"role": "user", "content": message}) | |
| # Get response from OpenAI | |
| response = client.chat.completions.create( | |
| model="gpt-3.5-turbo", # You can change to gpt-4 if available | |
| messages=messages, | |
| max_tokens=1000, | |
| temperature=0.7 | |
| ) | |
| assistant_response = response.choices[0].message.content | |
| # Update the last message in history with assistant response | |
| history[-1][1] = assistant_response | |
| return "", history | |
| except Exception as e: | |
| error_message = f"Error: {str(e)}" | |
| history[-1][1] = error_message | |
| return "", history | |
| def clear_chat() -> Tuple[str, List[List[str]]]: | |
| """Clear the current chat history""" | |
| global chat_history | |
| chat_history = [] | |
| return "", [] | |
| def get_chat_history() -> List[str]: | |
| """Get chat history for sidebar""" | |
| return chat_history | |
| # Custom CSS for ChatGPT-like styling | |
| custom_css = """ | |
| .gradio-container { | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| background: white !important; | |
| min-height: 100vh; | |
| } | |
| .chat-layout { | |
| display: flex; | |
| height: 100vh; | |
| max-width: 100%; | |
| margin: 0 auto; | |
| background: white; | |
| } | |
| .sidebar { | |
| width: 280px; | |
| background: #f7f7f8; | |
| color: #374151; | |
| padding: 0; | |
| display: flex; | |
| flex-direction: column; | |
| border-right: 1px solid #e5e7eb; | |
| overflow-y: auto; | |
| } | |
| .sidebar-header { | |
| padding: 16px; | |
| border-bottom: 1px solid #e5e7eb; | |
| background: white; | |
| } | |
| .history-list { | |
| flex: 1; | |
| padding: 8px; | |
| background: #f7f7f8; | |
| overflow-y: auto; | |
| } | |
| .history-item { | |
| background: transparent !important; | |
| color: #374151 !important; | |
| border: none !important; | |
| border-radius: 6px !important; | |
| padding: 8px 12px !important; | |
| font-size: 13px !important; | |
| cursor: pointer !important; | |
| transition: background-color 0.2s !important; | |
| width: 100% !important; | |
| text-align: left !important; | |
| margin-bottom: 4px !important; | |
| box-shadow: none !important; | |
| line-height: 1.4 !important; | |
| word-wrap: break-word !important; | |
| white-space: normal !important; | |
| } | |
| .history-item:hover { | |
| background: #e5e7eb !important; | |
| } | |
| .history-item.active { | |
| background: #e5e7eb !important; | |
| } | |
| .main-chat { | |
| flex: 1; | |
| display: flex; | |
| flex-direction: column; | |
| background: white; | |
| min-height: 0; | |
| } | |
| .chat-header { | |
| padding: 12px 24px; | |
| border-bottom: 1px solid #e5e7eb; | |
| color: #374151; | |
| font-size: 16px; | |
| font-weight: 600; | |
| background: white; | |
| } | |
| .chat-messages { | |
| flex: 1; | |
| overflow-y: auto; | |
| padding: 0; | |
| background: white; | |
| min-height: 0; | |
| } | |
| .chatbot { | |
| background: transparent !important; | |
| border: none !important; | |
| box-shadow: none !important; | |
| padding: 0 !important; | |
| height: 100% !important; | |
| } | |
| .chatbot .message { | |
| margin: 0 !important; | |
| padding: 16px 0 !important; | |
| border-radius: 0 !important; | |
| border-bottom: 1px solid #e5e7eb !important; | |
| } | |
| .chatbot .user-message { | |
| background: white !important; | |
| color: #374151 !important; | |
| margin: 0 !important; | |
| padding: 16px 24px !important; | |
| } | |
| .chatbot .bot-message { | |
| background: #f9fafb !important; | |
| color: #374151 !important; | |
| margin: 0 !important; | |
| padding: 16px 24px !important; | |
| } | |
| .chat-input-container { | |
| padding: 16px 24px; | |
| border-top: 1px solid #e5e7eb; | |
| background: white; | |
| position: sticky; | |
| bottom: 0; | |
| } | |
| .chat-input { | |
| background: white !important; | |
| border: 1px solid #d1d5db !important; | |
| color: #374151 !important; | |
| border-radius: 8px !important; | |
| padding: 12px 16px !important; | |
| font-size: 16px !important; | |
| resize: none !important; | |
| min-height: 48px !important; | |
| } | |
| .chat-input:focus { | |
| border-color: #3b82f6 !important; | |
| box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2) !important; | |
| } | |
| .send-button { | |
| background: #3b82f6 !important; | |
| color: white !important; | |
| border: none !important; | |
| border-radius: 6px !important; | |
| padding: 8px 16px !important; | |
| font-size: 14px !important; | |
| font-weight: 500 !important; | |
| cursor: pointer !important; | |
| transition: background-color 0.2s !important; | |
| height: 36px !important; | |
| } | |
| .send-button:hover { | |
| background: #2563eb !important; | |
| } | |
| .clear-button { | |
| background: #6b7280 !important; | |
| color: white !important; | |
| border: none !important; | |
| border-radius: 6px !important; | |
| padding: 8px 16px !important; | |
| font-size: 14px !important; | |
| cursor: pointer !important; | |
| transition: background-color 0.2s !important; | |
| height: 36px !important; | |
| } | |
| .clear-button:hover { | |
| background: #4b5563 !important; | |
| } | |
| @media (max-width: 768px) { | |
| .chat-layout { | |
| flex-direction: column; | |
| } | |
| .sidebar { | |
| width: 100%; | |
| height: auto; | |
| max-height: 200px; | |
| } | |
| .main-chat { | |
| flex: 1; | |
| } | |
| } | |
| """ | |
| # Create the Gradio interface | |
| with gr.Blocks(css=custom_css, title="ChatGPT Clone") as demo: | |
| with gr.Row(elem_classes="chat-layout"): | |
| # Left sidebar with chat history | |
| with gr.Column(elem_classes="sidebar"): | |
| # Sidebar header | |
| with gr.Row(elem_classes="sidebar-header"): | |
| gr.Markdown("### 💬 Chat History") | |
| # Chat history list | |
| with gr.Column(elem_classes="history-list"): | |
| chat_history_display = gr.Textbox( | |
| value="", | |
| label="", | |
| elem_classes="history-item", | |
| show_label=False, | |
| interactive=False, | |
| lines=25 | |
| ) | |
| # Main chat area | |
| with gr.Column(elem_classes="main-chat"): | |
| # Chat header | |
| with gr.Row(elem_classes="chat-header"): | |
| gr.Markdown("### AI Assistant") | |
| # Chat messages | |
| chatbot = gr.Chatbot( | |
| elem_classes="chatbot", | |
| height=500, | |
| show_label=False, | |
| container=True, | |
| bubble_full_width=True | |
| ) | |
| # Chat input area | |
| with gr.Row(elem_classes="chat-input-container"): | |
| with gr.Column(scale=4): | |
| user_input = gr.Textbox( | |
| placeholder="Type your message here...", | |
| show_label=False, | |
| lines=2, | |
| max_lines=4, | |
| elem_classes="chat-input" | |
| ) | |
| with gr.Column(scale=1): | |
| send_btn = gr.Button("Send", elem_classes="send-button") | |
| clear_btn = gr.Button("Clear", elem_classes="clear-button") | |
| # Event handlers | |
| def handle_send(message, history): | |
| result = respond_to_message(message, history) | |
| # Update chat history display as list items | |
| if chat_history: | |
| history_text = "" | |
| for i, msg in enumerate(chat_history): | |
| history_text += f"• {msg}\n" | |
| else: | |
| history_text = "No chat history yet" | |
| return result[0], result[1], history_text | |
| def handle_clear(): | |
| result = clear_chat() | |
| return result[0], result[1], "No chat history yet" | |
| # Connect events | |
| send_btn.click( | |
| fn=handle_send, | |
| inputs=[user_input, chatbot], | |
| outputs=[user_input, chatbot, chat_history_display] | |
| ) | |
| user_input.submit( | |
| fn=handle_send, | |
| inputs=[user_input, chatbot], | |
| outputs=[user_input, chatbot, chat_history_display] | |
| ) | |
| clear_btn.click( | |
| fn=handle_clear, | |
| outputs=[user_input, chatbot, chat_history_display] | |
| ) | |
| # Launch the app for Hugging Face | |
| demo.launch() |