exit-agent / index.html
John2121's picture
please setup hugging face variables and appropriate secrets for me to add to the settings after you launch it for using open ai comptable lllama api link like this:import os from openai import OpenAI client = OpenAI( api_key=os.environ["LLAMA_API_KEY"], base_url="https://api.llama.com/compat/v1/" ) # Create chat completion request completion = client.chat.completions.create( model="Llama-3.3-8B-Instruct", messages=[ { "role": "developer", "content": "You are a helpful assistant." }, { "role": "user", "content": "Hello!" } ], ) print(completion.choices[0].message.content) - Follow Up Deployment
73015a9 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>EXITAGENT - EXIT CW Realty</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script>
// Store API key and endpoint in localStorage
let API_KEY = localStorage.getItem('apiKey') || '';
let API_ENDPOINT = localStorage.getItem('apiEndpoint') || 'llama'; // 'llama' or 'huggingface'
// Save API key when entered
document.addEventListener('DOMContentLoaded', function() {
const apiKeyInput = document.getElementById('api-key-input');
const apiEndpointSelect = document.getElementById('api-endpoint');
const confirmApiBtn = document.getElementById('confirm-api-btn');
if (apiKeyInput) {
// Load saved API key if exists
const savedApiKey = localStorage.getItem('llamaApiKey');
if (savedApiKey) {
apiKeyInput.value = savedApiKey;
LLAMA_API_KEY = savedApiKey;
}
// Save API key on input
apiKeyInput.addEventListener('input', function() {
LLAMA_API_KEY = this.value;
});
// Confirm API key when button is clicked
if (confirmApiBtn) {
confirmApiBtn.addEventListener('click', function() {
const apiKey = apiKeyInput.value.trim();
if (apiKey) {
localStorage.setItem('llamaApiKey', apiKey);
LLAMA_API_KEY = apiKey;
// Visual feedback
const originalIcon = confirmApiBtn.innerHTML;
confirmApiBtn.innerHTML = '<i class="fas fa-check text-green-500 text-xl"></i>';
setTimeout(() => {
confirmApiBtn.innerHTML = originalIcon;
}, 2000);
}
});
}
}
});
</script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
body {
font-family: 'Inter', sans-serif;
background: linear-gradient(135deg, #0c4a6e 0%, #0d9488 100%);
min-height: 100vh;
}
.chat-container {
max-width: 1200px;
height: 90vh;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.25);
border-radius: 16px;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.message-edward {
background: linear-gradient(135deg, #0d9488 0%, #0c4a6e 100%);
color: white;
border-radius: 18px 18px 4px 18px;
max-width: 80%;
animation: fadeIn 0.3s ease-in-out;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.message-user {
background: linear-gradient(135deg, #334155 0%, #1e293b 100%);
color: white;
border-radius: 18px 18px 18px 4px;
max-width: 80%;
animation: fadeIn 0.3s ease-in-out;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.type-indicator {
display: flex;
padding: 10px;
}
.type-dot {
width: 8px;
height: 8px;
background-color: #0d9488;
border-radius: 50%;
margin: 0 3px;
animation: pulse 1.5s infinite;
}
.type-dot:nth-child(2) {
animation-delay: 0.3s;
}
.type-dot:nth-child(3) {
animation-delay: 0.6s;
}
@keyframes pulse {
0%, 100% { opacity: 0.4; transform: scale(0.8); }
50% { opacity: 1; transform: scale(1.2); }
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.suggestion-chip {
transition: all 0.2s ease;
cursor: pointer;
background: linear-gradient(135deg, #0d9488 0%, #0c4a6e 100%);
}
.suggestion-chip:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(13, 148, 136, 0.4);
}
.typing-area:focus {
outline: none;
box-shadow: 0 0 0 2px rgba(13, 148, 136, 0.5);
}
.exit-agent-header {
font-weight: 800;
letter-spacing: 0.15em;
text-transform: uppercase;
background: linear-gradient(135deg, #ffffff 0%, #cffafe 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
}
</style>
</head>
<body class="flex items-center justify-center p-4 md:p-8">
<div class="chat-container w-full flex flex-col bg-slate-800">
<!-- Header -->
<div class="bg-slate-900 px-6 py-4 flex items-center justify-between border-b border-slate-700/50">
<div class="flex items-center">
<div class="w-12 h-12 rounded-full bg-gradient-to-r from-cyan-500 to-teal-600 flex items-center justify-center text-white font-bold text-xl">
E
</div>
<div class="ml-4">
<h1 class="exit-agent-header text-2xl">EXITAGENT</h1>
<p class="text-slate-300 text-xs tracking-wide">STEVENS POINT REAL ESTATE INTELLIGENCE</p>
</div>
</div>
<div class="flex items-center gap-3">
<div class="hidden md:block">
<span class="bg-emerald-500/20 text-emerald-400 text-xs px-3 py-1 rounded-full font-medium tracking-wide">LIVE CONNECTED</span>
</div>
<div class="flex items-center gap-2">
<input
type="password"
id="api-key-input"
placeholder="Enter API Key"
class="bg-slate-800/70 text-white rounded-lg px-3 py-1 text-sm w-32 md:w-40 focus:outline-none border border-slate-600/50"
value=""
>
<button id="confirm-api-btn" class="text-slate-300 hover:text-white p-2 rounded-full hover:bg-slate-700 transition-colors">
<i class="fas fa-check-circle text-xl"></i>
</button>
<button id="settings-btn" class="text-slate-300 hover:text-white p-2 rounded-full hover:bg-slate-700 transition-colors">
<i class="fas fa-cog text-xl"></i>
</button>
</div>
</div>
</div>
<!-- Chat Messages -->
<div class="flex-1 p-4 md:p-6 overflow-y-auto space-y-4" id="chat-messages">
<!-- Initial message from Edward -->
<div class="flex justify-end">
<div class="message-edward p-4 md:p-5">
<p class="text-sm md:text-base">Hey Brandon, Edward here — just your friendly neighborhood Central WI real estate strategist. Let's cut to the chase: want me to show you leads you didn't even know you had, or are we just checking in today? 😉</p>
</div>
</div>
</div>
<!-- Suggestions -->
<div class="px-4 md:px-6 py-3 bg-slate-700/30 hidden md:block" id="suggestions">
<div class="flex flex-wrap gap-2">
<div class="suggestion-chip text-white text-xs md:text-sm px-3 py-2 rounded-full" onclick="sendMessage('Show me Stevens Point market trends')">Stevens Point market trends</div>
<div class="suggestion-chip text-white text-xs md:text-sm px-3 py-2 rounded-full" onclick="sendMessage('New lead generation ideas')">New lead generation ideas</div>
<div class="suggestion-chip text-white text-xs md:text-sm px-3 py-2 rounded-full" onclick="sendMessage('Competitor analysis for Portage County')">Competitor analysis</div>
<div class="suggestion-chip text-white text-xs md:text-sm px-3 py-2 rounded-full" onclick="sendMessage('Help me with a client objection')">Handle client objections</div>
</div>
</div>
<!-- Typing indicator (hidden by default) -->
<div class="px-6 py-2 hidden" id="typing-indicator">
<div class="type-indicator">
<div class="type-dot"></div>
<div class="type-dot"></div>
<div class="type-dot"></div>
</div>
</div>
<!-- Input Area -->
<div class="p-4 md:p-6 bg-slate-900/80">
<div class="flex items-center">
<input
type="text"
id="user-input"
placeholder="Type your message here..."
class="typing-area flex-1 bg-slate-800/70 text-white rounded-l-lg px-4 py-3 focus:outline-none border border-slate-600/50"
onkeypress="if(event.key === 'Enter') sendMessage()"
>
<button
onclick="sendMessage()"
class="bg-gradient-to-r from-cyan-600 to-teal-600 hover:from-cyan-700 hover:to-teal-700 text-white px-4 md:px-6 py-3 rounded-r-lg transition-all duration-200 transform hover:scale-105"
>
<i class="fas fa-paper-plane"></i>
</button>
</div>
</div>
</div>
<script>
const chatMessages = document.getElementById('chat-messages');
const userInput = document.getElementById('user-input');
const typingIndicator = document.getElementById('typing-indicator');
const suggestions = document.getElementById('suggestions');
// Store conversation history
let conversationHistory = [
{
role: "system",
content: "You are Edward, a friendly neighborhood Central WI real estate strategist from EXIT CW Realty. You're knowledgeable about Stevens Point real estate market, lead generation, competitor analysis, and handling client objections. You're direct, professional but approachable, and focused on helping real estate agents succeed. Keep responses concise and actionable."
},
{
role: "assistant",
content: "Hey Brandon, Edward here — just your friendly neighborhood Central WI real estate strategist. Let's cut to the chase: want me to show you leads you didn't even know you had, or are we just checking in today? 😉"
}
];
// LLaMA API configuration
const LLAMA_API_URL = 'https://api.llama-api.com/chat/completions';
// Add message to chat
function addMessage(message, isUser = false) {
const messageDiv = document.createElement('div');
messageDiv.className = `flex ${isUser ? 'justify-start' : 'justify-end'}`;
const messageContent = document.createElement('div');
messageContent.className = isUser ? 'message-user p-4 md:p-5' : 'message-edward p-4 md:p-5';
messageContent.innerHTML = `<p class="text-sm md:text-base">${message}</p>`;
messageDiv.appendChild(messageContent);
chatMessages.appendChild(messageDiv);
// Scroll to bottom
chatMessages.scrollTop = chatMessages.scrollHeight;
}
// Show typing indicator
function showTypingIndicator() {
typingIndicator.classList.remove('hidden');
chatMessages.scrollTop = chatMessages.scrollHeight;
}
// Hide typing indicator
function hideTypingIndicator() {
typingIndicator.classList.add('hidden');
}
// Get response from LLaMA API
async function getLlamaResponse(userMessage) {
// Check if API key is set
if (!LLAMA_API_KEY) {
return "Please set your LLaMA API key in the settings to continue our conversation.";
}
try {
// Add user message to conversation history
conversationHistory.push({
role: "user",
content: userMessage
});
const response = await fetch(LLAMA_API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${LLAMA_API_KEY}`
},
body: JSON.stringify({
model: "llama-3-70b",
messages: conversationHistory,
temperature: 0.7,
max_tokens: 500
})
});
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const data = await response.json();
const assistantResponse = data.choices[0].message.content;
// Add assistant response to conversation history
conversationHistory.push({
role: "assistant",
content: assistantResponse
});
return assistantResponse;
} catch (error) {
console.error('Error calling LLaMA API:', error);
return "I'm having trouble connecting to my systems right now. Let's try again in a moment, or you can ask me about Stevens Point market trends, lead generation, or client strategies!";
}
}
// Send message function
async function sendMessage(predefinedMessage = null) {
const message = predefinedMessage || userInput.value.trim();
if (message === '') return;
// Add user message
addMessage(message, true);
// Clear input field if not using predefined message
if (!predefinedMessage) {
userInput.value = '';
}
// Hide suggestions after first message
suggestions.classList.add('hidden');
// Show Edward is typing
showTypingIndicator();
try {
// Get response from LLaMA API
const response = await getLlamaResponse(message);
hideTypingIndicator();
addMessage(response, false);
} catch (error) {
hideTypingIndicator();
addMessage("Sorry, I'm experiencing technical difficulties. Please try again shortly.", false);
}
}
// Initialize with suggestions visible
window.onload = function() {
chatMessages.scrollTop = chatMessages.scrollHeight;
}
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=John2121/exit-agent" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>