Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <title>Agent Chat - Idea Generator</title> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.4/socket.io.js"></script> | |
| <style> | |
| /* Overall dark theme */ | |
| body { | |
| background-color: #1a1a2e; | |
| color: #eaeaea; | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| margin: 0; | |
| padding: 0; | |
| } | |
| .container { | |
| max-width: 800px; | |
| margin: 0 auto; | |
| padding: 20px; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 20px; | |
| } | |
| h1 { | |
| text-align: center; | |
| margin-bottom: 10px; | |
| color: #eaeaea; | |
| } | |
| /* Wrapper for chat area, logs, and input */ | |
| .chat-section { | |
| display: flex; | |
| flex-direction: column; | |
| border: 1px solid #0f3460; | |
| border-radius: 8px; | |
| overflow: hidden; | |
| } | |
| /* Chat container */ | |
| .chat-container { | |
| background-color: #16213e; | |
| padding: 20px; | |
| height: 400px; | |
| overflow-y: auto; | |
| } | |
| /* Logs container with a flash (fade-in) effect */ | |
| .logs-container { | |
| background-color: #0f3460; | |
| padding: 10px 20px; | |
| height: 80px; | |
| overflow-y: auto; | |
| } | |
| .bubble.log { | |
| background-color: #444; | |
| color: #ccc; | |
| font-size: 0.85rem; | |
| border-radius: 5px; | |
| padding: 5px 10px; | |
| margin: 2px 0; | |
| animation: flash 0.5s ease-in-out; | |
| } | |
| @keyframes flash { | |
| 0% { opacity: 0; } | |
| 100% { opacity: 1; } | |
| } | |
| /* Chat message styles */ | |
| .message { | |
| margin-bottom: 10px; | |
| display: flex; | |
| align-items: flex-start; | |
| } | |
| .message.user { | |
| justify-content: flex-end; | |
| } | |
| .message.agent { | |
| justify-content: flex-start; | |
| } | |
| .bubble { | |
| max-width: 70%; | |
| padding: 10px 15px; | |
| border-radius: 15px; | |
| line-height: 1.4; | |
| word-wrap: break-word; | |
| } | |
| .bubble.user { | |
| background-color: #007bff; | |
| color: #fff; | |
| border-bottom-right-radius: 0; | |
| } | |
| .bubble.agent { | |
| background-color: #2d3a55; | |
| color: #fff; | |
| border-bottom-left-radius: 0; | |
| position: relative; | |
| } | |
| /* Input area styles */ | |
| .input-area { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 10px; | |
| padding: 10px; /* Reduced padding */ | |
| background-color: #16213e; | |
| box-sizing: border-box; /* Ensure padding counts toward total width/height */ | |
| } | |
| .input-area input, | |
| .input-area textarea { | |
| width: 100%; | |
| padding: 10px; | |
| border-radius: 5px; | |
| border: none; | |
| resize: none; | |
| font-size: 1rem; | |
| box-sizing: border-box; /* Prevents overflow when combined with padding */ | |
| } | |
| .input-area button { | |
| padding: 10px 20px; | |
| border-radius: 5px; | |
| border: none; | |
| background-color: #007bff; | |
| color: #fff; | |
| cursor: pointer; | |
| align-self: flex-end; | |
| } | |
| .input-area button:hover { | |
| background-color: #0056b3; | |
| } | |
| /* Loader spinner styling */ | |
| .loader { | |
| border: 3px solid #f3f3f3; | |
| border-top: 3px solid #007bff; | |
| border-radius: 50%; | |
| width: 16px; | |
| height: 16px; | |
| animation: spin 1s linear infinite; | |
| margin-right: 10px; | |
| display: inline-block; | |
| vertical-align: middle; | |
| } | |
| @keyframes spin { | |
| 0% { transform: rotate(0deg); } | |
| 100% { transform: rotate(360deg); } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h1>Agent Chat - Idea Generator</h1> | |
| <div class="chat-section"> | |
| <!-- Chat conversation container --> | |
| <div class="chat-container" id="chat"> | |
| <!-- Conversation messages will appear here --> | |
| </div> | |
| <!-- Logs container --> | |
| <div class="logs-container" id="logs"> | |
| <!-- Log messages will appear here --> | |
| </div> | |
| <!-- Input area --> | |
| <div class="input-area"> | |
| <input type="text" id="title" placeholder="Title of Idea (optional)" /> | |
| <textarea id="roughIdea" rows="2" placeholder="Rough Idea (optional)"></textarea> | |
| <input type="text" id="category" placeholder="Category (optional)" /> | |
| <textarea id="query" rows="3" placeholder="User Query (mandatory)"></textarea> | |
| <button id="send">Send</button> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| const socket = io(); | |
| const chatContainer = document.getElementById("chat"); | |
| const logsContainer = document.getElementById("logs"); | |
| const sendButton = document.getElementById("send"); | |
| // Function to add a chat message bubble | |
| function addMessage(sender, text) { | |
| const messageDiv = document.createElement("div"); | |
| messageDiv.classList.add("message", sender); | |
| const bubbleDiv = document.createElement("div"); | |
| bubbleDiv.classList.add("bubble", sender); | |
| bubbleDiv.textContent = text; | |
| messageDiv.appendChild(bubbleDiv); | |
| chatContainer.appendChild(messageDiv); | |
| chatContainer.scrollTop = chatContainer.scrollHeight; | |
| } | |
| // Function to add a log message bubble with flash effect | |
| function addLogMessage(text) { | |
| const logDiv = document.createElement("div"); | |
| logDiv.classList.add("bubble", "log"); | |
| logDiv.textContent = text; | |
| logsContainer.appendChild(logDiv); | |
| logsContainer.scrollTop = logsContainer.scrollHeight; | |
| } | |
| // Variable to hold the agent's message bubble (with loader) | |
| let agentMessageBubble = null; | |
| // When the user clicks Send | |
| sendButton.addEventListener("click", () => { | |
| const title = document.getElementById("title").value.trim(); | |
| const roughIdea = document.getElementById("roughIdea").value.trim(); | |
| const category = document.getElementById("category").value.trim(); | |
| const query = document.getElementById("query").value.trim(); | |
| if (!query) { | |
| alert("User Query is required."); | |
| return; | |
| } | |
| // Display the user's message in chat. | |
| addMessage("user", query); | |
| // Clear input fields. | |
| document.getElementById("title").value = ""; | |
| document.getElementById("roughIdea").value = ""; | |
| document.getElementById("category").value = ""; | |
| document.getElementById("query").value = ""; | |
| // Create an agent bubble with a loader to indicate AI is processing. | |
| if (!agentMessageBubble) { | |
| const messageDiv = document.createElement("div"); | |
| messageDiv.classList.add("message", "agent"); | |
| agentMessageBubble = document.createElement("div"); | |
| agentMessageBubble.classList.add("bubble", "agent"); | |
| // Create and add loader element. | |
| const loader = document.createElement("div"); | |
| loader.classList.add("loader"); | |
| agentMessageBubble.appendChild(loader); | |
| messageDiv.appendChild(agentMessageBubble); | |
| chatContainer.appendChild(messageDiv); | |
| chatContainer.scrollTop = chatContainer.scrollHeight; | |
| } | |
| // Send the collected fields to the server. | |
| fetch("/generate", { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ | |
| title: title, | |
| rough_idea: roughIdea, | |
| category: category, | |
| query: query | |
| }) | |
| }); | |
| }); | |
| // Handle streaming tokens from the agent. | |
| socket.on("final_stream", (data) => { | |
| if (agentMessageBubble) { | |
| // Remove loader if still present. | |
| const loader = agentMessageBubble.querySelector(".loader"); | |
| if (loader) { | |
| loader.remove(); | |
| // Clear any leftover content. | |
| agentMessageBubble.textContent = ""; | |
| } | |
| // Append the streaming token. | |
| agentMessageBubble.textContent += data.message; | |
| chatContainer.scrollTop = chatContainer.scrollHeight; | |
| } else { | |
| // Fallback: create a new agent message if needed. | |
| addMessage("agent", data.message); | |
| } | |
| }); | |
| // When the final answer is complete. | |
| // When the final answer is complete. | |
| socket.on("final", (data) => { | |
| // If there's no existing agent bubble, create one. | |
| if (!agentMessageBubble) { | |
| addMessage("agent", ""); | |
| } | |
| // Use innerHTML to preserve any HTML tags or Markdown-converted HTML | |
| agentMessageBubble.innerHTML = data.message; | |
| // Reset agentMessageBubble for next time | |
| agentMessageBubble = null; | |
| }); | |
| // Append log messages as they arrive. | |
| socket.on("log", (data) => { | |
| addLogMessage(data.message); | |
| }); | |
| </script> | |
| </body> | |
| </html> | |