AnesKAM commited on
Commit
22bcaf5
·
verified ·
1 Parent(s): 3951471

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +191 -93
index.html CHANGED
@@ -3,58 +3,82 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Kimi K2.5 FW - Fast Mode</title>
7
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
8
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
 
 
 
 
 
 
9
  <style>
10
  :root {
11
  --bg: #0d1117;
12
  --sidebar: #161b22;
13
- --accent: #238636;
14
- --text: #c9d1d9;
15
  --border: #30363d;
 
16
  }
17
 
18
  * { box-sizing: border-box; margin: 0; padding: 0; }
19
  body {
20
- background-color: var(--bg);
21
  color: var(--text);
22
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
23
  display: flex;
24
  height: 100vh;
25
  overflow: hidden;
26
  }
27
 
28
  .sidebar {
29
- width: 260px;
30
  background: var(--sidebar);
31
  border-left: 1px solid var(--border);
 
32
  display: flex;
33
  flex-direction: column;
34
- padding: 24px;
35
  }
36
 
37
- .brand {
38
- font-size: 20px;
39
- font-weight: 800;
40
- color: white;
41
- margin-bottom: 24px;
42
  display: flex;
43
- align-items: center;
44
  gap: 10px;
 
 
 
 
 
45
  }
46
 
47
- .model-info {
48
- background: rgba(35, 134, 54, 0.1);
49
- border: 1px solid var(--accent);
50
- border-radius: 8px;
51
- padding: 12px;
 
52
  font-size: 13px;
53
- line-height: 1.5;
 
 
 
54
  }
55
 
