import gradio as gr import asyncio import json import time import io from typing import List from langchain_core.messages import AIMessage, HumanMessage, ToolMessage from core.agents.SkeletonGraphAgent import SkeletonGraphAgent from core.config.prompt import get_default_system_prompt from core.config.metadata import create_metadata # ----- State ----- conversation_history = [] # ----- Agent Initialization ----- async def initialize_agent_async(metadata): try: new_agent = await SkeletonGraphAgent.create(metadata) return new_agent, None except Exception as e: return None, str(e) def initialize_agent_handler(model_name, temperature, max_tokens, system_prompt, api_key): metadata = create_metadata(model_name, temperature, max_tokens, system_prompt, api_key) # Use the existing event loop if available, otherwise create a new one try: loop = asyncio.get_event_loop() except RuntimeError: loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) agent, error = loop.run_until_complete(initialize_agent_async(metadata)) if agent: return agent, "✅ Agent initialized successfully!", "🟢 Agent Ready" else: return None, f"❌ Failed to initialize agent: {error}", "🔴 Agent Failed" # ----- Chat Handler ----- async def get_agent_response_async(agent, user_input): global conversation_history human_msg = HumanMessage(content=user_input) conversation_history.append(human_msg) input_message = {"messages": conversation_history.copy()} try: result = await agent.workflow.ainvoke(input=input_message) if result and 'messages' in result: for msg in reversed(result['messages']): if isinstance(msg, AIMessage): conversation_history.append(msg) return msg.content, None fallback = AIMessage(content="No response generated") conversation_history.append(fallback) return fallback.content, None except Exception as e: conversation_history.pop() return None, str(e) def chat_with_agent(agent, user_input, chat_history): if not agent: chat_history.append([user_input, "❌ Please initialize your agent first."]) return chat_history, "" if not user_input.strip(): return chat_history, "" # Use the existing event loop if available, otherwise create a new one try: loop = asyncio.get_event_loop() except RuntimeError: loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) response, error = loop.run_until_complete(get_agent_response_async(agent, user_input)) if response: chat_history.append([user_input, response]) else: chat_history.append([user_input, f"❌ Error: {error}"]) return chat_history, "" def reset_conversation(): global conversation_history conversation_history = [] return [], "🔄 Conversation reset!", "🟢 Agent Ready" # ----- Gradio Interface ----- def create_interface(): with gr.Blocks( title="TrackMate AI", theme=gr.themes.Soft(), css=""" /* Dark theme colors */ :root { --bg-primary: #121212; --bg-secondary: #1e1e1e; --bg-tertiary: #252525; --text-primary: #e0e0e0; --text-secondary: #a0a0a0; --accent-primary: #3a506b; --accent-secondary: #1c2541; --accent-tertiary: #0b132b; --highlight: #5bc0be; --error: #ff6b6b; --success: #6bd425; } .documentation-container { background-color: var(--bg-secondary); color: var(--text-primary); padding: 2rem; border-radius: 15px; margin-bottom: 2rem; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); } .documentation-header { text-align: center; margin-bottom: 1.5rem; } .documentation-section { background-color: var(--bg-tertiary); padding: 1.5rem; border-radius: 10px; margin-bottom: 1.5rem; border-left: 4px solid var(--highlight); } .config-panel { background-color: var(--bg-secondary); padding: 1.5rem; border-radius: 15px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3); height: 100%; display: flex; flex-direction: column; } .chat-panel { background-color: var(--bg-secondary); padding: 1.5rem; border-radius: 15px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3); height: 100%; display: flex; flex-direction: column; } .panel-header { text-align: center; padding: 1rem; background-color: var(--accent-primary); color: var(--text-primary); border-radius: 10px; margin-bottom: 1rem; } .tools-table { width: 100%; border-collapse: collapse; margin-top: 1rem; } .tools-table th, .tools-table td { padding: 0.75rem; text-align: left; border-bottom: 1px solid var(--accent-secondary); } .tools-table th { font-weight: bold; background-color: var(--accent-tertiary); } .feature-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 0.5rem; margin-top: 1rem; } .feature-item { background-color: var(--accent-secondary); padding: 0.75rem; border-radius: 10px; } a { color: var(--highlight); text-decoration: none; font-weight: bold; } a:hover { text-decoration: underline; } /* Chat avatar styling */ .chatbot .avatar { display: flex !important; align-items: center; justify-content: center; width: 40px !important; height: 40px !important; border-radius: 50%; background-color: var(--accent-secondary); color: var(--text-primary); font-size: 20px; margin-right: 10px; } /* Ensure chat messages have proper contrast */ .chatbot .user-message { background-color: var(--accent-primary) !important; color: var(--text-primary) !important; border-radius: 10px !important; } .chatbot .bot-message { background-color: var(--accent-secondary) !important; color: var(--text-primary) !important; border-radius: 10px !important; } /* Override any theme styles that might hide avatars */ .chatbot .message-container { display: flex !important; align-items: flex-start !important; } """ ) as app: agent_state = gr.State(value=None) # Consolidated Documentation Section gr.HTML("""
Your smart companion for tracking and managing orders.
TrackMate AI is a Gradio-powered autonomous agent designed to interface with an ERP system via MCP tools. It connects to a custom MCP Server and lets users chat with an LLM to place, modify, or track orders — all through natural language. Designed for seamless interaction with ERP infrastructure, TrackMate AI empowers users to manage operational workflows via a conversational interface — no dashboards, no dropdowns, just intelligent dialogue. Whether you're tracking an order, generating invoices, or accessing global risk intelligence, TrackMate AI brings an intuitive, natural language layer to your business operations.
📹 Watch Demo Video - TrackMate AI Agent
TrackMate AI uses a bunch of tools provided by the TrackMate AI MCP Server :
| Tool Name | Description |
|---|---|
list_tables |
Lists all ERP database tables |
execute_query |
Executes a custom SQL query |
get_order_status |
Gets status of an order |
place_order |
Places a new order |
cancel_order |
Cancels an existing order |
get_active_disruptions |
Returns geopolitical disruptions between nations |
add, subtract, multiple |
Use a simple calculator |