| <!DOCTYPE html>
|
| <html lang="en">
|
| <head>
|
| <meta charset="UTF-8">
|
| <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| <title>Hyze Code</title>
|
| <link rel="icon" type="image/png" href="https://i.imgur.com/f5QyYpV.png">
|
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
|
| <script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"></script>
|
| <script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js"></script>
|
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
|
| <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
| <link href="https://fonts.googleapis.com/css2?family=VT323&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
| <style>
|
| :root {
|
| --bg-primary: #151A28;
|
| --bg-secondary: #1e2535;
|
| --bg-tertiary: #252d3f;
|
| --accent-primary: #1C4297;
|
| --accent-secondary: #2d5bc4;
|
| --accent-dim: #0f2a5c;
|
| --text-primary: #e0f0ff;
|
| --text-secondary: #8aa8c2;
|
| --text-muted: #4a6075;
|
| --border-color: #1C4297;
|
| --border-dim: #0f2a5c;
|
| --error: #ff3366;
|
| --success: #00ff88;
|
| --warning: #ffcc00;
|
| }
|
|
|
| * {
|
| margin: 0;
|
| padding: 0;
|
| box-sizing: border-box;
|
| image-rendering: pixelated;
|
| image-rendering: -moz-crisp-edges;
|
| image-rendering: crisp-edges;
|
| }
|
|
|
| body {
|
| font-family: 'VT323', monospace;
|
| background: var(--bg-primary);
|
| color: var(--text-primary);
|
| height: 100vh;
|
| overflow: hidden;
|
| font-size: 18px;
|
| line-height: 1.4;
|
| }
|
|
|
|
|
| body::before {
|
| content: "";
|
| position: fixed;
|
| top: 0;
|
| left: 0;
|
| width: 100%;
|
| height: 100%;
|
| background: repeating-linear-gradient(
|
| 0deg,
|
| rgba(0, 0, 0, 0.15),
|
| rgba(0, 0, 0, 0.15) 1px,
|
| transparent 1px,
|
| transparent 2px
|
| );
|
| pointer-events: none;
|
| z-index: 9999;
|
| opacity: 0.3;
|
| }
|
|
|
|
|
| body::after {
|
| content: "";
|
| position: fixed;
|
| top: 0;
|
| left: 0;
|
| width: 100%;
|
| height: 100%;
|
| background: radial-gradient(circle at center, rgba(28, 66, 151, 0.05) 0%, transparent 70%);
|
| pointer-events: none;
|
| z-index: 9998;
|
| }
|
|
|
| .terminal-container {
|
| display: flex;
|
| flex-direction: column;
|
| height: 100vh;
|
| padding: 20px;
|
| gap: 10px;
|
| }
|
|
|
|
|
| .terminal-header {
|
| border: 2px solid var(--border-color);
|
| background: var(--bg-secondary);
|
| padding: 15px 20px;
|
| display: flex;
|
| align-items: center;
|
| justify-content: space-between;
|
| box-shadow: 0 0 20px rgba(28, 66, 151, 0.3);
|
| }
|
|
|
| .logo-section {
|
| display: flex;
|
| align-items: center;
|
| gap: 15px;
|
| cursor: pointer;
|
| }
|
|
|
| .logo-ascii {
|
| color: var(--accent-primary);
|
| font-size: 10px;
|
| line-height: 1;
|
| white-space: pre;
|
| font-family: 'JetBrains Mono', monospace;
|
| text-shadow: 0 0 10px rgba(28, 66, 151, 0.5);
|
| }
|
|
|
| .header-status {
|
| display: flex;
|
| align-items: center;
|
| gap: 10px;
|
| color: var(--text-secondary);
|
| font-size: 16px;
|
| }
|
|
|
| .status-dot {
|
| width: 12px;
|
| height: 12px;
|
| background: var(--success);
|
| box-shadow: 0 0 10px var(--success);
|
| animation: blink 1s infinite;
|
| }
|
|
|
| @keyframes blink {
|
| 0%, 50% { opacity: 1; }
|
| 51%, 100% { opacity: 0.3; }
|
| }
|
|
|
|
|
| .terminal-main {
|
| flex: 1;
|
| border: 2px solid var(--border-color);
|
| background: var(--bg-primary);
|
| overflow: hidden;
|
| display: flex;
|
| flex-direction: column;
|
| position: relative;
|
| box-shadow: inset 0 0 30px rgba(28, 66, 151, 0.05);
|
| }
|
|
|
| .terminal-messages {
|
| flex: 1;
|
| overflow-y: auto;
|
| padding: 20px;
|
| display: flex;
|
| flex-direction: column;
|
| gap: 15px;
|
| }
|
|
|
|
|
| .terminal-messages::-webkit-scrollbar {
|
| width: 12px;
|
| }
|
|
|
| .terminal-messages::-webkit-scrollbar-track {
|
| background: var(--bg-secondary);
|
| border-left: 2px solid var(--border-dim);
|
| }
|
|
|
| .terminal-messages::-webkit-scrollbar-thumb {
|
| background: var(--accent-dim);
|
| border: 2px solid var(--bg-secondary);
|
| }
|
|
|
| .terminal-messages::-webkit-scrollbar-thumb:hover {
|
| background: var(--accent-primary);
|
| }
|
|
|
|
|
| .welcome-screen {
|
| display: flex;
|
| flex-direction: column;
|
| align-items: flex-start;
|
| justify-content: flex-start;
|
| height: 100%;
|
| text-align: left;
|
| gap: 20px;
|
| padding: 20px;
|
| animation: flicker 4s infinite;
|
| }
|
|
|
| @keyframes flicker {
|
| 0%, 100% { opacity: 1; }
|
| 50% { opacity: 0.95; }
|
| 52% { opacity: 0.8; }
|
| 54% { opacity: 0.95; }
|
| }
|
|
|
| .welcome-ascii {
|
| color: var(--accent-primary);
|
| font-size: 12px;
|
| line-height: 1.1;
|
| white-space: pre;
|
| text-shadow: 0 0 20px rgba(28, 66, 151, 0.5);
|
| font-family: 'JetBrains Mono', monospace;
|
| letter-spacing: 0;
|
| }
|
|
|
| .welcome-text {
|
| color: var(--text-secondary);
|
| font-size: 20px;
|
| max-width: 600px;
|
| }
|
|
|
| .command-hints {
|
| display: flex;
|
| flex-wrap: wrap;
|
| gap: 10px;
|
| justify-content: flex-start;
|
| margin-top: 20px;
|
| }
|
|
|
| .cmd-hint {
|
| border: 1px solid var(--border-dim);
|
| padding: 8px 16px;
|
| cursor: pointer;
|
| transition: all 0.2s;
|
| color: var(--text-secondary);
|
| font-size: 16px;
|
| }
|
|
|
| .cmd-hint:hover {
|
| border-color: var(--accent-primary);
|
| color: var(--accent-primary);
|
| background: rgba(28, 66, 151, 0.1);
|
| box-shadow: 0 0 15px rgba(28, 66, 151, 0.3);
|
| }
|
|
|
|
|
| .message {
|
| display: flex;
|
| flex-direction: column;
|
| gap: 5px;
|
| animation: typeIn 0.3s ease;
|
| align-items: flex-start;
|
| }
|
|
|
| @keyframes typeIn {
|
| from { opacity: 0; transform: translateX(-10px); }
|
| to { opacity: 1; transform: translateX(0); }
|
| }
|
|
|
| .message-header {
|
| display: flex;
|
| align-items: center;
|
| gap: 10px;
|
| color: var(--accent-primary);
|
| font-size: 16px;
|
| }
|
|
|
| .message.user .message-header {
|
| color: var(--success);
|
| }
|
|
|
| .message-timestamp {
|
| color: var(--text-muted);
|
| font-size: 14px;
|
| }
|
|
|
| .message-content {
|
| padding-left: 20px;
|
| color: var(--text-primary);
|
| line-height: 1.5;
|
| white-space: pre-wrap;
|
| text-align: left;
|
| width: 100%;
|
| }
|
|
|
| .message-content code {
|
| background: var(--bg-tertiary);
|
| color: var(--accent-primary);
|
| padding: 2px 6px;
|
| border: 1px solid var(--border-dim);
|
| font-family: 'JetBrains Mono', monospace;
|
| font-size: 14px;
|
| }
|
|
|
| .message-content pre {
|
| background: var(--bg-secondary);
|
| border: 1px solid var(--border-dim);
|
| padding: 15px;
|
| margin: 10px 0;
|
| overflow-x: auto;
|
| position: relative;
|
| width: 100%;
|
| }
|
|
|
| .message-content pre code {
|
| background: transparent;
|
| border: none;
|
| padding: 0;
|
| color: var(--text-primary);
|
| }
|
|
|
|
|
| .code-block-container {
|
| border: 2px solid var(--border-dim);
|
| margin: 15px 0;
|
| background: var(--bg-secondary);
|
| width: 100%;
|
| }
|
|
|
| .code-block-header {
|
| background: var(--bg-tertiary);
|
| padding: 10px 15px;
|
| display: flex;
|
| justify-content: space-between;
|
| align-items: center;
|
| border-bottom: 1px solid var(--border-dim);
|
| }
|
|
|
| .code-lang {
|
| color: var(--accent-primary);
|
| font-size: 16px;
|
| text-transform: uppercase;
|
| letter-spacing: 1px;
|
| }
|
|
|
| .copy-btn {
|
| background: transparent;
|
| border: 1px solid var(--accent-primary);
|
| color: var(--accent-primary);
|
| padding: 5px 15px;
|
| font-family: 'VT323', monospace;
|
| font-size: 16px;
|
| cursor: pointer;
|
| transition: all 0.2s;
|
| text-transform: uppercase;
|
| }
|
|
|
| .copy-btn:hover {
|
| background: var(--accent-primary);
|
| color: var(--bg-primary);
|
| box-shadow: 0 0 15px rgba(28, 66, 151, 0.5);
|
| }
|
|
|
| .copy-btn.copied {
|
| background: var(--success);
|
| border-color: var(--success);
|
| color: var(--bg-primary);
|
| }
|
|
|
|
|
| .help-menu {
|
| border: 2px solid var(--accent-primary);
|
| background: var(--bg-secondary);
|
| padding: 20px;
|
| margin: 10px 0;
|
| max-width: 500px;
|
| }
|
|
|
| .help-title {
|
| color: var(--accent-primary);
|
| font-size: 24px;
|
| margin-bottom: 15px;
|
| text-align: left;
|
| border-bottom: 1px solid var(--border-dim);
|
| padding-bottom: 10px;
|
| }
|
|
|
| .help-item {
|
| display: flex;
|
| gap: 20px;
|
| margin: 10px 0;
|
| font-size: 16px;
|
| }
|
|
|
| .help-cmd {
|
| color: var(--success);
|
| min-width: 100px;
|
| font-family: 'JetBrains Mono', monospace;
|
| }
|
|
|
| .help-desc {
|
| color: var(--text-secondary);
|
| }
|
|
|
|
|
| .terminal-input-area {
|
| border-top: 2px solid var(--border-color);
|
| background: var(--bg-secondary);
|
| padding: 15px 20px;
|
| }
|
|
|
| .input-wrapper {
|
| display: flex;
|
| align-items: flex-end;
|
| gap: 10px;
|
| max-width: 100%;
|
| }
|
|
|
| .input-prompt {
|
| color: var(--accent-primary);
|
| font-size: 20px;
|
| white-space: nowrap;
|
| text-shadow: 0 0 10px rgba(28, 66, 151, 0.5);
|
| }
|
|
|
| .terminal-input {
|
| flex: 1;
|
| background: transparent;
|
| border: none;
|
| color: var(--text-primary);
|
| font-family: 'VT323', monospace;
|
| font-size: 20px;
|
| outline: none;
|
| resize: none;
|
| min-height: 30px;
|
| max-height: 150px;
|
| line-height: 1.4;
|
| }
|
|
|
| .terminal-input::placeholder {
|
| color: var(--text-muted);
|
| }
|
|
|
| .send-btn {
|
| background: transparent;
|
| border: 2px solid var(--accent-primary);
|
| color: var(--accent-primary);
|
| width: 40px;
|
| height: 40px;
|
| display: flex;
|
| align-items: center;
|
| justify-content: center;
|
| cursor: pointer;
|
| font-size: 20px;
|
| transition: all 0.2s;
|
| }
|
|
|
| .send-btn:hover:not(:disabled) {
|
| background: var(--accent-primary);
|
| color: var(--bg-primary);
|
| box-shadow: 0 0 20px rgba(28, 66, 151, 0.5);
|
| }
|
|
|
| .send-btn:disabled {
|
| opacity: 0.3;
|
| cursor: not-allowed;
|
| border-color: var(--text-muted);
|
| color: var(--text-muted);
|
| }
|
|
|
| .input-footer {
|
| text-align: left;
|
| margin-top: 10px;
|
| color: var(--accent-primary);
|
| font-size: 14px;
|
| letter-spacing: 1px;
|
| font-family: 'JetBrains Mono', monospace;
|
| }
|
|
|
|
|
| .typing-indicator {
|
| display: flex;
|
| align-items: center;
|
| gap: 10px;
|
| color: var(--accent-primary);
|
| padding: 10px 0;
|
| }
|
|
|
| .typing-text {
|
| animation: pulse 1.5s infinite;
|
| }
|
|
|
| @keyframes pulse {
|
| 0%, 100% { opacity: 0.4; }
|
| 50% { opacity: 1; }
|
| }
|
|
|
|
|
| .cursor {
|
| display: inline-block;
|
| width: 10px;
|
| height: 20px;
|
| background: var(--accent-primary);
|
| animation: cursorBlink 1s infinite;
|
| vertical-align: middle;
|
| margin-left: 2px;
|
| }
|
|
|
| @keyframes cursorBlink {
|
| 0%, 50% { opacity: 1; }
|
| 51%, 100% { opacity: 0; }
|
| }
|
|
|
|
|
| @media (max-width: 768px) {
|
| body {
|
| font-size: 16px;
|
| }
|
|
|
| .logo-ascii {
|
| font-size: 8px;
|
| }
|
|
|
| .welcome-ascii {
|
| font-size: 8px;
|
| }
|
|
|
| .terminal-container {
|
| padding: 10px;
|
| }
|
| }
|
|
|
|
|
| ::selection {
|
| background: var(--accent-primary);
|
| color: var(--bg-primary);
|
| }
|
|
|
|
|
| pre::-webkit-scrollbar {
|
| height: 10px;
|
| }
|
|
|
| pre::-webkit-scrollbar-track {
|
| background: var(--bg-tertiary);
|
| }
|
|
|
| pre::-webkit-scrollbar-thumb {
|
| background: var(--accent-dim);
|
| }
|
|
|
| pre::-webkit-scrollbar-thumb:hover {
|
| background: var(--accent-primary);
|
| }
|
| </style>
|
| </head>
|
| <body>
|
| <div class="terminal-container">
|
| <header class="terminal-header">
|
| <div class="logo-section" title="Double-click to reset">
|
| <img src="https://i.imgur.com/f5QyYpV.png" alt="Hyze Code" class="logo-img">
|
| </div>
|
| <div class="header-status">
|
| <span>SYSTEM:</span>
|
| <div class="status-dot"></div>
|
| <span>ONLINE</span>
|
| </div>
|
| </header>
|
|
|
| <main class="terminal-main">
|
| <div class="terminal-messages" id="messagesContainer">
|
| <div class="welcome-screen" id="welcomeScreen">
|
| <div class="welcome-ascii">
|
| ██╗ ██╗██╗ ██╗███████╗███████╗ ██████╗ ██████╗ ██████╗ ███████╗
|
| ██║ ██║╚██╗ ██╔╝╚══███╔╝██╔════╝ ██╔════╝██╔═══██╗██╔══██╗██╔════╝
|
| ███████║ ╚████╔╝ ███╔╝ █████╗ ██║ ██║ ██║██║ ██║█████╗
|
| ██╔══██║ ╚██╔╝ ███╔╝ ██╔══╝ ██║ ██║ ██║██║ ██║██╔══╝
|
| ██║ ██║ ██║ ███████╗███████╗ ╚██████╗╚██████╔╝██████╔╝███████╗
|
| ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝
|
| </div>
|
| <div class="welcome-text">
|
| > Welcome to Hyze Code!<br>
|
| > Powered by Hyze H1 and Kimi K2<br>
|
| > TYPE /help FOR COMMANDS<br>
|
| > TYPE /clear for clearing HISTORY
|
| </div>
|
| <div class="command-hints">
|
| <div class="cmd-hint" onclick="sendSuggestion('Create HTML/CSS layout')">> CREATE_LAYOUT</div>
|
| <div class="cmd-hint" onclick="sendSuggestion('Debug JavaScript code')">> DEBUG_JS</div>
|
| <div class="cmd-hint" onclick="sendSuggestion('Explain Python functions')">> EXPLAIN_PY</div>
|
| <div class="cmd-hint" onclick="sendSuggestion('Optimize SQL query')">> OPTIMIZE_SQL</div>
|
| </div>
|
| </div>
|
| </div>
|
| </main>
|
|
|
| <div class="terminal-input-area">
|
| <div class="input-wrapper">
|
| <span class="input-prompt">></span>
|
| <textarea class="terminal-input" id="messageInput" placeholder="Enter command..." rows="1" onkeydown="handleKeyDown(event)" oninput="autoResize(this)"></textarea>
|
| <button class="send-btn" id="sendBtn" onclick="sendMessage()">➤</button>
|
| </div>
|
| <div class="input-footer">[ HYZE CODE v2.0 | SECURE CONNECTION ]</div>
|
| </div>
|
| </div>
|
|
|
| <script>
|
|
|
| const API_KEY = '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';
|
| const MODEL = 'moonshotai/kimi-k2-instruct-0905';
|
| const API_URL = 'https://api.groq.com/openai/v1/chat/completions';
|
|
|
|
|
| let messages = [];
|
| let isGenerating = false;
|
| let codeBlockCounter = 0;
|
|
|
|
|
| document.addEventListener('DOMContentLoaded', () => {
|
| loadChatHistory();
|
| document.getElementById('messageInput').focus();
|
| });
|
|
|
|
|
| function autoResize(textarea) {
|
| textarea.style.height = 'auto';
|
| textarea.style.height = Math.min(textarea.scrollHeight, 150) + 'px';
|
| }
|
|
|
| function handleKeyDown(e) {
|
| if (e.key === 'Enter' && !e.shiftKey) {
|
| e.preventDefault();
|
| sendMessage();
|
| }
|
| }
|
|
|
| function sendSuggestion(text) {
|
| document.getElementById('messageInput').value = text;
|
| autoResize(document.getElementById('messageInput'));
|
| sendMessage();
|
| }
|
|
|
| function getTimestamp() {
|
| const now = new Date();
|
| return now.toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit' });
|
| }
|
|
|
| function scrollToBottom() {
|
| const container = document.getElementById('messagesContainer');
|
| container.scrollTop = container.scrollHeight;
|
| }
|
|
|
|
|
| function showHelp() {
|
| const container = document.getElementById('messagesContainer');
|
| const helpDiv = document.createElement('div');
|
| helpDiv.className = 'message system';
|
| helpDiv.innerHTML = `
|
| <div class="message-header" style="color: var(--warning)">
|
| <span>SYSTEM</span>
|
| <span class="message-timestamp">[${getTimestamp()}]</span>
|
| </div>
|
| <div class="message-content">
|
| <div class="help-menu">
|
| <div class="help-title">=== HYZE CODE COMMANDS ===</div>
|
| <div class="help-item">
|
| <span class="help-cmd">/clear</span>
|
| <span class="help-desc">Clear all chat history and reset terminal</span>
|
| </div>
|
| <div class="help-item">
|
| <span class="help-cmd">/help</span>
|
| <span class="help-desc">Display this help menu</span>
|
| </div>
|
| <div class="help-item">
|
| <span class="help-cmd">[message]</span>
|
| <span class="help-desc">Send message to AI assistant</span>
|
| </div>
|
| <div style="margin-top: 15px; padding-top: 10px; border-top: 1px solid var(--border-dim); color: var(--text-muted); text-align: left;">
|
| Double-click logo to force reset
|
| </div>
|
| </div>
|
| </div>
|
| `;
|
| container.appendChild(helpDiv);
|
| scrollToBottom();
|
| }
|
|
|
| function clearChat() {
|
| messages = [];
|
| codeBlockCounter = 0;
|
| localStorage.removeItem('hyze_code_chats');
|
|
|
| const container = document.getElementById('messagesContainer');
|
| container.innerHTML = `
|
| <div class="welcome-screen" id="welcomeScreen">
|
| <div class="welcome-ascii">
|
| ██╗ ██╗██╗ ██╗███████╗███████╗ ██████╗ ██████╗ ██████╗ ███████╗
|
| ██║ ██║╚██╗ ██╔╝╚══███╔╝██╔════╝ ██╔════╝██╔═══██╗██╔══██╗██╔════╝
|
| ███████║ ╚████╔╝ ███╔╝ █████╗ ██║ ██║ ██║██║ ██║█████╗
|
| ██╔══██║ ╚██╔╝ ███╔╝ ██╔══╝ ██║ ██║ ██║██║ ██║██╔══╝
|
| ██║ ██║ ██║ ███████╗███████╗ ╚██████╗╚██████╔╝██████╔╝███████╗
|
| ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝
|
| </div>
|
| <div class="welcome-text">
|
| > TERMINAL INTERFACE INITIALIZED...<br>
|
| > CONNECTED TO NEURAL NETWORK<br>
|
| > TYPE /help FOR COMMANDS<br>
|
| > READY FOR INPUT_
|
| </div>
|
| <div class="command-hints">
|
| <div class="cmd-hint" onclick="sendSuggestion('Create HTML/CSS layout')">> CREATE_LAYOUT</div>
|
| <div class="cmd-hint" onclick="sendSuggestion('Debug JavaScript code')">> DEBUG_JS</div>
|
| <div class="cmd-hint" onclick="sendSuggestion('Explain Python functions')">> EXPLAIN_PY</div>
|
| <div class="cmd-hint" onclick="sendSuggestion('Optimize SQL query')">> OPTIMIZE_SQL</div>
|
| </div>
|
| </div>
|
| `;
|
|
|
|
|
| const confirmDiv = document.createElement('div');
|
| confirmDiv.className = 'message system';
|
| confirmDiv.innerHTML = `
|
| <div class="message-header" style="color: var(--success)">
|
| <span>SYSTEM</span>
|
| <span class="message-timestamp">[${getTimestamp()}]</span>
|
| </div>
|
| <div class="message-content">> TERMINAL CLEARED. HISTORY RESET.</div>
|
| `;
|
| container.appendChild(confirmDiv);
|
| scrollToBottom();
|
| }
|
|
|
|
|
| async function sendMessage() {
|
| const input = document.getElementById('messageInput');
|
| const text = input.value.trim();
|
|
|
| if (!text || isGenerating) return;
|
|
|
|
|
| if (text.toLowerCase() === '/clear') {
|
| clearChat();
|
| input.value = '';
|
| input.style.height = 'auto';
|
| return;
|
| }
|
|
|
| if (text.toLowerCase() === '/help') {
|
| showHelp();
|
| input.value = '';
|
| input.style.height = 'auto';
|
| return;
|
| }
|
|
|
| document.getElementById('welcomeScreen').style.display = 'none';
|
|
|
| const timestamp = getTimestamp();
|
| addMessage('user', text, timestamp);
|
| messages.push({ role: 'user', content: text });
|
|
|
| input.value = '';
|
| input.style.height = 'auto';
|
| showTypingIndicator();
|
|
|
| try {
|
| isGenerating = true;
|
| document.getElementById('sendBtn').disabled = true;
|
|
|
| const response = await fetch(API_URL, {
|
| method: 'POST',
|
| headers: {
|
| 'Authorization': `Bearer ${API_KEY}`,
|
| 'Content-Type': 'application/json'
|
| },
|
| body: JSON.stringify({
|
| model: MODEL,
|
| messages: [
|
| {
|
| role: 'system',
|
| content: 'You are Hyze Code, a terminal-style AI coding assistant. Provide concise, technical responses. Use code blocks with language specification.'
|
| },
|
| ...messages
|
| ],
|
| temperature: 0.6,
|
| max_tokens: 3000,
|
| stream: true
|
| })
|
| });
|
|
|
| if (!response.ok) throw new Error(`API Error: ${response.status}`);
|
|
|
| removeTypingIndicator();
|
|
|
| const messageDiv = document.createElement('div');
|
| messageDiv.className = 'message assistant';
|
| const msgTimestamp = getTimestamp();
|
| messageDiv.innerHTML = `
|
| <div class="message-header">
|
| <span>HYZE_AI</span>
|
| <span class="message-timestamp">[${msgTimestamp}]</span>
|
| </div>
|
| <div class="message-content" id="streamingContent"></div>
|
| `;
|
| document.getElementById('messagesContainer').appendChild(messageDiv);
|
|
|
| const contentDiv = messageDiv.querySelector('#streamingContent');
|
| const reader = response.body.getReader();
|
| const decoder = new TextDecoder();
|
| let fullContent = '';
|
|
|
| while (true) {
|
| const { done, value } = await reader.read();
|
| if (done) break;
|
|
|
| const chunk = decoder.decode(value);
|
| const lines = chunk.split('\n');
|
|
|
| for (const line of lines) {
|
| if (line.startsWith('data: ')) {
|
| const data = line.slice(6);
|
| if (data === '[DONE]') continue;
|
| try {
|
| const parsed = JSON.parse(data);
|
| const content = parsed.choices?.[0]?.delta?.content || '';
|
| if (content) {
|
| fullContent += content;
|
| contentDiv.innerHTML = formatMessage(fullContent);
|
| scrollToBottom();
|
| }
|
| } catch (e) {}
|
| }
|
| }
|
| }
|
|
|
|
|
| contentDiv.innerHTML = formatMessage(fullContent);
|
|
|
|
|
| contentDiv.querySelectorAll('pre code').forEach((block) => {
|
| hljs.highlightElement(block);
|
| });
|
|
|
|
|
| addCopyButtons(contentDiv);
|
|
|
| messages.push({ role: 'assistant', content: fullContent });
|
| saveChatHistory();
|
|
|
| } catch (error) {
|
| removeTypingIndicator();
|
| addMessage('assistant', `ERROR: ${error.message}`, getTimestamp());
|
| } finally {
|
| isGenerating = false;
|
| document.getElementById('sendBtn').disabled = false;
|
| }
|
| }
|
|
|
| function addMessage(role, content, timestamp) {
|
| const container = document.getElementById('messagesContainer');
|
| const messageDiv = document.createElement('div');
|
| messageDiv.className = `message ${role}`;
|
|
|
| const sender = role === 'user' ? 'USER' : 'HYZE_AI';
|
| const color = role === 'user' ? 'var(--success)' : 'var(--accent-primary)';
|
|
|
| messageDiv.innerHTML = `
|
| <div class="message-header" style="color: ${color}">
|
| <span>${sender}</span>
|
| <span class="message-timestamp">[${timestamp}]</span>
|
| </div>
|
| <div class="message-content">${formatMessage(content)}</div>
|
| `;
|
|
|
| container.appendChild(messageDiv);
|
| scrollToBottom();
|
|
|
|
|
| messageDiv.querySelectorAll('pre code').forEach((block) => {
|
| hljs.highlightElement(block);
|
| });
|
| addCopyButtons(messageDiv);
|
| }
|
|
|
| function showTypingIndicator() {
|
| const container = document.getElementById('messagesContainer');
|
| const indicator = document.createElement('div');
|
| indicator.className = 'typing-indicator';
|
| indicator.id = 'typingIndicator';
|
| indicator.innerHTML = `
|
| <span>HYZE_AI</span>
|
| <span class="typing-text">PROCESSING</span>
|
| <span class="cursor"></span>
|
| `;
|
| container.appendChild(indicator);
|
| scrollToBottom();
|
| }
|
|
|
| function removeTypingIndicator() {
|
| const indicator = document.getElementById('typingIndicator');
|
| if (indicator) indicator.remove();
|
| }
|
|
|
|
|
| function formatMessage(text) {
|
| let safeText = text.replace(/</g, '<').replace(/>/g, '>');
|
|
|
|
|
| let codeBlocks = [];
|
| safeText = safeText.replace(/```(\w+)?\n([\s\S]*?)```/g, (match, lang, code) => {
|
| const id = codeBlockCounter++;
|
| const language = lang || 'text';
|
| codeBlocks.push({id, lang: language, code: code});
|
| return `<!--CODEBLOCK_${id}-->`;
|
| });
|
|
|
|
|
| safeText = safeText.replace(/`([^`]+)`/g, '<code>$1</code>');
|
|
|
|
|
| safeText = safeText.replace(/\*\*(.*?)\*\*/g, '<strong style="color: var(--accent-primary)">$1</strong>');
|
|
|
|
|
| safeText = safeText.replace(/\*(.*?)\*/g, '<em>$1</em>');
|
|
|
|
|
| safeText = safeText.replace(/^\s*-\s+(.*$)/gim, ' ▸ $1');
|
| safeText = safeText.replace(/^\s*\d+\.\s+(.*$)/gim, ' $1');
|
|
|
|
|
| safeText = safeText.replace(/\n/g, '<br>');
|
|
|
|
|
| safeText = safeText.replace(/<!--CODEBLOCK_(\d+)-->/g, (match, id) => {
|
| const block = codeBlocks.find(b => b.id == id);
|
| if (!block) return match;
|
|
|
| return `
|
| <div class="code-block-container" id="code-block-${block.id}">
|
| <div class="code-block-header">
|
| <span class="code-lang">${block.lang.toUpperCase()}</span>
|
| <button class="copy-btn" onclick="copyCode('${block.id}')">COPY</button>
|
| </div>
|
| <pre><code class="language-${block.lang}">${block.code.replace(/</g, '<')}</code></pre>
|
| </div>
|
| `;
|
| });
|
|
|
| return safeText;
|
| }
|
|
|
| function addCopyButtons(container) {
|
|
|
| }
|
|
|
| function copyCode(blockId) {
|
| const block = document.querySelector(`#code-block-${blockId} code`);
|
| if (!block) return;
|
|
|
| const code = block.textContent;
|
| navigator.clipboard.writeText(code).then(() => {
|
| const btn = document.querySelector(`#code-block-${blockId} .copy-btn`);
|
| const originalText = btn.textContent;
|
| btn.textContent = 'COPIED!';
|
| btn.classList.add('copied');
|
|
|
| setTimeout(() => {
|
| btn.textContent = originalText;
|
| btn.classList.remove('copied');
|
| }, 2000);
|
| });
|
| }
|
|
|
|
|
| function saveChatHistory() {
|
| localStorage.setItem('hyze_code_chats', JSON.stringify(messages));
|
| }
|
|
|
| function loadChatHistory() {
|
| const saved = localStorage.getItem('hyze_code_chats');
|
| if (saved) {
|
| try {
|
| messages = JSON.parse(saved);
|
| if (messages.length > 0) {
|
| document.getElementById('welcomeScreen').style.display = 'none';
|
| messages.forEach(msg => {
|
| addMessage(msg.role, msg.content, getTimestamp());
|
| });
|
| }
|
| } catch(e) { console.error("Failed to load history", e); }
|
| }
|
| }
|
|
|
|
|
| document.querySelector('.logo-section').addEventListener('dblclick', () => {
|
| if (confirm('RESET TERMINAL?')) {
|
| clearChat();
|
| }
|
| });
|
| </script>
|
| </body>
|
| </html> |