File size: 3,742 Bytes
ec13f69 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | import React, { useState, useRef } from 'react';
import ChatMessage from './ChatMessage';
export default function App() {
const [messages, setMessages] = useState([]);
const [input, setInput] = useState('');
const [model, setModel] = useState('glm-5.1');
const [isLoading, setIsLoading] = useState(false);
const messagesEndRef = useRef(null);
const handleSend = async () => {
if (!input.trim() || isLoading) return;
const userMessage = { role: 'user', content: input };
const newMessages = [...messages, userMessage];
setMessages(newMessages);
setInput('');
setIsLoading(true);
// إضافة رسالة بوت فارغة باش نبدأ نملأها
setMessages(prev => [...prev, { role: 'assistant', content: '', thinking: '' }]);
try {
const response = await fetch('/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ messages: newMessages, model })
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
let fullText = '';
let isThinking = false;
let currentThinking = '';
let currentContent = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value, { stream: true });
// تفكيك الـ Chunk (هذا يعتمد على كيفية إرسال HuggingFace للبيانات)
// نفترض أن النموذج يرسل النص العادي أو بـ _XML tags للتفكير
fullText += chunk;
// منطق استخراج التفكير (إذا استخدم النموذج <think)> أو <Scalars)
if (fullText.includes("")) {
const parts = fullText.split("");
currentThinking = parts[0].replace("", "");
currentContent = parts[1] || "";
} else {
currentContent = fullText;
}
// تحديث الرسالة الأخيرة في الواجهة
setMessages(prev => {
const updated = [...prev];
updated[updated.length - 1] = {
role: 'assistant',
content: currentContent,
thinking: currentThinking
};
return updated;
});
}
} catch (error) {
console.error('Error:', error);
} finally {
setIsLoading(false);
}
};
return (
<div className="app-container">
<div className="sidebar">
<h1>AnesNT 🇩🇿</h1>
<h3>Genisi AI</h3>
<select value={model} onChange={(e) => setModel(e.target.value)}>
<option value="gemma-4-31b">Gemma 4 31B (Flash)</option>
<option value="glm-5.1">GLM 5.1 (Thinking)</option>
</select>
<button onClick={() => setMessages([])}>🗑️ مسح المحادثة</button>
</div>
<div className="chat-area">
<div className="chat-header">
<h2>Genisi AI - {model === 'glm-5.1' ? 'مفكر' : 'سريع'}</h2>
</div>
<div className="messages-container">
{messages.map((msg, idx) => (
<ChatMessage key={idx} message={msg} />
))}
<div ref={messagesEndRef} />
</div>
<div className="input-area">
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={(e) => e.key === 'Enter' && handleSend()}
placeholder="اكتب رسالتك هنا..."
disabled={isLoading}
/>
<button onClick={handleSend} disabled={isLoading}>إرسال</button>
</div>
</div>
</div>
);
} |