deepak191z commited on
Commit
35a87e3
·
verified ·
1 Parent(s): b511825

Update server.js

Browse files
Files changed (1) hide show
  1. server.js +63 -45
server.js CHANGED
@@ -35,6 +35,13 @@ const withBenchmarking = (request) => {
35
  request.start = Date.now();
36
  };
37
 
 
 
 
 
 
 
 
38
  const logger = (res, req) => {
39
  console.log(req.method, res.status, req.url, Date.now() - req.start, 'ms');
40
  };
@@ -45,9 +52,10 @@ const router = AutoRouter({
45
  finally: [corsify, logger],
46
  });
47
 
48
- router.get('/', () => json({ message: 'API Service Running!' }));
49
- router.get('/ping', () => json({ message: 'pong' }));
50
- router.get(config.API_PREFIX + 'v1/models', () =>
 
51
  json({
52
  object: 'list',
53
  data: [
@@ -67,21 +75,24 @@ async function handleCompletion(request) {
67
  const { model: inputModel, messages, stream: returnStream } = await request.json();
68
  const model = convertModel(inputModel);
69
  const content = messagesPrepare(messages);
70
- return createCompletion(model, content, returnStream);
 
 
71
  } catch (err) {
72
  console.error('Handle Completion Error:', err);
73
  return error(500, err.message);
74
  }
75
  }
76
 
77
- async function createCompletion(model, content, returnStream, retryCount = 0) {
78
  try {
79
- const token = await requestToken();
80
  const response = await fetch('https://duckduckgo.com/duckchat/v1/chat', {
81
  method: 'POST',
82
  headers: {
83
  ...config.FAKE_HEADERS,
84
  'x-vqd-4': token,
 
85
  },
86
  body: JSON.stringify({
87
  model,
@@ -103,7 +114,7 @@ async function createCompletion(model, content, returnStream, retryCount = 0) {
103
  if (retryCount < config.MAX_RETRY_COUNT && (err.message.includes('Rate limit') || err.message.includes('418'))) {
104
  console.log('Retrying... count', ++retryCount);
105
  await new Promise((resolve) => setTimeout(resolve, config.RETRY_DELAY));
106
- return createCompletion(model, content, returnStream, retryCount);
107
  }
108
  throw err;
109
  }
@@ -172,72 +183,79 @@ function messagesPrepare(messages) {
172
  .join('\n');
173
  }
174
 
175
- async function requestToken() {
176
  try {
177
  const response = await fetch('https://duckduckgo.com/duckchat/v1/status', {
178
  method: 'GET',
179
- headers: config.FAKE_HEADERS,
 
 
 
180
  });
181
- const token = response.headers.get('x-vqd-4');
182
- if (!token) {
183
- console.error('No x-vqd-4 token found in response headers');
184
- throw new Error('Failed to retrieve x-vqd-4 token');
185
  }
186
- console.log('Token retrieved:', token);
187
- return token;
188
  } catch (err) {
189
- console.error('Request token error:', err);
190
  throw err;
191
  }
192
  }
193
 
194
- function convertModel(inputModel) {
195
- const modelMap = {
196
- 'claude-3-haiku': 'claude-3-haiku-20240307',
197
- 'llama-3.1-70b': 'meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo',
198
- 'mixtral-8x7b': 'mistralai/Mixtral-8x7B-Instruct-v0.1',
199
- 'o3-mini': 'o3-mini', // Fallback to default if unsupported
200
- };
201
- const selectedModel = modelMap[inputModel.toLowerCase()] || 'gpt-4o-mini';
202
- console.log(`Converted model: ${inputModel} -> ${selectedModel}`);
203
- return selectedModel;
204
  }
205
 
206
- function newChatCompletionChunkWithModel(text, model) {
207
  return {
208
- id: 'chatcmpl-' + Math.random().toString(36).slice(2),
209
- object: 'chat.completion.chunk',
210
  created: Math.floor(Date.now() / 1000),
211
  model,
212
- choices: [{ index: 0, delta: { content: text }, finish_reason: null }],
 
 
 
 
 
 
213
  };
214
  }
215
 
216
- function newStopChunkWithModel(reason, model) {
217
  return {
218
- id: 'chatcmpl-' + Math.random().toString(36).slice(2),
219
  object: 'chat.completion.chunk',
220
  created: Math.floor(Date.now() / 1000),
221
  model,
222
- choices: [{ index: 0, finish_reason: reason }],
 
 
 
 
 
 
223
  };
224
  }
225
 
226
- function newChatCompletionWithModel(text, model) {
227
  return {
228
- id: 'chatcmpl-' + Math.random().toString(36).slice(2),
229
- object: 'chat.completion',
230
  created: Math.floor(Date.now() / 1000),
231
  model,
232
- usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },
233
- choices: [{ message: { content: text, role: 'assistant' }, index: 0 }],
 
 
 
 
 
234
  };
235
  }
236
 
237
- (async () => {
238
- if (typeof addEventListener === 'function') return;
239
- const ittyServer = createServerAdapter(router.fetch);
240
- console.log(`Listening on http://0.0.0.0:${config.PORT}`);
241
- const httpServer = createServer(ittyServer);
242
- httpServer.listen(config.PORT, '0.0.0.0');
243
- })();
 
35
  request.start = Date.now();
36
  };
37
 
38
+ const getClientIP = (req) => {
39
+ return req.headers['x-forwarded-for']?.split(',')[0]?.trim() ||
40
+ req.headers['x-real-ip'] ||
41
+ req.socket?.remoteAddress ||
42
+ null;
43
+ };
44
+
45
  const logger = (res, req) => {
46
  console.log(req.method, res.status, req.url, Date.now() - req.start, 'ms');
47
  };
 
52
  finally: [corsify, logger],
53
  });
54
 
55
+ router.get('/', (req) => json({ message: 'API Service Running!' }));
56
+ router.get('/ping', (req) => json({ message: 'pong' }));
57
+
58
+ router.get(config.API_PREFIX + 'v1/models', (req) =>
59
  json({
60
  object: 'list',
61
  data: [
 
75
  const { model: inputModel, messages, stream: returnStream } = await request.json();
76
  const model = convertModel(inputModel);
77
  const content = messagesPrepare(messages);
78
+ const clientIp = getClientIP(request);
79
+
80
+ return createCompletion(model, content, returnStream, clientIp);
81
  } catch (err) {
82
  console.error('Handle Completion Error:', err);
83
  return error(500, err.message);
84
  }
85
  }
86
 
87
+ async function createCompletion(model, content, returnStream, clientIp, retryCount = 0) {
88
  try {
89
+ const token = await requestToken(clientIp);
90
  const response = await fetch('https://duckduckgo.com/duckchat/v1/chat', {
91
  method: 'POST',
92
  headers: {
93
  ...config.FAKE_HEADERS,
94
  'x-vqd-4': token,
95
+ ...(clientIp ? { 'x-forwarded-for': clientIp } : {}),
96
  },
97
  body: JSON.stringify({
98
  model,
 
114
  if (retryCount < config.MAX_RETRY_COUNT && (err.message.includes('Rate limit') || err.message.includes('418'))) {
115
  console.log('Retrying... count', ++retryCount);
116
  await new Promise((resolve) => setTimeout(resolve, config.RETRY_DELAY));
117
+ return createCompletion(model, content, returnStream, clientIp, retryCount);
118
  }
119
  throw err;
120
  }
 
183
  .join('\n');
184
  }
185
 
186
+ async function requestToken(clientIp) {
187
  try {
188
  const response = await fetch('https://duckduckgo.com/duckchat/v1/status', {
189
  method: 'GET',
190
+ headers: {
191
+ ...config.FAKE_HEADERS,
192
+ ...(clientIp ? { 'x-forwarded-for': clientIp } : {}),
193
+ },
194
  });
195
+ if (!response.ok) {
196
+ throw new Error('Request Token failed!');
 
 
197
  }
198
+ const data = await response.json();
199
+ return data?.vqd;
200
  } catch (err) {
201
+ console.error('Request Token Error:', err);
202
  throw err;
203
  }
204
  }
205
 
206
+ function convertModel(model) {
207
+ return model; // Adjust if needed
 
 
 
 
 
 
 
 
208
  }
209
 
210
+ function newChatCompletionWithModel(content, model) {
211
  return {
212
+ id: 'chatcmpl-' + Date.now(),
213
+ object: 'chat.completion',
214
  created: Math.floor(Date.now() / 1000),
215
  model,
216
+ choices: [
217
+ {
218
+ index: 0,
219
+ message: { role: 'assistant', content },
220
+ finish_reason: 'stop',
221
+ },
222
+ ],
223
  };
224
  }
225
 
226
+ function newChatCompletionChunkWithModel(content, model) {
227
  return {
228
+ id: 'chatcmpl-' + Date.now(),
229
  object: 'chat.completion.chunk',
230
  created: Math.floor(Date.now() / 1000),
231
  model,
232
+ choices: [
233
+ {
234
+ delta: { content },
235
+ index: 0,
236
+ finish_reason: null,
237
+ },
238
+ ],
239
  };
240
  }
241
 
242
+ function newStopChunkWithModel(reason, model) {
243
  return {
244
+ id: 'chatcmpl-' + Date.now(),
245
+ object: 'chat.completion.chunk',
246
  created: Math.floor(Date.now() / 1000),
247
  model,
248
+ choices: [
249
+ {
250
+ delta: {},
251
+ index: 0,
252
+ finish_reason: reason,
253
+ },
254
+ ],
255
  };
256
  }
257
 
258
+ // Create Server
259
+ createServer(createServerAdapter(router.fetch)).listen(config.PORT, () => {
260
+ console.log('Server running at http://localhost:' + config.PORT);
261
+ });