# Path: QAgents-workflows/ui/chat_components.py # Relations: Uses orchestrators/orchestrator.py (NakedOrchestrator) # Used by __init__.py, app.py # Description: Chat UI components for interacting with quantum circuit agents """ Chat Components: Gradio 6.0 compatible chat interface for QAgents. Provides: - Chat tab creation - Message handling with NAKED mode orchestrator - Help and status commands """ import gradio as gr import logging from typing import List, Dict, Any, Tuple logger = logging.getLogger(__name__) def generate_circuit_with_naked(prompt: str) -> str: """ Generate a quantum circuit using NAKED mode (direct LLM call). This is the simplest and fastest mode. Args: prompt: User's natural language request Returns: Formatted response with circuit or error message """ try: # Lazy import to avoid startup issues from orchestrators import create_orchestrator orch = create_orchestrator("naked") result = orch.run(prompt) if result.success: output = f"āœ… **Success** ({result.execution_time_ms:.0f}ms)\n\n" if result.final_output: if 'OPENQASM' in str(result.final_output) or 'qreg' in str(result.final_output): output += f"```qasm\n{result.final_output}\n```" else: output += str(result.final_output) return output else: error_msg = "\n".join(result.errors) if result.errors else "Unknown error" return f"āŒ **Failed** ({result.execution_time_ms:.0f}ms)\n\n{error_msg}" except Exception as e: logger.error(f"NAKED mode error: {e}") return f"āŒ **Error**: {str(e)}" def get_help_text() -> str: """Return help text for the chat interface.""" return """## šŸ¤– QAgents Help I can help you with quantum circuits! Try asking me to: **Create Circuits:** - "Create a Bell state" - "Generate a 3-qubit GHZ state" - "Make a QFT circuit for 4 qubits" - "Build a simple superposition" **Examples:** - "Create a circuit that puts 2 qubits in superposition" - "Generate a CNOT gate between qubit 0 and 1" - "Build a quantum teleportation circuit" šŸ’” **Tip:** Be specific about the number of qubits and desired operations! **Commands:** - `help` - Show this help message - `status` - Check system status""" def get_status_text(mcp_server_url: str) -> str: """Return status text for the chat interface.""" try: from ui.mcp_health import check_mcp_health health = check_mcp_health() return f"## šŸ“Š System Status\n\n{health}\n\n**MCP Server:** `{mcp_server_url}`" except Exception as e: return f"## šŸ“Š System Status\n\nšŸ”“ **Error checking status**: {str(e)}" def chat_response(message: str, history: List, mcp_server_url: str = "") -> str: """ Handle chat messages and generate responses. Uses NAKED mode for circuit generation. Args: message: User's message history: Chat history mcp_server_url: URL of the MCP server Returns: Bot's response message """ if not message.strip(): return "" message_lower = message.lower().strip() # Help command if message_lower in ['help', '/help', '?']: return get_help_text() # Status command if message_lower in ['status', '/status']: return get_status_text(mcp_server_url) # Generate circuit logger.info(f"Generating circuit for: {message}") return generate_circuit_with_naked(message) def create_chat_tab(mcp_server_url: str = "") -> Tuple[gr.Chatbot, gr.Textbox, gr.Button]: """ Create the chat tab components for Gradio 6.0. Args: mcp_server_url: URL of the MCP server for status checks Returns: Tuple of (chatbot, textbox, send_button) components """ gr.Markdown("### Chat with Quantum Circuit Agent") gr.Markdown("Ask me to create quantum circuits! Try: *'Create a Bell state'* or *'Generate a 3-qubit GHZ state'*") chatbot = gr.Chatbot( value=[], height=400, label="Quantum Circuit Agent" ) with gr.Row(): msg_input = gr.Textbox( placeholder="Ask me to create a quantum circuit...", label="Your Message", scale=4, lines=1 ) send_btn = gr.Button("Send šŸš€", variant="primary", scale=1) with gr.Row(): clear_btn = gr.Button("šŸ—‘ļø Clear", size="sm") help_btn = gr.Button("ā“ Help", size="sm") status_btn = gr.Button("šŸ“Š Status", size="sm") # Chat handlers def respond(message: str, chat_history: List): if not message.strip(): return "", chat_history bot_response = chat_response(message, chat_history, mcp_server_url) chat_history.append({"role": "user", "content": message}) chat_history.append({"role": "assistant", "content": bot_response}) return "", chat_history def show_help(chat_history: List): help_text = get_help_text() chat_history.append({"role": "user", "content": "help"}) chat_history.append({"role": "assistant", "content": help_text}) return chat_history def show_status(chat_history: List): status_text = get_status_text(mcp_server_url) chat_history.append({"role": "user", "content": "status"}) chat_history.append({"role": "assistant", "content": status_text}) return chat_history # Wire up events send_btn.click(respond, [msg_input, chatbot], [msg_input, chatbot]) msg_input.submit(respond, [msg_input, chatbot], [msg_input, chatbot]) clear_btn.click(lambda: [], outputs=[chatbot]) help_btn.click(show_help, [chatbot], [chatbot]) status_btn.click(show_status, [chatbot], [chatbot]) return chatbot, msg_input, send_btn