Download index.html from CVNSS/Botchat: direct link, hf CLI and curl.
- Browser
- Download file 4.18 kB
-
https://huggingface.co/spaces/CVNSS/Botchat/resolve/main/index.html
- Command line
-
hf download hf://spaces/CVNSS/Botchat/index.html
-
curl -L -o index.html https://huggingface.co/spaces/CVNSS/Botchat/resolve/main/index.html
4.18 kB
| <html lang="vi"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <title>Botchat CVNSS 4.0</title> | |
| <!-- Bộ chuyển CVNSS 4.0 --> | |
| <script src="cvnss4.0-converter.js"></script> | |
| <style> | |
| body{font-family:Arial,Helvetica,sans-serif;background:#f5f7fa;margin:30px auto;max-width:760px;color:#333} | |
| h2{text-align:center;color:#2c3e50;margin-bottom:20px} | |
| #chat{background:#fff;border:1px solid #dcdcdc;border-radius:8px;min-height:340px;max-height:540px; | |
| overflow-y:auto;padding:18px;margin-bottom:16px} | |
| .msg{margin-bottom:16px;line-height:1.45} | |
| .user b{color:#2980b9}.bot b{color:#27ae60} | |
| #bar{display:flex;gap:8px} | |
| textarea{flex:1;padding:10px 12px;font-size:15px;border:1px solid #ccc;border-radius:6px;resize:vertical;min-height:48px} | |
| button{padding:11px 22px;font-size:15px;border:none;border-radius:6px;cursor:pointer;background:#2c97de;color:#fff} | |
| button:hover{filter:brightness(1.1)}button:active{filter:brightness(.93)} | |
| .spinner{display:inline-block;width:16px;height:16px;border:3px solid #bbb;border-top-color:#2c97de;border-radius:50%; | |
| animation:spin 1s linear infinite;margin-left:6px;vertical-align:middle} | |
| @keyframes spin{to{transform:rotate(360deg)}} | |
| </style> | |
| </head> | |
| <body> | |
| <h2>💬 Botchat - 1 sản phẩm của CVNSS4.0</h2> | |
| <div id="chat"></div> | |
| <div id="bar"> | |
| <!-- textarea đa dòng; Shift+Enter xuống dòng --> | |
| <textarea id="input" placeholder="Nhập tin nhắn…"></textarea> | |
| <button id="send">Gửi</button> | |
| </div> | |
| <script> | |
| /* ========= CẤU HÌNH ========= */ | |
| const GROQ_KEY = "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"; // chỉ dùng nội bộ! | |
| const ENDPOINT = "https://api.groq.com/openai/v1/chat/completions"; | |
| const MODEL = "meta-llama/llama-4-scout-17b-16e-instruct"; | |
| /* ============================ */ | |
| const chat = document.getElementById("chat"); | |
| const input = document.getElementById("input"); | |
| const sendBt = document.getElementById("send"); | |
| const spin = '<span class="spinner"></span>'; | |
| const toCVN = txt => CVNSSConverter.convert(txt,"cqn").cvn; | |
| const scroll = () => chat.scrollTop = chat.scrollHeight; | |
| /* Thêm tin nhắn vào khung chat */ | |
| function add(role, html){ | |
| chat.insertAdjacentHTML("beforeend", | |
| `<div class="msg ${role}"><b>${role==='user'?'Bạn':'GPT'}:</b> ${html}</div>`); | |
| scroll(); | |
| } | |
| /* Gọi Groq API (retry tối đa 3 lần nếu 429/503) */ | |
| async function askGroq(prompt){ | |
| const body = JSON.stringify({ | |
| model: MODEL, | |
| messages: [{ role:"user", content: prompt }] | |
| }); | |
| for(let i=0;i<3;i++){ | |
| const res = await fetch(ENDPOINT,{ | |
| method:"POST", | |
| headers:{ | |
| "Content-Type":"application/json", | |
| "Authorization":`Bearer ${GROQ_KEY}` | |
| }, | |
| body | |
| }); | |
| if(res.ok){ | |
| const j = await res.json(); | |
| return j.choices[0].message.content.trim(); // thành công | |
| } | |
| if([429,503].includes(res.status)){ // hết quota / quá tải → đợi | |
| const wait = 1500*(i+1); // 1.5s,3s,4.5s | |
| console.warn(`Groq ${res.status} – đợi ${wait/1000}s rồi thử lại`); | |
| await new Promise(r=>setTimeout(r,wait)); | |
| continue; | |
| } | |
| throw new Error(`HTTP ${res.status} – ${await res.text()}`); | |
| } | |
| throw new Error("Groq quá tải – thử lại sau."); | |
| } | |
| /* Gửi tin nhắn */ | |
| async function send(){ | |
| const text = input.value.trim(); | |
| if(!text) return; | |
| input.value=""; add("user", text); add("bot", spin); | |
| const last = chat.lastElementChild; sendBt.disabled=true; | |
| try{ | |
| const raw = await askGroq(text); | |
| last.innerHTML = `<b>GPT:</b> ${toCVN(raw)}`; | |
| }catch(err){ | |
| last.innerHTML = `<b>GPT:</b> ⚠️ ${err.message}`; | |
| console.error(err); | |
| }finally{ | |
| sendBt.disabled=false; input.focus(); | |
| } | |
| } | |
| /* Sự kiện UI */ | |
| sendBt.onclick = send; | |
| input.addEventListener("keydown", e=>{ | |
| if(e.key==="Enter" && !e.shiftKey){ // Enter để gửi | |
| e.preventDefault(); send(); | |
| } | |
| }); | |
| input.focus(); | |
| /* Khuyến nghị chạy qua localhost khi mở file trực tiếp */ | |
| if(location.protocol==='file:'){ | |
| console.warn("Chạy: python -m http.server 8080 ➔ http://localhost:8080/"); | |
| } | |
| </script> | |
| </body> | |
| </html> | |