alcex commited on
Commit
9e4ee7e
·
verified ·
1 Parent(s): 5f74cf9

Update index.js

Browse files
Files changed (1) hide show
  1. index.js +118 -140
index.js CHANGED
@@ -1,13 +1,11 @@
1
- import express from 'express';
2
- import fetch from 'node-fetch';
3
- import { v4 as uuidv4 } from 'uuid';
4
- import dotenv from 'dotenv';
5
- import { Buffer } from 'buffer';
6
-
7
- dotenv.config();
8
-
9
  const app = express();
10
 
 
 
 
11
 
12
  const modelMapping = {
13
  "gpt-4o-mini": "GPT-4o mini",
@@ -15,34 +13,42 @@ const modelMapping = {
15
  "llama-3": "Llama 3",
16
  "gemini-1.5": "Gemini 1.5",
17
  "gemini-flash": "Gemini Flash",
18
- "command-r": "Command R"
19
  };
20
 
21
- app.use(express.json());
 
 
 
 
 
 
 
 
 
 
 
22
 
23
- const getCurrentTimestamp = () => Math.floor(Date.now() / 1000);
 
 
 
 
24
 
 
25
  const splitIntoChunks = (text, chunkSize) => {
 
26
  const chunks = [];
27
- for (let i = 0; i < text.length; i += chunkSize) {
28
- chunks.push(text.slice(i, i + chunkSize));
29
  }
30
  return chunks;
31
  };
32
 
33
- const getTempUserID = async () => {
34
- try {
35
- const response = await fetch('https://playground.julius.ai/api/temp_user_id');
36
- const data = await response.json();
37
- return data.temp_user_id;
38
- } catch (error) {
39
- throw new Error('Failed to get temp user ID');
40
- }
41
- };
42
-
43
  const sendToJulius = async (tempUserID, message, model) => {
44
  const conversationID = uuidv4();
45
- const juliusReq = {
46
  message: {
47
  content: message,
48
  role: "user"
@@ -51,148 +57,120 @@ const sendToJulius = async (tempUserID, message, model) => {
51
  chat_mode: "auto",
52
  client_version: "20240130",
53
  theme: "dark",
 
 
 
54
  selectedModels: [model]
55
  };
56
 
57
- try {
58
- const response = await fetch('https://playground.julius.ai/api/chat/message', {
59
- method: 'POST',
60
- headers: {
61
- 'is-demo': tempUserID,
62
- 'Content-Type': 'application/json',
63
- 'Platform': 'web',
64
- 'conversation-id': conversationID,
65
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36'
66
- },
67
- body: JSON.stringify(juliusReq)
68
- });
69
-
70
- const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
71
- let fullResponse = '';
72
-
73
- while (true) {
74
- const { done, value } = await reader.read();
75
- if (done) break;
76
-
77
- const lines = value.split('\n');
78
- for (const line of lines) {
79
- try {
80
- const jsonResp = JSON.parse(line);
81
- if (jsonResp.content) {
82
- fullResponse += jsonResp.content;
83
- }
84
- } catch (e) {
85
- // 忽略解析错误
86
- }
87
- }
88
- }
89
-
90
- return fullResponse;
91
- } catch (error) {
92
- throw new Error('Failed to send to Julius');
93
- }
94
  };
95
 
96
- app.all('*', async (req, res) => {
97
- // 身份验证
98
- const authToken = process.env.AUTH_TOKEN;
99
- if (authToken) {
100
- const requestToken = req.headers.authorization?.replace('Bearer ', '');
101
- if (!requestToken || requestToken !== authToken) {
102
- return res.status(401).send('Access Denied');
103
- }
104
- }
105
-
106
- // 健康检查
107
- if (req.path !== '/v1/chat/completions') {
108
- return res.json({
109
- status: "Julius2Api Service Running...",
110
- message: "MoLoveSze..."
111
- });
112
- }
113
-
114
- if (req.method !== 'POST') {
115
- return res.status(405).send('Method not allowed');
116
- }
117
-
118
  try {
119
- const openAIReq = req.body;
120
- const isStream = openAIReq.stream || false;
 
 
121
 
122
- // 模型映射
123
- const mappedModel = modelMapping[openAIReq.model] || 'GPT-4o mini';
124
- openAIReq.model = mappedModel;
125
 
126
- const tempUserID = await getTempUserID();
127
- const juliusResp = await sendToJulius(tempUserID,
128
- openAIReq.messages[openAIReq.messages.length - 1].content,
129
- mappedModel
130
- );
131
-
132
- const respId = `chatcmpl-${tempUserID}`;
133
- const created = getCurrentTimestamp();
134
-
135
- if (isStream) {
136
- res.writeHead(200, {
137
- 'Content-Type': 'text/event-stream',
138
- 'Cache-Control': 'no-cache',
139
- 'Connection': 'keep-alive'
140
- });
141
 
142
- // 发送初始响应
143
- const firstResponse = {
144
  id: respId,
145
  object: "chat.completion.chunk",
146
- created: created,
147
- model: mappedModel,
148
- choices: [{
149
- delta: { role: "assistant" },
150
- index: 0
151
- }]
152
- };
153
- res.write(`data: ${JSON.stringify(firstResponse)}\n\n`);
154
-
155
- // 分块发送内容
156
- const chunks = splitIntoChunks(juliusResp, 50);
157
  chunks.forEach((chunk, index) => {
158
- const response = {
159
  id: respId,
160
  object: "chat.completion.chunk",
161
- created: created,
162
- model: mappedModel,
163
  choices: [{
164
  delta: { content: chunk },
165
  index: 0,
166
- finish_reason: index === chunks.length - 1 ? 'stop' : null
167
  }]
168
- };
169
- res.write(`data: ${JSON.stringify(response)}\n\n`);
170
  });
171
 
 
172
  res.write('data: [DONE]\n\n');
173
- res.end();
174
- } else {
175
- const response = {
176
- id: respId,
177
- object: "chat.completion",
178
- created: created,
179
- model: mappedModel,
180
- choices: [{
181
- message: {
182
- role: "assistant",
183
- content: juliusResp
184
- },
185
- finish_reason: "stop"
186
- }]
187
- };
188
- res.json(response);
189
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
  } catch (error) {
191
- console.error(error);
192
- res.status(500).send(error.message);
193
  }
194
  });
195
 
 
 
 
 
 
 
 
 
 
196
  const PORT = process.env.PORT || 3000;
197
  app.listen(PORT, () => {
198
  console.log(`Server running on port ${PORT}`);
 
1
+ const express = require('express');
2
+ const axios = require('axios');
3
+ const { v4: uuidv4 } = require('uuid');
 
 
 
 
 
4
  const app = express();
5
 
6
+ // 中间件
7
+ app.use(express.json());
8
+ app.use(express.text());
9
 
10
  const modelMapping = {
11
  "gpt-4o-mini": "GPT-4o mini",
 
13
  "llama-3": "Llama 3",
14
  "gemini-1.5": "Gemini 1.5",
15
  "gemini-flash": "Gemini Flash",
16
+ "command-r": "Command R",
17
  };
18
 
19
+ // 认证中间件
20
+ const authMiddleware = (req, res, next) => {
21
+ const authToken = process.env.AUTH_TOKEN;
22
+ if (authToken) {
23
+ const requestToken = req.headers.authorization || '';
24
+ const token = requestToken.replace('Bearer ', '');
25
+ if (token !== authToken) {
26
+ return res.status(401).send('Access Denied');
27
+ }
28
+ }
29
+ next();
30
+ };
31
 
32
+ // 获取临时用户ID
33
+ const getTempUserID = async () => {
34
+ const response = await axios.get('https://playground.julius.ai/api/temp_user_id');
35
+ return response.data.temp_user_id;
36
+ };
37
 
38
+ // 分割文本为块
39
  const splitIntoChunks = (text, chunkSize) => {
40
+ const chars = Array.from(text);
41
  const chunks = [];
42
+ for (let i = 0; i < chars.length; i += chunkSize) {
43
+ chunks.push(chars.slice(i, i + chunkSize).join(''));
44
  }
45
  return chunks;
46
  };
47
 
48
+ // 发送消息到 Julius
 
 
 
 
 
 
 
 
 
49
  const sendToJulius = async (tempUserID, message, model) => {
50
  const conversationID = uuidv4();
51
+ const data = {
52
  message: {
53
  content: message,
54
  role: "user"
 
57
  chat_mode: "auto",
58
  client_version: "20240130",
59
  theme: "dark",
60
+ new_images: null,
61
+ new_attachments: null,
62
+ dataframe_format: "json",
63
  selectedModels: [model]
64
  };
65
 
66
+ const response = await axios({
67
+ method: 'post',
68
+ url: 'https://playground.julius.ai/api/chat/message',
69
+ data,
70
+ headers: {
71
+ 'is-demo': tempUserID,
72
+ 'conversation-id': conversationID,
73
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36',
74
+ 'interactive-charts': 'true',
75
+ 'use-dict': 'true',
76
+ 'Gcs': 'true',
77
+ 'Is-Native': 'false',
78
+ 'sec-ch-ua-platform': 'Windows'
79
+ },
80
+ responseType: 'text'
81
+ });
82
+
83
+ return response.data.split('\n')
84
+ .filter(line => line.trim())
85
+ .map(line => {
86
+ try { return JSON.parse(line); }
87
+ catch { return null; }
88
+ })
89
+ .filter(Boolean)
90
+ .reduce((acc, item) => acc + (item.content || ''), '');
 
 
 
 
 
 
 
 
 
 
 
 
91
  };
92
 
93
+ // 处理聊天请求
94
+ app.post('/v1/chat/completions', authMiddleware, async (req, res) => {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  try {
96
+ const { messages, model: originalModel, stream } = req.body;
97
+ const model = modelMapping[originalModel] || "GPT-4o mini";
98
+ const tempUserID = await getTempUserID();
99
+ const content = messages[messages.length - 1].content;
100
 
101
+ // 获取 Julius 响应
102
+ const juliusResp = await sendToJulius(tempUserID, content, model);
 
103
 
104
+ // 流式响应
105
+ if (stream) {
106
+ res.setHeader('Content-Type', 'text/event-stream');
107
+ res.setHeader('Cache-Control', 'no-cache');
108
+ res.setHeader('Connection', 'keep-alive');
109
+
110
+ const respId = `chatcmpl-${tempUserID}`;
111
+ const created = Math.floor(Date.now() / 1000);
112
+ const chunks = splitIntoChunks(juliusResp, 50);
 
 
 
 
 
 
113
 
114
+ // 发送初始化消息
115
+ res.write(`data: ${JSON.stringify({
116
  id: respId,
117
  object: "chat.completion.chunk",
118
+ created,
119
+ model,
120
+ choices: [{ delta: { role: "assistant" }, index: 0 }]
121
+ })}\n\n`);
122
+
123
+ // 发送内容块
 
 
 
 
 
124
  chunks.forEach((chunk, index) => {
125
+ res.write(`data: ${JSON.stringify({
126
  id: respId,
127
  object: "chat.completion.chunk",
128
+ created,
129
+ model,
130
  choices: [{
131
  delta: { content: chunk },
132
  index: 0,
133
+ finish_reason: index === chunks.length - 1 ? "stop" : null
134
  }]
135
+ })}\n\n`);
 
136
  });
137
 
138
+ // 结束标志
139
  res.write('data: [DONE]\n\n');
140
+ return res.end();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  }
142
+
143
+ // 普通响应
144
+ res.json({
145
+ id: `chatcmpl-${tempUserID}`,
146
+ object: "chat.completion",
147
+ created: Math.floor(Date.now() / 1000),
148
+ model,
149
+ choices: [{
150
+ message: {
151
+ role: "assistant",
152
+ content: juliusResp
153
+ },
154
+ finish_reason: "stop",
155
+ index: 0
156
+ }]
157
+ });
158
+
159
  } catch (error) {
160
+ console.error('Error:', error);
161
+ res.status(500).json({ error: error.message });
162
  }
163
  });
164
 
165
+ // 根路径响应
166
+ app.all('*', (req, res) => {
167
+ res.json({
168
+ status: "Julius2Api Service Running...",
169
+ message: "MoLoveSze..."
170
+ });
171
+ });
172
+
173
+ // 启动服务器
174
  const PORT = process.env.PORT || 3000;
175
  app.listen(PORT, () => {
176
  console.log(`Server running on port ${PORT}`);