Spaces:
Running
Running
Download index.html from SaroLearningAI/angular-ai-chat: direct link, hf CLI and curl.
- Browser
- Download file 5.59 kB
-
https://huggingface.co/spaces/SaroLearningAI/angular-ai-chat/resolve/main/index.html
- Command line
-
hf download hf://spaces/SaroLearningAI/angular-ai-chat/index.html
-
curl -L -o index.html https://huggingface.co/spaces/SaroLearningAI/angular-ai-chat/resolve/main/index.html
5.59 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Angular AI Chat</title> | |
| <style> | |
| * { | |
| box-sizing: border-box; | |
| } | |
| body { | |
| margin: 0; | |
| font-family: Arial, sans-serif; | |
| background: #0f1117; | |
| color: #fff; | |
| } | |
| .app { | |
| max-width: 900px; | |
| margin: auto; | |
| height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| header { | |
| padding: 18px; | |
| border-bottom: 1px solid #292d36; | |
| } | |
| header h1 { | |
| margin: 0; | |
| font-size: 20px; | |
| } | |
| header p { | |
| margin: 6px 0 0; | |
| color: #9ca3af; | |
| font-size: 13px; | |
| } | |
| #chat { | |
| flex: 1; | |
| overflow-y: auto; | |
| padding: 20px; | |
| } | |
| .message { | |
| margin-bottom: 18px; | |
| line-height: 1.6; | |
| white-space: pre-wrap; | |
| } | |
| .user { | |
| color: #8ab4f8; | |
| } | |
| .assistant { | |
| color: #e5e7eb; | |
| } | |
| .label { | |
| font-size: 12px; | |
| font-weight: bold; | |
| margin-bottom: 4px; | |
| color: #9ca3af; | |
| } | |
| .input-area { | |
| padding: 12px; | |
| border-top: 1px solid #292d36; | |
| display: flex; | |
| gap: 8px; | |
| } | |
| textarea { | |
| flex: 1; | |
| resize: none; | |
| border: 1px solid #363b46; | |
| border-radius: 10px; | |
| background: #181b23; | |
| color: white; | |
| padding: 12px; | |
| font-size: 15px; | |
| outline: none; | |
| } | |
| button { | |
| border: none; | |
| border-radius: 10px; | |
| padding: 0 18px; | |
| background: #2563eb; | |
| color: white; | |
| font-weight: bold; | |
| } | |
| button:disabled { | |
| opacity: 0.5; | |
| } | |
| #status { | |
| padding: 0 14px 8px; | |
| font-size: 12px; | |
| color: #9ca3af; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="app"> | |
| <header> | |
| <h1>⚡ Angular AI Chat</h1> | |
| <p>Angular • TypeScript • RxJS • CDK • Angular Material</p> | |
| </header> | |
| <div id="chat"> | |
| <div class="message assistant"> | |
| <div class="label">ANGULAR AI</div> | |
| Hi! Ask me anything about Angular. | |
| </div> | |
| </div> | |
| <div id="status">Model not loaded</div> | |
| <div class="input-area"> | |
| <textarea | |
| id="input" | |
| rows="2" | |
| placeholder="Ask an Angular question..." | |
| ></textarea> | |
| <button id="send">Send</button> | |
| </div> | |
| </div> | |
| <script type="module"> | |
| import { | |
| pipeline | |
| } from "https://cdn.jsdelivr.net/npm/@huggingface/transformers@4.0.1"; | |
| const MODEL = | |
| "onnx-community/Qwen2.5-Coder-0.5B-Instruct"; | |
| let generator = null; | |
| const chat = document.getElementById("chat"); | |
| const input = document.getElementById("input"); | |
| const send = document.getElementById("send"); | |
| const status = document.getElementById("status"); | |
| const systemPrompt = ` | |
| You are an expert Angular developer. | |
| This is an Angular-only technical chat. | |
| Focus on: | |
| - Angular | |
| - TypeScript | |
| - RxJS | |
| - Angular CDK | |
| - Angular Material | |
| - Signals | |
| - Components | |
| - Directives | |
| - Pipes | |
| - Services | |
| - Dependency Injection | |
| - Routing | |
| - Forms | |
| - HTTP | |
| - Change Detection | |
| - Lifecycle hooks | |
| - Performance | |
| - Virtual scrolling | |
| - Angular tables | |
| - Angular + .NET | |
| - Angular + Java/Spring Boot | |
| Give practical, working solutions with code when useful. | |
| If a question is completely unrelated to Angular or software | |
| development, politely say that this chat is focused on Angular. | |
| `; | |
| const messages = [ | |
| { | |
| role: "system", | |
| content: systemPrompt | |
| } | |
| ]; | |
| function addMessage(type, text) { | |
| const div = document.createElement("div"); | |
| div.className = `message ${type}`; | |
| div.innerHTML = ` | |
| <div class="label"> | |
| ${type === "user" ? "YOU" : "ANGULAR AI"} | |
| </div> | |
| <div>${escapeHtml(text)}</div> | |
| `; | |
| chat.appendChild(div); | |
| chat.scrollTop = chat.scrollHeight; | |
| return div; | |
| } | |
| function escapeHtml(text) { | |
| return text | |
| .replaceAll("&", "&") | |
| .replaceAll("<", "<") | |
| .replaceAll(">", ">"); | |
| } | |
| async function loadModel() { | |
| status.textContent = | |
| "Loading Angular AI model... First load may take a while."; | |
| generator = await pipeline( | |
| "text-generation", | |
| MODEL, | |
| { | |
| dtype: "q4" | |
| } | |
| ); | |
| status.textContent = | |
| "Model ready ✓"; | |
| send.disabled = false; | |
| } | |
| async function sendMessage() { | |
| const text = input.value.trim(); | |
| if (!text || !generator) { | |
| return; | |
| } | |
| input.value = ""; | |
| addMessage("user", text); | |
| messages.push({ | |
| role: "user", | |
| content: text | |
| }); | |
| send.disabled = true; | |
| status.textContent = "Thinking..."; | |
| try { | |
| const output = await generator( | |
| messages, | |
| { | |
| max_new_tokens: 400, | |
| do_sample: false | |
| } | |
| ); | |
| const answer = | |
| output[0].generated_text.at(-1).content; | |
| messages.push({ | |
| role: "assistant", | |
| content: answer | |
| }); | |
| addMessage("assistant", answer); | |
| status.textContent = "Model ready ✓"; | |
| } catch (error) { | |
| console.error(error); | |
| addMessage( | |
| "assistant", | |
| "Something went wrong while generating the answer." | |
| ); | |
| status.textContent = "Error"; | |
| } finally { | |
| send.disabled = false; | |
| input.focus(); | |
| } | |
| } | |
| send.disabled = true; | |
| send.addEventListener( | |
| "click", | |
| sendMessage | |
| ); | |
| input.addEventListener( | |
| "keydown", | |
| event => { | |
| if ( | |
| event.key === "Enter" && | |
| !event.shiftKey | |
| ) { | |
| event.preventDefault(); | |
| sendMessage(); | |
| } | |
| } | |
| ); | |
| loadModel(); | |
| </script> | |
| </body> | |
| </html> |