AnesKAM commited on
Commit
501607d
·
verified ·
1 Parent(s): ec70e9b

Update genisi.js

Browse files
Files changed (1) hide show
  1. genisi.js +81 -71
genisi.js CHANGED
@@ -1,7 +1,6 @@
1
  import express from 'express';
2
  import cors from 'cors';
3
  import { OpenAI } from "openai";
4
- import fetch from 'node-fetch'; // أو fetch الأصلي في Node 18+
5
  import path from 'path';
6
  import { fileURLToPath } from 'url';
7
 
@@ -12,58 +11,7 @@ app.use(cors());
12
  app.use(express.json());
13
  app.use(express.static(__dirname));
14
 
15
- // ✅ الوضع السريع: MiniMax عبر Hugging Face Inference API (بدون @gradio/client)
16
- app.post('/api/fast', async (req, res) => {
17
- const { message } = req.body;
18
-
19
- try {
20
- // استدعاء مباشر لـ Hugging Face Space API
21
- const response = await fetch('https://ostarling-minimax-m2-5-chat.hf.space/api/predict', {
22
- method: 'POST',
23
- headers: {
24
- 'Content-Type': 'application/json',
25
- // إذا احتجت token لاحقاً: 'Authorization': 'Bearer hf_...'
26
- },
27
- body: JSON.stringify({
28
- fn_index: 0, // عادةً 0 للدالة الأولى
29
- data: [
30
- message, // message
31
- "You are a helpful assistant.", // system_message
32
- 2048, // max_tokens
33
- 0.7, // temperature
34
- 0.95 // top_p
35
- ]
36
- })
37
- });
38
-
39
- if (!response.ok) throw new Error(`HTTP ${response.status}`);
40
-
41
- const result = await response.json();
42
- // result.data يحتوي على الرد
43
-
44
- res.json({
45
- success: true,
46
- content: result.data?.[0] || result.data || "لا يوجد رد",
47
- model: "MiniMax-M2.5-Chat (HF)"
48
- });
49
-
50
- } catch (err) {
51
- console.error('HF Error:', err);
52
- // fallback: استخدام pollinations مباشرة
53
- try {
54
- const pollRes = await fetch('https://text.pollinations.ai/' + encodeURIComponent(message));
55
- const text = await pollRes.text();
56
- res.json({ success: true, content: text, model: "Pollinations (Fallback)" });
57
- } catch (pollErr) {
58
- res.status(500).json({
59
- success: false,
60
- error: "فشل الاتصال: " + err.message
61
- });
62
- }
63
- }
64
- });
65
-
66
- // ✅ الوضع المفكر: Kimi (كما هو)
67
  app.post('/api/think', async (req, res) => {
68
  const { message } = req.body;
69
  const POE_KEY = process.env.POE_API_KEY;
@@ -72,32 +20,101 @@ app.post('/api/think', async (req, res) => {
72
 
73
  res.setHeader('Content-Type', 'text/event-stream');
74
  res.setHeader('Cache-Control', 'no-cache');
 
75
 
76
- const poeClient = new OpenAI({
77
  apiKey: POE_KEY,
78
  baseURL: "https://api.poe.com/v1"
79
  });
80
 
81
  try {
82
- res.write(`data: ${JSON.stringify({ status: "thinking" })}\n\n`);
83
-
84
- const stream = await poeClient.chat.completions.create({
85
- model: "kimi-k2.5-fw",
 
86
  messages: [{ role: "user", content: message }],
87
- stream: true
 
 
 
 
88
  });
89
 
90
- res.write(`data: ${JSON.stringify({ status: "responding" })}\n\n`);
 
 
91
 
92
  for await (const chunk of stream) {
93
- const content = chunk.choices[0]?.delta?.content || "";
94
- if (content) res.write(`data: ${JSON.stringify({ content })}\n\n`);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  }
96
 
97
  res.write('data: [DONE]\n\n');
98
  res.end();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  } catch (err) {
100
- res.write(`data: ${JSON.stringify({ error: err.message })}\n\n`);
101
  res.end();
102
  }
103
  });
@@ -106,12 +123,5 @@ app.get('/', (req, res) => res.sendFile(path.join(__dirname, 'index.html')));
106
 
107
  const PORT = process.env.PORT || 7860;
108
  app.listen(PORT, () => {
109
- console.log(`
110
- ✅ Server Ready (No @gradio/client needed)
111
- -------------------------------------------
112
- ⚡ Fast: MiniMax (HF API) or Pollinations
113
- 🧠 Think: Kimi K2.5 FW (Poe API)
114
- Port: ${PORT}
115
- -------------------------------------------
116
- `);
117
  });
 
1
  import express from 'express';
2
  import cors from 'cors';
3
  import { OpenAI } from "openai";
 
4
  import path from 'path';
5
  import { fileURLToPath } from 'url';
6
 
 
11
  app.use(express.json());
12
  app.use(express.static(__dirname));
13
 
14
+ // ✅ Kimi مع دعم Reasoning المنفصل
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  app.post('/api/think', async (req, res) => {
16
  const { message } = req.body;
17
  const POE_KEY = process.env.POE_API_KEY;
 
20
 
21
  res.setHeader('Content-Type', 'text/event-stream');
22
  res.setHeader('Cache-Control', 'no-cache');
23
+ res.setHeader('Connection', 'keep-alive');
24
 
25
+ const client = new OpenAI({
26
  apiKey: POE_KEY,
27
  baseURL: "https://api.poe.com/v1"
28
  });
29
 
30
  try {
31
+ // إشارة بدء التفكير
32
+ res.write(`data: ${JSON.stringify({ type: 'status', status: 'reasoning' })}\n\n`);
33
+
34
+ const stream = await client.chat.completions.create({
35
+ model: "kimi-k2.5-fw", // النموذج المفكر إجبارياً
36
  messages: [{ role: "user", content: message }],
37
+ stream: true,
38
+ // محاولة طلب Reasoning منفصل (إن دعمته Poe لاحقاً)
39
+ extra_body: {
40
+ show_reasoning: true
41
+ }
42
  });
43
 
44
+ let reasoningBuffer = "";
45
+ let isReasoningPhase = true;
46
+ let contentBuffer = "";
47
 
48
  for await (const chunk of stream) {
49
+ const delta = chunk.choices[0]?.delta;
50
+ const content = delta?.content || "";
51
+
52
+ // ✅ محاولة استخراج Reasoning إن وُجد (OpenAI o1-style أو أTag)
53
+ if (delta?.reasoning && isReasoningPhase) {
54
+ res.write(`data: ${JSON.stringify({ type: 'reasoning', content: delta.reasoning })}\n\n`);
55
+ }
56
+ // ✅ إذا لم يوجد حقل منفصل، نفترض أن البداية هي التفكير ( heuristic )
57
+ else if (content) {
58
+ // نبحث عن علامة نهاية التفكير (إذا كان النموذج يستخدم <thinking> أو ---)
59
+ if (isReasoningPhase && (content.includes('</thinking>') || content.includes('\n\n**Answer:**'))) {
60
+ isReasoningPhase = false;
61
+ // إرسال ما سبق كتفكير
62
+ if (reasoningBuffer) {
63
+ res.write(`data: ${JSON.stringify({ type: 'reasoning_end' })}\n\n`);
64
+ }
65
+ }
66
+
67
+ if (isReasoningPhase) {
68
+ reasoningBuffer += content;
69
+ res.write(`data: ${JSON.stringify({ type: 'reasoning', content })}\n\n`);
70
+ } else {
71
+ res.write(`data: ${JSON.stringify({ type: 'content', content })}\n\n`);
72
+ }
73
+ }
74
  }
75
 
76
  res.write('data: [DONE]\n\n');
77
  res.end();
78
+
79
+ } catch (err) {
80
+ res.write(`data: ${JSON.stringify({ type: 'error', error: err.message })}\n\n`);
81
+ res.end();
82
+ }
83
+ });
84
+
85
+ // ⚡ الوضع السريع: MiniMax (بدون تفكير معقد)
86
+ app.post('/api/fast', async (req, res) => {
87
+ const { message } = req.body;
88
+
89
+ res.setHeader('Content-Type', 'text/event-stream');
90
+ res.setHeader('Cache-Control', 'no-cache');
91
+
92
+ try {
93
+ const response = await fetch('https://ostarling-minimax-m2-5-chat.hf.space/api/predict', {
94
+ method: 'POST',
95
+ headers: { 'Content-Type': 'application/json' },
96
+ body: JSON.stringify({
97
+ fn_index: 0,
98
+ data: [message, "You are helpful", 1024, 0.7, 0.95]
99
+ })
100
+ });
101
+
102
+ const result = await response.json();
103
+ const text = result.data?.[0] || "";
104
+
105
+ // محاكاة Streaming للنص الكامل
106
+ const chars = text.split('');
107
+ for (let i = 0; i < chars.length; i += 2) {
108
+ const chunk = chars.slice(i, i + 2).join('');
109
+ res.write(`data: ${JSON.stringify({ type: 'content', content: chunk })}\n\n`);
110
+ await new Promise(r => setTimeout(r, 10));
111
+ }
112
+
113
+ res.write('data: [DONE]\n\n');
114
+ res.end();
115
+
116
  } catch (err) {
117
+ res.write(`data: ${JSON.stringify({ type: 'error', error: err.message })}\n\n`);
118
  res.end();
119
  }
120
  });
 
123
 
124
  const PORT = process.env.PORT || 7860;
125
  app.listen(PORT, () => {
126
+ console.log(`🧠 Server: Kimi Reasoning Mode | Port ${PORT}`);
 
 
 
 
 
 
 
127
  });