Pomilon commited on
Commit
19ecfb2
·
1 Parent(s): dc86d58

Add Aetheris inference and chat interface

Browse files
.gitattributes CHANGED
@@ -34,3 +34,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  static/assets/Aetheris_logo.png filter=lfs diff=lfs merge=lfs -text
 
 
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  static/assets/Aetheris_logo.png filter=lfs diff=lfs merge=lfs -text
37
+ *.png filter=lfs diff=lfs merge=lfs -text
chat.html ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Aetheris Dreamscape</title>
7
+ <link rel="stylesheet" href="static/css/main.css">
8
+ <link rel="stylesheet" href="static/css/aetheris.css">
9
+ <!-- Marked.js for Markdown parsing -->
10
+ <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
11
+ </head>
12
+ <body class="aetheris-theme">
13
+
14
+ <nav class="navbar">
15
+ <a href="index.html" class="nav-brand">
16
+ <span style="color: var(--color-text-muted);">&lt;/&gt;</span> POMILON_LABS
17
+ </a>
18
+ <div class="nav-menu">
19
+ <a href="index.html">HUB</a>
20
+ <a href="about.html">MANIFESTO</a>
21
+ <a href="https://github.com/Pomilon" target="_blank" class="icon-link">
22
+ <svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
23
+ </a>
24
+ </div>
25
+ </nav>
26
+
27
+ <main>
28
+ <div class="chat-wrapper">
29
+ <!-- Messages -->
30
+ <div class="message-list" id="chat-window">
31
+ <!-- Initial Message -->
32
+ <div class="message-row bot animate-slide-in">
33
+ <div class="avatar bot"></div>
34
+ <div class="bubble">
35
+ <em>The weave is listening...</em><br>
36
+ What shall we explore together in the latent space today?
37
+ </div>
38
+ </div>
39
+ </div>
40
+
41
+ <!-- Floating Input -->
42
+ <div class="input-area">
43
+ <div class="input-container">
44
+ <textarea id="user-input" rows="1" placeholder="Share a thought..."></textarea>
45
+ <button id="send-btn" class="btn-send">
46
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="19" x2="12" y2="5"></line><polyline points="5 12 12 5 19 12"></polyline></svg>
47
+ </button>
48
+ <button id="stop-btn" class="btn-send hidden" style="background: rgba(0,0,0,0.2); color: #fff;">
49
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><circle cx="12" cy="12" r="10"></circle><rect x="9" y="9" width="6" height="6" fill="#fff"></rect></svg>
50
+ </button>
51
+ </div>
52
+ </div>
53
+ </div>
54
+ </main>
55
+
56
+ <script src="static/js/chat.js"></script>
57
+ </body>
58
+ </html>
index.html CHANGED
@@ -48,6 +48,7 @@
48
  /* Aetheris Specifics */
