File size: 4,643 Bytes
8f8420b 07986da 5f74cf9 9e4ee7e 07986da 9e4ee7e 2c66a64 9e4ee7e 2c66a64 9e4ee7e 2c66a64 9e4ee7e 07986da 9e4ee7e 07986da 9e4ee7e 07986da 2c66a64 9e4ee7e 07986da 9e4ee7e 07986da 9e4ee7e 07986da 9e4ee7e 07986da 541e463 9e4ee7e 07986da 9e4ee7e d757633 9e4ee7e 07986da 9e4ee7e 07986da 9e4ee7e 07986da 9e4ee7e 07986da 9e4ee7e 07986da 9e4ee7e 07986da 9e4ee7e 07986da 9e4ee7e 07986da 9e4ee7e 07986da 2c66a64 9e4ee7e 07986da 9e4ee7e 07986da 9e4ee7e 07986da 9e4ee7e 07986da 2c66a64 9e4ee7e 07986da 0c0fa0b |
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 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
import express from 'express';
import axios from 'axios';
import { v4 as uuidv4 } from 'uuid';
const app = express();
// 中间件
app.use(express.json());
app.use(express.text());
const modelMapping = {
"gpt-4o-mini": "GPT-4o mini",
"claude-haiku": "Claude Haiku",
"llama-3": "Llama 3",
"gemini-1.5": "Gemini 1.5",
"gemini-flash": "Gemini Flash",
"command-r": "Command R",
};
// 认证中间件
const authMiddleware = (req, res, next) => {
const authToken = process.env.AUTH_TOKEN;
if (authToken) {
const requestToken = req.headers.authorization || '';
const token = requestToken.replace('Bearer ', '');
if (token !== authToken) {
return res.status(401).send('Access Denied');
}
}
next();
};
// 获取临时用户ID
const getTempUserID = async () => {
const response = await axios.get('https://playground.julius.ai/api/temp_user_id');
return response.data.temp_user_id;
};
// 分割文本为块
const splitIntoChunks = (text, chunkSize) => {
const chars = Array.from(text);
const chunks = [];
for (let i = 0; i < chars.length; i += chunkSize) {
chunks.push(chars.slice(i, i + chunkSize).join(''));
}
return chunks;
};
// 发送消息到 Julius
const sendToJulius = async (tempUserID, message, model) => {
const conversationID = uuidv4();
const data = {
message: {
content: message,
role: "user"
},
provider: "default",
chat_mode: "auto",
client_version: "20240130",
theme: "dark",
new_images: null,
new_attachments: null,
dataframe_format: "json",
selectedModels: [model]
};
const response = await axios({
method: 'post',
url: 'https://playground.julius.ai/api/chat/message',
data,
headers: {
'is-demo': tempUserID,
'conversation-id': conversationID,
'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',
'interactive-charts': 'true',
'use-dict': 'true',
'Gcs': 'true',
'Is-Native': 'false',
'sec-ch-ua-platform': 'Windows'
},
responseType: 'text'
});
return response.data.split('\n')
.filter(line => line.trim())
.map(line => {
try { return JSON.parse(line); }
catch { return null; }
})
.filter(Boolean)
.reduce((acc, item) => acc + (item.content || ''), '');
};
// 处理聊天请求
app.post('/v1/chat/completions', authMiddleware, async (req, res) => {
try {
const { messages, model: originalModel, stream } = req.body;
const model = modelMapping[originalModel] || originalModel;
const tempUserID = await getTempUserID();
const content = messages[messages.length - 1].content;
// 获取 Julius 响应
const juliusResp = await sendToJulius(tempUserID, content, model);
// 流式响应
if (stream) {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
const respId = `chatcmpl-${tempUserID}`;
const created = Math.floor(Date.now() / 1000);
const chunks = splitIntoChunks(juliusResp, 50);
// 发送初始化消息
res.write(`data: ${JSON.stringify({
id: respId,
object: "chat.completion.chunk",
created,
model,
choices: [{ delta: { role: "assistant" }, index: 0 }]
})}\n\n`);
// 发送内容块
chunks.forEach((chunk, index) => {
res.write(`data: ${JSON.stringify({
id: respId,
object: "chat.completion.chunk",
created,
model,
choices: [{
delta: { content: chunk },
index: 0,
finish_reason: index === chunks.length - 1 ? "stop" : null
}]
})}\n\n`);
});
// 结束标志
res.write('data: [DONE]\n\n');
return res.end();
}
// 普通响应
res.json({
id: `chatcmpl-${tempUserID}`,
object: "chat.completion",
created: Math.floor(Date.now() / 1000),
model,
choices: [{
message: {
role: "assistant",
content: juliusResp
},
finish_reason: "stop",
index: 0
}]
});
} catch (error) {
console.error('Error:', error);
res.status(500).json({ error: error.message });
}
});
// 根路径响应
app.all('*', (req, res) => {
res.json({
status: "Julius2Api Service Running...",
message: "MoLoveSze..."
});
});
// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
}); |