← back to Designer Wallcoverings

DW-Agents/dw-agents/master-hub-chat.js

651 lines

const express = require('express');
const cors = require('cors');
const path = require('path');
const fs = require('fs');

const app = express();
const PORT = 9893;

// Middleware
app.use(cors());
app.use(express.json());
app.use(express.static('public'));

// Read agent configurations
const getAgentConfigs = () => {
  const agents = [
    { name: 'Purchasing Office', port: 9880, icon: '🛒', description: 'Manages purchase orders and vendor relations' },
    { name: 'Marketing Agent', port: 9881, icon: '📢', description: 'Handles marketing campaigns and social media' },
    { name: 'Accounting Agent', port: 9882, icon: '💰', description: 'Financial tracking and reporting' },
    { name: 'Trend Research', port: 9883, icon: '📊', description: 'Analyzes market trends and patterns' },
    { name: 'Zendesk Chat', port: 9884, icon: '💬', description: 'Customer support integration' },
    { name: 'Digital Samples', port: 9879, icon: '🎨', description: 'Digital sample management' },
    { name: 'Legal Team', port: 9878, icon: '⚖️', description: 'Legal document processing' },
    { name: 'Needs Attention', port: 9886, icon: '⚠️', description: 'Priority items requiring attention' },
    { name: 'Parallel Processes', port: 9887, icon: '🔄', description: 'Concurrent task management' },
    { name: 'Server Uptime', port: 9888, icon: '🖥️', description: 'Monitor server health' },
    { name: 'Task Orchestrator', port: 9900, icon: '🎯', description: 'Coordinate agent tasks' },
    { name: 'Completed Tasks', port: 9889, icon: '✅', description: 'Track finished work' },
    { name: "Today's Highlights", port: 9885, icon: '⭐', description: 'Daily summary and highlights' },
    { name: 'New Client Signup', port: 9890, icon: '👤', description: 'Onboard new clients' },
    { name: 'In Parallel', port: 9891, icon: '⚡', description: 'Simultaneous operations' },
    { name: 'Skills Manager', port: 9894, icon: '🧠', description: 'AI capabilities registry' }
  ];
  
  return agents;
};

// Health check endpoint
app.get('/health', (req, res) => {
  res.json({
    status: 'healthy',
    service: 'Master Hub Chat',
    port: PORT,
    uptime: process.uptime(),
    timestamp: new Date().toISOString()
  });
});

// Get all agents
app.get('/api/agents', (req, res) => {
  const agents = getAgentConfigs();
  res.json(agents);
});

