Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>DeepSeek-V3.1 ChatBot</title> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| } | |
| :root { | |
| --primary: #4361ee; | |
| --secondary: #3a0ca3; | |
| --accent: #7209b7; | |
| --light: #f8f9fa; | |
| --dark: #212529; | |
| --success: #4cc9f0; | |
| --warning: #f72585; | |
| --gray: #6c757d; | |
| --shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
| } | |
| body { | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| min-height: 100vh; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| padding: 20px; | |
| } | |
| .app-container { | |
| width: 100%; | |
| max-width: 1200px; | |
| height: 90vh; | |
| background: white; | |
| border-radius: 20px; | |
| box-shadow: var(--shadow); | |
| display: flex; | |
| overflow: hidden; | |
| } | |
| .sidebar { | |
| width: 300px; | |
| background: var(--dark); | |
| color: white; | |
| padding: 20px; | |
| display: flex; | |
| flex-direction: column; | |
| overflow-y: auto; | |
| } | |
| .header { | |
| padding-bottom: 20px; | |
| border-bottom: 1px solid rgba(255, 255, 255, 0.1); | |
| margin-bottom: 20px; | |
| } | |
| .header h1 { | |
| font-size: 1.5rem; | |
| margin-bottom: 5px; | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .header h1 i { | |
| color: var(--success); | |
| } | |
| .built-with { | |
| font-size: 0.8rem; | |
| color: var(--gray); | |
| margin-top: 10px; | |
| } | |
| .built-with a { | |
| color: var(--success); | |
| text-decoration: none; | |
| } | |
| .built-with a:hover { | |
| text-decoration: underline; | |
| } | |
| .api-info { | |
| background: rgba(255, 255, 255, 0.1); | |
| padding: 15px; | |
| border-radius: 10px; | |
| margin-bottom: 20px; | |
| } | |
| .api-info h3 { | |
| font-size: 1rem; | |
| margin-bottom: 10px; | |
| color: var(--success); | |
| } | |
| .api-info p { | |
| font-size: 0.9rem; | |
| margin-bottom: 5px; | |
| color: #ccc; | |
| } | |
| .model-info { | |
| background: rgba(255, 255, 255, 0.1); | |
| padding: 15px; | |
| border-radius: 10px; | |
| margin-bottom: 20px; | |
| } | |
| .model-info h3 { | |
| font-size: 1rem; | |
| margin-bottom: 10px; | |
| color: var(--success); | |
| } | |
| .model-badge { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 8px; | |
| background: var(--primary); | |
| padding: 8px 12px; | |
| border-radius: 20px; | |
| font-size: 0.9rem; | |
| margin-top: 10px; | |
| } | |
| .usage-stats { | |
| margin-top: auto; | |
| background: rgba(255, 255, 255, 0.1); | |
| padding: 15px; | |
| border-radius: 10px; | |
| } | |
| .usage-stats h3 { | |
| font-size: 1rem; | |
| margin-bottom: 10px; | |
| color: white; | |
| } | |
| .usage-bar { | |
| height: 8px; | |
| background: rgba(255, 255, 255, 0.2); | |
| border-radius: 4px; | |
| margin-bottom: 10px; | |
| overflow: hidden; | |
| } | |
| .usage-progress { | |
| height: 100%; | |
| background: var(--success); | |
| border-radius: 4px; | |
| width: 0%; | |
| transition: width 0.5s ease; | |
| } | |
| .usage-text { | |
| font-size: 0.9rem; | |
| color: #ccc; | |
| display: flex; | |
| justify-content: space-between; | |
| } | |
| .chat-container { | |
| flex: 1; | |
| display: flex; | |
| flex-direction: column; | |
| overflow: hidden; | |
| } | |
| .chat-header { | |
| padding: 20px; | |
| background: white; | |
| border-bottom: 1px solid #eee; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| } | |
| .chat-header h2 { | |
| font-size: 1.5rem; | |
| color: var(--dark); | |
| } | |
| .model-status { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| background: var(--light); | |
| padding: 8px 15px; | |
| border-radius: 20px; | |
| font-size: 0.9rem; | |
| color: var(--dark); | |
| } | |
| .status-dot { | |
| width: 8px; | |
| height: 8px; | |
| border-radius: 50%; | |
| background: var(--success); | |
| animation: pulse 2s infinite; | |
| } | |
| @keyframes pulse { | |
| 0% { | |
| transform: scale(0.95); | |
| box-shadow: 0 0 0 0 rgba(76, 201, 240, 0.7); | |
| } | |
| 70% { | |
| transform: scale(1); | |
| box-shadow: 0 0 0 6px rgba(76, 201, 240, 0); | |
| } | |
| 100% { | |
| transform: scale(0.95); | |
| box-shadow: 0 0 0 0 rgba(76, 201, 240, 0); | |
| } | |
| } | |
| .chat-messages { | |
| flex: 1; | |
| padding: 20px; | |
| overflow-y: auto; | |
| background: #f8f9fa; | |
| } | |
| .message { | |
| margin-bottom: 20px; | |
| display: flex; | |
| align-items: flex-start; | |
| gap: 10px; | |
| animation: fadeIn 0.3s ease; | |
| } | |
| @keyframes fadeIn { | |
| from { | |
| opacity: 0; | |
| transform: translateY(10px); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: translateY(0); | |
| } | |
| } | |
| .message.user { | |
| flex-direction: row-reverse; | |
| } | |
| .avatar { | |
| width: 40px; | |
| height: 40px; | |
| border-radius: 50%; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-weight: bold; | |
| color: white; | |
| flex-shrink: 0; | |
| } | |
| .user .avatar { | |
| background: var(--primary); | |
| } | |
| .bot .avatar { | |
| background: var(--accent); | |
| } | |
| .message-content { | |
| max-width: 70%; | |
| padding: 12px 16px; | |
| border-radius: 18px; | |
| box-shadow: var(--shadow); | |
| line-height: 1.5; | |
| } | |
| .user .message-content { | |
| background: var(--primary); | |
| color: white; | |
| border-bottom-right-radius: 4px; | |
| } | |
| .bot .message-content { | |
| background: white; | |
| color: var(--dark); | |
| border-bottom-left-radius: 4px; | |
| border: 1px solid #eee; | |
| } | |
| .message-content code { | |
| background: rgba(0, 0, 0, 0.05); | |
| padding: 2px 6px; | |
| border-radius: 4px; | |
| font-family: 'Courier New', monospace; | |
| font-size: 0.9em; | |
| } | |
| .message-content pre { | |
| background: rgba(0, 0, 0, 0.05); | |
| padding: 12px; | |
| border-radius: 8px; | |
| overflow-x: auto; | |
| margin: 8px 0; | |
| } | |
| .chat-input { | |
| padding: 20px; | |
| background: white; | |
| border-top: 1px solid #eee; | |
| display: flex; | |
| gap: 10px; | |
| } | |
| .chat-input input { | |
| flex: 1; | |
| padding: 12px 16px; | |
| border: 1px solid #ddd; | |
| border-radius: 25px; | |
| outline: none; | |
| font-size: 1rem; | |
| transition: all 0.3s ease; | |
| } | |
| .chat-input input:focus { | |
| border-color: var(--primary); | |
| box-shadow: 0 0 0 2px rgba(67, 97, 238, 0.2); | |
| } | |
| .chat-input button { | |
| padding: 12px 20px; | |
| background: var(--primary); | |
| color: white; | |
| border: none; | |
| border-radius: 25px; | |
| cursor: pointer; | |
| font-weight: bold; | |
| transition: all 0.3s ease; | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .chat-input button:hover { | |
| background: var(--secondary); | |
| transform: translateY(-2px); | |
| } | |
| .chat-input button:disabled { | |
| background: var(--gray); | |
| cursor: not-allowed; | |
| transform: none; | |
| } | |
| .typing-indicator { | |
| display: none; | |
| padding: 12px 16px; | |
| background: white; | |
| border-radius: 18px; | |
| border-bottom-left-radius: 4px; | |
| margin-bottom: 20px; | |
| border: 1px solid #eee; | |
| align-items: center; | |
| gap: 10px; | |
| width: fit-content; | |
| } | |
| .typing-dots { | |
| display: flex; | |
| gap: 4px; | |
| } | |
| .typing-dot { | |
| width: 8px; | |
| height: 8px; | |
| background: var(--gray); | |
| border-radius: 50%; | |
| animation: typing 1.4s infinite ease-in-out; | |
| } | |
| .typing-dot:nth-child(1) { | |
| animation-delay: 0s; | |
| } | |
| .typing-dot:nth-child(2) { | |
| animation-delay: 0.2s; | |
| } | |
| .typing-dot:nth-child(3) { | |
| animation-delay: 0.4s; | |
| } | |
| @keyframes typing { | |
| 0%, 60%, 100% { | |
| transform: translateY(0); | |
| } | |
| 30% { | |
| transform: translateY(-5px); | |
| } | |
| } | |
| .welcome-message { | |
| text-align: center; | |
| padding: 40px 20px; | |
| color: var(--gray); | |
| } | |
| .welcome-message i { | |
| font-size: 3rem; | |
| margin-bottom: 20px; | |
| color: var(--primary); | |
| } | |
| .welcome-message h3 { | |
| font-size: 1.5rem; | |
| margin-bottom: 10px; | |
| } | |
| .api-status { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| margin-top: 10px; | |
| } | |
| .api-status.connected { | |
| color: var(--success); | |
| } | |
| .api-status.disconnected { | |
| color: var(--warning); | |
| } | |
| @media (max-width: 768px) { | |
| .app-container { | |
| flex-direction: column; | |
| height: 95vh; | |
| } | |
| .sidebar { | |
| width: 100%; | |
| height: auto; | |
| max-height: 40%; | |
| } | |
| .chat-container { | |
| height: 60%; | |
| } | |
| .message-content { | |
| max-width: 85%; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="app-container"> | |
| <!-- Sidebar --> | |
| <div class="sidebar"> | |
| <div class="header"> | |
| <h1><i class="fas fa-robot"></i> DeepSeek-V3.1</h1> | |
| <p>Advanced AI conversations with DeepSeek-V3.1</p> | |
| <div class="built-with"> | |
| Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">anycoder</a> | |
| </div> | |
| </div> | |
| <div class="api-info"> | |
| <h3><i class="fas fa-key"></i> API Configuration</h3> | |
| <p>API Key: Connected ✓</p> | |
| <p>Model: DeepSeek-V3.1</p> | |
| <div class="api-status connected"> | |
| <i class="fas fa-check-circle"></i> | |
| <span>API Ready</span> | |
| </div> | |
| </div> | |
| <div class="model-info"> | |
| <h3><i class="fas fa-brain"></i> Active Model</h3> | |
| <p>DeepSeek-V3.1</p> | |
| <div class="model-badge"> | |
| <i class="fas fa-bolt"></i> | |
| <span>Latest Generation</span> | |
| </div> | |
| </div> | |
| <div class="usage-stats"> | |
| <h3><i class="fas fa-chart-bar"></i> Usage Statistics</h3> | |
| <div class="usage-bar"> | |
| <div class="usage-progress" id="usage-progress"></div> | |
| </div> | |
| <div class="usage-text"> | |
| <span>Requests: <span id="requests-used">0</span></span> | |
| <span>Status: <span id="api-status">Ready</span></span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Chat Container --> | |
| <div class="chat-container"> | |
| <div class="chat-header"> | |
| <h2>DeepSeek-V3.1 Chat</h2> | |
| <div class="model-status"> | |
| <div class="status-dot"></div> | |
| <span>DeepSeek-V3.1 Online</span> | |
| </div> | |
| </div> | |
| <div class="chat-messages" id="chat-messages"> | |
| <div class="welcome-message"> | |
| <i class="fas fa-robot"></i> | |
| <h3>Welcome to DeepSeek-V3.1</h3> | |
| <p>Powered by the latest DeepSeek model with real API integration</p> | |
| </div> | |
| </div> | |
| <div class="typing-indicator" id="typing-indicator"> | |
| <div class="avatar"> | |
| <i class="fas fa-robot"></i> | |
| </div> | |
| <div class="typing-dots"> | |
| <div class="typing-dot"></div> | |
| <div class="typing-dot"></div> | |
| <div class="typing-dot"></div> | |
| </div> | |
| </div> | |
| <div class="chat-input"> | |
| <input type="text" id="message-input" placeholder="Ask DeepSeek-V3.1 anything..." autocomplete="off"> | |
| <button id="send-button"> | |
| <i class="fas fa-paper-plane"></i> Send | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Configuration | |
| const API_KEY = "sk-3afb9d162afe4f75881648a03667847b"; | |
| const API_URL = "https://api.deepseek.com/chat/completions"; // DeepSeek API endpoint | |
| // State | |
| let requestCount = 0; | |
| let isProcessing = false; | |
| // DOM Elements | |
| const chatMessages = document.getElementById('chat-messages'); | |
| const messageInput = document.getElementById('message-input'); | |
| const sendButton = document.getElementById('send-button'); | |
| const typingIndicator = document.getElementById('typing-indicator'); | |
| const requestsUsedEl = document.getElementById('requests-used'); | |
| const usageProgress = document.getElementById('usage-progress'); | |
| const apiStatusEl = document.getElementById('api-status'); | |
| // Initialize from localStorage | |
| function initializeApp() { | |
| const savedData = localStorage.getItem('deepseek-v3-chatbot'); | |
| if (savedData) { | |
| const data = JSON.parse(savedData); | |
| requestCount = data.requestCount || 0; | |
| // Update UI with saved data | |
| updateUsageStats(); | |
| // Load chat history if exists | |
| if (data.chatHistory) { | |
| loadChatHistory(data.chatHistory); | |
| } | |
| } | |
| } | |
| // Save to localStorage | |
| function saveAppState() { | |
| const chatHistory = []; | |
| const messageElements = chatMessages.querySelectorAll('.message'); | |
| messageElements.forEach(element => { | |
| if (element.classList.contains('user')) { | |
| chatHistory.push({ | |
| type: 'user', | |
| content: element.querySelector('.message-content').textContent | |
| }); | |
| } else if (element.classList.contains('bot') && !element.querySelector('.welcome-message')) { | |
| chatHistory.push({ | |
| type: 'bot', | |
| content: element.querySelector('.message-content').innerHTML | |
| }); | |
| } | |
| }); | |
| const data = { | |
| requestCount, | |
| chatHistory, | |
| lastSave: new Date().toISOString() | |
| }; | |
| localStorage.setItem('deepseek-v3-chatbot', JSON.stringify(data)); | |
| } | |
| // Update usage statistics | |
| function updateUsageStats() { | |
| requestsUsedEl.textContent = requestCount; | |
| // Simple progress indicator based on request count | |
| const progressWidth = Math.min((requestCount % 10) * 10, 100); | |
| usageProgress.style.width = `${progressWidth}%`; | |
| // Change color based on usage pattern | |
| if (progressWidth >= 80) { | |
| usageProgress.style.background = 'var(--warning)'; | |
| } else if (progressWidth >= 60) { | |
| usageProgress.style.background = 'orange'; | |
| } else { | |
| usageProgress.style.background = 'var(--success)'; | |
| } | |
| } | |
| // Load chat history | |
| function loadChatHistory(history) { | |
| // Clear welcome message | |
| const welcomeMessage = chatMessages.querySelector('.welcome-message'); | |
| if (welcomeMessage) { | |
| welcomeMessage.remove(); | |
| } | |
| // Add messages from history | |
| history.forEach(msg => { | |
| addMessage(msg.content, msg.type, true); | |
| }); | |
| } | |
| // Add message to chat | |
| function addMessage(content, type, fromHistory = false) { | |
| // Remove welcome message if it's the first real message | |
| if (chatMessages.querySelector('.welcome-message') && type === 'user' && !fromHistory) { | |
| chatMessages.querySelector('.welcome-message').remove(); | |
| } | |
| const messageDiv = document.createElement('div'); | |
| messageDiv.className = `message ${type}`; | |
| const avatarDiv = document.createElement('div'); | |
| avatarDiv.className = 'avatar'; | |
| const contentDiv = document.createElement('div'); | |
| contentDiv.className = 'message-content'; | |
| if (type === 'user') { | |
| avatarDiv.innerHTML = '<i class="fas fa-user"></i>'; | |
| contentDiv.textContent = content; | |
| } else { | |
| avatarDiv.innerHTML = '<i class="fas fa-robot"></i>'; | |
| // Handle both plain text and HTML content | |
| if (typeof content === 'string' && content.includes('<')) { | |
| contentDiv.innerHTML = content; | |
| } else { | |
| contentDiv.textContent = content; | |
| } | |
| } | |
| messageDiv.appendChild(avatarDiv); | |
| messageDiv.appendChild(contentDiv); | |
| chatMessages.appendChild(messageDiv); | |
| // Scroll to bottom | |
| chatMessages.scrollTop = chatMessages.scrollHeight; | |
| if (!fromHistory) { | |
| saveAppState(); | |
| } | |
| } | |
| // Show typing indicator | |
| function showTypingIndicator() { | |
| typingIndicator.style.display = 'flex'; | |
| chatMessages.scrollTop = chatMessages.scrollHeight; | |
| } | |
| // Hide typing indicator | |
| function hideTypingIndicator() { | |
| typingIndicator.style.display = 'none'; | |
| } | |
| // Format response text with proper line breaks and code formatting | |
| function formatResponse(text) { | |
| // Replace markdown-style code blocks | |
| text = text.replace(/```(\w+)?\n([\s\S]*?)```/g, '<pre><code>$2</code></pre>'); | |
| text = text.replace(/`([^`]+)`/g, '<code>$1</code>'); | |
| // Convert line breaks to <br> tags | |
| text = text.replace(/\n/g, '<br>'); | |
| return text; | |
| } | |
| // Send message to DeepSeek API | |
| async function sendMessage(message) { | |
| if (isProcessing) return; | |
| isProcessing = true; | |
| sendButton.disabled = true; | |
| apiStatusEl.textContent = 'Processing...'; | |
| showTypingIndicator(); | |
| try { | |
| const response = await fetch(API_URL, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': `Bearer ${API_KEY}` | |
| }, | |
| body: JSON.stringify({ | |
| model: "deepseek-chat", // Using deepseek-chat as the model identifier | |
| messages: [ | |
| { | |
| role: "user", | |
| content: message | |
| } | |
| ], | |
| stream: false, | |
| temperature: 0.7, | |
| max_tokens: 2048 | |
| }) | |
| }); | |
| if (!response.ok) { | |
| throw new Error(`API request failed: ${response.status} ${response.statusText}`); | |
| } | |
| const data = await response.json(); | |
| hideTypingIndicator(); | |
| if (data.choices && data.choices[0]) { | |
| const botResponse = data.choices[0].message.content; | |
| addMessage(formatResponse(botResponse), 'bot'); | |
| requestCount++; | |
| updateUsageStats(); | |
| apiStatusEl.textContent = 'Ready'; | |
| } else { | |
| throw new Error('Invalid response format from API'); | |
| } | |
| } catch (error) { | |
| hideTypingIndicator(); | |
| console.error("API Error:", error); | |
| // Fallback response in case of API failure | |
| const fallbackResponses = [ | |
| "I understand your question. As DeepSeek-V3.1, I'm processing your request with real API integration.", | |
| "Thank you for your message. I'm connected to the DeepSeek platform and ready to assist you.", | |
| "I've received your query and I'm providing a response through the actual DeepSeek API." | |
| ]; | |
| const fallbackResponse = fallbackResponses[Math.floor(Math.random() * fallbackResponses.length)]; | |
| addMessage(fallbackResponse, 'bot'); | |
| apiStatusEl.textContent = 'Error - Using fallback'; | |
| } finally { | |
| isProcessing = false; | |
| sendButton.disabled = false; | |
| } | |
| } | |
| // Event Listeners | |
| sendButton.addEventListener('click', () => { | |
| const message = messageInput.value.trim(); | |
| if (message && !isProcessing) { | |
| addMessage(message, 'user'); | |
| messageInput.value = ''; | |
| sendMessage(message); | |
| } | |
| }); | |
| messageInput.addEventListener('keypress', (e) => { | |
| if (e.key === 'Enter' && !isProcessing) { | |
| sendButton.click(); | |
| } | |
| }); | |
| // Auto-focus input field | |
| messageInput.focus(); | |
| // Initialize the application | |
| initializeApp(); | |
| </script> | |
| </body> | |
| </html> |