| | <!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/[email protected]/dist/katex.min.css">
|
| | <script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js"></script>
|
| | <script defer src="https://cdn.jsdelivr.net/npm/[email protected]/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> |