// Main dashboard HTML
app.get('/', (req, res) => {
  const html = `
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Master Hub - DW Agents</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      min-height: 100vh;
      padding: 20px;
    }

    .container {
      max-width: 1400px;
      margin: 0 auto;
    }

    .header {
      text-align: center;
      color: white;
      margin-bottom: 40px;
      padding: 30px;
      background: rgba(255,255,255,0.1);
      border-radius: 20px;
      backdrop-filter: blur(10px);
    }

    h1 {
      font-size: 3em;
      margin-bottom: 10px;
      text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
    }

    .subtitle {
      font-size: 1.2em;
      opacity: 0.95;
    }

    .agents-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
      gap: 25px;
      margin-bottom: 40px;
    }

    .agent-card {
      background: white;
      border-radius: 15px;
      padding: 25px;
      box-shadow: 0 10px 30px rgba(0,0,0,0.2);
      transition: all 0.3s ease;
      position: relative;
      overflow: hidden;
    }

    .agent-card:hover {
      transform: translateY(-5px);
      box-shadow: 0 15px 40px rgba(0,0,0,0.3);
    }

    .agent-header {
      display: flex;
      align-items: center;
      gap: 15px;
      margin-bottom: 15px;
    }

    .agent-icon {
      font-size: 2.5em;
      min-width: 60px;
      text-align: center;
    }

    .agent-info {
      flex: 1;
    }

    .agent-name {
      font-size: 1.3em;
      font-weight: 700;
      color: #333;
      margin-bottom: 5px;
    }

    .agent-port {
      color: #666;
      font-size: 0.9em;
      font-family: monospace;
      background: #f0f0f0;
      padding: 2px 8px;
      border-radius: 4px;
      display: inline-block;
    }

    .agent-description {
      color: #555;
      line-height: 1.5;
      margin-bottom: 20px;
      min-height: 40px;
    }

    .agent-actions {
      display: flex;
      gap: 10px;
    }

    .btn {
      flex: 1;
      padding: 12px 20px;
      border: none;
      border-radius: 8px;
      font-size: 1em;
      font-weight: 600;
      cursor: pointer;
      transition: all 0.2s;
      text-decoration: none;
      text-align: center;
      display: inline-block;
    }

    .btn-primary {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      color: white;
    }

    .btn-primary:hover {
      transform: scale(1.05);
      box-shadow: 0 5px 15px rgba(102,126,234,0.4);
    }

    .btn-secondary {
      background: #f0f0f0;
      color: #333;
    }

    .btn-secondary:hover {
      background: #e0e0e0;
    }

    .status-indicator {
      position: absolute;
      top: 15px;
      right: 15px;
      width: 12px;
      height: 12px;
      border-radius: 50%;
      background: #4CAF50;
      box-shadow: 0 0 10px #4CAF50;
      animation: pulse 2s infinite;
    }

    .status-indicator.offline {
      background: #f44336;
      box-shadow: 0 0 10px #f44336;
    }

    @keyframes pulse {
      0% { transform: scale(1); opacity: 1; }
      50% { transform: scale(1.2); opacity: 0.7; }
      100% { transform: scale(1); opacity: 1; }
    }

    .footer {
      text-align: center;
      color: white;
      padding: 20px;
      background: rgba(255,255,255,0.1);
      border-radius: 15px;
      backdrop-filter: blur(10px);
    }

    /* Chat Modal */
    .chat-modal {
      display: none;
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(0,0,0,0.7);
      z-index: 10000;
      justify-content: center;
      align-items: center;
    }

    .chat-container {
      width: 500px;
      height: 700px;
      background: white;
      border-radius: 20px;
      display: flex;
      flex-direction: column;
      overflow: hidden;
      box-shadow: 0 20px 60px rgba(0,0,0,0.5);
    }

    .chat-header {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      color: white;
      padding: 20px;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .chat-title {
      font-size: 1.3em;
      font-weight: 600;
      display: flex;
      align-items: center;
      gap: 10px;
    }

    .chat-close {
      background: rgba(255,255,255,0.2);
      border: none;
      color: white;
      width: 36px;
      height: 36px;
      border-radius: 50%;
      cursor: pointer;
      font-size: 1.5em;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .chat-close:hover {
      background: rgba(255,255,255,0.3);
    }

    .chat-messages {
      flex: 1;
      overflow-y: auto;
      padding: 20px;
      background: #f8f9fa;
    }

    .chat-input-container {
      padding: 20px;
      border-top: 1px solid #e0e0e0;
      background: white;
    }

    .chat-input-wrapper {
      display: flex;
      gap: 10px;
    }

    .chat-input {
      flex: 1;
      padding: 12px;
      border: 2px solid #e0e0e0;
      border-radius: 25px;
      font-size: 1em;
      outline: none;
    }

    .chat-input:focus {
      border-color: #667eea;
    }

    .chat-send {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      color: white;
      border: none;
      padding: 12px 24px;
      border-radius: 25px;
      cursor: pointer;
      font-weight: 600;
    }

    .chat-send:hover {
      transform: scale(1.05);
    }

    .message {
      margin-bottom: 15px;
      animation: slideIn 0.3s ease;
    }

    @keyframes slideIn {
      from {
        opacity: 0;
        transform: translateY(10px);
      }
      to {
        opacity: 1;
        transform: translateY(0);
      }
    }

    .message.user {
      text-align: right;
    }

    .message-content {
      display: inline-block;
      padding: 12px 16px;
      border-radius: 12px;
      max-width: 80%;
      word-wrap: break-word;
    }

    .message.user .message-content {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      color: white;
    }

    .message.assistant .message-content {
      background: white;
      color: #333;
      border: 1px solid #e0e0e0;
    }

    .typing-indicator {
      display: none;
      padding: 12px 16px;
      background: white;
      border: 1px solid #e0e0e0;
      border-radius: 12px;
      display: inline-block;
      margin-bottom: 15px;
    }

    .typing-indicator span {
      display: inline-block;
      width: 8px;
      height: 8px;
      background: #666;
      border-radius: 50%;
      margin: 0 2px;
      animation: typing 1.4s infinite;
    }

    .typing-indicator span:nth-child(2) {
      animation-delay: 0.2s;
    }

    .typing-indicator span:nth-child(3) {
      animation-delay: 0.4s;
    }

    @keyframes typing {
      0%, 60%, 100% {
        transform: translateY(0);
      }
      30% {
        transform: translateY(-10px);
      }
    }

    @media (max-width: 768px) {
      .agents-grid {
        grid-template-columns: 1fr;
      }

      .chat-container {
        width: 90%;
        height: 80%;
        margin: 20px;
      }

      h1 {
        font-size: 2em;
      }
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="header">
      <h1>🚀 Master Hub</h1>
      <div class="subtitle">DW Agents Central Command</div>
    </div>

    <div class="agents-grid" id="agentsGrid">
      <!-- Agent cards will be loaded here -->
    </div>

    <div class="footer">
      <p>© 2024 Designer Wallcoverings - AI Agent Network</p>
      <p style="margin-top: 10px; opacity: 0.8;">Powered by Claude AI</p>
    </div>
  </div>

  <!-- Chat Modal -->
  <div class="chat-modal" id="chatModal">
    <div class="chat-container">
      <div class="chat-header">
        <div class="chat-title">
          <span id="chatAgentIcon">💬</span>
          <span id="chatAgentName">Agent Assistant</span>
        </div>
        <button class="chat-close" onclick="closeChat()">×</button>
      </div>
      <div class="chat-messages" id="chatMessages">
        <div style="text-align: center; color: #888; padding: 20px;">
          👋 Hi! How can I help you today?
        </div>
      </div>
      <div class="chat-input-container">
        <div class="chat-input-wrapper">
          <input
            type="text"
            class="chat-input"
            id="chatInput"
            placeholder="Type your message..."
            onkeypress="if(event.key==='Enter') sendMessage()"
          />
          <button class="chat-send" onclick="sendMessage()">Send</button>
        </div>
      </div>
    </div>
  </div>

  <script>
    let currentAgent = null;
    let chatHistory = [];

    // Load agents on page load
    async function loadAgents() {
      try {
        const response = await fetch('/api/agents');
        const agents = await response.json();
        
        const grid = document.getElementById('agentsGrid');
        grid.innerHTML = agents.map(agent => \`
          <div class="agent-card">
            <div class="status-indicator" id="status-\${agent.port}"></div>
            <div class="agent-header">
              <div class="agent-icon">\${agent.icon}</div>
              <div class="agent-info">
                <div class="agent-name">\${agent.name}</div>
                <div class="agent-port">Port: \${agent.port}</div>
              </div>
            </div>
            <div class="agent-description">\${agent.description}</div>
            <div class="agent-actions">
              <a href="http://45.61.58.125:\${agent.port}" target="_blank" class="btn btn-secondary">
                🔗 Open
              </a>
              <button class="btn btn-primary" onclick='openChat(\${JSON.stringify(agent)})'>
                💬 Chat
              </button>
            </div>
          </div>
        \`).join('');
        
        // Check agent status
        agents.forEach(agent => {
          checkAgentStatus(agent.port);
        });
      } catch (error) {
        console.error('Failed to load agents:', error);
      }
    }

    // Check if agent is online
    async function checkAgentStatus(port) {
      try {
        const response = await fetch(\`http://45.61.58.125:\${port}/health\`, {
          mode: 'no-cors',
          timeout: 2000
        });
        document.getElementById(\`status-\${port}\`).classList.remove('offline');
      } catch (error) {
        document.getElementById(\`status-\${port}\`).classList.add('offline');
      }
    }

    // Open chat modal
    function openChat(agent) {
      currentAgent = agent;
      chatHistory = [];
      
      document.getElementById('chatAgentIcon').textContent = agent.icon;
      document.getElementById('chatAgentName').textContent = agent.name;
      document.getElementById('chatModal').style.display = 'flex';
      document.getElementById('chatMessages').innerHTML = \`
        <div style="text-align: center; color: #888; padding: 20px;">
          👋 Hi! I'm the AI assistant for \${agent.name}. How can I help you?
        </div>
      \`;
      document.getElementById('chatInput').focus();
    }

    // Close chat modal
    function closeChat() {
      document.getElementById('chatModal').style.display = 'none';
      currentAgent = null;
      chatHistory = [];
    }

    // Send message
    async function sendMessage() {
      const input = document.getElementById('chatInput');
      const message = input.value.trim();
      
      if (!message || !currentAgent) return;
      
      // Add user message
      addMessage('user', message);
      input.value = '';
      
      // Show typing indicator
      showTyping();
      
      // Simulate AI response (in production, this would call the agent's API)
      setTimeout(() => {
        hideTyping();
        const response = generateAgentResponse(currentAgent, message);
        addMessage('assistant', response);
      }, 1000);
    }

    // Add message to chat
    function addMessage(role, content) {
      const messagesDiv = document.getElementById('chatMessages');
      const messageDiv = document.createElement('div');
      messageDiv.className = \`message \${role}\`;
      messageDiv.innerHTML = \`<div class="message-content">\${content}</div>\`;
      messagesDiv.appendChild(messageDiv);
      messagesDiv.scrollTop = messagesDiv.scrollHeight;
      
      chatHistory.push({ role, content });
    }

    // Show typing indicator
    function showTyping() {
      const messagesDiv = document.getElementById('chatMessages');
      const typingDiv = document.createElement('div');
      typingDiv.className = 'typing-indicator';
      typingDiv.id = 'typingIndicator';
      typingDiv.style.display = 'inline-block';
      typingDiv.innerHTML = '<span></span><span></span><span></span>';
      messagesDiv.appendChild(typingDiv);
      messagesDiv.scrollTop = messagesDiv.scrollHeight;
    }

    // Hide typing indicator
    function hideTyping() {
      const indicator = document.getElementById('typingIndicator');
      if (indicator) indicator.remove();
    }

    // Generate agent-specific response
    function generateAgentResponse(agent, message) {
      const responses = {
        'Purchasing Office': 'I can help you with purchase orders, vendor management, and procurement processes.',
        'Marketing Agent': 'I handle marketing campaigns, social media strategies, and brand management.',
        'Accounting Agent': 'I manage financial reports, invoices, and budget tracking.',
        'Trend Research': 'I analyze market trends, consumer behavior, and industry patterns.',
        'Skills Manager': 'I manage the AI capabilities registry and track skill usage across all agents.',
        'Needs Attention': 'I track priority items and urgent tasks that require immediate attention.',
        'Task Orchestrator': 'I coordinate tasks between agents and manage workflow automation.'
      };
      
      return responses[agent.name] || \`I'm the \${agent.name} assistant. I can help you with tasks related to \${agent.description.toLowerCase()}.\`;
    }

    // Initialize on load
    loadAgents();
    
    // Refresh status every 30 seconds
    setInterval(loadAgents, 30000);

    // Close modal on outside click
    document.getElementById('chatModal').addEventListener('click', (e) => {
      if (e.target.id === 'chatModal') {
        closeChat();
      }
    });
  </script>
</body>
</html>
  `;
  res.send(html);
});

// Start server
app.listen(PORT, () => {
  console.log(`✅ Master Hub Chat running on http://45.61.58.125:${PORT}`);
  console.log(`📊 Dashboard: http://45.61.58.125:${PORT}/`);
  console.log(`❤️ Health check: http://45.61.58.125:${PORT}/health`);
});