|
|
|
|
|
import logging |
|
|
import asyncio |
|
|
import gradio as gr |
|
|
from environs import Env |
|
|
|
|
|
from mcp_client import MCPClient |
|
|
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
env = Env() |
|
|
env.read_env() |
|
|
|
|
|
AUTH_USERNAME = env.str("AUTH_USERNAME", "admin") |
|
|
AUTH_PASSWORD = env.str("AUTH_PASSWORD", "admin") |
|
|
|
|
|
async def initialize_client(): |
|
|
logger.info("Initializing MCP client...") |
|
|
client = MCPClient() |
|
|
logger.info("MCP client created") |
|
|
await client.initialize() |
|
|
result = client |
|
|
logger.info("MCP client initialized") |
|
|
return result |
|
|
|
|
|
|
|
|
def launch_ui(): |
|
|
with gr.Blocks(title="MCP Chatbot UI", fill_height=True, fill_width=True) as demo: |
|
|
gr.Markdown("## Dnext Product Catalog AI Assistant") |
|
|
|
|
|
|
|
|
with gr.Row() as auth_section: |
|
|
with gr.Column(scale=1): |
|
|
gr.Markdown("### Authentication") |
|
|
username = gr.Textbox(label="Username", placeholder="Enter your username") |
|
|
password = gr.Textbox(label="Password", placeholder="Enter your password", type="password") |
|
|
login_btn = gr.Button("Login", variant="primary") |
|
|
|
|
|
|
|
|
with gr.Row(visible=False) as main_content: |
|
|
with gr.Column(scale=2): |
|
|
gr.Markdown("### Chat Interface") |
|
|
chatbot = gr.Chatbot(height=500, label="Chatbot", type="messages") |
|
|
with gr.Row(): |
|
|
msg = gr.Textbox( |
|
|
label="Enter your request", |
|
|
placeholder="Type your message here...", |
|
|
lines=2, |
|
|
scale=4 |
|
|
) |
|
|
submit_btn = gr.Button("Submit", scale=1) |
|
|
clear_btn = gr.Button("Clear Chat", variant="secondary") |
|
|
|
|
|
with gr.Column(scale=1): |
|
|
gr.Markdown("### Example Use Cases") |
|
|
with gr.Accordion("Product Creation Flow", open=False): |
|
|
gr.Markdown(""" |
|
|
**Step 1:** Define a product characteristic |
|
|
``` |
|
|
define a product characteristic named 'characteristic1' with various attributes like 'Simple Value', 'MBPS' as the unit of measure, and a value of '1000' |
|
|
``` |
|
|
|
|
|
**Step 2:** Define price structure |
|
|
``` |
|
|
define the price structure for the product 'price1'. The price is set to a one-time charge of 100 USD, with a unit of measure 'Day' and no recurring charges |
|
|
``` |
|
|
|
|
|
**Step 3:** Create product specification |
|
|
``` |
|
|
create a product specification for 'specification1', which links the previously created characteristic (characteristic1) to the product specification |
|
|
``` |
|
|
|
|
|
**Step 4:** Define complete product offering |
|
|
``` |
|
|
define a complete product offering. Tie the product specification (specification1), pricing (price1), and characteristics (characteristic1) that you previously created |
|
|
``` |
|
|
""") |
|
|
|
|
|
def authenticate(username, password): |
|
|
if username == AUTH_USERNAME and password == AUTH_PASSWORD: |
|
|
return { |
|
|
auth_section: gr.Row.update(visible=False), |
|
|
main_content: gr.Row.update(visible=True) |
|
|
} |
|
|
return { |
|
|
auth_section: gr.Row.update(visible=True), |
|
|
main_content: gr.Row.update(visible=False) |
|
|
} |
|
|
|
|
|
async def respond(user_message): |
|
|
bot_response = await client.invoke(user_message) |
|
|
return [ |
|
|
{"role": "user", "content": user_message}, |
|
|
{"role": "assistant", "content": bot_response}, |
|
|
], "" |
|
|
|
|
|
|
|
|
async def clear_chat_and_memory(): |
|
|
await client.clear_memory() |
|
|
return [], "" |
|
|
|
|
|
login_btn.click( |
|
|
fn=authenticate, |
|
|
inputs=[username, password], |
|
|
outputs=[auth_section, main_content] |
|
|
) |
|
|
submit_btn.click(fn=respond, inputs=[msg], outputs=[chatbot, msg]) |
|
|
clear_btn.click(fn=clear_chat_and_memory, inputs=[], outputs=[chatbot, msg]) |
|
|
|
|
|
return demo |
|
|
|
|
|
|
|
|
async def main(): |
|
|
try: |
|
|
logger.info("Starting application...") |
|
|
global client |
|
|
logger.info("Initializing MCP client...") |
|
|
client = await initialize_client() |
|
|
logger.info("MCP client initialized successfully") |
|
|
|
|
|
logger.info("Launching Gradio UI...") |
|
|
demo = launch_ui() |
|
|
logger.info("Gradio UI created successfully") |
|
|
|
|
|
logger.info(f"Starting Gradio server on {env.str('GRADIO_SERVER_HOST', '0.0.0.0')}:{env.int('GRADIO_SERVER_PORT', 7860)}") |
|
|
demo.launch( |
|
|
server_name=env.str("GRADIO_SERVER_HOST", "0.0.0.0"), |
|
|
server_port=env.int("GRADIO_SERVER_PORT", 7860), |
|
|
share=False, |
|
|
show_error=True, |
|
|
show_api=False |
|
|
) |
|
|
logger.info("Gradio server started successfully") |
|
|
except Exception as e: |
|
|
logger.error(f"Error starting application: {str(e)}") |
|
|
raise |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
try: |
|
|
logger.info("Starting main application...") |
|
|
asyncio.run(main()) |
|
|
except Exception as e: |
|
|
logger.error(f"Fatal error in main: {str(e)}") |
|
|
raise |
|
|
|
|
|
|
|
|
|