yt-claw-v9 / health_server.py
Arshit Malik
fix: clean Dockerfile with /v1/ proxy, OpenAI-compatible API
f7d419b
Raw
History Blame
3.86 kB
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()