🐘
Test2.php
Back
📝 Php ⚡ Executable Ctrl+S: Save • Ctrl+R: Run • Ctrl+F: Find
<?php // ask-deepseek-coding.php // Minimal coding-focused DeepSeek client that only sends: // - a system rule // - the saved "working code doc" (optional) // - the current prompt // No rolling conversation history. session_start(); // === CONFIG === $DEEPSEEK_API_KEY = getenv('DEEPSEEK_API_KEY') ?: 'sk-b1d3560509194a4182ace023c083476a'; $API_URL = 'https://api.deepseek.com/chat/completions'; $DEFAULT_MODEL = 'deepseek-chat'; // or 'deepseek-reasoner' $DEFAULT_TEMPERATURE = 0.4; // lower for coding determinism $DEFAULT_MAXTOKENS = 800; // your cap // Session bucket for working code, artifacts, and conversation history if (!isset($_SESSION['working_code_doc'])) $_SESSION['working_code_doc'] = ''; if (!isset($_SESSION['artifacts'])) $_SESSION['artifacts'] = []; if (!isset($_SESSION['conversation_history'])) $_SESSION['conversation_history'] = []; // Helpers function h($s){ return htmlspecialchars($s ?? '', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); } function render_markdown_with_code_separators($text) { $text = str_replace(["\r\n", "\r"], "\n", $text); $pat = '/```([a-zA-Z0-9_\-]+)?\s*\n([\s\S]*?)```/m'; $html=''; $pos=0; while (preg_match($pat,$text,$m,PREG_OFFSET_CAPTURE,$pos)) { $start=$m[0][1]; $len=strlen($m[0][0]); $lang=$m[1][0]??''; $code=$m[2][0]??''; $before = substr($text,$pos,$start-$pos); if ($before!=='') $html.='<div class="md-p">'.nl2br(h($before)).'</div>'; $html.='<div class="code-sep"></div>'; $html.='<div class="codeblock">'.($lang?'<div class="code-lang">'.h($lang).'</div>':'') .'<pre><code>'.h($code).'</code></pre></div>'; $pos = $start+$len; } if ($pos < strlen($text)) { $tail = substr($text,$pos); if ($tail!=='') $html.='<div class="md-p">'.nl2br(h($tail)).'</div>'; } if ($html==='') $html = '<div class="md-p">'.nl2br(h($text)).'</div>'; return $html; } // Handle actions $error = null; $answer = null; $rawJson = null; $usage = null; $action = $_POST['action'] ?? ''; if ($action === 'save_working') { $_SESSION['working_code_doc'] = $_POST['working_code_doc'] ?? ''; } if ($action === 'clear_working') { $_SESSION['working_code_doc'] = ''; } if ($action === 'clear_history') { $_SESSION['conversation_history'] = []; } if ($action === 'save_artifact') { $artifactCode = $_POST['artifact_code'] ?? ''; $artifactName = trim($_POST['artifact_name'] ?? '') ?: 'Artifact ' . (count($_SESSION['artifacts']) + 1); if ($artifactCode !== '') { $artifact = [ 'id' => uniqid(), 'name' => $artifactName, 'code' => $artifactCode, 'timestamp' => time() ]; $_SESSION['artifacts'][] = $artifact; $_SESSION['working_code_doc'] = $artifactCode; // Make it current } } if ($action === 'make_current') { $artifactId = $_POST['artifact_id'] ?? ''; foreach ($_SESSION['artifacts'] as $artifact) { if ($artifact['id'] === $artifactId) { $_SESSION['working_code_doc'] = $artifact['code']; break; } } } if ($action === 'delete_artifact') { $artifactId = $_POST['artifact_id'] ?? ''; $_SESSION['artifacts'] = array_filter($_SESSION['artifacts'], function($artifact) use ($artifactId) { return $artifact['id'] !== $artifactId; }); $_SESSION['artifacts'] = array_values($_SESSION['artifacts']); // Re-index } if ($action === 'ask') { $question = trim($_POST['question'] ?? ''); $model = $_POST['model'] ?? $DEFAULT_MODEL; $maxTokens = max(50, min(8000, (int)($_POST['max_tokens'] ?? $DEFAULT_MAXTOKENS))); $temperature = max(0.0, min(2.0, (float)($_POST['temperature'] ?? $DEFAULT_TEMPERATURE))); $includeCode = isset($_POST['include_working']) ? true : false; $codeStyle = $_POST['code_response_style'] ?? 'complete'; if ($DEEPSEEK_API_KEY === 'REPLACE_WITH_YOUR_KEY' || $DEEPSEEK_API_KEY === '') { $error = 'Missing API key. Set DEEPSEEK_API_KEY on the server.'; } elseif ($question === '') { $error = 'Please enter a prompt.'; } else { // Build minimal message list: system -> (optional code doc) -> user prompt $systemPrompt = "You are a meticulous coding assistant. Only use the provided 'working code doc' as context. " . "Do not invent prior history. "; if ($codeStyle === 'changes_only') { $systemPrompt .= "When modifying existing code, show ONLY the specific changes needed - use concise diffs, " . "highlight the modified sections, or show just the functions/blocks that need updates. " . "Avoid repeating unchanged code unless necessary for context."; } else { $systemPrompt .= "When modifying code, provide the complete updated file or function. " . "Show the full code that the user can copy and use directly."; } $messages = [ ['role'=>'system','content'=>$systemPrompt] ]; if ($includeCode && $_SESSION['working_code_doc'] !== '') { // Keep it short by wrapping in a label + fenced code $messages[] = [ 'role' => 'system', 'content' => "CURRENT WORKING CODE DOC (single file):\n```text\n" . $_SESSION['working_code_doc'] . "\n```" ]; } $messages[] = ['role'=>'user','content'=>$question]; $payload = [ 'model' => $model, 'messages' => $messages, 'temperature' => $temperature, 'max_tokens' => $maxTokens, // 'stream' => false, ]; $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)'; $usage = $json['usage'] ?? null; // Save to conversation history (but don't send history to AI) $historyEntry = [ 'timestamp' => time(), 'question' => $question, 'answer' => $answer, 'model' => $model, 'usage' => $usage, 'included_code' => $includeCode, 'code_style' => $codeStyle ]; $_SESSION['conversation_history'][] = $historyEntry; // Keep only last 50 entries to prevent session bloat if (count($_SESSION['conversation_history']) > 50) { $_SESSION['conversation_history'] = array_slice($_SESSION['conversation_history'], -50); } } } } // Sticky UI $stickyQuestion = $_POST['question'] ?? ''; $stickyModel = $_POST['model'] ?? $DEFAULT_MODEL; $stickyTemp = $_POST['temperature'] ?? $DEFAULT_TEMPERATURE; $stickyMaxTokens = (int)($_POST['max_tokens'] ?? $DEFAULT_MAXTOKENS); $workingDoc = $_SESSION['working_code_doc']; $stickyInclude = isset($_POST['include_working']) ? 'checked' : 'checked'; // default ON $stickyCodeStyle = $_POST['code_response_style'] ?? 'complete'; // 'complete' or 'changes_only' ?> <!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1" /> <title>DeepSeek Coding (prompt + working doc only)</title> <style> :root{--card:#fafafa;--br:#e6e6e6;--sep:#d0d7de;--ink:#111;--muted:#666;--overlay-bg:rgba(0,0,0,0.5)} body{font-family:system-ui,Segoe UI,Roboto,Helvetica,Arial,sans-serif;margin:1rem;max-width:1000px;color:var(--ink);padding-bottom:120px} h1{margin:0 0 .5rem;font-size:1.5rem} .header{display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem;flex-wrap:wrap;gap:.5rem} .nav-buttons{display:flex;gap:.5rem;flex-wrap:wrap} .nav-btn{padding:.5rem .75rem;border-radius:8px;border:1px solid var(--br);background:#fff;cursor:pointer;font-size:.9rem;white-space:nowrap} .nav-btn:hover{border-color:#2f6feb} @media (max-width: 768px) { body{margin:.5rem;font-size:14px} h1{font-size:1.25rem} .header{flex-direction:column;align-items:stretch} .nav-buttons{justify-content:center} .nav-btn{font-size:.85rem;padding:.4rem .6rem} } /* Fixed bottom question area */ .question-area{position:fixed;bottom:0;left:0;right:0;background:#fff;border-top:1px solid var(--br);padding:1rem;box-shadow:0 -2px 10px rgba(0,0,0,0.1)} .question-form{display:flex;gap:.75rem;align-items:center;max-width:1000px;margin:0 auto} .question-input{flex:1;padding:.75rem;border:1px solid var(--br);border-radius:8px;font-size:1rem;min-width:0} .send-btn{padding:.75rem 1.5rem;border-radius:8px;border:1px solid var(--br);background:#2f6feb;color:#fff;cursor:pointer;font-weight:500;white-space:nowrap} .send-btn:hover{background:#1a5feb} @media (max-width: 768px) { .question-area{padding:.75rem} .question-form{gap:.5rem} .question-input{padding:.6rem;font-size:.9rem} .send-btn{padding:.6rem 1rem;font-size:.9rem} } /* Overlay styles */ .overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:var(--overlay-bg);display:none;align-items:center;justify-content:center;z-index:1000;padding:1rem} .overlay-content{background:#fff;border-radius:12px;padding:2rem;max-width:90vw;max-height:90vh;overflow:auto;box-shadow:0 10px 30px rgba(0,0,0,0.3)} .code-overlay{width:95vw;height:90vh} .code-layout{display:flex;flex-direction:column;gap:1rem;height:calc(90vh - 6rem)} @media (max-width: 768px) { .overlay{padding:.5rem} .overlay-content{padding:1rem;max-width:95vw;max-height:95vh;border-radius:8px} .code-overlay{width:100%;height:95vh} .code-layout{height:calc(95vh - 4rem);gap:.75rem} } /* Artifacts panel - now stacked on top */ .artifacts-panel{border-bottom:1px solid var(--br);padding-bottom:1rem;max-height:35vh;overflow-y:auto;flex-shrink:0} .artifacts-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:0.75rem} .artifact-item{border:1px solid var(--br);border-radius:8px;padding:0.75rem;background:#f9f9f9;cursor:pointer} .artifact-item:hover{background:#f0f0f0} .artifact-item.current{background:#e3f2fd;border-color:#2196f3} .artifact-name{font-weight:500;margin-bottom:0.25rem;font-size:0.9rem} .artifact-meta{font-size:0.75rem;color:var(--muted)} .artifact-actions{display:flex;gap:0.25rem;margin-top:0.5rem} .artifact-btn{padding:0.25rem 0.5rem;font-size:0.75rem;border:1px solid var(--br);background:#fff;border-radius:4px;cursor:pointer} .artifact-btn:hover{border-color:#2f6feb} /* Code editor - now takes remaining space at bottom */ .code-editor{display:flex;flex-direction:column;flex:1;min-height:0} .editor-header{margin-bottom:1rem;flex-shrink:0} .editor-textarea{flex:1;min-height:300px;resize:vertical} .overlay-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem} .close-btn{background:none;border:none;font-size:1.5rem;cursor:pointer;color:var(--muted)} .close-btn:hover{color:var(--ink)} textarea{min-height:120px;padding:.75rem;font-size:1rem;width:100%;box-sizing:border-box} textarea.code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace} select,input[type="number"]{padding:.5rem .6rem;font-size:1rem} button{padding:.6rem .9rem;border-radius:10px;border:1px solid var(--br);background:#fff;cursor:pointer} button:hover{border-color:#2f6feb} .card{border:1px solid var(--br);border-radius:14px;padding:1rem;margin-top:1rem;background:var(--card)} .meta{color:var(--muted);font-size:.9rem} .md-p{margin:.4rem 0;line-height:1.45} .code-sep{height:10px;border-top:3px double var(--sep);margin:.8rem 0} .codeblock{border:1px solid var(--sep);border-radius:10px;background:#fff} .code-lang{font-size:.8rem;color:var(--muted);padding:.4rem .6rem;border-bottom:1px solid var(--sep);background:#f6f8fa;border-top-left-radius:10px;border-top-right-radius:10px} pre{margin:0;padding:.75rem;overflow:auto;white-space:pre} code{font-size:.95rem} .settings-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:1rem;margin-bottom:1rem} .overlay-actions{display:flex;gap:.75rem;justify-content:flex-end;margin-top:1rem;flex-wrap:wrap} /* Responsive adjustments */ @media (max-width: 768px) { .artifacts-grid{grid-template-columns:1fr} .artifacts-panel{max-height:30vh} .settings-grid{grid-template-columns:1fr;gap:.75rem} .overlay-actions{justify-content:stretch} .overlay-actions button{flex:1} .artifact-actions{flex-direction:column;gap:.25rem} .artifact-actions form{width:100%} .artifact-btn{text-align:center} /* Better mobile form elements */ textarea, select, input[type="number"], input[type="text"]{font-size:16px} /* Prevents zoom on iOS */ .editor-textarea{min-height:200px} } </style> </head> <body> <div class="header"> <div> <h1>DeepSeek Coding</h1> <p class="meta">Each request uses only the <strong>working code doc</strong> (optional) + your <strong>current prompt</strong>. No full chat memory.</p> </div> <div class="nav-buttons"> <button class="nav-btn" onclick="showHistoryOverlay()">History (<?= count($_SESSION['conversation_history']) ?>)</button> <button class="nav-btn" onclick="showCodeOverlay()">Code Artifacts (<?= count($_SESSION['artifacts']) ?>)</button> <button class="nav-btn" onclick="showSettingsOverlay()">Settings</button> </div> </div> <!-- Main content area for responses --> <?php if ($error): ?> <div class="card" style="color:#b00020"><strong>Error:</strong> <?= h($error) ?></div> <?php endif; ?> <?php if ($answer): ?> <div class="card"> <div style="display:flex;justify-content:space-between;align-items:start;margin-bottom:1rem"> <div> <div style="font-weight:500;margin-bottom:.5rem">Q: <?= h($stickyQuestion) ?></div> <div class="meta"> <?= date('M j, g:i A') ?> • <?= h($stickyModel) ?> • <?= isset($_POST['include_working']) ? 'with code' : 'no code' ?> • <?= $stickyCodeStyle === 'complete' ? 'full code' : 'changes only' ?> <?php if ($usage): ?> • <?= (int)($usage['total_tokens'] ?? 0) ?> tokens <?php endif; ?> </div> </div> <button onclick="saveToArtifacts()" class="nav-btn">Add to Artifacts</button> </div> <div style="border-left:3px solid #2f6feb;padding-left:1rem"> <?= render_markdown_with_code_separators($answer) ?> </div> <?php if ($rawJson): ?> <details style="margin-top:1rem"><summary class="meta">Raw JSON</summary> <pre><code><?= h(json_encode($rawJson, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES)) ?></code></pre> </details> <?php endif; ?> </div> <?php endif; ?> <div class="card"> <h3>How it works</h3> <ul> <li>We do <em>not</em> resend prior turns. Only the <strong>system rule</strong>, optional <strong>working code doc</strong>, and your <strong>current prompt</strong> are included.</li> <li>Use a single-file "working doc." If you need multi-file context, paste the relevant parts or switch to a short summary of the non-active files to save tokens.</li> <li>Lower <code>temperature</code> (e.g., 0.2–0.5) for more deterministic code.</li> <li>Adjust <code>max_tokens</code> to cap output length (your real usage prints above).</li> </ul> </div> <!-- Fixed bottom question area --> <div class="question-area"> <form method="post" class="question-form" id="mainForm"> <input type="hidden" name="model" id="hiddenModel" value="<?= h($stickyModel) ?>"> <input type="hidden" name="max_tokens" id="hiddenMaxTokens" value="<?= (int)$stickyMaxTokens ?>"> <input type="hidden" name="temperature" id="hiddenTemperature" value="<?= h($stickyTemp) ?>"> <input type="hidden" name="include_working" id="hiddenIncludeWorking" value="<?= $stickyInclude ? '1' : '0' ?>"> <input type="hidden" name="code_response_style" id="hiddenCodeStyle" value="<?= h($stickyCodeStyle) ?>"> <input type="hidden" name="working_code_doc" id="hiddenWorkingDoc" value="<?= h($workingDoc) ?>"> <input type="text" name="question" class="question-input" placeholder="Describe the change, ask for a fix, or request a new function..." value="<?= $action === 'ask' ? '' : h($stickyQuestion) ?>" autofocus> <button type="submit" name="action" value="ask" class="send-btn">Send</button> </form> </div> <!-- History Overlay --> <div class="overlay" id="historyOverlay"> <div class="overlay-content code-overlay"> <div class="overlay-header"> <h3>Conversation History</h3> <button class="close-btn" onclick="hideHistoryOverlay()">&times;</button> </div> <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem"> <p class="meta">Total conversations: <?= count($_SESSION['conversation_history']) ?></p> <form method="post" style="display:inline"> <button type="submit" name="action" value="clear_history" class="nav-btn" style="background:#dc3545;color:#fff" onclick="return confirm('Clear all conversation history?')">Clear History</button> </form> </div> <div style="max-height:70vh;overflow-y:auto"> <?php if (empty($_SESSION['conversation_history'])): ?> <p class="meta">No conversation history yet. Start by asking a question!</p> <?php else: ?> <?php foreach (array_reverse($_SESSION['conversation_history']) as $index => $entry): ?> <div class="card" style="margin-bottom:1rem"> <div style="display:flex;justify-content:space-between;align-items:start;margin-bottom:.5rem"> <div class="meta"> <?= date('M j, Y g:i A', $entry['timestamp']) ?> • <?= h($entry['model']) ?> • <?= $entry['included_code'] ? 'with code context' : 'no code context' ?> • <?= ($entry['code_style'] ?? 'complete') === 'complete' ? 'full code responses' : 'changes only' ?> <?php if ($entry['usage']): ?> • <?= (int)($entry['usage']['total_tokens'] ?? 0) ?> tokens <?php endif; ?> </div> <button onclick="restoreQuestion('<?= h(addslashes($entry['question'])) ?>')" class="artifact-btn">Restore Question</button> </div> <div style="background:#f8f9fa;padding:.75rem;border-radius:6px;margin-bottom:.75rem"> <strong>Question:</strong> <?= h($entry['question']) ?> </div> <div style="border-left:3px solid #2f6feb;padding-left:1rem"> <strong>Answer:</strong> <div style="margin-top:.5rem"><?= render_markdown_with_code_separators($entry['answer']) ?></div> </div> </div> <?php endforeach; ?> <?php endif; ?> </div> </div> </div> <!-- Code Doc Overlay --> <div class="overlay" id="codeOverlay"> <div class="overlay-content code-overlay"> <div class="overlay-header"> <h3>Code Artifacts</h3> <button class="close-btn" onclick="hideCodeOverlay()">&times;</button> </div> <div class="code-layout"> <!-- Artifacts Panel (Top) --> <div class="artifacts-panel"> <h4>Saved Artifacts (<?= count($_SESSION['artifacts']) ?>)</h4> <div style="margin-bottom:1rem;font-size:0.8rem;color:var(--muted)"> Debug: Session has <?= count($_SESSION['artifacts']) ?> artifacts <?php if (!empty($_SESSION['artifacts'])): ?> - First artifact: "<?= h($_SESSION['artifacts'][0]['name'] ?? 'unknown') ?>" <?php endif; ?> </div> <?php if (empty($_SESSION['artifacts'])): ?> <p class="meta">No artifacts saved yet. Use "Add to Artifacts" button after getting code from DeepSeek.</p> <?php else: ?> <div class="artifacts-grid"> <?php foreach ($_SESSION['artifacts'] as $index => $artifact): ?> <div class="artifact-item <?= $artifact['code'] === $workingDoc ? 'current' : '' ?>" data-id="<?= h($artifact['id']) ?>"> <div class="artifact-name"><?= h($artifact['name']) ?> (#<?= $index + 1 ?>)</div> <div class="artifact-meta"><?= date('M j, g:i A', $artifact['timestamp']) ?></div> <div class="artifact-meta" style="font-size:0.7rem">ID: <?= h(substr($artifact['id'], 0, 8)) ?>...</div> <div class="artifact-actions"> <form method="post" style="display:inline"> <input type="hidden" name="artifact_id" value="<?= h($artifact['id']) ?>"> <button type="submit" name="action" value="make_current" class="artifact-btn">Make Current</button> </form> <form method="post" style="display:inline"> <input type="hidden" name="artifact_id" value="<?= h($artifact['id']) ?>"> <button type="submit" name="action" value="delete_artifact" class="artifact-btn" style="color:#d73502" onclick="return confirm('Delete this artifact?')">Delete</button> </form> </div> </div> <?php endforeach; ?> </div> <?php endif; ?> </div> <!-- Code Editor (Bottom) --> <div class="code-editor"> <div class="editor-header"> <h4>Current Working Code</h4> <p class="meta">This code will be sent as context with your prompts</p> </div> <form method="post" style="height:100%;display:flex;flex-direction:column" id="codeForm"> <textarea class="code editor-textarea" name="working_code_doc" id="workingCodeDoc" placeholder="// Paste your current single-file code here..."><?= h($workingDoc) ?></textarea> <div class="overlay-actions" style="margin-top:1rem"> <button type="submit" name="action" value="clear_working">Clear</button> <button type="submit" name="action" value="save_working">Save Working Code</button> </div> </form> </div> </div> </div> </div> <!-- Settings Overlay --> <div class="overlay" id="settingsOverlay"> <div class="overlay-content"> <div class="overlay-header"> <h3>Settings</h3> <button class="close-btn" onclick="hideSettingsOverlay()">&times;</button> </div> <div class="settings-grid"> <label>Model <select id="modelSelect"> <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> </label> <label>Max tokens <select id="maxTokensSelect"> <?php foreach ([200,500,800,1000,1500,2000,4000,6000,8000] as $c): ?> <option value="<?= (int)$c ?>" <?= $stickyMaxTokens==$c?'selected':''; ?>><?= (int)$c ?></option> <?php endforeach; ?> </select> </label> <label>Temperature <input id="temperatureInput" type="number" step="0.1" min="0" max="2" value="<?= h($stickyTemp) ?>"> </label> </div> <label style="margin:1rem 0;display:block"> <input type="checkbox" id="includeWorkingCheck" <?= $stickyInclude ?>> Include working code doc </label> <div style="margin:1rem 0"> <label style="display:block;margin-bottom:.5rem;font-weight:500">Code Response Style</label> <div style="display:flex;flex-direction:column;gap:.5rem"> <label style="display:flex;align-items:start;gap:.5rem"> <input type="radio" name="code_style" id="codeStyleComplete" value="complete" <?= $stickyCodeStyle === 'complete' ? 'checked' : '' ?> style="margin-top:.2rem"> <span><strong>Complete Code</strong> - Return full updated files/functions (easier to copy-paste)</span> </label> <label style="display:flex;align-items:start;gap:.5rem"> <input type="radio" name="code_style" id="codeStyleChanges" value="changes_only" <?= $stickyCodeStyle === 'changes_only' ? 'checked' : '' ?> style="margin-top:.2rem"> <span><strong>Changes Only</strong> - Show only diffs/modifications (saves tokens, faster responses)</span> </label> </div> </div> <div class="overlay-actions"> <button onclick="hideSettingsOverlay()">Close</button> </div> </div> </div> <script> function restoreQuestion(question) { hideHistoryOverlay(); document.querySelector('.question-input').value = question; document.querySelector('.question-input').focus(); } function showHistoryOverlay() { document.getElementById('historyOverlay').style.display = 'flex'; } function hideHistoryOverlay() { document.getElementById('historyOverlay').style.display = 'none'; } function saveToArtifacts() { // Find any card that contains an answer (look for the blue border div) const answerElements = document.querySelectorAll('div[style*="border-left:3px solid #2f6feb"]'); if (answerElements.length === 0) { alert('No answer found to save.'); return; } // Use the first (most recent) answer element const answerSection = answerElements[0]; // Extract code blocks from the answer const codeBlocks = answerSection.querySelectorAll('.codeblock pre code'); if (codeBlocks.length === 0) { alert('No code blocks found in the answer to save.'); return; } // If multiple code blocks, take the largest one let selectedCode = ''; let maxLength = 0; codeBlocks.forEach(block => { if (block.textContent.length > maxLength) { maxLength = block.textContent.length; selectedCode = block.textContent; } }); // Prompt for artifact name const artifactName = prompt('Enter a name for this artifact:', 'Code ' + new Date().toLocaleTimeString()); if (!artifactName) return; // Create form and submit const form = document.createElement('form'); form.method = 'post'; form.style.display = 'none'; const actionInput = document.createElement('input'); actionInput.type = 'hidden'; actionInput.name = 'action'; actionInput.value = 'save_artifact'; const codeInput = document.createElement('input'); codeInput.type = 'hidden'; codeInput.name = 'artifact_code'; codeInput.value = selectedCode; const nameInput = document.createElement('input'); nameInput.type = 'hidden'; nameInput.name = 'artifact_name'; nameInput.value = artifactName; form.appendChild(actionInput); form.appendChild(codeInput); form.appendChild(nameInput); document.body.appendChild(form); form.submit(); } function showCodeOverlay() { document.getElementById('codeOverlay').style.display = 'flex'; } function hideCodeOverlay() { document.getElementById('codeOverlay').style.display = 'none'; // Sync the working doc to hidden field document.getElementById('hiddenWorkingDoc').value = document.getElementById('workingCodeDoc').value; } function showSettingsOverlay() { document.getElementById('settingsOverlay').style.display = 'flex'; } function hideSettingsOverlay() { document.getElementById('settingsOverlay').style.display = 'none'; // Sync all settings to hidden fields document.getElementById('hiddenModel').value = document.getElementById('modelSelect').value; document.getElementById('hiddenMaxTokens').value = document.getElementById('maxTokensSelect').value; document.getElementById('hiddenTemperature').value = document.getElementById('temperatureInput').value; document.getElementById('hiddenIncludeWorking').value = document.getElementById('includeWorkingCheck').checked ? '1' : '0'; document.getElementById('hiddenCodeStyle').value = document.querySelector('input[name="code_style"]:checked')?.value || 'complete'; // Save settings to localStorage localStorage.setItem('deepseek_settings', JSON.stringify({ model: document.getElementById('modelSelect').value, maxTokens: document.getElementById('maxTokensSelect').value, temperature: document.getElementById('temperatureInput').value, includeWorking: document.getElementById('includeWorkingCheck').checked, codeStyle: document.querySelector('input[name="code_style"]:checked')?.value || 'complete' })); } // Close overlays when clicking outside document.getElementById('historyOverlay').addEventListener('click', function(e) { if (e.target === this) hideHistoryOverlay(); }); document.getElementById('codeOverlay').addEventListener('click', function(e) { if (e.target === this) hideCodeOverlay(); }); document.getElementById('settingsOverlay').addEventListener('click', function(e) { if (e.target === this) hideSettingsOverlay(); }); // Close overlays with Escape key document.addEventListener('keydown', function(e) { if (e.key === 'Escape') { hideHistoryOverlay(); hideCodeOverlay(); hideSettingsOverlay(); } }); // Load saved settings on page load document.addEventListener('DOMContentLoaded', function() { const savedSettings = localStorage.getItem('deepseek_settings'); if (savedSettings) { try { const settings = JSON.parse(savedSettings); if (document.getElementById('modelSelect')) { document.getElementById('modelSelect').value = settings.model || '<?= h($stickyModel) ?>'; document.getElementById('maxTokensSelect').value = settings.maxTokens || '<?= (int)$stickyMaxTokens ?>'; document.getElementById('temperatureInput').value = settings.temperature || '<?= h($stickyTemp) ?>'; document.getElementById('includeWorkingCheck').checked = settings.includeWorking !== undefined ? settings.includeWorking : <?= $stickyInclude ? 'true' : 'false' ?>; // Set code style radio buttons const codeStyleRadios = document.querySelectorAll('input[name="code_style"]'); const savedCodeStyle = settings.codeStyle || '<?= h($stickyCodeStyle) ?>'; codeStyleRadios.forEach(radio => { if (radio.value === savedCodeStyle) { radio.checked = true; } }); // Update hidden fields too document.getElementById('hiddenModel').value = settings.model || '<?= h($stickyModel) ?>'; document.getElementById('hiddenMaxTokens').value = settings.maxTokens || '<?= (int)$stickyMaxTokens ?>'; document.getElementById('hiddenTemperature').value = settings.temperature || '<?= h($stickyTemp) ?>'; document.getElementById('hiddenIncludeWorking').value = (settings.includeWorking !== undefined ? settings.includeWorking : <?= $stickyInclude ? 'true' : 'false' ?>) ? '1' : '0'; document.getElementById('hiddenCodeStyle').value = settings.codeStyle || '<?= h($stickyCodeStyle) ?>'; } } catch(e) { console.log('Error loading settings:', e); } } }); // Update hidden fields when settings change document.getElementById('modelSelect')?.addEventListener('change', function() { document.getElementById('hiddenModel').value = this.value; }); document.getElementById('maxTokensSelect')?.addEventListener('change', function() { document.getElementById('hiddenMaxTokens').value = this.value; }); document.getElementById('temperatureInput')?.addEventListener('change', function() { document.getElementById('hiddenTemperature').value = this.value; }); document.getElementById('includeWorkingCheck')?.addEventListener('change', function() { document.getElementById('hiddenIncludeWorking').value = this.checked ? '1' : '0'; }); document.querySelectorAll('input[name="code_style"]').forEach(radio => { radio.addEventListener('change', function() { if (this.checked) { document.getElementById('hiddenCodeStyle').value = this.value; } }); }); document.getElementById('workingCodeDoc')?.addEventListener('input', function() { document.getElementById('hiddenWorkingDoc').value = this.value; }); </script> </body> </html>