Spaces:
Paused
Paused
| import http.server, json, urllib.parse, io | |
| CHAT_PAGE = b"""<!DOCTYPE html> | |
| <html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"> | |
| <title>YT Claw Chat</title> | |
| <style> | |
| *{box-sizing:border-box}body{font-family:monospace;background:#111;color:#0f0;margin:0;padding:0;height:100vh;display:flex;flex-direction:column} | |
| #header{background:#0a0a0a;padding:12px 20px;border-bottom:1px solid #333;text-align:center} | |
| h1{margin:0;font-size:1.1em;color:#0f0} | |
| #info{font-size:0.7em;color:#666;margin-top:3px} | |
| #chat{flex:1;overflow-y:auto;padding:15px} | |
| .msg{margin:8px 0;padding:10px 14px;border-radius:8px;max-width:85%;word-wrap:break-word;white-space:pre-wrap} | |
| .user{background:#1a3a1a;align-self:flex-end;margin-left:auto} | |
| .ai{background:#1a1a3a;align-self:flex-start} | |
| #input-area{display:flex;padding:12px;background:#0a0a0a;border-top:1px solid #333} | |
| #prompt{flex:1;padding:10px;background:#222;color:#0f0;border:1px solid #444;border-radius:6px;font-family:monospace;font-size:0.95em;resize:none} | |
| #send{padding:10px 18px;margin-left:8px;background:#0a0;color:#fff;border:none;border-radius:6px;cursor:pointer;font-weight:bold} | |
| #send:hover{background:#0d0}#send:disabled{background:#333;cursor:not-allowed} | |
| #status{color:#666;font-size:0.7em;padding:4px 12px;text-align:center} | |
| </style></head><body> | |
| <div id=header><h1>YT Claw - DeepSeek R1 14B IQ3_XS</h1><div id=info>128K context | CoT reasoning</div></div> | |
| <div id=chat></div> | |
| <div id=status>Ready</div> | |
| <div id=input-area><textarea id=prompt rows=2 placeholder="Type a message..."></textarea> | |
| <button id=send onclick=chat()>Send</button></div> | |
| <script> | |
| const chatDiv=document.getElementById('chat'),statusDiv=document.getElementById('status'), | |
| prompt=document.getElementById('prompt'),sendBtn=document.getElementById('send'); | |
| let messages=[]; | |
| function addMsg(text,role){ | |
| const d=document.createElement('div');d.className='msg '+role;d.textContent=text; | |
| chatDiv.appendChild(d);chatDiv.scrollTop=chatDiv.scrollHeight} | |
| async function chat(){ | |
| const p=prompt.value.trim();if(!p)return;addMsg(p,'user');messages.push({role:'user',content:p}); | |
| prompt.value='';sendBtn.disabled=prompt.disabled=true;statusDiv.textContent='Thinking...'; | |
| try{ | |
| const r=await fetch('/v1/chat/completions',{method:'POST', | |
| headers:{'Content-Type':'application/json'}, | |
| body:JSON.stringify({model:'ollama/hf.co/bartowski/DeepSeek-R1-Distill-Qwen-14B-GGUF:IQ3_XS', | |
| messages:messages,max_tokens:4096,temperature:0.7})}); | |
| if(!r.ok)throw new Error(await r.text()); | |
| const j=await r.json();const reply=j.choices[0].message.content; | |
| addMsg(reply,'ai');messages.push({role:'assistant',content:reply});statusDiv.textContent='Ready'; | |
| }catch(e){addMsg('Error: '+e.message,'ai');statusDiv.textContent='Error'}finally{ | |
| sendBtn.disabled=prompt.disabled=false;prompt.focus()}} | |
| prompt.addEventListener('keydown',e=>{if(e.key==='Enter'&&!e.shiftKey){e.preventDefault();chat()}}) | |
| prompt.focus() | |
| </script></body></html>""" | |
| class H(http.server.BaseHTTPRequestHandler): | |
| def do_GET(self): | |
| if self.path == '/': | |
| self.send_response(200) | |
| self.send_header('Content-Type', 'text/html; charset=utf-8') | |
| self.end_headers() | |
| self.wfile.write(CHAT_PAGE) | |
| elif self.path == '/health': | |
| self.send_response(200) | |
| self.send_header('Content-Type', 'application/json') | |
| self.end_headers() | |
| self.wfile.write(b'{"status":"ok"}') | |
| else: | |
| self.send_response(200) | |
| self.send_header('Content-Type', 'text/html; charset=utf-8') | |
| self.end_headers() | |
| self.wfile.write(CHAT_PAGE) | |
| def do_POST(self): | |
| self.send_response(200) | |
| self.end_headers() | |
| self.wfile.write(b'OK') | |
| def log_message(self, *a): pass | |
| http.server.HTTPServer(('0.0.0.0', 8080), H).serve_forever() | |