🐘
Test4.php
← Back
📝 Php ⚡ Executable Ctrl+S: Save â€ĸ Ctrl+R: Run â€ĸ Ctrl+F: Find
<?php // ask-deepseek-convo.php // Modern DeepSeek chat with session-based memory + mobile-friendly UI session_start(); // === CONFIG === $DEEPSEEK_API_KEY = getenv('DEEPSEEK_API_KEY') ?: 'sk-b1d3560509194a4182ace023c083476a'; $API_URL = 'https://api.deepseek.com/chat/completions'; $DEFAULT_MODEL = 'deepseek-chat'; $DEFAULT_TEMPERATURE = 0.7; $DEFAULT_MAXTOKENS = 800; // session bucket if (!isset($_SESSION['deepseek_convo'])) { $_SESSION['deepseek_convo'] = []; } // helpers function h($s){ return htmlspecialchars($s ?? '', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); } function render($text){ $text = str_replace(["\r\n","\r"], "\n", $text); $pat = '/```([a-zA-Z0-9_\-]+)?\s*\n([\s\S]*?)```/m'; $html=''; $pos=0; $codeBlockId = 0; while (preg_match($pat,$text,$m,PREG_OFFSET_CAPTURE,$pos)) { $start=$m[0][1]; $len=strlen($m[0][0]); $lang=$m[1][0] ?? 'text'; $code=$m[2][0] ?? ''; $codeBlockId++; $before = substr($text,$pos,$start-$pos); if ($before !== '') { $html .= '<div class="message-text">'.nl2br(h($before)).'</div>'; } $html .= '<div class="code-block-container">'; $html .= '<div class="code-header">'; $html .= '<span class="code-lang">'.h($lang).'</span>'; $html .= '<button class="copy-btn" onclick="copyCode(\'code-'.$codeBlockId.'\')">Copy</button>'; $html .= '</div>'; $html .= '<div class="ace-editor" id="code-'.$codeBlockId.'" data-lang="'.h($lang).'">'.h($code).'</div>'; $html .= '</div>'; $pos = $start+$len; } if ($pos < strlen($text)) { $tail = substr($text,$pos); if ($tail !== '') { $html .= '<div class="message-text">'.nl2br(h($tail)).'</div>'; } } if ($html === '') { $html = '<div class="message-text">'.nl2br(h($text)).'</div>'; } return $html; } // handle actions $error = null; $answer = null; $rawJson = null; $action = $_POST['action'] ?? ''; if ($action === 'clear') { $_SESSION['deepseek_convo'] = []; // Redirect to prevent resubmission header('Location: ' . $_SERVER['PHP_SELF']); exit; } if ($action === 'delete_last') { $n = count($_SESSION['deepseek_convo']); if ($n > 0) { $last = array_pop($_SESSION['deepseek_convo']); if ($last['role'] === 'assistant' && $n-2 >= 0) { $prev = end($_SESSION['deepseek_convo']); if ($prev && $prev['role'] === 'user') array_pop($_SESSION['deepseek_convo']); } } // Redirect to prevent resubmission header('Location: ' . $_SERVER['PHP_SELF']); exit; } if ($action === 'ask') { $question = trim($_POST['question'] ?? ''); $model = $_POST['model'] ?? $DEFAULT_MODEL; $continueChat = isset($_POST['continue']) ? true : false; $maxTokens = max(50, min(8000, (int)($_POST['max_tokens'] ?? $DEFAULT_MAXTOKENS))); $temperature = max(0.0, min(2.0, (float)($_POST['temperature'] ?? $DEFAULT_TEMPERATURE))); if ($DEEPSEEK_API_KEY === 'REPLACE_WITH_YOUR_KEY' || $DEEPSEEK_API_KEY === '') { $error = 'Missing API key. Set DEEPSEEK_API_KEY on the server or paste it in the file (not recommended).'; } elseif ($question === '') { $error = 'Please enter a question.'; } else { $messages = [['role'=>'system','content'=>'You are a helpful assistant.']]; if ($continueChat) { foreach ($_SESSION['deepseek_convo'] as $m) { if ($m['role']==='user' || $m['role']==='assistant') $messages[] = $m; } } $messages[] = ['role'=>'user','content'=>$question]; $payload = [ 'model' => $model, 'messages' => $messages, 'temperature' => $temperature, 'max_tokens' => $maxTokens, ]; $ch = curl_init($API_URL); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Authorization: Bearer ' . $DEEPSEEK_API_KEY, ], CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 120, ]); $raw = curl_exec($ch); $http = curl_getinfo($ch, CURLINFO_HTTP_CODE); $cerr = curl_error($ch); curl_close($ch); if ($cerr) { $error = 'cURL error: ' . $cerr; } elseif ($http < 200 || $http >= 300) { $error = "HTTP $http: " . $raw; } else { $json = json_decode($raw, true); $rawJson = $json; $answer = $json['choices'][0]['message']['content'] ?? '(no content)'; if ($continueChat) { $_SESSION['deepseek_convo'][] = ['role'=>'user','content'=>$question]; $_SESSION['deepseek_convo'][] = ['role'=>'assistant','content'=>$answer]; } else { $_SESSION['deepseek_convo'] = [ ['role'=>'user','content'=>$question], ['role'=>'assistant','content'=>$answer], ]; } } } } // sticky UI values - clear question after successful non-ask actions $stickyQuestion = ($action === 'clear' || $action === 'delete_last') ? '' : ($_POST['question'] ?? ''); $stickyModel = $_POST['model'] ?? $DEFAULT_MODEL; $stickyTemp = $_POST['temperature'] ?? $DEFAULT_TEMPERATURE; $stickyMaxTokens = (int)($_POST['max_tokens'] ?? $DEFAULT_MAXTOKENS); $stickyContinue = isset($_POST['continue']) ? 'checked' : ''; $history = $_SESSION['deepseek_convo']; ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>DeepSeek Chat</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.2/theme/github.min.css"> <style> * { margin: 0; padding: 0; box-sizing: border-box; } :root { --primary: #2563eb; --primary-hover: #1d4ed8; --primary-light: #dbeafe; --surface: #ffffff; --background: #f8fafc; --border: #e2e8f0; --text-primary: #1e293b; --text-secondary: #64748b; --success: #10b981; --error: #ef4444; --warning: #f59e0b; --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05); --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); --radius: 12px; --radius-sm: 8px; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background: var(--background); color: var(--text-primary); line-height: 1.6; } .container { max-width: 1200px; margin: 0 auto; padding: 1rem; } .header { background: var(--surface); border-radius: var(--radius); padding: 1.5rem; margin-bottom: 1.5rem; box-shadow: var(--shadow-sm); border: 1px solid var(--border); } .header h1 { font-size: 1.875rem; font-weight: 700; color: var(--text-primary); margin-bottom: 0.5rem; } .header p { color: var(--text-secondary); font-size: 0.875rem; } .chat-form { background: var(--surface); border-radius: var(--radius); padding: 1.5rem; margin-bottom: 1.5rem; box-shadow: var(--shadow-sm); border: 1px solid var(--border); } .form-group { margin-bottom: 1rem; } .form-group label { display: block; font-weight: 500; margin-bottom: 0.5rem; color: var(--text-primary); } textarea { width: 100%; min-height: 120px; padding: 0.875rem; border: 1px solid var(--border); border-radius: var(--radius-sm); font-size: 0.875rem; font-family: inherit; resize: vertical; transition: border-color 0.2s, box-shadow 0.2s; } textarea:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-light); } .form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-bottom: 1rem; } select, input[type="number"] { width: 100%; padding: 0.75rem; border: 1px solid var(--border); border-radius: var(--radius-sm); font-size: 0.875rem; transition: border-color 0.2s, box-shadow 0.2s; } select:focus, input[type="number"]:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-light); } .checkbox-group { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 1rem; } .checkbox-group input[type="checkbox"] { width: 1rem; height: 1rem; accent-color: var(--primary); } .button-group { display: flex; gap: 0.75rem; flex-wrap: wrap; } .btn { padding: 0.75rem 1.5rem; border-radius: var(--radius-sm); border: 1px solid var(--border); font-size: 0.875rem; font-weight: 500; cursor: pointer; transition: all 0.2s; display: inline-flex; align-items: center; gap: 0.5rem; text-decoration: none; } .btn-primary { background: var(--primary); color: white; border-color: var(--primary); } .btn-primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); } .btn-secondary { background: var(--surface); color: var(--text-primary); } .btn-secondary:hover { background: var(--background); } .btn-danger { color: var(--error); border-color: var(--error); } .btn-danger:hover { background: var(--error); color: white; } .alert { padding: 1rem; border-radius: var(--radius-sm); margin-bottom: 1rem; border: 1px solid; } .alert-error { background: #fef2f2; border-color: #fecaca; color: #dc2626; } .chat-container { background: var(--surface); border-radius: var(--radius); padding: 1.5rem; margin-bottom: 1.5rem; box-shadow: var(--shadow-sm); border: 1px solid var(--border); } .chat-container h3 { font-size: 1.25rem; font-weight: 600; margin-bottom: 1rem; color: var(--text-primary); } .message { margin-bottom: 1.5rem; } .message-role { font-size: 0.75rem; font-weight: 600; text-transform: uppercase; color: var(--text-secondary); margin-bottom: 0.5rem; letter-spacing: 0.05em; } .message-role.user { color: var(--primary); } .message-role.assistant { color: var(--success); } .message-bubble { background: var(--background); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 1rem; } .message-text { line-height: 1.6; margin-bottom: 0.75rem; } .message-text:last-child { margin-bottom: 0; } .code-block-container { margin: 1rem 0; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; } .code-header { display: flex; justify-content: space-between; align-items: center; padding: 0.75rem 1rem; background: var(--background); border-bottom: 1px solid var(--border); } .code-lang { font-size: 0.75rem; font-weight: 600; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.05em; } .copy-btn { font-size: 0.75rem; padding: 0.25rem 0.5rem; background: var(--primary); color: white; border: none; border-radius: 4px; cursor: pointer; transition: background 0.2s; } .copy-btn:hover { background: var(--primary-hover); } .ace-editor { height: 200px; font-size: 14px; } .details-container { margin-top: 1rem; } .details-container details { border: 1px solid var(--border); border-radius: var(--radius-sm); } .details-container summary { padding: 0.75rem; background: var(--background); cursor: pointer; font-weight: 500; } .details-container pre { padding: 1rem; background: var(--surface); overflow: auto; font-size: 0.875rem; margin: 0; } .notes-container { background: var(--surface); border-radius: var(--radius); padding: 1.5rem; box-shadow: var(--shadow-sm); border: 1px solid var(--border); } .notes-container h3 { font-size: 1.25rem; font-weight: 600; margin-bottom: 1rem; color: var(--text-primary); } .notes-container ul { padding-left: 1.5rem; } .notes-container li { margin-bottom: 0.5rem; color: var(--text-secondary); } .notes-container code { background: var(--background); padding: 0.125rem 0.25rem; border-radius: 4px; font-size: 0.875rem; color: var(--text-primary); } .loading { display: none; text-align: center; padding: 2rem; color: var(--text-secondary); } .spinner { display: inline-block; width: 20px; height: 20px; border: 3px solid var(--border); border-radius: 50%; border-top-color: var(--primary); animation: spin 1s ease-in-out infinite; margin-right: 0.5rem; } @keyframes spin { to { transform: rotate(360deg); } } /* Mobile responsiveness */ @media (max-width: 768px) { .container { padding: 0.5rem; } .header, .chat-form, .chat-container, .notes-container { padding: 1rem; margin-bottom: 1rem; } .form-row { grid-template-columns: 1fr; } .button-group { flex-direction: column; } .btn { justify-content: center; } .code-header { padding: 0.5rem; } .ace-editor { height: 150px; } } /* Dark mode support */ @media (prefers-color-scheme: dark) { :root { --background: #0f172a; --surface: #1e293b; --border: #334155; --text-primary: #f1f5f9; --text-secondary: #94a3b8; --primary-light: #1e40af; } } </style> </head> <body> <div class="container"> <div class="header"> <h1>🤖 DeepSeek Chat</h1> <p>Modern AI chat interface with session-based memory and advanced code editing</p> </div> <form method="post" class="chat-form" id="chatForm"> <div class="form-group"> <label for="question">Your Message</label> <textarea name="question" id="question" placeholder="Type your message here..." <?= $action === 'ask' ? 'required' : '' ?> ><?= h($stickyQuestion) ?></textarea> </div> <div class="form-row"> <div class="form-group"> <label for="model">Model</label> <select name="model" id="model"> <option value="deepseek-chat" <?= $stickyModel==='deepseek-chat'?'selected':''; ?>> đŸ’Ŧ DeepSeek Chat </option> <option value="deepseek-reasoner" <?= $stickyModel==='deepseek-reasoner'?'selected':''; ?>> 🧠 DeepSeek Reasoner (R1-style) </option> </select> </div> <div class="form-group"> <label for="max_tokens">Max Tokens</label> <select name="max_tokens" id="max_tokens"> <?php foreach ([200,500,800,1000,1500,2000,4000,6000,8000] as $c): ?> <option value="<?= (int)$c ?>" <?= $stickyMaxTokens==$c?'selected':''; ?>> <?= number_format($c) ?> </option> <?php endforeach; ?> </select> </div> <div class="form-group"> <label for="temperature">Temperature</label> <input name="temperature" id="temperature" type="number" step="0.1" min="0" max="2" value="<?= h($stickyTemp) ?>"> </div> </div> <div class="checkbox-group"> <input type="checkbox" name="continue" id="continue" <?= $stickyContinue ?: 'checked' ?>> <label for="continue">Continue this conversation</label> </div> <div class="button-group"> <button type="button" onclick="submitAction('ask')" class="btn btn-primary" id="sendBtn"> <span>📤</span> Send Message </button> <button type="button" onclick="submitAction('delete_last')" class="btn btn-secondary" title="Remove the most recent exchange"> <span>â†Šī¸</span> Delete Last </button> <button type="button" onclick="submitAction('clear')" class="btn btn-danger" title="Clear entire conversation"> <span>đŸ—‘ī¸</span> Clear All </button> </div> <input type="hidden" name="action" id="actionInput" value=""> <div class="loading" id="loading"> <div class="spinner"></div> <span id="loadingText">Processing...</span> </div> </form> <?php if ($error): ?> <div class="alert alert-error"> <strong>❌ Error:</strong> <?= h($error) ?> </div> <?php endif; ?> <?php if (!empty($history)): ?> <div class="chat-container"> <h3>đŸ’Ŧ Conversation History</h3> <?php foreach ($history as $m): ?> <div class="message"> <div class="message-role <?= $m['role'] ?>"><?= h(ucfirst($m['role'])) ?></div> <div class="message-bubble"><?= render($m['content']) ?></div> </div> <?php endforeach; ?> </div> <?php endif; ?> <?php if ($answer): ?> <div class="chat-container"> <h3>✨ Latest Response</h3> <div class="message-bubble"> <?= render($answer) ?> </div> <?php if ($rawJson): ?> <div class="details-container"> <details> <summary>🔍 Raw JSON Response</summary> <pre><code><?= h(json_encode($rawJson, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES)) ?></code></pre> </details> </div> <?php endif; ?> </div> <?php endif; ?> <div class="notes-container"> <h3>📋 Notes</h3> <ul> <li><strong>Memory:</strong> Implemented with PHP sessions. For persistence across browsers/servers, use MySQL with a <code>conversation_id</code>.</li> <li><strong>Privacy:</strong> Conversations are stored locally in your session. Clear them using the controls above.</li> <li><strong>API:</strong> Uses OpenAI-compatible <code>POST /chat/completions</code> endpoint.</li> <li><strong>Code Editing:</strong> Code blocks now use ACE Editor for better syntax highlighting and editing.</li> </ul> </div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.2/ace.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.2/ext-language_tools.min.js"></script> <script> // Initialize ACE editors for code blocks document.addEventListener('DOMContentLoaded', function() { const codeBlocks = document.querySelectorAll('.ace-editor'); codeBlocks.forEach(function(block) { const editor = ace.edit(block); const lang = block.getAttribute('data-lang') || 'text'; // Set theme and mode editor.setTheme('ace/theme/github'); editor.setReadOnly(true); editor.setShowPrintMargin(false); // Map language to ACE mode const langMap = { 'javascript': 'javascript', 'python': 'python', 'php': 'php', 'html': 'html', 'css': 'css', 'json': 'json', 'sql': 'sql', 'bash': 'sh', 'shell': 'sh', 'xml': 'xml', 'yaml': 'yaml', 'markdown': 'markdown', 'java': 'java', 'cpp': 'c_cpp', 'c': 'c_cpp', 'text': 'text' }; const mode = langMap[lang.toLowerCase()] || 'text'; editor.session.setMode(`ace/mode/${mode}`); // Configure editor editor.setOptions({ maxLines: 30, minLines: 3, fontSize: 14, wrap: true, showLineNumbers: true, showGutter: true }); }); }); // Copy code functionality function copyCode(editorId) { const editor = ace.edit(editorId); const code = editor.getValue(); navigator.clipboard.writeText(code).then(function() { const btn = document.querySelector(`#${editorId}`).parentNode.querySelector('.copy-btn'); const originalText = btn.textContent; btn.textContent = 'Copied!'; btn.style.background = 'var(--success)'; setTimeout(function() { btn.textContent = originalText; btn.style.background = 'var(--primary)'; }, 2000); }).catch(function(err) { console.error('Failed to copy code: ', err); }); } // Handle form submission with proper action function submitAction(action) { const form = document.getElementById('chatForm'); const actionInput = document.getElementById('actionInput'); const loading = document.getElementById('loading'); const loadingText = document.getElementById('loadingText'); const buttons = document.querySelectorAll('.btn'); const questionField = document.getElementById('question'); // Validate input for ask action if (action === 'ask' && questionField.value.trim() === '') { alert('Please enter a message before sending.'); return; } // Set the action actionInput.value = action; // Show loading state loading.style.display = 'block'; buttons.forEach(btn => { btn.disabled = true; btn.style.opacity = '0.6'; }); // Update loading text based on action switch(action) { case 'ask': loadingText.textContent = 'Thinking...'; break; case 'delete_last': loadingText.textContent = 'Deleting last message...'; break; case 'clear': loadingText.textContent = 'Clearing conversation...'; break; } // Submit the form form.submit(); } // Auto-resize textarea const textarea = document.getElementById('question'); textarea.addEventListener('input', function() { this.style.height = 'auto'; this.style.height = Math.min(this.scrollHeight, 300) + 'px'; }); // Keyboard shortcuts document.addEventListener('keydown', function(e) { // Ctrl/Cmd + Enter to submit if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { e.preventDefault(); submitAction('ask'); } }); // Clear question field after non-ask actions <?php if ($action === 'clear' || $action === 'delete_last'): ?> document.getElementById('question').value = ''; <?php endif; ?> </script> </body> </html>