yxmiler commited on
Commit
f74dba7
·
verified ·
1 Parent(s): bfef66c

Update index.js

Browse files
Files changed (1) hide show
  1. index.js +156 -119
index.js CHANGED
@@ -172,127 +172,164 @@ class ResponseHandler {
172
 
173
  // WebSocket工具类
174
  class WebSocketUtils {
175
- // 生成WebSocket密钥
176
- static generateWebSocketKey() {
177
- return randomBytes(16).toString('base64');
178
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
 
180
- // 创建WebSocket客户端
181
- static createWebSocketClient(requestPayload) {
182
- return new Promise((resolve, reject) => {
183
- const websocketKey = this.generateWebSocketKey();
184
- const ws = new WebSocket(CONFIG.API.BASE_URL, 'graphql-transport-ws', {
185
- headers: {
186
- ...CONFIG.DEFAULT_HEADERS,
187
- 'Sec-WebSocket-Key': websocketKey,
188
- }
189
- });
190
-
191
- let responseContent = '';
192
- let isComplete = false;
193
-
194
- ws.on('open', () => {
195
- console.log('WebSocket连接已建立');
196
- const connectionInitMessage = {
197
- type: 'connection_init',
198
- payload: {
199
- headers: {
200
- Authorization: 'Bearer ee5b7c15ed3553cd6abc407340aad09ac7cb3b9f76d8613a'
201
- }
202
- }
203
- };
204
- ws.send(JSON.stringify(connectionInitMessage));
205
- });
206
-
207
- ws.on('message', async (data) => {
208
- const message = data.toString();
209
- const parsedMessage = JSON.parse(message);
210
-
211
- switch (parsedMessage.type) {
212
- case 'connection_ack':
213
- console.log('WebSocket连接请求中');
214
- this.sendChatSubscription(ws, requestPayload);
215
- break;
216
- case 'next':
217
- const chatResponse = await this.handleChatResponse(parsedMessage);
218
- if (chatResponse) {
219
- responseContent = chatResponse;
220
- // 获取到响应后立即关闭连接
221
- isComplete = true;
222
  ws.close();
223
- resolve(responseContent);
224
  }
225
- break;
226
- case 'complete':
227
- isComplete = true;
228
- ws.close();
229
- resolve(responseContent);
230
- break;
231
- }
232
- });
233
-
234
- ws.on('error', (err) => {
235
- console.error('WebSocket错误:', err);
236
- reject(err);
237
- });
238
-
239
- ws.on('close', (code, reason) => {
240
- console.log('请求完毕,关闭连接');
241
- if (!isComplete) {
242
- reject(new Error('WebSocket closed unexpectedly'));
243
- }
244
- });
245
- });
246
- }
247
-
248
- // 发送聊天订阅
249
- static sendChatSubscription(ws, requestPayload) {
250
- const subscribeMessage = {
251
- id: uuidv4(),
252
- type: 'subscribe',
253
- payload: {
254
- variables: {
255
- messageInput: requestPayload.contextMessages,
256
- messageContext: null,
257
- organizationId: 'org_JfjtEvzbwOikUEUn',
258
- integrationId: 'clwtqz9sq001izszu8ms5g4om',
259
- chatMode: 'AUTO',
260
- context: requestPayload.systemMessage,
261
- messageAttributes: {},
262
- includeAIAnnotations: false,
263
- environment: 'production'
264
- },
265
- extensions: {},
266
- operationName: 'OnNewSessionChatResult',
267
- query: `subscription OnNewSessionChatResult($messageInput: String!, $messageContext: String, $organizationId: ID!, $integrationId: ID, $chatMode: ChatMode, $filters: ChatFiltersInput, $messageAttributes: JSON, $tags: [String!], $workflowId: String, $context: String, $guidance: String, $includeAIAnnotations: Boolean!, $environment: String) {
268
- newSessionChatResult(
269
- input: {messageInput: $messageInput, messageContext: $messageContext, organizationId: $organizationId, integrationId: $integrationId, chatMode: $chatMode, filters: $filters, messageAttributes: $messageAttributes, tags: $tags, workflowId: $workflowId, context: $context, guidance: $guidance, environment: $environment}
270
- ) {
271
- isEnd
272
- sessionId
273
- message {
274
- id
275
- content
276
- }
277
- __typename
278
- }
279
- }`
280
- }
281
- };
282
-
283
- ws.send(JSON.stringify(subscribeMessage));
284
- }
285
 
286
- // 处理聊天响应
287
- static async handleChatResponse(message) {
288
- if (message.payload && message.payload.data) {
289
- const chatResult = message.payload.data.newSessionChatResult;
290
- if (chatResult && chatResult.isEnd == true && chatResult.message) {
291
- return chatResult.message.content;
292
- }
293
- }
294
- return null;
295
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
  }
297
 
298
  // 创建Express应用
@@ -308,7 +345,7 @@ app.use(cors({
308
  }));
309
 
310
  // 获取模型列表路由
311
- app.get('/hf/v1/models', (req, res) => {
312
  res.json({
313
  object: "list",
314
  data: [{
@@ -321,7 +358,7 @@ app.get('/hf/v1/models', (req, res) => {
321
  });
322
 
323
  // 聊天完成路由
324
- app.post('/hf/v1/chat/completions', async (req, res) => {
325
  try {
326
  const { messages, model, stream } = req.body;
327
  const authToken = req.headers.authorization?.replace('Bearer ', '');
 
172
 
173
  // WebSocket工具类
174
  class WebSocketUtils {
175
+ static isProcessing = false; // 添加静态属性用于并行控制
176
+ static TIMEOUT = 5 * 60 * 1000; // 5分钟超时时间
177
+
178
+ // 生成WebSocket密钥
179
+ static generateWebSocketKey() {
180
+ return randomBytes(16).toString('base64');
181
+ }
182
+
183
+ // 创建WebSocket客户端
184
+ static async createWebSocketClient(requestPayload) {
185
+ if (this.isProcessing) {
186
+ throw new Error('上游服务繁忙,只允许单次请求,请稍后重试!');
187
+ }
188
+
189
+ this.isProcessing = true;
190
+ let timeoutId;
191
+ let ws;
192
+
193
+ try {
194
+ return await new Promise((resolve, reject) => {
195
+ const websocketKey = this.generateWebSocketKey();
196
+ ws = new WebSocket(CONFIG.API.BASE_URL, 'graphql-transport-ws', {
197
+ headers: {
198
+ ...CONFIG.DEFAULT_HEADERS,
199
+ 'Sec-WebSocket-Key': websocketKey,
200
+ }
201
+ });
202
 
203
+ // 设置超时处理
204
+ timeoutId = setTimeout(() => {
205
+ if (ws.readyState === WebSocket.OPEN) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  ws.close();
 
207
  }
208
+ reject(new Error('WebSocket连接超时(5分钟)'));
209
+ }, this.TIMEOUT);
210
+
211
+ let responseContent = '';
212
+ let isComplete = false;
213
+
214
+ ws.on('open', () => {
215
+ console.log('WebSocket连接已建立');
216
+ const connectionInitMessage = {
217
+ type: 'connection_init',
218
+ payload: {
219
+ headers: {
220
+ Authorization: 'Bearer ee5b7c15ed3553cd6abc407340aad09ac7cb3b9f76d8613a'
221
+ }
222
+ }
223
+ };
224
+ ws.send(JSON.stringify(connectionInitMessage));
225
+ });
226
+
227
+ ws.on('message', async (data) => {
228
+ const message = data.toString();
229
+ const parsedMessage = JSON.parse(message);
230
+
231
+ switch (parsedMessage.type) {
232
+ case 'connection_ack':
233
+ console.log('WebSocket连接请求中');
234
+ this.sendChatSubscription(ws, requestPayload);
235
+ break;
236
+ case 'next':
237
+ const chatResponse = await this.handleChatResponse(parsedMessage);
238
+ if (chatResponse) {
239
+ responseContent = chatResponse;
240
+ // 获取到响应后立即关闭连接
241
+ isComplete = true;
242
+ ws.close();
243
+ resolve(responseContent);
244
+ }
245
+ break;
246
+ case 'complete':
247
+ isComplete = true;
248
+ ws.close();
249
+ resolve(responseContent);
250
+ break;
251
+ }
252
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
 
254
+ ws.on('error', (err) => {
255
+ console.error('WebSocket错误:', err);
256
+ clearTimeout(timeoutId);
257
+ this.isProcessing = false;
258
+ if (ws.readyState === WebSocket.OPEN) {
259
+ ws.close();
260
+ }
261
+ reject(err);
262
+ });
263
+
264
+ ws.on('close', (code, reason) => {
265
+ console.log('请求完毕,关闭连接');
266
+ clearTimeout(timeoutId);
267
+ this.isProcessing = false;
268
+ if (!isComplete) {
269
+ reject(new Error('WebSocket closed unexpectedly'));
270
+ }
271
+ });
272
+ });
273
+ } catch (error) {
274
+ clearTimeout(timeoutId);
275
+ this.isProcessing = false;
276
+ if (ws && ws.readyState === WebSocket.OPEN) {
277
+ ws.close();
278
+ }
279
+ throw error;
280
+ }
281
+ }
282
+
283
+ // 发送聊天订阅
284
+ static sendChatSubscription(ws, requestPayload) {
285
+ const subscribeMessage = {
286
+ id: uuidv4(),
287
+ type: 'subscribe',
288
+ payload: {
289
+ variables: {
290
+ messageInput: requestPayload.contextMessages,
291
+ messageContext: null,
292
+ organizationId: 'org_JfjtEvzbwOikUEUn',
293
+ integrationId: 'clwtqz9sq001izszu8ms5g4om',
294
+ chatMode: 'AUTO',
295
+ context: requestPayload.systemMessage,
296
+ messageAttributes: {},
297
+ includeAIAnnotations: false,
298
+ environment: 'production'
299
+ },
300
+ extensions: {},
301
+ operationName: 'OnNewSessionChatResult',
302
+ query: `subscription OnNewSessionChatResult($messageInput: String!, $messageContext: String, $organizationId: ID!, $integrationId: ID, $chatMode: ChatMode, $filters: ChatFiltersInput, $messageAttributes: JSON, $tags: [String!], $workflowId: String, $context: String, $guidance: String, $includeAIAnnotations: Boolean!, $environment: String) {
303
+ newSessionChatResult(
304
+ input: {messageInput: $messageInput, messageContext: $messageContext, organizationId: $organizationId, integrationId: $integrationId, chatMode: $chatMode, filters: $filters, messageAttributes: $messageAttributes, tags: $tags, workflowId: $workflowId, context: $context, guidance: $guidance, environment: $environment}
305
+ ) {
306
+ isEnd
307
+ sessionId
308
+ message {
309
+ id
310
+ content
311
+ }
312
+ __typename
313
+ }
314
+ }`
315
+ }
316
+ };
317
+
318
+ if (ws.readyState === WebSocket.OPEN) {
319
+ ws.send(JSON.stringify(subscribeMessage));
320
+ }
321
+ }
322
+
323
+ // 处理聊天响应
324
+ static async handleChatResponse(message) {
325
+ if (message.payload && message.payload.data) {
326
+ const chatResult = message.payload.data.newSessionChatResult;
327
+ if (chatResult && chatResult.isEnd == true && chatResult.message) {
328
+ return chatResult.message.content;
329
+ }
330
+ }
331
+ return null;
332
+ }
333
  }
334
 
335
  // 创建Express应用
 
345
  }));
346
 
347
  // 获取模型列表路由
348
+ app.get('/v1/models', (req, res) => {
349
  res.json({
350
  object: "list",
351
  data: [{
 
358
  });
359
 
360
  // 聊天完成路由
361
+ app.post('/v1/chat/completions', async (req, res) => {
362
  try {
363
  const { messages, model, stream } = req.body;
364
  const authToken = req.headers.authorization?.replace('Bearer ', '');