|
|
<!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> |