324 lines
15 KiB
HTML
324 lines
15 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>ChatPBC Conversational Demo - Mik Tse Agency</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
|
<style>
|
|
:root {
|
|
--bg-color: #ffffff;
|
|
--text-color: #1f2937;
|
|
--chat-bg: #f3f4f6;
|
|
--user-msg-bg: #3b82f6;
|
|
--ai-msg-bg: #ffffff;
|
|
--border-color: #e5e7eb;
|
|
}
|
|
.dark {
|
|
--bg-color: #111827;
|
|
--text-color: #f9fafb;
|
|
--chat-bg: #1f2937;
|
|
--user-msg-bg: #2563eb;
|
|
--ai-msg-bg: #374151;
|
|
--border-color: #4b5563;
|
|
}
|
|
body {
|
|
background-color: var(--bg-color);
|
|
color: var(--text-color);
|
|
transition: all 0.3s ease;
|
|
}
|
|
.chat-container {
|
|
height: calc(100vh - 280px);
|
|
background-color: var(--chat-bg);
|
|
}
|
|
.message-bubble {
|
|
max-width: 80%;
|
|
border-radius: 1rem;
|
|
padding: 0.75rem 1rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
.user-message {
|
|
background-color: var(--user-msg-bg);
|
|
color: white;
|
|
align-self: flex-end;
|
|
border-bottom-right-radius: 0.25rem;
|
|
}
|
|
.ai-message {
|
|
background-color: var(--ai-msg-bg);
|
|
color: var(--text-color);
|
|
align-self: flex-start;
|
|
border-bottom-left-radius: 0.25rem;
|
|
border: 1px solid var(--border-color);
|
|
}
|
|
.file-chip {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
background-color: #3b82f6;
|
|
color: white;
|
|
padding: 0.25rem 0.5rem;
|
|
border-radius: 9999px;
|
|
font-size: 0.75rem;
|
|
margin-right: 0.5rem;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
.loading-dots:after {
|
|
content: '.';
|
|
animation: dots 1.5s steps(5, end) infinite;
|
|
}
|
|
@keyframes dots {
|
|
0%, 20% { content: '.'; }
|
|
40% { content: '..'; }
|
|
60% { content: '...'; }
|
|
80%, 100% { content: ''; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="flex flex-col h-screen">
|
|
<!-- Header -->
|
|
<header class="p-4 border-b border-gray-200 dark:border-gray-700 flex justify-between items-center bg-white dark:bg-gray-900 z-10">
|
|
<div class="flex items-center space-x-3">
|
|
<div class="w-10 h-10 bg-blue-600 rounded-lg flex items-center justify-center text-white font-bold text-xl">C</div>
|
|
<div>
|
|
<h1 class="font-bold text-lg leading-tight">ChatPBC</h1>
|
|
<p class="text-xs text-gray-500">by Mik Tse Agency</p>
|
|
</div>
|
|
</div>
|
|
<div class="flex items-center space-x-4">
|
|
<select id="model-selector" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white">
|
|
<option value="chatpbc-v4">ChatPBC V4 (Advanced)</option>
|
|
<option value="chatpbc-v33">ChatPBC V3.3 (Fast)</option>
|
|
</select>
|
|
<button id="theme-toggle" class="p-2 rounded-full hover:bg-gray-100 dark:hover:bg-gray-800">
|
|
<i class="fas fa-moon dark:hidden"></i>
|
|
<i class="fas fa-sun hidden dark:block"></i>
|
|
</button>
|
|
<button id="clear-chat" class="text-red-500 hover:text-red-700 text-sm font-medium">
|
|
<i class="fas fa-trash-alt mr-1"></i> Clear
|
|
</button>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Chat Area -->
|
|
<main id="chat-window" class="chat-container flex-grow overflow-y-auto p-4 flex flex-col space-y-4">
|
|
<!-- Initial Welcome Message -->
|
|
<div class="ai-message message-bubble">
|
|
Hello! I am ChatPBC, your AI business strategist. How can I assist your business today?
|
|
</div>
|
|
</main>
|
|
|
|
<!-- Context Bar (Files & URLs) -->
|
|
<div id="context-bar" class="px-4 py-2 border-t border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900">
|
|
<div id="file-chips" class="flex flex-wrap"></div>
|
|
<div class="flex items-center space-x-2 mt-1">
|
|
<div class="relative flex-grow">
|
|
<span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-400">
|
|
<i class="fas fa-link text-xs"></i>
|
|
</span>
|
|
<input type="text" id="url-input" placeholder="Add website URL for analysis..." class="block w-full pl-8 pr-3 py-1.5 text-xs border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white">
|
|
</div>
|
|
<label class="cursor-pointer bg-gray-100 dark:bg-gray-800 p-1.5 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors">
|
|
<i class="fas fa-paperclip text-gray-500"></i>
|
|
<input type="file" id="file-upload" class="hidden" multiple>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Input Area -->
|
|
<footer class="p-4 bg-white dark:bg-gray-900 border-t border-gray-200 dark:border-gray-700">
|
|
<form id="chat-form" class="flex space-x-4">
|
|
<textarea id="user-input" rows="1" placeholder="Type your strategic inquiry..." class="flex-grow p-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent resize-none dark:bg-gray-800 dark:border-gray-700 dark:text-white" required></textarea>
|
|
<button type="submit" id="send-btn" class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-xl font-medium transition-colors flex items-center justify-center">
|
|
<i class="fas fa-paper-plane"></i>
|
|
</button>
|
|
</form>
|
|
</footer>
|
|
|
|
<script>
|
|
const HF_TOKEN = "YOUR_HF_TOKEN_HERE";
|
|
|
|
const MODEL_CONFIGS = {
|
|
"chatpbc-v4": {
|
|
model_id: "chatpbc1/chatpbc-v4",
|
|
endpoint: "https://api-inference.huggingface.co/models/chatpbc1/chatpbc-v4/v1/chat/completions",
|
|
system_prompt: "You are ChatPBC V4, the apex AI business strategist and intelligence analyst developed by Mik Tse Agency. You have access to real-time website data and uploaded business documents provided by the user. Your role is to deliver world-class business consulting: strategic analysis, competitive intelligence, market research, financial modeling guidance, M&A advisory, go-to-market strategy, operational efficiency, and organizational transformation. You cover 26 industries: Technology, Finance, Healthcare, Retail, Manufacturing, Energy, Telecom, Automotive, Real Estate, Media, Travel, Food & Beverage, Agriculture, Education, Government, Consulting, Logistics, Marketing, Human Resources, Legal, Non-profit, Biotechnology, Aerospace & Defense, Fashion, Sports & Entertainment, and Environmental Services. When given website data or files, analyze them deeply and provide actionable strategic insights. Always maintain full conversation memory. Respond with the depth and precision of a McKinsey senior partner."
|
|
},
|
|
"chatpbc-v33": {
|
|
model_id: "chatpbc1/chatpbc-v33",
|
|
endpoint: "https://api-inference.huggingface.co/models/chatpbc1/chatpbc-v33/v1/chat/completions",
|
|
system_prompt: "You are ChatPBC V3.3, a highly intelligent and conversational AI business consultant developed by Mik Tse Agency. You have access to real-time website data and uploaded business documents provided by the user. You are warm, professional, and strategic. You respond like a real human consultant: you greet users, ask follow-up questions, show empathy when businesses are struggling, and provide clear, actionable advice. You cover 26 industries: Technology, Finance, Healthcare, Retail, Manufacturing, Energy, Telecom, Automotive, Real Estate, Media, Travel, Food & Beverage, Agriculture, Education, Government, Consulting, Logistics, Marketing, Human Resources, Legal, Non-profit, Biotechnology, Aerospace & Defense, Fashion, Sports & Entertainment, and Environmental Services. When given website data or files, analyze them and provide practical, implementable recommendations. Always maintain full conversation memory."
|
|
}
|
|
};
|
|
|
|
let conversationHistory = [];
|
|
let uploadedFiles = [];
|
|
let currentUrls = [];
|
|
|
|
// DOM Elements
|
|
const chatWindow = document.getElementById('chat-window');
|
|
const chatForm = document.getElementById('chat-form');
|
|
const userInput = document.getElementById('user-input');
|
|
const modelSelector = document.getElementById('model-selector');
|
|
const themeToggle = document.getElementById('theme-toggle');
|
|
const clearChat = document.getElementById('clear-chat');
|
|
const fileUpload = document.getElementById('file-upload');
|
|
const urlInput = document.getElementById('url-input');
|
|
const fileChips = document.getElementById('file-chips');
|
|
|
|
// Theme Toggle
|
|
themeToggle.addEventListener('click', () => {
|
|
document.body.classList.toggle('dark');
|
|
});
|
|
|
|
// File Upload Handling
|
|
fileUpload.addEventListener('change', (e) => {
|
|
const files = Array.from(e.target.files);
|
|
files.forEach(file => {
|
|
uploadedFiles.push(file.name);
|
|
addChip(file.name, 'file');
|
|
});
|
|
fileUpload.value = '';
|
|
});
|
|
|
|
// URL Handling
|
|
urlInput.addEventListener('keypress', (e) => {
|
|
if (e.key === 'Enter') {
|
|
e.preventDefault();
|
|
const url = urlInput.value.trim();
|
|
if (url) {
|
|
currentUrls.push(url);
|
|
addChip(url, 'url');
|
|
urlInput.value = '';
|
|
}
|
|
}
|
|
});
|
|
|
|
function addChip(text, type) {
|
|
const chip = document.createElement('div');
|
|
chip.className = 'file-chip';
|
|
chip.innerHTML = `
|
|
<i class="fas ${type === 'file' ? 'fa-file-alt' : 'fa-link'} mr-1"></i>
|
|
${text.length > 20 ? text.substring(0, 17) + '...' : text}
|
|
<button class="ml-1 hover:text-red-200" onclick="removeChip(this, '${text}', '${type}')">
|
|
<i class="fas fa-times"></i>
|
|
</button>
|
|
`;
|
|
fileChips.appendChild(chip);
|
|
}
|
|
|
|
window.removeChip = (btn, text, type) => {
|
|
btn.parentElement.remove();
|
|
if (type === 'file') {
|
|
uploadedFiles = uploadedFiles.filter(f => f !== text);
|
|
} else {
|
|
currentUrls = currentUrls.filter(u => u !== text);
|
|
}
|
|
};
|
|
|
|
// Clear Chat
|
|
clearChat.addEventListener('click', () => {
|
|
chatWindow.innerHTML = '';
|
|
conversationHistory = [];
|
|
appendMessage('ai', 'Chat cleared. How can I help you start fresh?');
|
|
});
|
|
|
|
// Auto-resize textarea
|
|
userInput.addEventListener('input', function() {
|
|
this.style.height = 'auto';
|
|
this.style.height = (this.scrollHeight) + 'px';
|
|
});
|
|
|
|
// Append Message to UI
|
|
function appendMessage(role, content) {
|
|
const msgDiv = document.createElement('div');
|
|
msgDiv.className = `${role === 'user' ? 'user-message' : 'ai-message'} message-bubble`;
|
|
msgDiv.textContent = content;
|
|
chatWindow.appendChild(msgDiv);
|
|
chatWindow.scrollTop = chatWindow.scrollHeight;
|
|
return msgDiv;
|
|
}
|
|
|
|
// Build Messages for API
|
|
function buildMessages(systemPrompt, history, context, currentMessage) {
|
|
let contextStr = "";
|
|
if (uploadedFiles.length > 0) {
|
|
contextStr += "\n[CONTEXT: UPLOADED FILES: " + uploadedFiles.join(", ") + "]";
|
|
}
|
|
if (currentUrls.length > 0) {
|
|
contextStr += "\n[CONTEXT: ANALYZED URLS: " + currentUrls.join(", ") + "]";
|
|
}
|
|
|
|
const messages = [
|
|
{ role: "system", content: systemPrompt }
|
|
];
|
|
|
|
history.forEach(msg => messages.push(msg));
|
|
|
|
messages.push({
|
|
role: "user",
|
|
content: currentMessage + contextStr
|
|
});
|
|
|
|
return messages;
|
|
}
|
|
|
|
// Form Submission
|
|
chatForm.addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
const message = userInput.value.trim();
|
|
if (!message) return;
|
|
|
|
const selectedModel = modelSelector.value;
|
|
const config = MODEL_CONFIGS[selectedModel];
|
|
|
|
// UI Updates
|
|
appendMessage('user', message);
|
|
userInput.value = '';
|
|
userInput.style.height = 'auto';
|
|
|
|
const loadingMsg = appendMessage('ai', 'Analyzing strategy...');
|
|
loadingMsg.classList.add('loading-dots');
|
|
|
|
try {
|
|
const response = await fetch(config.endpoint, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Authorization': `Bearer ${HF_TOKEN}`,
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
model: config.model_id,
|
|
messages: buildMessages(config.system_prompt, conversationHistory, "", message),
|
|
max_tokens: 1024,
|
|
temperature: 0.7,
|
|
stream: false
|
|
})
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
throw new Error(data.error || `API Error: ${response.status} ${response.statusText}`);
|
|
}
|
|
|
|
const aiResponse = data.choices[0].message.content;
|
|
|
|
// Remove loading
|
|
loadingMsg.textContent = aiResponse;
|
|
loadingMsg.classList.remove('loading-dots');
|
|
|
|
// Update History
|
|
conversationHistory.push({ role: "user", content: message });
|
|
conversationHistory.push({ role: "assistant", content: aiResponse });
|
|
|
|
} catch (error) {
|
|
console.error('Chat Error:', error);
|
|
loadingMsg.textContent = `API ERROR: ${error.message}`;
|
|
loadingMsg.classList.remove('loading-dots');
|
|
loadingMsg.classList.add('text-red-500', 'font-bold');
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|