56
- .model-info .name { color: var(--accent); font-weight: bold; }
57
- .model-info .mode { color: #8b949e; font-size: 11px; margin-top: 4px; }
 
 
 
 
 
 
 
 
 
 
 
58
 
59
  .chat-container {
60
  flex: 1;
@@ -65,7 +89,7 @@
65
 
66
  #chat-flow {
67
  flex: 1;
68
- padding: 40px 15% 100px;
69
  overflow-y: auto;
70
  display: flex;
71
  flex-direction: column;
@@ -79,38 +103,46 @@
79
  animation: fadeIn 0.3s ease;
80
  }
81
 
82
- @keyframes fadeIn {
83
- from { opacity: 0; transform: translateY(10px); }
84
- to { opacity: 1; transform: translateY(0); }
85
- }
86
 
87
  .message.user { align-self: flex-end; flex-direction: row-reverse; }
88
  .message.ai { align-self: flex-start; }
89
 
90
  .avatar {
91
- width: 36px;
92
- height: 36px;
93
- border-radius: 8px;
94
- display: flex;
95
- align-items: center;
96
- justify-content: center;
97
  flex-shrink: 0;
98
- font-size: 16px;
99
  }
100
- .user .avatar { background: #1f6feb; color: white; }
101
- .ai .avatar { background: var(--accent); color: white; }
 
 
 
 
 
 
102
 
103
  .bubble {
104
- padding: 16px;
105
- border-radius: 12px;
106
- line-height: 1.6;
107
- font-size: 15px;
108
- border: 1px solid var(--border);
109
- word-wrap: break-word;
110
  }
111
 
112
  .user .bubble { background: #21262d; }
113
- .ai .bubble { background: transparent; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
 
115
  .input-wrapper {
116
  position: absolute;
@@ -125,81 +157,99 @@
125
  padding: 12px;
126
  display: flex;
127
  align-items: center;
128
- box-shadow: 0 8px 24px rgba(0,0,0,0.5);
129
  }
130
 
131
  #userInput {
132
- flex: 1;
133
- background: transparent;
134
- border: none;
135
- color: white;
136
- padding: 10px;
137
- font-size: 16px;
138
- outline: none;
139
  }
140
 
141
  .send-btn {
142
- background: var(--accent);
143
- color: white;
144
- border: none;
145
- width: 36px;
146
- height: 36px;
147
- border-radius: 6px;
148
- cursor: pointer;
149
  transition: 0.2s;
150
  }
151
- .send-btn:hover { filter: brightness(1.2); }
152
- .send-btn:disabled { background: #30363d; cursor: not-allowed; }
153
-
154
- .bubble pre {
155
- background: #161b22;
156
- padding: 12px;
157
- border-radius: 6px;
158
- overflow-x: auto;
159
- margin: 8px 0;
160
- border: 1px solid var(--border);
161
- }
162
 
163
- .bubble code { font-family: monospace; font-size: 13px; }
 
 
164
  </style>
165
  </head>
166
  <body>
167
 
168
  <aside class="sidebar">
169
- <div class="brand"><i class="fas fa-bolt"></i> Kimi Direct</div>
170
 
171
- <div class="model-info">
172
- <div class="name">kimi-k2.5-fw</div>
173
- <div class="mode">⚡ Fast Mode (Thinking Disabled)</div>
 
 
 
 
 
 
 
 
 
 
174
  </div>
175
 
176
- <div style="margin-top: auto; font-size: 12px; color: #8b949e;">
177
- <p>Mode: Streaming</p>
178
- <p style="margin-top: 4px; color: #484f58;">v1.0 - No Reasoning</p>
179
  </div>
180
  </aside>
181
 
182
  <main class="chat-container">
183
  <div id="chat-flow">
184
- <div class="message ai">
185
  <div class="avatar"><i class="fas fa-robot"></i></div>
186
  <div class="bubble">
187
- مرحباً! أنا Kimi K2.5 في الوضع السريع (بدون تفكير).<br>
188
- جاهز للرد الفوري على أسئلتك.
 
189
  </div>
190
  </div>
191
  </div>
192
 
193
  <div class="input-wrapper">
194
  <input type="text" id="userInput" placeholder="اكتب رسالتك..." autocomplete="off">
195
- <button class="send-btn" id="sendBtn" onclick="send()">
196
  <i class="fas fa-paper-plane"></i>
197
  </button>
198
  </div>
199
  </main>
200
 
201
  <script>
202
- async function send() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
  const input = document.getElementById('userInput');
204
  const btn = document.getElementById('sendBtn');
205
  const text = input.value.trim();
@@ -212,12 +262,52 @@
212
  input.disabled = true;
213
  btn.disabled = true;
214
 
215
- // إنشاء رسالة AI فارغة
216
- const msgId = addMessage("", 'ai');
 
 
 
 
 
 
 
 
 
 
 
 
217
  const bubble = document.getElementById(msgId).querySelector('.bubble');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
 
219
  try {
220
- const res = await fetch('/api/chat', {
221
  method: 'POST',
222
  headers: { 'Content-Type': 'application/json' },
223
  body: JSON.stringify({ message: text })
@@ -226,6 +316,7 @@
226
  const reader = res.body.getReader();
227
  const decoder = new TextDecoder();
228
  let fullText = "";
 
229
 
230
  while (true) {
231
  const { done, value } = await reader.read();
@@ -242,32 +333,39 @@
242
 
243
  try {
244
  const json = JSON.parse(data);
 
 
 
 
 
 
 
 
245
  if (json.content) {
246
  fullText += json.content;
247
  bubble.innerHTML = marked.parse(fullText);
248
- } else if (json.error) {
249
- bubble.innerHTML = `<span style="color:#f85149">خطأ: ${json.error}</span>`;
250
  }
251
  } catch (e) {}
252
  }
253
  }
254
 
255
  } catch (err) {
256
- bubble.innerHTML = `<span style="color:#f85149">فشل الاتصال</span>`;
257
  } finally {
258
- input.disabled = false;
259
- btn.disabled = false;
260
- input.focus();
261
  }
262
  }
263
 
264
- function addMessage(text, role) {
265
  const flow = document.getElementById('chat-flow');
266
  const id = 'msg-' + Date.now();
267
  const icon = role === 'user' ? 'fa-user' : 'fa-robot';
 
268
 
269
  const html = `
270
- <div class="message ${role}" id="${id}">
271
  <div class="avatar"><i class="fas ${icon}"></i></div>
272
  <div class="bubble">${text}</div>
273
  </div>
@@ -279,7 +377,7 @@
279
  }
280
 
281
  document.getElementById('userInput').addEventListener('keypress', (e) => {
282
- if (e.key === 'Enter') send();
283
  });
284
  </script>
285
  </body>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Dual Mode AI</title>
7
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
8
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
9
+ <!-- ✅ G4F Library للوضع السريع -->
10
+ <script type="module">
11
+ import { createClient } from 'https://g4f.dev/dist/js/providers.js';
12
+ window.g4fClient = createClient('default');
13
+ </script>
14
+
15
  <style>
16
  :root {
17
  --bg: #0d1117;
18
  --sidebar: #161b22;
19
+ --fast: #238636; /* أخضر للسريع */
20
+ --think: #a371f7; /* بنفسجي للمفكر */
21
  --border: #30363d;
22
+ --text: #c9d1d9;
23
  }
24
 
25
  * { box-sizing: border-box; margin: 0; padding: 0; }
26
  body {
27
+ background: var(--bg);
28
  color: var(--text);
29
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
30
  display: flex;
31
  height: 100vh;
32
  overflow: hidden;
33
  }
34
 
35
  .sidebar {
36
+ width: 280px;
37
  background: var(--sidebar);
38
  border-left: 1px solid var(--border);
39
+ padding: 24px;
40
  display: flex;
41
  flex-direction: column;
 
42
  }
43
 
44
+ .brand { font-size: 22px; font-weight: 800; color: white; margin-bottom: 30px; }
45
+
46
+ .mode-selector {
 
 
47
  display: flex;
 
48
  gap: 10px;
49
+ margin-bottom: 20px;
50
+ background: var(--bg);
51
+ padding: 4px;
52
+ border-radius: 8px;
53
+ border: 1px solid var(--border);
54
  }
55
 
56
+ .mode-btn {
57
+ flex: 1;
58
+ padding: 10px;
59
+ border: none;
60
+ border-radius: 6px;
61
+ cursor: pointer;
62
  font-size: 13px;
63
+ font-weight: 600;
64
+ transition: 0.2s;
65
+ background: transparent;
66
+ color: var(--text);
67
  }
68
 
69
+ .mode-btn.active.fast { background: var(--fast); color: white; }
70
+ .mode-btn.active.think { background: var(--think); color: white; }
71
+
72
+ .mode-info {
73
+ font-size: 12px;
74
+ line-height: 1.6;
75
+ padding: 12px;
76
+ border-radius: 8px;
77
+ margin-bottom: 20px;
78
+ }
79
+
80
+ .mode-info.fast { background: rgba(35,134,54,0.1); border: 1px solid var(--fast); }
81
+ .mode-info.think { background: rgba(163,113,247,0.1); border: 1px solid var(--think); }
82
 
83
  .chat-container {
84
  flex: 1;
 
89
 
90
  #chat-flow {
91
  flex: 1;
92
+ padding: 40px 15% 120px;
93
  overflow-y: auto;
94
  display: flex;
95
  flex-direction: column;
 
103
  animation: fadeIn 0.3s ease;
104
  }
105
 
106
+ @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
 
 
 
107
 
108
  .message.user { align-self: flex-end; flex-direction: row-reverse; }
109
  .message.ai { align-self: flex-start; }
110
 
111
  .avatar {
112
+ width: 36px; height: 36px; border-radius: 8px;
113
+ display: flex; align-items: center; justify-content: center;
 
 
 
 
114
  flex-shrink: 0;
 
115
  }
116
+
117
+ .message.fast .avatar { background: var(--fast); color: white; }
118
+ .message.think .avatar { background: var(--think); color: white; animation: pulse 2s infinite; }
119
+
120
+ @keyframes pulse {
121
+ 0%, 100% { box-shadow: 0 0 0 0 rgba(163,113,247,0.4); }
122
+ 50% { box-shadow: 0 0 0 10px rgba(163,113,247,0); }
123
+ }
124
 
125
  .bubble {
126
+ padding: 16px; border-radius: 12px; line-height: 1.6;
127
+ border: 1px solid var(--border); word-wrap: break-word;
 
 
 
 
128
  }
129
 
130
  .user .bubble { background: #21262d; }
131
+ .ai.fast .bubble { border-color: var(--fast); }
132
+ .ai.think .bubble { border-color: var(--think); }
133
+
134
+ /* مؤشر التفكير */
135
+ .thinking-indicator {
136
+ display: flex;
137
+ align-items: center;
138
+ gap: 8px;
139
+ color: var(--think);
140
+ font-size: 13px;
141
+ margin-bottom: 8px;
142
+ }
143
+
144
+ .thinking-indicator i { animation: spin 1s linear infinite; }
145
+ @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
146
 
147
  .input-wrapper {
148
  position: absolute;
 
157
  padding: 12px;
158
  display: flex;
159
  align-items: center;
160
+ gap: 12px;
161
  }
162
 
163
  #userInput {
164
+ flex: 1; background: transparent; border: none;
165
+ color: white; padding: 10px; font-size: 16px; outline: none;
 
 
 
 
 
166
  }
167
 
168
  .send-btn {
169
+ width: 36px; height: 36px; border-radius: 6px;
170
+ border: none; cursor: pointer; color: white;
 
 
 
 
 
171
  transition: 0.2s;
172
  }
 
 
 
 
 
 
 
 
 
 
 
173
 
174
+ .send-btn.fast { background: var(--fast); }
175
+ .send-btn.think { background: var(--think); }
176
+ .send-btn:disabled { background: #30363d !important; cursor: not-allowed; }
177
  </style>
178
  </head>
179
  <body>
180
 
181
  <aside class="sidebar">
182
+ <div class="brand"><i class="fas fa-layer-group"></i> Dual AI</div>
183
 
184
+ <div class="mode-selector">
185
+ <button class="mode-btn fast active" onclick="setMode('fast')">
186
+ <i class="fas fa-bolt"></i> ⚡ سريع
187
+ </button>
188
+ <button class="mode-btn think" onclick="setMode('think')">
189
+ <i class="fas fa-brain"></i> 🧠 مفكر
190
+ </button>
191
+ </div>
192
+
193
+ <div class="mode-info fast" id="modeInfo">
194
+ <strong>G4F Mode</strong><br>
195
+ مجاني • فوري • بدون API Key<br>
196
+ يستخدم providers متعددة للرد السريع
197
  </div>
198
 
199
+ <div style="margin-top: auto; font-size: 11px; color: #8b949e;">
200
+ <div id="currentMode">الوضع الحالي: سريع (G4F)</div>
 
201
  </div>
202
  </aside>
203
 
204
  <main class="chat-container">
205
  <div id="chat-flow">
206
+ <div class="message ai fast">
207
  <div class="avatar"><i class="fas fa-robot"></i></div>
208
  <div class="bubble">
209
+ مرحباً! اختر الوضع المناسب:<br><br>
210
+ ⚡ <strong>الوضع السريع:</strong> ردود فورية مجانية عبر G4F<br>
211
+ 🧠 <strong>الوضع المفكر:</strong> تحليل عميق عبر Kimi (يحتاج Poe API)
212
  </div>
213
  </div>
214
  </div>
215
 
216
  <div class="input-wrapper">
217
  <input type="text" id="userInput" placeholder="اكتب رسالتك..." autocomplete="off">
218
+ <button class="send-btn fast" id="sendBtn" onclick="handleSend()">
219
  <i class="fas fa-paper-plane"></i>
220
  </button>
221
  </div>
222
  </main>
223
 
224
  <script>
225
+ let currentMode = 'fast'; // 'fast' أو 'think'
226
+
227
+ function setMode(mode) {
228
+ currentMode = mode;
229
+
230
+ // تحديث الأزرار
231
+ document.querySelectorAll('.mode-btn').forEach(btn => btn.classList.remove('active'));
232
+ document.querySelector(`.mode-btn.${mode}`).classList.add('active');
233
+
234
+ // تحديث المعلومات
235
+ const info = document.getElementById('modeInfo');
236
+ const btn = document.getElementById('sendBtn');
237
+ const status = document.getElementById('currentMode');
238
+
239
+ if (mode === 'fast') {
240
+ info.className = 'mode-info fast';
241
+ info.innerHTML = '<strong>G4F Mode</strong><br>مجاني • فوري • بدون API Key';
242
+ btn.className = 'send-btn fast';
243
+ status.textContent = 'الوضع الحالي: سريع (G4F)';
244
+ } else {
245
+ info.className = 'mode-info think';
246
+ info.innerHTML = '<strong>Kimi Think Mode</strong><br>يبحث ويفكر قبل الإجابة<br>يحتاج Poe API Key في السيرفر';
247
+ btn.className = 'send-btn think';
248
+ status.textContent = 'الوضع الحالي: مفكر (Kimi)';
249
+ }
250
+ }
251
+
252
+ async function handleSend() {
253
  const input = document.getElementById('userInput');
254
  const btn = document.getElementById('sendBtn');
255
  const text = input.value.trim();
 
262
  input.disabled = true;
263
  btn.disabled = true;
264
 
265
+ if (currentMode === 'fast') {
266
+ await sendFast(text);
267
+ } else {
268
+ await sendThink(text);
269
+ }
270
+
271
+ input.disabled = false;
272
+ btn.disabled = false;
273
+ input.focus();
274
+ }
275
+
276
+ // ✅ الوضع السريع: G4F مباشرة في المتصفح
277
+ async function sendFast(text) {
278
+ const msgId = addMessage('', 'ai', 'fast');
279
  const bubble = document.getElementById(msgId).querySelector('.bubble');
280
+
281
+ try {
282
+ // استخدام G4F client المستورد من CDN
283
+ const result = await window.g4fClient.chat.completions.create({
284
+ model: 'auto', // يختار أفضل provider تلقائياً
285
+ messages: [{ role: 'user', content: text }]
286
+ });
287
+
288
+ const content = result.choices[0].message.content;
289
+ bubble.innerHTML = marked.parse(content);
290
+
291
+ } catch (err) {
292
+ bubble.innerHTML = `<span style="color:#f85149">خطأ في G4F: ${err.message}</span>`;
293
+ }
294
+ }
295
+
296
+ // ✅ الوضع المفكر: Poe API مع Kimi وإظهار التفكير
297
+ async function sendThink(text) {
298
+ const msgId = addMessage('', 'ai', 'think');
299
+ const container = document.getElementById(msgId);
300
+ const bubble = container.querySelector('.bubble');
301
+
302
+ // إضافة مؤشر التفكير
303
+ const thinkingDiv = document.createElement('div');
304
+ thinkingDiv.className = 'thinking-indicator';
305
+ thinkingDiv.id = `thinking-${msgId}`;
306
+ thinkingDiv.innerHTML = '<i class="fas fa-circle-notch"></i> يفكر...';
307
+ container.insertBefore(thinkingDiv, bubble);
308
 
309
  try {
310
+ const res = await fetch('/api/think', {
311
  method: 'POST',
312
  headers: { 'Content-Type': 'application/json' },
313
  body: JSON.stringify({ message: text })
 
316
  const reader = res.body.getReader();
317
  const decoder = new TextDecoder();
318
  let fullText = "";
319
+ let isResponding = false;
320
 
321
  while (true) {
322
  const { done, value } = await reader.read();
 
333
 
334
  try {
335
  const json = JSON.parse(data);
336
+
337
+ // ✅ إخفاء مؤشر التفكير عند بدء الرد
338
+ if (json.status === 'responding' && !isResponding) {
339
+ isResponding = true;
340
+ const indicator = document.getElementById(`thinking-${msgId}`);
341
+ if (indicator) indicator.style.display = 'none';
342
+ }
343
+
344
  if (json.content) {
345
  fullText += json.content;
346
  bubble.innerHTML = marked.parse(fullText);
 
 
347
  }
348
  } catch (e) {}
349
  }
350
  }
351
 
352
  } catch (err) {
353
+ bubble.innerHTML = `<span style="color:#f85149">خطأ: ${err.message}</span>`;
354
  } finally {
355
+ // إخفاء المؤشر إذا بقي ظاهراً
356
+ const indicator = document.getElementById(`thinking-${msgId}`);
357
+ if (indicator) indicator.style.display = 'none';
358
  }
359
  }
360
 
361
+ function addMessage(text, role, mode = 'fast') {
362
  const flow = document.getElementById('chat-flow');
363
  const id = 'msg-' + Date.now();
364
  const icon = role === 'user' ? 'fa-user' : 'fa-robot';
365
+ const modeClass = role === 'ai' ? mode : '';
366
 
367
  const html = `
368
+ <div class="message ${role} ${modeClass}" id="${id}">
369
  <div class="avatar"><i class="fas ${icon}"></i></div>
370
  <div class="bubble">${text}</div>
371
  </div>
 
377
  }
378
 
379
  document.getElementById('userInput').addEventListener('keypress', (e) => {
380
+ if (e.key === 'Enter') handleSend();
381
  });
382
  </script>
383
  </body>