AnesKAM commited on
Commit
0eba8d4
·
verified ·
1 Parent(s): fe873f5

Rename genisi.js to server.js

Browse files
Files changed (2) hide show
  1. genisi.js +0 -155
  2. server.js +187 -0
genisi.js DELETED
@@ -1,155 +0,0 @@
1
- import express from 'express';
2
- import cors from 'cors';
3
- import { OpenAI } from "openai";
4
- import fetch from 'node-fetch';
5
- import path from 'path';
6
- import { fileURLToPath } from 'url';
7
-
8
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
- const app = express();
10
-
11
- app.use(cors());
12
- app.use(express.json());
13
- app.use(express.static(__dirname));
14
-
15
- // ⚡ الوضع السريع: Chat Completions (بدون reasoning)
16
- app.post('/api/fast', async (req, res) => {
17
- const { message } = req.body;
18
-
19
- res.setHeader('Content-Type', 'text/event-stream');
20
- res.setHeader('Cache-Control', 'no-cache');
21
-
22
- const client = new OpenAI({
23
- apiKey: process.env.POE_API_KEY,
24
- baseURL: "https://api.poe.com/v1"
25
- });
26
-
27
- try {
28
- // استخدام Chat Completions للسرعة (GPT-5.4 أو Gemini أو Claude بدون reasoning)
29
- const stream = await client.chat.completions.create({
30
- model: "kimi-k2.5-fw", // أو "Gemini-3.1-Pro" - سريع ولا يفكر طويلاً
31
- messages: [{ role: "user", content: message }],
32
- stream: true,
33
- temperature: 0.7
34
- });
35
-
36
- for await (const chunk of stream) {
37
- const content = chunk.choices[0]?.delta?.content || "";
38
- if (content) {
39
- res.write(`data: ${JSON.stringify({ type: 'content', content })}\n\n`);
40
- }
41
- }
42
-
43
- res.write('data: [DONE]\n\n');
44
- res.end();
45
-
46
- } catch (err) {
47
- // Fallback إلى Pollinations
48
- try {
49
- const pollRes = await fetch('https://text.pollinations.ai/' + encodeURIComponent(message));
50
- const text = await pollRes.text();
51
- const chars = text.split('');
52
- for (let i = 0; i < chars.length; i += 3) {
53
- res.write(`data: ${JSON.stringify({ type: 'content', content: chars.slice(i, i+3).join('') })}\n\n`);
54
- await new Promise(r => setTimeout(r, 10));
55
- }
56
- res.write('data: [DONE]\n\n');
57
- res.end();
58
- } catch {
59
- res.write(`data: ${JSON.stringify({ type: 'error', error: err.message })}\n\n`);
60
- res.end();
61
- }
62
- }
63
- });
64
-
65
- // 🧠 الوضع المفكر: Responses API (مع reasoning حقيقي)
66
- app.post('/api/think', async (req, res) => {
67
- const { message } = req.body;
68
- const POE_KEY = process.env.POE_API_KEY;
69
-
70
- if (!POE_KEY) return res.status(401).json({ error: "POE_API_KEY missing" });
71
-
72
- res.setHeader('Content-Type', 'text/event-stream');
73
- res.setHeader('Cache-Control', 'no-cache');
74
-
75
- const client = new OpenAI({
76
- apiKey: POE_KEY,
77
- baseURL: "https://api.poe.com/v1"
78
- });
79
-
80
- try {
81
- // ✅ إشارة بدء التفكير (محاكاة UI)
82
- res.write(`data: ${JSON.stringify({ type: 'status', status: 'reasoning' })}\n\n`);
83
-
84
- // ✅ استخدام Responses API (وليس Chat Completions) للـ Reasoning
85
- const stream = await client.responses.create({
86
- model: "kimi-k2.5-fw", // ✅ يدعم reasoning حسب التوثيق
87
- input: message, // ملاحظة: "input" وليس "messages"
88
- stream: true,
89
- reasoning: false,
90
- temperature: 0.7
91
- });
92
-
93
- // إشالة بدء الرد الفعلي
94
- res.write(`data: ${JSON.stringify({ type: 'status', status: 'responding' })}\n\n`);
95
-
96
- // استلام الرد (output_text في Responses API)
97
- for await (const chunk of stream) {
98
- // في Responses API، المحتوى يأتي بشكل مختلف قليلاً
99
- const content = chunk.output_text || chunk.delta?.content || "";
100
- if (content) {
101
- res.write(`data: ${JSON.stringify({ type: 'content', content })}\n\n`);
102
- }
103
- }
104
-
105
- res.write('data: [DONE]\n\n');
106
- res.end();
107
-
108
- } catch (err) {
109
- // إذا فشل Claude، نرجع إلى Chat Completions العادي مع محاكاة التفكير
110
- console.error("Responses API Error:", err);
111
-
112
- try {
113
- res.write(`data: ${JSON.stringify({ type: 'status', status: 'reasoning_fallback' })}\n\n`);
114
-
115
- const stream = await client.chat.completions.create({
116
- model: "kimi-k2.5-fw", // الرجوع إلى kimi بدون reasoning parameter
117
- messages: [{
118
- role: "user",
119
- content: `اشرح خطوات تفكيرك بالتفصيل ثم أعطِ الإجابة النهائية: ${message}`
120
- }],
121
- stream: true
122
- });
123
-
124
- res.write(`data: ${JSON.stringify({ type: 'status', status: 'responding' })}\n\n`);
125
-
126
- for await (const chunk of stream) {
127
- const content = chunk.choices[0]?.delta?.content || "";
128
- if (content) {
129
- res.write(`data: ${JSON.stringify({ type: 'content', content })}\n\n`);
130
- }
131
- }
132
-
133
- res.write('data: [DONE]\n\n');
134
- res.end();
135
-
136
- } catch (fallbackErr) {
137
- res.write(`data: ${JSON.stringify({ type: 'error', error: fallbackErr.message })}\n\n`);
138
- res.end();
139
- }
140
- }
141
- });
142
-
143
- app.get('/', (req, res) => res.sendFile(path.join(__dirname, 'index.html')));
144
-
145
- const PORT = process.env.PORT || 7860;
146
- app.listen(PORT, () => {
147
- console.log(`
148
- ✅ Poe API - Correct Implementation
149
- ----------------------------------
150
- ⚡ Fast: Chat Completions (GPT-5.4)
151
- 🧠 Think: Responses API (Claude + reasoning)
152
- Docs: OpenAI Compatible API
153
- ----------------------------------
154
- `);
155
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
server.js ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import express from 'express';
2
+ import { Client } from '@gradio/client';
3
+ import cors from 'cors';
4
+ import dotenv from 'dotenv';
5
+
6
+ dotenv.config();
7
+
8
+ const app = express();
9
+ const PORT = process.env.PORT || 3000;
10
+
11
+ app.use(cors());
12
+ app.use(express.json());
13
+ app.use(express.static('public'));
14
+
15
+ // إعدادات النموذج
16
+ const MODEL_CONFIGS = {
17
+ flash: {
18
+ temperature: 1.0,
19
+ top_p: 0.95,
20
+ max_tokens: 2048,
21
+ system_message: "أنت مساعد ودود وسريع. اسمك MiniMax-M2.5. قدم إجابات مباشرة وواضحة. عندما تريد التفكير في مشكلة معقدة، استخدم علامة 'genisi thought' ثم اكتب تفكيرك، ثم أغلق العلامة.",
22
+ description: "وضع الفلاش - سريع ومناسب للمحادثات العامة"
23
+ },
24
+ pro: {
25
+ temperature: 0.7,
26
+ top_p: 0.9,
27
+ max_tokens: 4096,
28
+ system_message: "أنت مساعد خبير ومحلل عميق. اسمك MiniMax-M2.5-Pro. استخدم علامة 'genisi thought' لتحليل المشكلات بعمق قبل الإجابة. قدم حلولاً متقدمة ومفصلة مع أمثلة عملية. فكر خطوة بخطوة باستخدام genisi thought ثم قدم الإجابة النهائية.",
29
+ description: "وضع البرو - تحليل عميق وتفكير متقدم"
30
+ }
31
+ };
32
+
33
+ let currentMode = 'flash';
34
+
35
+ // الاتصال بالنموذج
36
+ let client = null;
37
+
38
+ async function initClient() {
39
+ try {
40
+ client = await Client.connect("ostarling/MiniMax-M2.5-Chat");
41
+ console.log('✅ تم الاتصال بـ MiniMax M2.5 بنجاح');
42
+ } catch (error) {
43
+ console.error('❌ فشل الاتصال:', error);
44
+ }
45
+ }
46
+
47
+ // دالة لإرسال الرسالة للنموذج
48
+ async function sendToModel(message, mode) {
49
+ const config = MODEL_CONFIGS[mode];
50
+
51
+ try {
52
+ if (!client) {
53
+ await initClient();
54
+ }
55
+
56
+ // إضافة إرشادات للتفكير بناءً على الوضع
57
+ let enhancedMessage = message;
58
+ if (mode === 'pro') {
59
+ enhancedMessage = `استخدم تحليل genisi thought قبل الإجابة: ${message}`;
60
+ }
61
+
62
+ const result = await client.predict("/respond", {
63
+ message: enhancedMessage,
64
+ system_message: config.system_message,
65
+ max_tokens: config.max_tokens,
66
+ temperature: config.temperature,
67
+ top_p: config.top_p
68
+ });
69
+
70
+ return result.data;
71
+ } catch (error) {
72
+ console.error('خطأ في الاتصال:', error);
73
+ throw error;
74
+ }
75
+ }
76
+
77
+ // دالة لتحليل نص الرد واستخراج أجزاء التفكير
78
+ function parseResponse(text) {
79
+ const thoughtRegex = /genisi thought\s*([\s\S]*?)(?=genisi thought|$)/gi;
80
+ const parts = [];
81
+ let lastIndex = 0;
82
+ let match;
83
+
84
+ while ((match = thoughtRegex.exec(text)) !== null) {
85
+ // النص قبل التفكير
86
+ if (match.index > lastIndex) {
87
+ parts.push({
88
+ type: 'text',
89
+ content: text.substring(lastIndex, match.index).trim()
90
+ });
91
+ }
92
+
93
+ // محتوى التفكير
94
+ parts.push({
95
+ type: 'thought',
96
+ content: match[1].trim()
97
+ });
98
+
99
+ lastIndex = match.index + match[0].length;
100
+ }
101
+
102
+ // باقي النص بعد آخر تفكير
103
+ if (lastIndex < text.length) {
104
+ parts.push({
105
+ type: 'text',
106
+ content: text.substring(lastIndex).trim()
107
+ });
108
+ }
109
+
110
+ // إذا لم يتم العثور على أي تفكير
111
+ if (parts.length === 0) {
112
+ parts.push({
113
+ type: 'text',
114
+ content: text
115
+ });
116
+ }
117
+
118
+ return parts;
119
+ }
120
+
121
+ // API endpoint للدردشة
122
+ app.post('/api/chat', async (req, res) => {
123
+ const { message, mode } = req.body;
124
+
125
+ if (!message) {
126
+ return res.status(400).json({ error: 'الرسالة مطلوبة' });
127
+ }
128
+
129
+ if (mode) {
130
+ currentMode = mode;
131
+ }
132
+
133
+ try {
134
+ const response = await sendToModel(message, currentMode);
135
+ const modelResponse = response[0] || response;
136
+
137
+ // تحليل الرد لاستخراج أجزاء التفكير
138
+ const parsedResponse = parseResponse(modelResponse);
139
+
140
+ res.json({
141
+ success: true,
142
+ response: parsedResponse,
143
+ mode: currentMode,
144
+ rawResponse: modelResponse
145
+ });
146
+ } catch (error) {
147
+ res.status(500).json({
148
+ success: false,
149
+ error: error.message
150
+ });
151
+ }
152
+ });
153
+
154
+ // API endpoint لتغيير الوضع
155
+ app.post('/api/mode', (req, res) => {
156
+ const { mode } = req.body;
157
+ if (mode === 'flash' || mode === 'pro') {
158
+ currentMode = mode;
159
+ res.json({
160
+ success: true,
161
+ mode: currentMode,
162
+ config: MODEL_CONFIGS[mode]
163
+ });
164
+ } else {
165
+ res.status(400).json({ error: 'وضع غير صالح' });
166
+ }
167
+ });
168
+
169
+ // API endpoint للحصول على الوضع الحالي
170
+ app.get('/api/mode', (req, res) => {
171
+ res.json({
172
+ mode: currentMode,
173
+ config: MODEL_CONFIGS[currentMode]
174
+ });
175
+ });
176
+
177
+ // بدء الخادم
178
+ async function startServer() {
179
+ await initClient();
180
+ app.listen(PORT, () => {
181
+ console.log(`🚀 الخادم يعمل على http://localhost:${PORT}`);
182
+ console.log(`📌 الوضع الحالي: ${currentMode}`);
183
+ console.log(`⚙️ إعدادات: ${MODEL_CONFIGS[currentMode].description}`);
184
+ });
185
+ }
186
+
187
+ startServer();