Noname980799's picture
it doesnt send messages
e04f6ad verified
Raw
History Blame Contribute Delete
22 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HermesMind - AI Agent Interface</title>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<script src="https://unpkg.com/feather-icons"></script>
<script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.net.min.js"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
* {
font-family: 'Inter', sans-serif;
}
.chat-message.user {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 18px 18px 4px 18px;
margin-left: auto;
}
.chat-message.ai {
background: #f1f5f9;
color: #334155;
border-radius: 18px 18px 18px 4px;
}
.typing-indicator {
display: inline-flex;
align-items: center;
justify-content: center;
}
.typing-dot {
width: 8px;
height: 8px;
margin: 0 3px;
background-color: #94a3b8;
border-radius: 50%;
animation: typing-dot 1.4s infinite ease-in-out both;
}
.typing-dot:nth-child(1) { animation-delay: -0.32s; }
.typing-dot:nth-child(2) { animation-delay: -0.16s; }
@keyframes typing-dot {
0%, 80%, 100% { transform: scale(0.8); }
40% { transform: scale(1); }
}
.vanta-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
}
</style>
</head>
<body class="bg-gray-50 min-h-screen flex flex-col">
<div id="vanta-background" class="vanta-background"></div>
<!-- Header -->
<header class="bg-white/80 backdrop-blur-sm border-b border-gray-200/50 sticky top-0 z-10">
<div class="container mx-auto px-4 py-4">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-3">
<div class="bg-gradient-to-r from-purple-600 to-blue-600 p-2 rounded-lg">
<i data-feather="cpu" class="text-white w-6 h-6"></i>
</div>
<h1 class="text-2xl font-bold text-gray-800">HermesMind</h1>
</div>
<div class="flex items-center space-x-4">
<button class="text-gray-600 hover:text-purple-600 transition-colors" onclick="showSettings()">
<i data-feather="settings" class="w-5 h-5"></i>
</button>
<button class="text-gray-600 hover:text-purple-600 transition-colors" onclick="showHelp()">
<i data-feather="help-circle" class="w-5 h-5"></i>
</button>
</div>
</div>
</div>
</header>
<!-- Main Content -->
<main class="flex-1 container mx-auto px-4 py-8 max-w-4xl">
<div class="bg-white/90 backdrop-blur-sm rounded-xl shadow-lg border border-gray-200/50 overflow-hidden">
<!-- Chat Header -->
<div class="bg-gradient-to-r from-purple-50 to-blue-50 px-6 py-4 border-b border-gray-200/50">
<div class="flex items-center space-x-3">
<div class="bg-gradient-to-r from-purple-600 to-blue-600 p-2 rounded-full">
<i data-feather="message-circle" class="text-white w-5 h-5"></i>
</div>
<div>
<h2 class="font-semibold text-gray-800">DeepHermes 3 Llama 3 8B</h2>
<p class="text-sm text-gray-600">Powered by OpenRouter AI</p>
</div>
</div>
</div>
<!-- Chat Messages -->
<div id="chat-container" class="h-96 overflow-y-auto p-6 space-y-4">
<div class="chat-message ai max-w-xs md:max-w-md p-4">
<p>Hello! I'm HermesMind, your AI assistant powered by DeepHermes 3. How can I help you today?</p>
</div>
</div>
<!-- Input Area -->
<div class="border-t border-gray-200/50 p-6">
<form id="chat-form" class="flex space-x-3">
<div class="flex-1 relative">
<input
type="text"
id="user-input"
placeholder="Ask me anything..."
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent outline-none transition-all"
autocomplete="off"
>
<div class="absolute right-3 top-3 text-gray-400">
<i data-feather="edit-3" class="w-4 h-4"></i>
</div>
</div>
<button
type="submit"
class="bg-gradient-to-r from-purple-600 to-blue-600 text-white px-6 py-3 rounded-lg hover:from-purple-700 hover:to-blue-700 transition-all flex items-center space-x-2 disabled:opacity-50 disabled:cursor-not-allowed"
id="send-button"
>
<i data-feather="send" class="w-4 h-4"></i>
<span>Send</span>
</button>
</form>
<p class="text-xs text-gray-500 mt-3 text-center">
Powered by OpenRouter API • Your conversations are secure and private
</p>
</div>
</div>
<!-- Features Section -->
<div class="grid md:grid-cols-3 gap-6 mt-8">
<div class="bg-white/90 backdrop-blur-sm p-6 rounded-xl shadow border border-gray-200/50">
<div class="bg-purple-100 p-3 rounded-lg inline-block mb-4">
<i data-feather="zap" class="text-purple-600 w-6 h-6"></i>
</div>
<h3 class="font-semibold text-gray-800 mb-2">Fast Responses</h3>
<p class="text-gray-600 text-sm">Get instant answers from our advanced AI model with minimal latency.</p>
</div>
<div class="bg-white/90 backdrop-blur-sm p-6 rounded-xl shadow border border-gray-200/50">
<div class="bg-blue-100 p-3 rounded-lg inline-block mb-4">
<i data-feather="shield" class="text-blue-600 w-6 h-6"></i>
</div>
<h3 class="font-semibold text-gray-800 mb-2">Secure API</h3>
<p class="text-gray-600 text-sm">Your API key is handled securely with encrypted communication channels.</p>
</div>
<div class="bg-white/90 backdrop-blur-sm p-6 rounded-xl shadow border border-gray-200/50">
<div class="bg-green-100 p-3 rounded-lg inline-block mb-4">
<i data-feather="code" class="text-green-600 w-6 h-6"></i>
</div>
<h3 class="font-semibold text-gray-800 mb-2">Open Source</h3>
<p class="text-gray-600 text-sm">Built on open standards and transparent AI models for trust and reliability.</p>
</div>
</div>
</main>
<!-- Footer -->
<footer class="bg-white/80 backdrop-blur-sm border-t border-gray-200/50 mt-12">
<div class="container mx-auto px-4 py-6">
<div class="flex flex-col md:flex-row justify-between items-center">
<div class="flex items-center space-x-2 mb-4 md:mb-0">
<i data-feather="brain" class="text-purple-600 w-6 h-6"></i>
<span class="font-medium text-gray-800">HermesMind AI</span>
</div>
<div class="flex space-x-6 text-sm text-gray-600">
<a href="#" class="hover:text-purple-600 transition-colors">Privacy</a>
<a href="#" class="hover:text-purple-600 transition-colors">Terms</a>
<a href="#" class="hover:text-purple-600 transition-colors">API Docs</a>
</div>
</div>
<p class="text-center text-xs text-gray-500 mt-4">
© 2023 HermesMind AI Agent. Powered by DeepHermes 3 and OpenRouter.
</p>
</div>
</footer>
<script>
// Settings modal
function showSettings() {
const modal = document.createElement('div');
modal.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50';
modal.innerHTML = `
<div class="bg-white rounded-xl p-6 max-w-md w-full mx-4">
<h3 class="text-lg font-semibold text-gray-800 mb-4">Settings</h3>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">OpenRouter API Key</label>
<input
type="password"
id="settings-api-key"
value="${API_KEY.replace(/./g, '*')}"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent outline-none"
placeholder="Enter your API key..."
>
</div>
<div class="flex space-x-3">
<button
onclick="updateApiKey()"
class="bg-purple-600 text-white px-4 py-2 rounded-lg hover:bg-purple-700 transition-colors flex-1"
>
Save
</button>
<button
onclick="resetApiKey()"
class="bg-red-600 text-white px-4 py-2 rounded-lg hover:bg-red-700 transition-colors flex-1"
>
Reset
</button>
<button
onclick="document.querySelector('.fixed').remove()"
class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition-colors flex-1"
>
Cancel
</button>
</div>
</div>
</div>
`;
document.body.appendChild(modal);
}
window.updateApiKey = function() {
const apiKey = document.getElementById('settings-api-key').value.trim();
if (apiKey) {
localStorage.setItem('hermesmind_api_key', apiKey);
API_KEY = apiKey;
document.querySelector('.fixed').remove();
}
}
window.resetApiKey = function() {
localStorage.removeItem('hermesmind_api_key');
API_KEY = '';
document.querySelector('.fixed').remove();
setTimeout(showApiKeyModal, 500);
}
window.showHelp = function() {
const modal = document.createElement('div');
modal.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50';
modal.innerHTML = `
<div class="bg-white rounded-xl p-6 max-w-md w-full mx-4">
<h3 class="text-lg font-semibold text-gray-800 mb-4">Help & Support</h3>
<div class="space-y-3 text-gray-600">
<p><strong>Getting Started:</strong></p>
<p>1. Get your free API key from <a href="https://openrouter.ai/" target="_blank" class="text-purple-600 hover:underline">OpenRouter</a></p>
<p>2. Click the settings icon to enter your API key</p>
<p>3. Start chatting with the AI assistant!</p>
<p class="mt-4"><strong>Note:</strong> Free tier has usage limits. For unlimited access, consider upgrading your OpenRouter plan.</p>
</div>
<button
onclick="document.querySelector('.fixed').remove()"
class="mt-6 w-full bg-purple-600 text-white px-4 py-2 rounded-lg hover:bg-purple-700 transition-colors"
>
Got it!
</button>
</div>
`;
document.body.appendChild(modal);
}
// API Configuration
let API_KEY = localStorage.getItem('hermesmind_api_key') || '';
const API_URL = "https://openrouter.ai/api/v1/chat/completions";
// Initialize Vanta.js after DOM is loaded
document.addEventListener('DOMContentLoaded', function() {
VANTA.NET({
el: "#vanta-background",
mouseControls: true,
touchControls: true,
gyroControls: false,
minHeight: 200.00,
minWidth: 200.00,
scale: 1.00,
scaleMobile: 1.00,
color: 0x7c73e6,
backgroundColor: 0xf1f5f9,
points: 10.00,
maxDistance: 25.00,
spacing: 18.00
});
feather.replace();
userInput.focus();
if (!API_KEY) {
setTimeout(showApiKeyModal, 1000);
}
});
// DOM Elements
const chatForm = document.getElementById('chat-form');
const userInput = document.getElementById('user-input');
const chatContainer = document.getElementById('chat-container');
const sendButton = document.getElementById('send-button');
// Add message to chat
function addMessage(content, isUser = false) {
const messageDiv = document.createElement('div');
messageDiv.className = `chat-message ${isUser ? 'user' : 'ai'} max-w-xs md:max-w-md p-4`;
messageDiv.innerHTML = `<p>${content}</p>`;
chatContainer.appendChild(messageDiv);
chatContainer.scrollTop = chatContainer.scrollHeight;
}
// Show typing indicator
window.showTypingIndicator = function() {
const typingDiv = document.createElement('div');
typingDiv.className = 'chat-message ai max-w-xs md:max-w-md p-4';
typingDiv.id = 'typing-indicator';
typingDiv.innerHTML = `
<div class="typing-indicator">
<div class="typing-dot"></div>
<div class="typing-dot"></div>
<div class="typing-dot"></div>
</div>
`;
chatContainer.appendChild(typingDiv);
chatContainer.scrollTop = chatContainer.scrollHeight;
}
// Remove typing indicator
window.removeTypingIndicator = function() {
const typingIndicator = document.getElementById('typing-indicator');
if (typingIndicator) {
typingIndicator.remove();
}
}
// API Key Management
function showApiKeyModal() {
const modal = document.createElement('div');
modal.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50';
modal.innerHTML = `
<div class="bg-white rounded-xl p-6 max-w-md w-full mx-4">
<h3 class="text-lg font-semibold text-gray-800 mb-4">API Key Required</h3>
<p class="text-gray-600 mb-4">Please enter your OpenRouter API key to use HermesMind:</p>
<input
type="password"
id="api-key-input"
placeholder="Enter your API key..."
class="w-full px-4 py-2 border border-gray-300 rounded-lg mb-4 focus:ring-2 focus:ring-purple-500 focus:border-transparent outline-none"
>
<div class="flex space-x-3">
<button
onclick="saveApiKey()"
class="bg-purple-600 text-white px-4 py-2 rounded-lg hover:bg-purple-700 transition-colors flex-1"
>
Save & Continue
</button>
<button
onclick="document.querySelector('.fixed').remove()"
class="bg-gray-300 text-gray-700 px-4 py-2 rounded-lg hover:bg-gray-400 transition-colors flex-1"
>
Cancel
</button>
</div>
</div>
`;
document.body.appendChild(modal);
// Focus the input
setTimeout(() => {
document.getElementById('api-key-input').focus();
}, 100);
}
window.saveApiKey = function() {
const apiKey = document.getElementById('api-key-input').value.trim();
if (apiKey) {
localStorage.setItem('hermesmind_api_key', apiKey);
API_KEY = apiKey;
document.querySelector('.fixed').remove();
}
}
// Send message to API
async function sendMessage(message) {
if (!API_KEY) {
showApiKeyModal();
return;
}
showTypingIndicator();
try {
const response = await fetch(API_URL, {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"HTTP-Referer": window.location.href,
"X-Title": "HermesMind AI Agent",
"Content-Type": "application/json"
},
body: JSON.stringify({
"model": "nousresearch/deephermes-3-llama-3-8b-preview:free",
"messages": [
{
"role": "system",
"content": "You are HermesMind, a helpful AI assistant. Respond concisely and helpfully."
},
{
"role": "user",
"content": message
}
],
"temperature": 0.7,
"max_tokens": 1000
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.error?.message || `API Error: ${response.status}`);
}
const data = await response.json();
removeTypingIndicator();
if (data.choices && data.choices.length > 0) {
const aiResponse = data.choices[0].message.content;
addMessage(aiResponse, false);
} else {
addMessage("I didn't get a response. Could you try asking again?", false);
}
} catch (error) {
removeTypingIndicator();
console.error("API Error:", error);
let errorMessage = "There was an error connecting to the AI service.";
if (error.message.includes('401') || error.message.includes('403')) {
errorMessage = "Your API key might be invalid. Please check it in settings.";
} else if (error.message.includes('rate limit')) {
errorMessage = "You've hit the rate limit. Please wait a moment before trying again.";
}
addMessage(errorMessage, false);
}
}
// Handle form submission
chatForm.addEventListener('submit', async (e) => {
e.preventDefault();
const message = userInput.value.trim();
if (!message) return;
// Add user message to chat
addMessage(message, true);
userInput.value = '';
// Disable send button while processing
sendButton.disabled = true;
userInput.disabled = true;
try {
// Send to API
await sendMessage(message);
} catch (error) {
console.error("Error:", error);
addMessage("Sorry, something went wrong. Please try again.", false);
} finally {
// Re-enable send button
sendButton.disabled = false;
userInput.disabled = false;
userInput.focus();
}
});
// Allow pressing Enter to send (but Shift+Enter for new line)
userInput.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
chatForm.dispatchEvent(new Event('submit'));
}
});
</script>
</body>
</html>