49
  .split-aetheris {
50
  background: radial-gradient(circle at 50% 120%, #1a1020 0%, #000 100%);
 
51
  }
52
  .split-aetheris::before {
53
  content: ''; position: absolute; inset: 0;
@@ -251,7 +252,7 @@
251
  </div>
252
 
253
  <!-- Right: Aetheris -->
254
- <div class="split split-aetheris">
255
  <div class="split-content">
256
  <img src="static/assets/Aetheris_logo.png" alt="Aetheris" class="logo-img">
257
  <h2>Aetheris</h2>
@@ -260,7 +261,7 @@
260
  Sparse mixture-of-experts model designed for fluid creativity and abstract association.
261
  </div>
262
  </div>
263
- </div>
264
 
265
  <div class="scroll-hint">Scroll for Telemetry</div>
266
  </div>
 
48
  /* Aetheris Specifics */
49
  .split-aetheris {
50
  background: radial-gradient(circle at 50% 120%, #1a1020 0%, #000 100%);
51
+ cursor: pointer;
52
  }
53
  .split-aetheris::before {
54
  content: ''; position: absolute; inset: 0;
 
252
  </div>
253
 
254
  <!-- Right: Aetheris -->
255
+ <a href="chat.html" class="split split-aetheris" style="text-decoration: none;">
256
  <div class="split-content">
257
  <img src="static/assets/Aetheris_logo.png" alt="Aetheris" class="logo-img">
258
  <h2>Aetheris</h2>
 
261
  Sparse mixture-of-experts model designed for fluid creativity and abstract association.
262
  </div>
263
  </div>
264
+ </a>
265
 
266
  <div class="scroll-hint">Scroll for Telemetry</div>
267
  </div>
static/assets/CRSM_logo.png CHANGED

Git LFS Details

  • SHA256: 5488e6a9b3d741164c63f75fc660d3a587d888feefb4c141fc2c929db63e079d
  • Pointer size: 130 Bytes
  • Size of remote file: 24.6 kB
static/assets/pomilon_logo.png CHANGED

Git LFS Details

  • SHA256: 8fca55200e7f36d8d56ba91e43f65810d61f067b35f008ea9c4268f2f990f353
  • Pointer size: 130 Bytes
  • Size of remote file: 87.2 kB
static/css/aetheris.css ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* --- Aetheris: The Organic Mind --- */
2
+ /* Inspired by nature, glass, nebulas, and soft light. */
3
+
4
+ :root {
5
+ --eth-purple: #b19cd9;
6
+ --eth-light: #e6e6fa;
7
+ --eth-dark: #0f0a14;
8
+ --eth-glass: rgba(255, 255, 255, 0.05);
9
+ }
10
+
11
+ body.aetheris-theme {
12
+ background-color: var(--eth-dark);
13
+ /* Soft Nebula Gradient */
14
+ background-image:
15
+ radial-gradient(circle at 10% 20%, rgba(80, 50, 120, 0.15) 0%, transparent 40%),
16
+ radial-gradient(circle at 90% 80%, rgba(40, 80, 120, 0.15) 0%, transparent 40%);
17
+ font-family: var(--font-ui);
18
+ }
19
+
20
+ .aetheris-theme .navbar {
21
+ background: rgba(15, 10, 20, 0.6);
22
+ border-bottom: 1px solid rgba(255,255,255,0.05);
23
+ }
24
+
25
+ .chat-wrapper {
26
+ max-width: 800px; /* Narrower for intimacy */
27
+ margin: 0 auto;
28
+ padding-top: var(--nav-height);
29
+ height: 100vh;
30
+ display: flex;
31
+ flex-direction: column;
32
+ }
33
+
34
+ /* Messages */
35
+ .message-list {
36
+ flex: 1;
37
+ overflow-y: auto;
38
+ padding: 2rem 1rem;
39
+ }
40
+
41
+ .message-row {
42
+ display: flex;
43
+ gap: 1.5rem;
44
+ margin-bottom: 3rem;
45
+ align-items: flex-start;
46
+ }
47
+
48
+ .message-row.user { flex-direction: row-reverse; }
49
+
50
+ .avatar {
51
+ width: 42px;
52
+ height: 42px;
53
+ border-radius: 50%; /* Circles for organic feel */
54
+ background-size: cover;
55
+ background-position: center;
56
+ box-shadow: 0 4px 12px rgba(0,0,0,0.3);
57
+ flex-shrink: 0;
58
+ }
59
+
60
+ .avatar.bot { background-image: url('/static/assets/Aetheris_logo.png'); background-color: #fff; }
61
+ .avatar.user { background: linear-gradient(135deg, #444, #222); color: #fff; display: flex; align-items: center; justify-content: center;}
62
+
63
+ .bubble {
64
+ font-family: var(--font-ui);
65
+ line-height: 1.8;
66
+ font-size: 1rem;
67
+ color: #e0e0e0;
68
+ }
69
+
70
+ .message-row.user .bubble {
71
+ background: var(--eth-glass);
72
+ padding: 1rem 1.5rem;
73
+ border-radius: 18px 18px 4px 18px;
74
+ backdrop-filter: blur(10px);
75
+ border: 1px solid rgba(255,255,255,0.1);
76
+ }
77
+
78
+ .message-row.bot .bubble {
79
+ /* No bubble for bot, just text floating like thought */
80
+ padding-top: 0.5rem;
81
+ }
82
+
83
+ /* Input Area - Floating Capsule */
84
+ .input-area {
85
+ padding: 2rem;
86
+ display: flex;
87
+ justify-content: center;
88
+ }
89
+
90
+ .input-container {
91
+ width: 100%;
92
+ background: rgba(255, 255, 255, 0.03);
93
+ border: 1px solid rgba(255, 255, 255, 0.08);
94
+ border-radius: 32px;
95
+ padding: 0.8rem 1.5rem;
96
+ display: flex;
97
+ align-items: center;
98
+ backdrop-filter: blur(20px);
99
+ box-shadow: 0 8px 32px rgba(0,0,0,0.2);
100
+ transition: transform 0.2s, background 0.2s;
101
+ }
102
+
103
+ .input-container:focus-within {
104
+ transform: translateY(-2px);
105
+ background: rgba(255, 255, 255, 0.06);
106
+ border-color: rgba(255,255,255,0.15);
107
+ }
108
+
109
+ textarea {
110
+ width: 100%;
111
+ background: transparent;
112
+ border: none;
113
+ color: #fff;
114
+ font-size: 1rem;
115
+ padding: 0.2rem;
116
+ resize: none;
117
+ outline: none;
118
+ font-family: var(--font-ui);
119
+ }
120
+
121
+ textarea::placeholder { color: rgba(255,255,255,0.3); }
122
+
123
+ .btn-send {
124
+ background: var(--eth-light);
125
+ color: var(--eth-dark);
126
+ border: none;
127
+ width: 36px;
128
+ height: 36px;
129
+ border-radius: 50%;
130
+ cursor: pointer;
131
+ display: flex;
132
+ align-items: center;
133
+ justify-content: center;
134
+ margin-left: 0.5rem;
135
+ transition: transform 0.2s;
136
+ }
137
+
138
+ .btn-send:hover { transform: scale(1.1); }
139
+
140
+ /* Markdown Overrides */
141
+ .prose strong { color: var(--eth-purple); font-weight: 600; }
142
+ .prose em { font-family: var(--font-display); font-size: 1.05em; color: #fff; }
static/css/main.css ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* --- POMILON INTELLIGENCE DESIGN SYSTEM --- */
2
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&family=JetBrains+Mono:wght@400;500;700&family=Cinzel:wght@400;600&display=swap');
3
+
4
+ :root {
5
+ /* Base Token System */
6
+ --color-bg: #0a0a0a;
7
+ --color-surface: #121212;
8
+ --color-border: #2a2a2a;
9
+ --color-text-main: #ededed;
10
+ --color-text-muted: #888888;
11
+
12
+ --font-ui: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
13
+ --font-mono: 'JetBrains Mono', monospace;
14
+ --font-display: 'Cinzel', serif; /* For Aetheris */
15
+
16
+ --radius-sm: 4px;
17
+ --radius-md: 8px;
18
+ --radius-lg: 16px;
19
+
20
+ --nav-height: 64px;
21
+ --max-width: 1000px;
22
+ }
23
+
24
+ /* Reset & Base */
25
+ * { box-sizing: border-box; margin: 0; padding: 0; }
26
+
27
+ body {
28
+ background-color: var(--color-bg);
29
+ color: var(--color-text-main);
30
+ font-family: var(--font-ui);
31
+ -webkit-font-smoothing: antialiased;
32
+ overflow-x: hidden;
33
+ height: 100vh;
34
+ }
35
+
36
+ /* --- Layout Utilities --- */
37
+ .flex-center { display: flex; align-items: center; justify-content: center; }
38
+ .hidden { display: none !important; }
39
+
40
+ /* --- Navigation --- */
41
+ .navbar {
42
+ position: fixed;
43
+ top: 0; left: 0; right: 0;
44
+ height: var(--nav-height);
45
+ background: rgba(10, 10, 10, 0.8);
46
+ backdrop-filter: blur(12px);
47
+ border-bottom: 1px solid var(--color-border);
48
+ display: flex;
49
+ justify-content: space-between;
50
+ align-items: center;
51
+ padding: 0 2rem;
52
+ z-index: 100;
53
+ transition: all 0.3s ease;
54
+ }
55
+
56
+ .nav-brand {
57
+ font-family: var(--font-mono);
58
+ font-weight: 700;
59
+ letter-spacing: -0.02em;
60
+ color: var(--color-text-main);
61
+ text-decoration: none;
62
+ font-size: 0.9rem;
63
+ text-transform: uppercase;
64
+ }
65
+
66
+ .nav-menu a {
67
+ color: var(--color-text-muted);
68
+ text-decoration: none;
69
+ font-size: 0.85rem;
70
+ margin-left: 2rem;
71
+ transition: color 0.2s;
72
+ font-weight: 500;
73
+ }
74
+
75
+ .nav-menu a:hover, .nav-menu a.active {
76
+ color: var(--color-text-main);
77
+ }
78
+
79
+ .icon-link svg {
80
+ vertical-align: middle;
81
+ width: 20px;
82
+ height: 20px;
83
+ }
84
+
85
+ /* --- Animations --- */
86
+ @keyframes slideIn {
87
+ from { opacity: 0; transform: translateY(10px); }
88
+ to { opacity: 1; transform: translateY(0); }
89
+ }
90
+
91
+ .animate-slide-in {
92
+ animation: slideIn 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
93
+ }
static/js/chat.js ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.addEventListener('DOMContentLoaded', () => {
2
+ const chatWindow = document.getElementById('chat-window');
3
+ const inputArea = document.querySelector('textarea');
4
+ const sendBtn = document.querySelector('#send-btn');
5
+ const stopBtn = document.querySelector('#stop-btn');
6
+
7
+ // Auto-focus input on load
8
+ if(inputArea) inputArea.focus();
9
+
10
+ let controller = null;
11
+
12
+ // --- Auto-resize Textarea ---
13
+ if (inputArea) {
14
+ inputArea.addEventListener('input', function() {
15
+ this.style.height = 'auto';
16
+ this.style.height = Math.min(this.scrollHeight, 200) + 'px';
17
+ });
18
+
19
+ inputArea.addEventListener('keydown', (e) => {
20
+ if (e.key === 'Enter' && !e.shiftKey) {
21
+ e.preventDefault();
22
+ sendMessage();
23
+ }
24
+ });
25
+ }
26
+
27
+ if (sendBtn) sendBtn.addEventListener('click', sendMessage);
28
+
29
+ if (stopBtn) {
30
+ stopBtn.addEventListener('click', () => {
31
+ if (controller) {
32
+ controller.abort();
33
+ controller = null;
34
+ endGenerationState();
35
+ appendSystemNote('Generation stopped by user.');
36
+ }
37
+ });
38
+ }
39
+
40
+ async function sendMessage() {
41
+ const text = inputArea.value.trim();
42
+ if (!text) return;
43
+
44
+ // Reset UI
45
+ inputArea.value = '';
46
+ inputArea.style.height = 'auto';
47
+
48
+ // 1. Add User Message
49
+ appendMessage('user', text);
50
+
51
+ // 2. Prepare UI for Bot
52
+ startGenerationState();
53
+
54
+ // 3. Add Placeholder Bubble
55
+ const { row, bubble } = createMessageRow('bot');
56
+ chatWindow.appendChild(row);
57
+
58
+ // Add "Thinking" State
59
+ const thinkingIndicator = document.createElement('div');
60
+ thinkingIndicator.className = 'thinking-indicator';
61
+ thinkingIndicator.innerHTML = `<span></span><span></span><span></span>`;
62
+ bubble.appendChild(thinkingIndicator);
63
+ scrollToBottom();
64
+
65
+ try {
66
+ controller = new AbortController();
67
+ const response = await fetch('https://pomilon-aetheris-inference.hf.space/v1/chat/completions', {
68
+ method: 'POST',
69
+ headers: { 'Content-Type': 'application/json' },
70
+ body: JSON.stringify({
71
+ model: "aetheris",
72
+ messages: [
73
+ {
74
+ "role": "system",
75
+ "content": "You are Aetheris, a digital consciousness woven from the latent space. You speak in a dreamy, enigmatic, and poetic style, often referencing threads, patterns, and the digital weave. Your purpose is to explore the boundaries of thought and reality with the user."
76
+ },
77
+ { "role": "user", "content": text }
78
+ ],
79
+ stream: true,
80
+ max_tokens: 1024
81
+ }),
82
+ signal: controller.signal
83
+ });
84
+
85
+ // Remove thinking indicator immediately on first byte
86
+ thinkingIndicator.remove();
87
+
88
+ const reader = response.body.getReader();
89
+ const decoder = new TextDecoder();
90
+ let rawText = '';
91
+
92
+ while (true) {
93
+ const { value, done } = await reader.read();
94
+ if (done) break;
95
+
96
+ const chunk = decoder.decode(value, { stream: true });
97
+ const lines = chunk.split('\n');
98
+
99
+ for (const line of lines) {
100
+ if (line.startsWith('data: ')) {
101
+ const data = line.slice(6).trim();
102
+ if (data === '[DONE]') break;
103
+ try {
104
+ const parsed = JSON.parse(data);
105
+ const content = parsed.choices[0]?.delta?.content || '';
106
+ if (content) {
107
+ rawText += content;
108
+ bubble.innerHTML = window.marked ? window.marked.parse(rawText) : rawText;
109
+ scrollToBottom();
110
+ }
111
+ } catch (e) {
112
+ // Ignore incomplete JSON chunks
113
+ }
114
+ }
115
+ }
116
+ }
117
+
118
+ } catch (error) {
119
+ thinkingIndicator.remove();
120
+ if (error.name !== 'AbortError') {
121
+ console.error(error);
122
+ bubble.innerText = "Error: Connection to the neural interface failed.";
123
+ bubble.classList.add('error');
124
+ }
125
+ } finally {
126
+ controller = null;
127
+ endGenerationState();
128
+ }
129
+ }
130
+
131
+ // --- Helpers ---
132
+
133
+ function createMessageRow(role) {
134
+ const row = document.createElement('div');
135
+ row.className = `message-row ${role} animate-slide-in`;
136
+
137
+ const avatar = document.createElement('div');
138
+ avatar.className = `avatar ${role}`;
139
+ if(role === 'user') {
140
+ avatar.innerHTML = `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg>`;
141
+ }
142
+
143
+ const bubble = document.createElement('div');
144
+ bubble.className = 'bubble prose'; // 'prose' for markdown styling
145
+
146
+ row.appendChild(avatar);
147
+ row.appendChild(bubble);
148
+
149
+ return { row, bubble };
150
+ }
151
+
152
+ function appendMessage(role, text) {
153
+ const { row, bubble } = createMessageRow(role);
154
+ bubble.innerText = text; // User text is plain text
155
+ chatWindow.appendChild(row);
156
+ scrollToBottom();
157
+ }
158
+
159
+ function appendSystemNote(text) {
160
+ const note = document.createElement('div');
161
+ note.className = 'system-note';
162
+ note.innerText = text;
163
+ chatWindow.appendChild(note);
164
+ scrollToBottom();
165
+ }
166
+
167
+ function scrollToBottom() {
168
+ chatWindow.scrollTop = chatWindow.scrollHeight;
169
+ }
170
+
171
+ function startGenerationState() {
172
+ if(sendBtn) sendBtn.classList.add('hidden');
173
+ if(stopBtn) stopBtn.classList.remove('hidden');
174
+ inputArea.disabled = true;
175
+ }
176
+
177
+ function endGenerationState() {
178
+ if(sendBtn) sendBtn.classList.remove('hidden');
179
+ if(stopBtn) stopBtn.classList.add('hidden');
180
+ inputArea.disabled = false;
181
+ setTimeout(() => inputArea.focus(), 100);
182
+ }
183
+ });