Spaces:
Sleeping
Sleeping
Deminiko
commited on
Commit
·
89bf8af
1
Parent(s):
5dea71c
add
Browse files- app.py +526 -72
- client/mcp_client.py +7 -4
- tasks-project-state.json +65 -116
app.py
CHANGED
|
@@ -1,120 +1,574 @@
|
|
| 1 |
"""
|
| 2 |
QAgents-Workflows: Hugging Face Space Entry Point
|
| 3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
Reads all configuration from environment variables for HF Space deployment.
|
| 5 |
"""
|
| 6 |
|
| 7 |
import os
|
| 8 |
import gradio as gr
|
| 9 |
import logging
|
|
|
|
|
|
|
|
|
|
| 10 |
from config import LLMConfig
|
| 11 |
from orchestrators import create_orchestrator
|
| 12 |
-
from client.mcp_client import get_client
|
| 13 |
|
| 14 |
# Configure logging
|
| 15 |
logging.basicConfig(level=logging.INFO)
|
| 16 |
logger = logging.getLogger(__name__)
|
| 17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
# Log environment configuration at startup
|
| 19 |
logger.info("=" * 70)
|
| 20 |
logger.info("QAgents Quantum Circuit Orchestrator - Initialization")
|
| 21 |
logger.info("=" * 70)
|
| 22 |
logger.info(f"LLM Provider: {os.getenv('LLM_PROVIDER', 'gemini (default)')}")
|
| 23 |
logger.info(f"LLM Model: {os.getenv('LLM_MODEL', 'gemini-2.5-flash-lite (default)')}")
|
| 24 |
-
logger.info(f"MCP Server URL: {
|
| 25 |
logger.info(f"Google API Key configured: {bool(os.getenv('GOOGLE_API_KEY') or os.getenv('GENAI_API_KEY'))}")
|
| 26 |
logger.info("=" * 70)
|
| 27 |
|
| 28 |
-
# Initialize MCP client
|
| 29 |
-
mcp_client = get_client()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
|
| 31 |
-
|
| 32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
try:
|
| 34 |
-
logger.info(f"
|
| 35 |
-
logger.info(f"
|
| 36 |
|
| 37 |
-
#
|
| 38 |
-
|
| 39 |
|
| 40 |
-
#
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
|
| 45 |
if result.success:
|
| 46 |
-
|
| 47 |
if result.final_output:
|
| 48 |
-
output
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
else:
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
# Add metrics if available
|
| 53 |
-
metrics = f"LLM Calls: {result.steps_completed}\n"
|
| 54 |
-
if hasattr(result, 'tokens_used'):
|
| 55 |
-
metrics += f"Tokens: {result.tokens_used}\n"
|
| 56 |
-
|
| 57 |
-
return output, metrics
|
| 58 |
-
else:
|
| 59 |
-
error_msg = "\n".join(result.errors)
|
| 60 |
-
return f"❌ Failed ({result.execution_time_ms:.0f}ms)\n\nErrors:\n{error_msg}", "N/A"
|
| 61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
except Exception as e:
|
| 63 |
-
logger.error(f"
|
| 64 |
-
|
|
|
|
|
|
|
| 65 |
|
| 66 |
-
|
| 67 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
try:
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
except Exception as e:
|
| 74 |
-
return f"🔴 Error
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
gr.
|
| 79 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
with gr.Row():
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
)
|
|
|
|
| 99 |
|
| 100 |
-
|
| 101 |
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
generate_btn.click(
|
| 111 |
-
fn=generate_circuit,
|
| 112 |
-
inputs=[prompt_input, mode_select, difficulty_select],
|
| 113 |
-
outputs=[qasm_output, metrics_output]
|
| 114 |
)
|
| 115 |
-
|
| 116 |
-
# Refresh status on load
|
| 117 |
-
demo.load(fn=check_mcp_status, outputs=[mcp_status])
|
| 118 |
|
|
|
|
| 119 |
if __name__ == "__main__":
|
| 120 |
-
demo.launch(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
"""
|
| 2 |
QAgents-Workflows: Hugging Face Space Entry Point
|
| 3 |
+
Path: QAgents-workflows/app.py
|
| 4 |
+
Related: client/mcp_client.py (MCP connection), orchestrators/ (agent orchestration)
|
| 5 |
+
|
| 6 |
+
Provides a Gradio interface with:
|
| 7 |
+
- Chat UI for interacting with quantum circuit agents
|
| 8 |
+
- MCP Endpoints health monitoring tab
|
| 9 |
+
- Circuit generation and validation tools
|
| 10 |
+
|
| 11 |
Reads all configuration from environment variables for HF Space deployment.
|
| 12 |
"""
|
| 13 |
|
| 14 |
import os
|
| 15 |
import gradio as gr
|
| 16 |
import logging
|
| 17 |
+
import requests
|
| 18 |
+
import time
|
| 19 |
+
from typing import Optional, List, Tuple
|
| 20 |
from config import LLMConfig
|
| 21 |
from orchestrators import create_orchestrator
|
| 22 |
+
from client.mcp_client import get_client, MCPClient
|
| 23 |
|
| 24 |
# Configure logging
|
| 25 |
logging.basicConfig(level=logging.INFO)
|
| 26 |
logger = logging.getLogger(__name__)
|
| 27 |
|
| 28 |
+
# MCP Server URL for QuantumArchitect-MCP on HuggingFace
|
| 29 |
+
MCP_SERVER_URL = os.environ.get(
|
| 30 |
+
"MCP_SERVER_URL",
|
| 31 |
+
"https://mcp-1st-birthday-quantumarchitect-mcp.hf.space"
|
| 32 |
+
)
|
| 33 |
+
|
| 34 |
# Log environment configuration at startup
|
| 35 |
logger.info("=" * 70)
|
| 36 |
logger.info("QAgents Quantum Circuit Orchestrator - Initialization")
|
| 37 |
logger.info("=" * 70)
|
| 38 |
logger.info(f"LLM Provider: {os.getenv('LLM_PROVIDER', 'gemini (default)')}")
|
| 39 |
logger.info(f"LLM Model: {os.getenv('LLM_MODEL', 'gemini-2.5-flash-lite (default)')}")
|
| 40 |
+
logger.info(f"MCP Server URL: {MCP_SERVER_URL}")
|
| 41 |
logger.info(f"Google API Key configured: {bool(os.getenv('GOOGLE_API_KEY') or os.getenv('GENAI_API_KEY'))}")
|
| 42 |
logger.info("=" * 70)
|
| 43 |
|
| 44 |
+
# Initialize MCP client
|
| 45 |
+
mcp_client = get_client(MCP_SERVER_URL)
|
| 46 |
+
|
| 47 |
+
# =============================================================================
|
| 48 |
+
# MCP ENDPOINTS DEFINITIONS
|
| 49 |
+
# =============================================================================
|
| 50 |
+
|
| 51 |
+
MCP_ENDPOINTS = [
|
| 52 |
+
{"name": "create_circuit", "category": "Creation", "description": "Create circuit from template"},
|
| 53 |
+
{"name": "parse_qasm", "category": "Creation", "description": "Parse OpenQASM code"},
|
| 54 |
+
{"name": "build_circuit", "category": "Creation", "description": "Build custom circuit from gates"},
|
| 55 |
+
{"name": "validate_circuit", "category": "Validation", "description": "Full circuit validation"},
|
| 56 |
+
{"name": "check_hardware", "category": "Validation", "description": "Hardware compatibility check"},
|
| 57 |
+
{"name": "simulate", "category": "Simulation", "description": "Simulate with measurements"},
|
| 58 |
+
{"name": "get_statevector", "category": "Simulation", "description": "Extract statevector"},
|
| 59 |
+
{"name": "estimate_fidelity", "category": "Simulation", "description": "Hardware fidelity estimation"},
|
| 60 |
+
{"name": "score_circuit", "category": "Scoring", "description": "Circuit scoring metrics"},
|
| 61 |
+
{"name": "compare_circuits", "category": "Scoring", "description": "Compare multiple circuits"},
|
| 62 |
+
{"name": "get_gate_info", "category": "Documentation", "description": "Gate documentation"},
|
| 63 |
+
{"name": "get_algorithm_info", "category": "Documentation", "description": "Algorithm documentation"},
|
| 64 |
+
{"name": "list_hardware", "category": "Documentation", "description": "Available hardware profiles"},
|
| 65 |
+
{"name": "list_templates", "category": "Documentation", "description": "Available circuit templates"},
|
| 66 |
+
]
|
| 67 |
+
|
| 68 |
+
# =============================================================================
|
| 69 |
+
# CHAT FUNCTIONALITY
|
| 70 |
+
# =============================================================================
|
| 71 |
+
|
| 72 |
+
def format_circuit_response(result) -> str:
|
| 73 |
+
"""Format circuit generation result for chat display."""
|
| 74 |
+
if result.success:
|
| 75 |
+
output = f"✅ **Circuit Generated Successfully** ({result.execution_time_ms:.0f}ms)\n\n"
|
| 76 |
+
if result.final_output:
|
| 77 |
+
output += f"```qasm\n{result.final_output}\n```\n"
|
| 78 |
+
if hasattr(result, 'metrics') and result.metrics:
|
| 79 |
+
output += f"\n**Metrics:** {result.metrics}"
|
| 80 |
+
return output
|
| 81 |
+
else:
|
| 82 |
+
error_msg = "\n".join(result.errors) if hasattr(result, 'errors') else str(result)
|
| 83 |
+
return f"❌ **Generation Failed**\n\n{error_msg}"
|
| 84 |
|
| 85 |
+
|
| 86 |
+
def chat_with_agent(
|
| 87 |
+
message: str,
|
| 88 |
+
history: List[Tuple[str, str]],
|
| 89 |
+
mode: str,
|
| 90 |
+
difficulty: str
|
| 91 |
+
) -> Tuple[str, List[Tuple[str, str]]]:
|
| 92 |
+
"""
|
| 93 |
+
Process user message and generate response from quantum circuit agent.
|
| 94 |
+
|
| 95 |
+
Args:
|
| 96 |
+
message: User's input message
|
| 97 |
+
history: Chat history [(user_msg, bot_msg), ...]
|
| 98 |
+
mode: Orchestration mode (naked, quasar, hybrid, blackboard)
|
| 99 |
+
difficulty: Problem difficulty level
|
| 100 |
+
|
| 101 |
+
Returns:
|
| 102 |
+
Tuple of (bot_response, updated_history)
|
| 103 |
+
"""
|
| 104 |
try:
|
| 105 |
+
logger.info(f"Chat: mode={mode}, difficulty={difficulty}")
|
| 106 |
+
logger.info(f"User message: {message}")
|
| 107 |
|
| 108 |
+
# Check for special commands
|
| 109 |
+
message_lower = message.lower().strip()
|
| 110 |
|
| 111 |
+
# Help command
|
| 112 |
+
if message_lower in ['help', '/help', '?']:
|
| 113 |
+
response = """## 🤖 QAgents Help
|
| 114 |
+
|
| 115 |
+
I can help you with quantum circuits! Try asking me to:
|
| 116 |
+
|
| 117 |
+
**Create Circuits:**
|
| 118 |
+
- "Create a Bell state"
|
| 119 |
+
- "Generate a 3-qubit GHZ state"
|
| 120 |
+
- "Make a QFT circuit for 4 qubits"
|
| 121 |
+
- "Build a Grover search circuit"
|
| 122 |
+
|
| 123 |
+
**Analyze Circuits:**
|
| 124 |
+
- Paste QASM code and ask "validate this circuit"
|
| 125 |
+
- "Score this circuit for IBM hardware"
|
| 126 |
+
|
| 127 |
+
**Learn:**
|
| 128 |
+
- "Explain the Hadamard gate"
|
| 129 |
+
- "How does quantum entanglement work?"
|
| 130 |
+
|
| 131 |
+
**Settings:**
|
| 132 |
+
- Use the dropdowns to change orchestration mode and difficulty
|
| 133 |
+
- `naked`: Direct LLM + MCP tools
|
| 134 |
+
- `quasar`: Structured workflow with validation
|
| 135 |
+
- `hybrid`: Combined approach
|
| 136 |
+
- `blackboard`: Multi-agent collaboration
|
| 137 |
+
|
| 138 |
+
💡 **Tip:** Start with simple requests and increase complexity!
|
| 139 |
+
"""
|
| 140 |
+
history.append((message, response))
|
| 141 |
+
return response, history
|
| 142 |
+
|
| 143 |
+
# Status command
|
| 144 |
+
if message_lower in ['status', '/status']:
|
| 145 |
+
mcp_status = check_mcp_health()
|
| 146 |
+
response = f"## 📊 System Status\n\n{mcp_status}"
|
| 147 |
+
history.append((message, response))
|
| 148 |
+
return response, history
|
| 149 |
+
|
| 150 |
+
# Generate circuit using orchestrator
|
| 151 |
+
orch = create_orchestrator(mode.lower())
|
| 152 |
+
result = orch.run(message)
|
| 153 |
|
| 154 |
if result.success:
|
| 155 |
+
response = f"✅ **Success** ({result.execution_time_ms:.0f}ms)\n\n"
|
| 156 |
if result.final_output:
|
| 157 |
+
# Check if output looks like QASM
|
| 158 |
+
if 'OPENQASM' in str(result.final_output) or 'qreg' in str(result.final_output):
|
| 159 |
+
response += f"```qasm\n{result.final_output}\n```"
|
| 160 |
+
else:
|
| 161 |
+
response += result.final_output
|
| 162 |
else:
|
| 163 |
+
response += "Circuit generated but no QASM output available."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
|
| 165 |
+
# Add step info if available
|
| 166 |
+
if result.steps_completed > 0:
|
| 167 |
+
response += f"\n\n*Completed {result.steps_completed} steps*"
|
| 168 |
+
else:
|
| 169 |
+
error_msg = "\n".join(result.errors) if result.errors else "Unknown error"
|
| 170 |
+
response = f"❌ **Failed** ({result.execution_time_ms:.0f}ms)\n\n{error_msg}"
|
| 171 |
+
|
| 172 |
+
history.append((message, response))
|
| 173 |
+
return response, history
|
| 174 |
+
|
| 175 |
except Exception as e:
|
| 176 |
+
logger.error(f"Chat error: {e}")
|
| 177 |
+
error_response = f"❌ **System Error**\n\n{str(e)}"
|
| 178 |
+
history.append((message, error_response))
|
| 179 |
+
return error_response, history
|
| 180 |
|
| 181 |
+
|
| 182 |
+
# =============================================================================
|
| 183 |
+
# MCP HEALTH CHECK FUNCTIONS
|
| 184 |
+
# =============================================================================
|
| 185 |
+
|
| 186 |
+
def check_mcp_health() -> str:
|
| 187 |
+
"""Check overall MCP server health."""
|
| 188 |
try:
|
| 189 |
+
response = requests.head(f"{MCP_SERVER_URL}/", timeout=10)
|
| 190 |
+
if response.status_code == 200:
|
| 191 |
+
return f"🟢 **Connected** to `{MCP_SERVER_URL}`"
|
| 192 |
+
else:
|
| 193 |
+
return f"🟡 **Partial** - Status {response.status_code}"
|
| 194 |
+
except requests.exceptions.Timeout:
|
| 195 |
+
return f"🟠 **Timeout** - Server slow to respond"
|
| 196 |
+
except requests.exceptions.ConnectionError:
|
| 197 |
+
return f"🔴 **Disconnected** - Cannot reach server"
|
| 198 |
except Exception as e:
|
| 199 |
+
return f"🔴 **Error**: {str(e)}"
|
| 200 |
+
|
| 201 |
+
|
| 202 |
+
def check_endpoint_health(endpoint_name: str) -> dict:
|
| 203 |
+
"""Check health of a specific MCP endpoint."""
|
| 204 |
+
start = time.perf_counter()
|
| 205 |
+
try:
|
| 206 |
+
# Try to call the Gradio API endpoint
|
| 207 |
+
url = f"{MCP_SERVER_URL}/gradio_api/call/ui_{endpoint_name}"
|
| 208 |
+
response = requests.post(
|
| 209 |
+
url,
|
| 210 |
+
json={"data": []},
|
| 211 |
+
timeout=15
|
| 212 |
+
)
|
| 213 |
+
elapsed = (time.perf_counter() - start) * 1000
|
| 214 |
+
|
| 215 |
+
if response.status_code == 200:
|
| 216 |
+
return {"status": "🟢", "latency_ms": round(elapsed, 1), "error": None}
|
| 217 |
+
elif response.status_code == 404:
|
| 218 |
+
return {"status": "🟡", "latency_ms": round(elapsed, 1), "error": "Not found"}
|
| 219 |
+
else:
|
| 220 |
+
return {"status": "🟠", "latency_ms": round(elapsed, 1), "error": f"HTTP {response.status_code}"}
|
| 221 |
+
except requests.exceptions.Timeout:
|
| 222 |
+
return {"status": "🟠", "latency_ms": 15000, "error": "Timeout"}
|
| 223 |
+
except Exception as e:
|
| 224 |
+
elapsed = (time.perf_counter() - start) * 1000
|
| 225 |
+
return {"status": "🔴", "latency_ms": round(elapsed, 1), "error": str(e)[:50]}
|
| 226 |
+
|
| 227 |
+
|
| 228 |
+
def get_all_endpoints_health() -> str:
|
| 229 |
+
"""Get health status of all MCP endpoints as formatted markdown."""
|
| 230 |
+
output_lines = [
|
| 231 |
+
"## 🔗 MCP Endpoints Health Check",
|
| 232 |
+
f"**Server:** `{MCP_SERVER_URL}`\n",
|
| 233 |
+
"| Endpoint | Category | Status | Latency | Error |",
|
| 234 |
+
"|----------|----------|--------|---------|-------|"
|
| 235 |
+
]
|
| 236 |
+
|
| 237 |
+
# Check server first
|
| 238 |
+
server_status = check_mcp_health()
|
| 239 |
+
|
| 240 |
+
for endpoint in MCP_ENDPOINTS:
|
| 241 |
+
health = check_endpoint_health(endpoint["name"])
|
| 242 |
+
error_str = health["error"] or "-"
|
| 243 |
+
output_lines.append(
|
| 244 |
+
f"| `{endpoint['name']}` | {endpoint['category']} | {health['status']} | {health['latency_ms']}ms | {error_str} |"
|
| 245 |
+
)
|
| 246 |
+
|
| 247 |
+
output_lines.append(f"\n**Last checked:** {time.strftime('%Y-%m-%d %H:%M:%S UTC')}")
|
| 248 |
+
output_lines.append(f"\n**Server Status:** {server_status}")
|
| 249 |
+
|
| 250 |
+
return "\n".join(output_lines)
|
| 251 |
+
|
| 252 |
+
|
| 253 |
+
def refresh_health_check():
|
| 254 |
+
"""Refresh the health check display."""
|
| 255 |
+
return get_all_endpoints_health()
|
| 256 |
+
|
| 257 |
+
|
| 258 |
+
def check_single_endpoint(endpoint_name: str) -> str:
|
| 259 |
+
"""Check a single endpoint and return formatted result."""
|
| 260 |
+
if not endpoint_name:
|
| 261 |
+
return "Please select an endpoint to check."
|
| 262 |
+
|
| 263 |
+
health = check_endpoint_health(endpoint_name)
|
| 264 |
+
|
| 265 |
+
output = f"## Endpoint: `{endpoint_name}`\n\n"
|
| 266 |
+
output += f"- **Status:** {health['status']}\n"
|
| 267 |
+
output += f"- **Latency:** {health['latency_ms']}ms\n"
|
| 268 |
+
if health['error']:
|
| 269 |
+
output += f"- **Error:** {health['error']}\n"
|
| 270 |
+
output += f"\n*Checked at {time.strftime('%H:%M:%S')}*"
|
| 271 |
+
|
| 272 |
+
return output
|
| 273 |
+
|
| 274 |
+
|
| 275 |
+
# =============================================================================
|
| 276 |
+
# GRADIO INTERFACE
|
| 277 |
+
# =============================================================================
|
| 278 |
+
|
| 279 |
+
# Custom CSS for better chat appearance
|
| 280 |
+
CUSTOM_CSS = """
|
| 281 |
+
.chat-container {
|
| 282 |
+
max-height: 600px;
|
| 283 |
+
overflow-y: auto;
|
| 284 |
+
}
|
| 285 |
+
.status-panel {
|
| 286 |
+
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
|
| 287 |
+
border-radius: 10px;
|
| 288 |
+
padding: 15px;
|
| 289 |
+
}
|
| 290 |
+
"""
|
| 291 |
|
| 292 |
+
with gr.Blocks(
|
| 293 |
+
title="QAgents - Quantum Circuit Assistant",
|
| 294 |
+
theme=gr.themes.Soft(
|
| 295 |
+
primary_hue="blue",
|
| 296 |
+
secondary_hue="purple",
|
| 297 |
+
),
|
| 298 |
+
css=CUSTOM_CSS
|
| 299 |
+
) as demo:
|
| 300 |
|
| 301 |
+
# Header
|
| 302 |
+
gr.Markdown("""
|
| 303 |
+
# ⚛️ QAgents: Quantum Circuit Assistant
|
| 304 |
+
|
| 305 |
+
Multi-agent system for generating optimized quantum circuits using MCP tools.
|
| 306 |
+
|
| 307 |
+
**Connected to:** [QuantumArchitect-MCP](https://huggingface.co/spaces/MCP-1st-Birthday/QuantumArchitect-MCP) on HuggingFace
|
| 308 |
+
""")
|
| 309 |
+
|
| 310 |
+
with gr.Tabs():
|
| 311 |
+
# =================================================================
|
| 312 |
+
# TAB 1: CHAT INTERFACE
|
| 313 |
+
# =================================================================
|
| 314 |
+
with gr.TabItem("💬 Chat", id="chat-tab"):
|
| 315 |
+
with gr.Row():
|
| 316 |
+
with gr.Column(scale=3):
|
| 317 |
+
chatbot = gr.Chatbot(
|
| 318 |
+
label="Quantum Circuit Agent",
|
| 319 |
+
height=500,
|
| 320 |
+
show_label=True,
|
| 321 |
+
avatar_images=(None, "https://em-content.zobj.net/source/twitter/376/atom-symbol_269b.png"),
|
| 322 |
+
bubble_full_width=False,
|
| 323 |
+
)
|
| 324 |
+
|
| 325 |
+
with gr.Row():
|
| 326 |
+
msg_input = gr.Textbox(
|
| 327 |
+
label="Your Message",
|
| 328 |
+
placeholder="Ask me to create a quantum circuit... (e.g., 'Create a Bell state')",
|
| 329 |
+
lines=2,
|
| 330 |
+
scale=4,
|
| 331 |
+
)
|
| 332 |
+
send_btn = gr.Button("Send 🚀", variant="primary", scale=1)
|
| 333 |
+
|
| 334 |
+
with gr.Row():
|
| 335 |
+
clear_btn = gr.Button("🗑️ Clear Chat", size="sm")
|
| 336 |
+
help_btn = gr.Button("❓ Help", size="sm")
|
| 337 |
+
status_btn = gr.Button("📊 Status", size="sm")
|
| 338 |
+
|
| 339 |
+
with gr.Column(scale=1):
|
| 340 |
+
gr.Markdown("### ⚙️ Settings")
|
| 341 |
+
|
| 342 |
+
mode_select = gr.Dropdown(
|
| 343 |
+
choices=["naked", "quasar", "hybrid", "blackboard"],
|
| 344 |
+
value="naked",
|
| 345 |
+
label="Orchestration Mode",
|
| 346 |
+
info="How agents collaborate"
|
| 347 |
+
)
|
| 348 |
+
|
| 349 |
+
difficulty_select = gr.Dropdown(
|
| 350 |
+
choices=["EASY", "MEDIUM", "HARD", "VERY_HARD"],
|
| 351 |
+
value="EASY",
|
| 352 |
+
label="Complexity Level",
|
| 353 |
+
info="Expected circuit complexity"
|
| 354 |
+
)
|
| 355 |
+
|
| 356 |
+
gr.Markdown("---")
|
| 357 |
+
gr.Markdown("### 📡 Quick Status")
|
| 358 |
+
mcp_status_display = gr.Markdown(value="⏳ Checking...")
|
| 359 |
+
refresh_btn = gr.Button("🔄 Refresh", size="sm")
|
| 360 |
+
|
| 361 |
+
# Chat event handlers
|
| 362 |
+
def user_submit(message, history, mode, difficulty):
|
| 363 |
+
if not message.strip():
|
| 364 |
+
return "", history
|
| 365 |
+
response, new_history = chat_with_agent(message, history, mode, difficulty)
|
| 366 |
+
return "", new_history
|
| 367 |
+
|
| 368 |
+
send_btn.click(
|
| 369 |
+
fn=user_submit,
|
| 370 |
+
inputs=[msg_input, chatbot, mode_select, difficulty_select],
|
| 371 |
+
outputs=[msg_input, chatbot]
|
| 372 |
+
)
|
| 373 |
+
|
| 374 |
+
msg_input.submit(
|
| 375 |
+
fn=user_submit,
|
| 376 |
+
inputs=[msg_input, chatbot, mode_select, difficulty_select],
|
| 377 |
+
outputs=[msg_input, chatbot]
|
| 378 |
+
)
|
| 379 |
+
|
| 380 |
+
clear_btn.click(
|
| 381 |
+
fn=lambda: [],
|
| 382 |
+
outputs=[chatbot]
|
| 383 |
+
)
|
| 384 |
+
|
| 385 |
+
help_btn.click(
|
| 386 |
+
fn=lambda h: chat_with_agent("help", h, "naked", "EASY"),
|
| 387 |
+
inputs=[chatbot],
|
| 388 |
+
outputs=[msg_input, chatbot]
|
| 389 |
)
|
| 390 |
+
|
| 391 |
+
status_btn.click(
|
| 392 |
+
fn=lambda h: chat_with_agent("status", h, "naked", "EASY"),
|
| 393 |
+
inputs=[chatbot],
|
| 394 |
+
outputs=[msg_input, chatbot]
|
| 395 |
+
)
|
| 396 |
+
|
| 397 |
+
refresh_btn.click(
|
| 398 |
+
fn=check_mcp_health,
|
| 399 |
+
outputs=[mcp_status_display]
|
| 400 |
+
)
|
| 401 |
+
|
| 402 |
+
# =================================================================
|
| 403 |
+
# TAB 2: MCP ENDPOINTS HEALTH
|
| 404 |
+
# =================================================================
|
| 405 |
+
with gr.TabItem("🔗 MCP Endpoints", id="mcp-tab"):
|
| 406 |
+
gr.Markdown("""
|
| 407 |
+
## 🔗 MCP Endpoints Health Monitor
|
| 408 |
+
|
| 409 |
+
Monitor the health and availability of QuantumArchitect-MCP endpoints.
|
| 410 |
+
|
| 411 |
+
**MCP Server:** [QuantumArchitect-MCP](https://huggingface.co/spaces/MCP-1st-Birthday/QuantumArchitect-MCP)
|
| 412 |
+
""")
|
| 413 |
+
|
| 414 |
with gr.Row():
|
| 415 |
+
check_all_btn = gr.Button("🔄 Check All Endpoints", variant="primary")
|
| 416 |
+
|
| 417 |
+
health_display = gr.Markdown(value="Click 'Check All Endpoints' to start health check...")
|
| 418 |
+
|
| 419 |
+
gr.Markdown("---")
|
| 420 |
+
gr.Markdown("### 🔍 Check Single Endpoint")
|
| 421 |
+
|
| 422 |
+
with gr.Row():
|
| 423 |
+
endpoint_dropdown = gr.Dropdown(
|
| 424 |
+
choices=[ep["name"] for ep in MCP_ENDPOINTS],
|
| 425 |
+
label="Select Endpoint",
|
| 426 |
+
value=None,
|
| 427 |
+
scale=3
|
| 428 |
)
|
| 429 |
+
check_single_btn = gr.Button("Check", scale=1)
|
| 430 |
|
| 431 |
+
single_result = gr.Markdown(value="")
|
| 432 |
|
| 433 |
+
gr.Markdown("---")
|
| 434 |
+
gr.Markdown("""
|
| 435 |
+
### 📚 Available MCP Endpoints
|
| 436 |
+
|
| 437 |
+
| Category | Endpoints |
|
| 438 |
+
|----------|-----------|
|
| 439 |
+
| **Creation** | `create_circuit`, `parse_qasm`, `build_circuit` |
|
| 440 |
+
| **Validation** | `validate_circuit`, `check_hardware` |
|
| 441 |
+
| **Simulation** | `simulate`, `get_statevector`, `estimate_fidelity` |
|
| 442 |
+
| **Scoring** | `score_circuit`, `compare_circuits` |
|
| 443 |
+
| **Documentation** | `get_gate_info`, `get_algorithm_info`, `list_hardware`, `list_templates` |
|
| 444 |
+
|
| 445 |
+
All endpoints accept JSON and return JSON via the Gradio MCP protocol.
|
| 446 |
+
""")
|
| 447 |
+
|
| 448 |
+
# Event handlers
|
| 449 |
+
check_all_btn.click(
|
| 450 |
+
fn=refresh_health_check,
|
| 451 |
+
outputs=[health_display]
|
| 452 |
+
)
|
| 453 |
+
|
| 454 |
+
check_single_btn.click(
|
| 455 |
+
fn=check_single_endpoint,
|
| 456 |
+
inputs=[endpoint_dropdown],
|
| 457 |
+
outputs=[single_result]
|
| 458 |
+
)
|
| 459 |
+
|
| 460 |
+
# =================================================================
|
| 461 |
+
# TAB 3: QUICK CIRCUIT BUILDER
|
| 462 |
+
# =================================================================
|
| 463 |
+
with gr.TabItem("🛠️ Quick Build", id="build-tab"):
|
| 464 |
+
gr.Markdown("""
|
| 465 |
+
## 🛠️ Quick Circuit Builder
|
| 466 |
+
|
| 467 |
+
Generate circuits directly from templates without chat.
|
| 468 |
+
""")
|
| 469 |
+
|
| 470 |
+
with gr.Row():
|
| 471 |
+
with gr.Column():
|
| 472 |
+
template_select = gr.Dropdown(
|
| 473 |
+
choices=["bell_state", "ghz_state", "qft", "grover", "vqe", "superposition"],
|
| 474 |
+
value="bell_state",
|
| 475 |
+
label="Circuit Template"
|
| 476 |
+
)
|
| 477 |
+
qubits_slider = gr.Slider(
|
| 478 |
+
minimum=2,
|
| 479 |
+
maximum=10,
|
| 480 |
+
value=2,
|
| 481 |
+
step=1,
|
| 482 |
+
label="Number of Qubits"
|
| 483 |
+
)
|
| 484 |
+
build_btn = gr.Button("⚡ Generate Circuit", variant="primary")
|
| 485 |
+
|
| 486 |
+
with gr.Column():
|
| 487 |
+
qasm_output = gr.Code(
|
| 488 |
+
label="Generated QASM",
|
| 489 |
+
language="python",
|
| 490 |
+
lines=15
|
| 491 |
+
)
|
| 492 |
+
|
| 493 |
+
def quick_build(template, num_qubits):
|
| 494 |
+
try:
|
| 495 |
+
result = mcp_client.create_circuit_from_template(template, int(num_qubits))
|
| 496 |
+
if result.success and result.data:
|
| 497 |
+
if isinstance(result.data, dict) and 'qasm' in result.data:
|
| 498 |
+
return result.data['qasm']
|
| 499 |
+
return str(result.data)
|
| 500 |
+
return f"# Error: {result.error or 'Unknown error'}"
|
| 501 |
+
except Exception as e:
|
| 502 |
+
return f"# Error: {str(e)}"
|
| 503 |
+
|
| 504 |
+
build_btn.click(
|
| 505 |
+
fn=quick_build,
|
| 506 |
+
inputs=[template_select, qubits_slider],
|
| 507 |
+
outputs=[qasm_output]
|
| 508 |
+
)
|
| 509 |
+
|
| 510 |
+
# =================================================================
|
| 511 |
+
# TAB 4: ABOUT
|
| 512 |
+
# =================================================================
|
| 513 |
+
with gr.TabItem("ℹ️ About", id="about-tab"):
|
| 514 |
+
gr.Markdown("""
|
| 515 |
+
## ℹ️ About QAgents
|
| 516 |
+
|
| 517 |
+
**QAgents** is a multi-agent system for quantum circuit generation and optimization.
|
| 518 |
+
|
| 519 |
+
### 🏗️ Architecture
|
| 520 |
+
|
| 521 |
+
```
|
| 522 |
+
┌─────────────────────────────────────────────┐
|
| 523 |
+
│ QAgents-Workflows │
|
| 524 |
+
│ (This App - Agent Orchestration) │
|
| 525 |
+
├─────────────────────────────────────────────┤
|
| 526 |
+
│ • Chat Interface │
|
| 527 |
+
│ • Multi-mode Orchestrators │
|
| 528 |
+
│ • LLM Integration (Gemini/LiteLLM) │
|
| 529 |
+
└─────────────────┬───────────────────────────┘
|
| 530 |
+
│ MCP Protocol
|
| 531 |
+
▼
|
| 532 |
+
┌─────────────────────────────────────────────┐
|
| 533 |
+
│ QuantumArchitect-MCP │
|
| 534 |
+
│ (HuggingFace Space - Circuit Tools) │
|
| 535 |
+
├─────────────────────────────────────────────┤
|
| 536 |
+
│ ��� Circuit Creation & Templates │
|
| 537 |
+
│ • Validation & Syntax Checking │
|
| 538 |
+
│ • Simulation & Statevectors │
|
| 539 |
+
│ • Scoring & Hardware Fitness │
|
| 540 |
+
└─────────────────────────────────────────────┘
|
| 541 |
+
```
|
| 542 |
+
|
| 543 |
+
### 🤖 Orchestration Modes
|
| 544 |
+
|
| 545 |
+
| Mode | Description | Best For |
|
| 546 |
+
|------|-------------|----------|
|
| 547 |
+
| **naked** | Direct LLM + MCP tools | Simple queries |
|
| 548 |
+
| **quasar** | Structured workflow | Complex circuits |
|
| 549 |
+
| **hybrid** | Adaptive approach | General use |
|
| 550 |
+
| **blackboard** | Multi-agent collab | Hard problems |
|
| 551 |
+
|
| 552 |
+
### 🔗 Links
|
| 553 |
+
|
| 554 |
+
- [QuantumArchitect-MCP](https://huggingface.co/spaces/MCP-1st-Birthday/QuantumArchitect-MCP)
|
| 555 |
+
- [QAgents Source](https://github.com/NLarchive/QAgents-workflows)
|
| 556 |
+
|
| 557 |
+
### 📝 License
|
| 558 |
+
|
| 559 |
+
MIT License - Feel free to use and modify!
|
| 560 |
+
""")
|
| 561 |
|
| 562 |
+
# Load initial status on app start
|
| 563 |
+
demo.load(
|
| 564 |
+
fn=check_mcp_health,
|
| 565 |
+
outputs=[mcp_status_display]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 566 |
)
|
|
|
|
|
|
|
|
|
|
| 567 |
|
| 568 |
+
# Launch configuration for HuggingFace Spaces
|
| 569 |
if __name__ == "__main__":
|
| 570 |
+
demo.launch(
|
| 571 |
+
server_name="0.0.0.0",
|
| 572 |
+
show_error=True,
|
| 573 |
+
mcp_server=True,
|
| 574 |
+
)
|
client/mcp_client.py
CHANGED
|
@@ -684,15 +684,18 @@ _client: Optional[MCPClient] = None
|
|
| 684 |
def get_client(base_url: Optional[str] = None) -> MCPClient:
|
| 685 |
"""
|
| 686 |
Get or create the MCP client singleton.
|
| 687 |
-
|
| 688 |
Args:
|
| 689 |
base_url: Optional URL override. If None, checks MCP_SERVER_URL env var,
|
| 690 |
-
|
| 691 |
"""
|
| 692 |
global _client
|
| 693 |
if _client is None:
|
| 694 |
if base_url is None:
|
| 695 |
import os
|
| 696 |
-
base_url = os.environ.get(
|
|
|
|
|
|
|
|
|
|
| 697 |
_client = MCPClient(base_url)
|
| 698 |
-
return _client
|
|
|
|
| 684 |
def get_client(base_url: Optional[str] = None) -> MCPClient:
|
| 685 |
"""
|
| 686 |
Get or create the MCP client singleton.
|
| 687 |
+
|
| 688 |
Args:
|
| 689 |
base_url: Optional URL override. If None, checks MCP_SERVER_URL env var,
|
| 690 |
+
then defaults to the HuggingFace Space URL
|
| 691 |
"""
|
| 692 |
global _client
|
| 693 |
if _client is None:
|
| 694 |
if base_url is None:
|
| 695 |
import os
|
| 696 |
+
base_url = os.environ.get(
|
| 697 |
+
"MCP_SERVER_URL",
|
| 698 |
+
"https://mcp-1st-birthday-quantumarchitect-mcp.hf.space"
|
| 699 |
+
)
|
| 700 |
_client = MCPClient(base_url)
|
| 701 |
+
return _client
|
tasks-project-state.json
CHANGED
|
@@ -1,80 +1,67 @@
|
|
| 1 |
{
|
| 2 |
"project": "QAgents-Workflows",
|
| 3 |
-
"version": "0.
|
| 4 |
-
"description": "Multi-agent quantum circuit optimization system with
|
| 5 |
-
"last_updated": "2024-11-
|
| 6 |
-
"status": "
|
| 7 |
-
"notes": "
|
| 8 |
|
| 9 |
-
"
|
| 10 |
-
"
|
| 11 |
-
"
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
"blackboard": {"success": "2/9 (22%)", "avg_time_ms": 13507}
|
| 15 |
-
},
|
| 16 |
-
"latest_test_20241129": {
|
| 17 |
-
"problem": "HARD - Deutsch Algorithm",
|
| 18 |
-
"naked": {"success": true, "time_ms": 3914, "gates": 5},
|
| 19 |
-
"quasar": {"success": true, "time_ms": 7254, "gates": 5},
|
| 20 |
-
"hybrid": {"success": true, "time_ms": 7181, "gates": 5},
|
| 21 |
-
"blackboard": {"success": true, "time_ms": 20915, "gates": 2},
|
| 22 |
-
"result": "ALL 4 MODES PASSED"
|
| 23 |
-
},
|
| 24 |
-
"very_hard_test": {
|
| 25 |
-
"problem": "VERY_HARD - 4-Qubit QFT",
|
| 26 |
-
"naked": {"success": true, "time_ms": 4473, "gates": 12},
|
| 27 |
-
"quasar": {"success": true, "time_ms": 7811, "gates": 12},
|
| 28 |
-
"hybrid": "interrupted - rate limiting",
|
| 29 |
-
"blackboard": "interrupted - rate limiting"
|
| 30 |
-
}
|
| 31 |
},
|
| 32 |
|
| 33 |
-
"
|
| 34 |
-
"
|
| 35 |
-
"
|
| 36 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
},
|
| 38 |
-
"
|
| 39 |
-
"
|
| 40 |
-
"
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
"quasar": {
|
| 46 |
-
"file": "orchestrators/quasar_orchestrator.py",
|
| 47 |
-
"description": "Tiered verification orchestrator (QUASAR-lite)",
|
| 48 |
-
"tiers": [
|
| 49 |
-
"Tier 1: Syntax validation via MCP",
|
| 50 |
-
"Tier 2: Circuit analysis (depth, gates)",
|
| 51 |
-
"Tier 3: Simulation verification",
|
| 52 |
-
"Tier 4: Semantic correctness"
|
| 53 |
]
|
| 54 |
},
|
| 55 |
-
"
|
| 56 |
-
"description": "
|
|
|
|
| 57 |
}
|
| 58 |
},
|
| 59 |
|
| 60 |
-
"
|
| 61 |
-
"
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
|
| 69 |
-
"
|
| 70 |
-
"
|
| 71 |
-
"
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
{"
|
| 75 |
-
|
| 76 |
-
{"name": "gemini-2.5-pro", "rpd": 50, "priority": 5}
|
| 77 |
-
]
|
| 78 |
},
|
| 79 |
|
| 80 |
"architectures": {
|
|
@@ -84,66 +71,28 @@
|
|
| 84 |
"success_rate": "100%",
|
| 85 |
"recommended": true
|
| 86 |
},
|
| 87 |
-
"guided": {
|
| 88 |
-
"description": "4-agent pipeline (Analyzer, Designer, Generator, Validator)",
|
| 89 |
-
"status": "DEPRECATED",
|
| 90 |
-
"success_rate": "78%",
|
| 91 |
-
"note": "Replaced by QUASAR"
|
| 92 |
-
},
|
| 93 |
-
"blackboard": {
|
| 94 |
-
"description": "Event-driven multi-agent blackboard",
|
| 95 |
-
"status": "FIXED",
|
| 96 |
-
"success_rate": "~100% (needs full retest)",
|
| 97 |
-
"note": "NoneType errors fixed, ~5x slower than NAKED"
|
| 98 |
-
},
|
| 99 |
"quasar": {
|
| 100 |
"description": "Tiered verification with MCP tools",
|
| 101 |
-
"status": "
|
| 102 |
-
"file": "orchestrators/quasar_orchestrator.py"
|
| 103 |
},
|
| 104 |
"hybrid": {
|
| 105 |
"description": "NAKED first, QUASAR fallback",
|
| 106 |
-
"status": "
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
}
|
| 108 |
},
|
| 109 |
|
| 110 |
-
"new_files_created": [
|
| 111 |
-
{"file": "prompts/optimized_prompts.py", "purpose": "Enhanced prompts for NAKED mode"},
|
| 112 |
-
{"file": "orchestrators/router.py", "purpose": "Difficulty-aware orchestrator selection"},
|
| 113 |
-
{"file": "tests/comprehensive_test.py", "purpose": "Full diagnostic test script"},
|
| 114 |
-
{"file": "docs/COMPREHENSIVE_TEST_ANALYSIS.md", "purpose": "Analysis of all test results"},
|
| 115 |
-
{"file": "docs/STRATEGIC_IMPROVEMENTS.md", "purpose": "Improvement roadmap based on findings"},
|
| 116 |
-
{"file": "docs/PROJECT_ANALYSIS_20251128.md", "purpose": "Deep project analysis"}
|
| 117 |
-
],
|
| 118 |
-
|
| 119 |
-
"recommendations": {
|
| 120 |
-
"immediate": [
|
| 121 |
-
"Adopt NAKED mode for production - 100% success, fastest, most efficient",
|
| 122 |
-
"Fix BLACKBOARD null-checking or deprecate entirely",
|
| 123 |
-
"Integrate optimized_prompts.py into NAKED orchestrator"
|
| 124 |
-
],
|
| 125 |
-
"short_term": [
|
| 126 |
-
"Add circuit quality scoring beyond gate count",
|
| 127 |
-
"Improve GUIDED generator for hard problems",
|
| 128 |
-
"Implement hybrid: NAKED first, GUIDED on failure"
|
| 129 |
-
],
|
| 130 |
-
"long_term": [
|
| 131 |
-
"Auto-select mode based on problem difficulty",
|
| 132 |
-
"MCP validation integration for correctness verification",
|
| 133 |
-
"Cost-aware orchestrator selection"
|
| 134 |
-
]
|
| 135 |
-
},
|
| 136 |
-
|
| 137 |
"usage": {
|
| 138 |
-
"
|
| 139 |
-
|
| 140 |
-
"
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
"
|
| 145 |
-
"quality_eval": "python tests/run_quality_eval.py --mode all --difficulty all",
|
| 146 |
-
"quick_test": "python tests/run_quality_eval.py --quick"
|
| 147 |
}
|
| 148 |
}
|
| 149 |
}
|
|
|
|
| 1 |
{
|
| 2 |
"project": "QAgents-Workflows",
|
| 3 |
+
"version": "0.9.0",
|
| 4 |
+
"description": "Multi-agent quantum circuit optimization system with chat UI and MCP integration",
|
| 5 |
+
"last_updated": "2024-11-30",
|
| 6 |
+
"status": "CHAT_UI_AND_MCP_HEALTH_MONITOR_ADDED",
|
| 7 |
+
"notes": "Added Gradio chat interface for agent interaction. Added MCP endpoints health monitor tab. Updated MCP client to connect to HuggingFace Space.",
|
| 8 |
|
| 9 |
+
"huggingface_deployment": {
|
| 10 |
+
"qagents_space": "https://huggingface.co/spaces/NLarchive/Qagents-workflows",
|
| 11 |
+
"mcp_server_space": "https://mcp-1st-birthday-quantumarchitect-mcp.hf.space",
|
| 12 |
+
"gradio_version": "6.0.0",
|
| 13 |
+
"mcp_enabled": true
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
},
|
| 15 |
|
| 16 |
+
"app_features": {
|
| 17 |
+
"chat_tab": {
|
| 18 |
+
"description": "Interactive chat UI for quantum circuit generation",
|
| 19 |
+
"features": [
|
| 20 |
+
"Natural language circuit requests",
|
| 21 |
+
"Multiple orchestration modes (naked, quasar, hybrid, blackboard)",
|
| 22 |
+
"Difficulty level selection",
|
| 23 |
+
"Help and status commands"
|
| 24 |
+
]
|
| 25 |
},
|
| 26 |
+
"mcp_endpoints_tab": {
|
| 27 |
+
"description": "Health monitor for QuantumArchitect-MCP endpoints",
|
| 28 |
+
"features": [
|
| 29 |
+
"Check all endpoints health",
|
| 30 |
+
"Individual endpoint testing",
|
| 31 |
+
"Latency monitoring",
|
| 32 |
+
"Status indicators (🟢🟡🟠🔴)"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
]
|
| 34 |
},
|
| 35 |
+
"quick_build_tab": {
|
| 36 |
+
"description": "Direct circuit template generation",
|
| 37 |
+
"templates": ["bell_state", "ghz_state", "qft", "grover", "vqe", "superposition"]
|
| 38 |
}
|
| 39 |
},
|
| 40 |
|
| 41 |
+
"mcp_endpoints": [
|
| 42 |
+
{"name": "create_circuit", "category": "Creation"},
|
| 43 |
+
{"name": "parse_qasm", "category": "Creation"},
|
| 44 |
+
{"name": "build_circuit", "category": "Creation"},
|
| 45 |
+
{"name": "validate_circuit", "category": "Validation"},
|
| 46 |
+
{"name": "check_hardware", "category": "Validation"},
|
| 47 |
+
{"name": "simulate", "category": "Simulation"},
|
| 48 |
+
{"name": "get_statevector", "category": "Simulation"},
|
| 49 |
+
{"name": "estimate_fidelity", "category": "Simulation"},
|
| 50 |
+
{"name": "score_circuit", "category": "Scoring"},
|
| 51 |
+
{"name": "compare_circuits", "category": "Scoring"},
|
| 52 |
+
{"name": "get_gate_info", "category": "Documentation"},
|
| 53 |
+
{"name": "get_algorithm_info", "category": "Documentation"},
|
| 54 |
+
{"name": "list_hardware", "category": "Documentation"},
|
| 55 |
+
{"name": "list_templates", "category": "Documentation"}
|
| 56 |
+
],
|
| 57 |
|
| 58 |
+
"comprehensive_test_results": {
|
| 59 |
+
"test_date": "2024-11-29",
|
| 60 |
+
"previous_results": {
|
| 61 |
+
"naked": {"success": "9/9 (100%)", "avg_time_ms": 3929},
|
| 62 |
+
"guided": {"success": "7/9 (78%)", "avg_time_ms": 23120},
|
| 63 |
+
"blackboard": {"success": "2/9 (22%)", "avg_time_ms": 13507}
|
| 64 |
+
}
|
|
|
|
|
|
|
| 65 |
},
|
| 66 |
|
| 67 |
"architectures": {
|
|
|
|
| 71 |
"success_rate": "100%",
|
| 72 |
"recommended": true
|
| 73 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
"quasar": {
|
| 75 |
"description": "Tiered verification with MCP tools",
|
| 76 |
+
"status": "STABLE"
|
|
|
|
| 77 |
},
|
| 78 |
"hybrid": {
|
| 79 |
"description": "NAKED first, QUASAR fallback",
|
| 80 |
+
"status": "STABLE"
|
| 81 |
+
},
|
| 82 |
+
"blackboard": {
|
| 83 |
+
"description": "Event-driven multi-agent blackboard",
|
| 84 |
+
"status": "FIXED"
|
| 85 |
}
|
| 86 |
},
|
| 87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
"usage": {
|
| 89 |
+
"huggingface": "Visit https://huggingface.co/spaces/NLarchive/Qagents-workflows",
|
| 90 |
+
"local": {
|
| 91 |
+
"prerequisites": [
|
| 92 |
+
"Activate venv: & .venv/Scripts/Activate.ps1",
|
| 93 |
+
"Set GOOGLE_API_KEY environment variable"
|
| 94 |
+
],
|
| 95 |
+
"run": "python app.py"
|
|
|
|
|
|
|
| 96 |
}
|
| 97 |
}
|
| 98 |
}
|