jeff86 commited on
Commit
29f01c3
·
verified ·
1 Parent(s): df34968

Delete app.js

Browse files
Files changed (1) hide show
  1. app.js +0 -401
app.js DELETED
@@ -1,401 +0,0 @@
1
- const express = require("express");
2
- const bodyParser = require("body-parser");
3
- const axios = require("axios");
4
- const https = require("https");
5
- const { encode } = require("gpt-3-encoder");
6
- const { randomUUID, randomInt, createHash } = require("crypto");
7
- const { config } = require("dotenv");
8
-
9
- config();
10
-
11
- // Constants for the server and API configuration
12
- const port = process.env.SERVER_PORT || 3040;
13
- const baseUrl = "https://chat.openai.com";
14
- const apiUrl = `${baseUrl}/backend-api/conversation`;
15
- const refreshInterval = 60000; // Interval to refresh token in ms
16
- const errorWait = 120000; // Wait time in ms after an error
17
- const newSessionRetries = parseInt(process.env.NEW_SESSION_RETRIES) || 5;
18
- const userAgent = process.env.USER_AGENT || "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36";
19
-
20
- // Initialize global variables to store the session token and device ID
21
- let token;
22
- let oaiDeviceId;
23
-
24
- // Function to wait for a specified duration
25
- const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
26
-
27
- function GenerateCompletionId(prefix = "cmpl-") {
28
- const characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
29
- const length = 28;
30
-
31
- for (let i = 0; i < length; i++) {
32
- prefix += characters.charAt(Math.floor(Math.random() * characters.length));
33
- }
34
-
35
- return prefix;
36
- }
37
-
38
- async function* chunksToLines(chunksAsync) {
39
- let previous = "";
40
- for await (const chunk of chunksAsync) {
41
- const bufferChunk = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
42
- previous += bufferChunk;
43
- let eolIndex;
44
- while ((eolIndex = previous.indexOf("\n")) >= 0) {
45
- // line includes the EOL
46
- const line = previous.slice(0, eolIndex + 1).trimEnd();
47
- if (line === "data: [DONE]") break;
48
- if (line.startsWith("data: ")) yield line;
49
- previous = previous.slice(eolIndex + 1);
50
- }
51
- }
52
- }
53
-
54
- async function* linesToMessages(linesAsync) {
55
- for await (const line of linesAsync) {
56
- const message = line.substring("data :".length);
57
-
58
- yield message;
59
- }
60
- }
61
-
62
- async function* StreamCompletion(data) {
63
- yield* linesToMessages(chunksToLines(data));
64
- }
65
-
66
- // Setup axios instance for API requests with predefined configurations
67
- const axiosInstance = axios.create({
68
- httpsAgent: new https.Agent({ rejectUnauthorized: false }),
69
- headers: {
70
- accept: "*/*",
71
- "accept-language": "en-US,en;q=0.9",
72
- "cache-control": "no-cache",
73
- "content-type": "application/json",
74
- "oai-language": "en-US",
75
- origin: baseUrl,
76
- pragma: "no-cache",
77
- referer: baseUrl,
78
- "sec-ch-ua": '"Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"',
79
- "sec-ch-ua-mobile": "?0",
80
- "sec-ch-ua-platform": '"Windows"',
81
- "sec-fetch-dest": "empty",
82
- "sec-fetch-mode": "cors",
83
- "sec-fetch-site": "same-origin",
84
- "user-agent": userAgent,
85
- },
86
- });
87
-
88
- function generateProofToken(seed, diff, userAgent) {
89
- const cores = [8, 12, 16, 24];
90
- const screens = [3000, 4000, 6000];
91
- const core = cores[randomInt(0, cores.length)];
92
- const screen = screens[randomInt(0, screens.length)];
93
- const now = new Date(Date.now() - 8 * 3600 * 1000);
94
- const parseTime = now.toUTCString().replace("GMT", "GMT-0500 (Eastern Time)");
95
- const config = [core + screen, parseTime, 4294705152, 0, userAgent];
96
- const diffLen = diff.length / 2;
97
- for (let i = 0; i < 100000; i++) {
98
- config[3] = i;
99
- const jsonData = JSON.stringify(config);
100
- const base = Buffer.from(jsonData).toString("base64");
101
- const hashValue = createHash("sha3-512")
102
- .update(seed + base)
103
- .digest();
104
- if (hashValue.toString("hex").substring(0, diffLen) <= diff) {
105
- const result = "gAAAAAB" + base;
106
- return result;
107
- }
108
- }
109
- const fallbackBase = Buffer.from(`"${seed}"`).toString("base64");
110
- return "gAAAAABwQ8Lk5FbGpA2NcR9dShT6gYjU7VxZ4D" + fallbackBase;
111
- }
112
-
113
- // Function to get a new session ID and token from the OpenAI API
114
- async function getNewSession(retries = 0) {
115
- let newDeviceId = randomUUID();
116
- try {
117
- const response = await axiosInstance.post(
118
- `${baseUrl}/backend-anon/sentinel/chat-requirements`,
119
- {},
120
- {
121
- headers: { "oai-device-id": newDeviceId },
122
- }
123
- );
124
-
125
- let session = response.data;
126
- session.deviceId = newDeviceId;
127
-
128
- console.log(
129
- `System: Successfully refreshed session ID and token. ${
130
- !token ? "(Now it's ready to process requests)" : ""
131
- }`
132
- );
133
- oaiDeviceId = newDeviceId;
134
- token = session.token;
135
-
136
- return session;
137
- } catch (error) {
138
- await wait(500);
139
- return retries < newSessionRetries ? getNewSession(retries + 1) : null;
140
- }
141
- }
142
-
143
- // Middleware to enable CORS and handle pre-flight requests
144
- function enableCORS(req, res, next) {
145
- res.header("Access-Control-Allow-Origin", "*");
146
- res.header("Access-Control-Allow-Headers", "*");
147
- res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
148
- if (req.method === "OPTIONS") {
149
- return res.status(200).end();
150
- }
151
- next();
152
- }
153
-
154
- // Middleware to handle chat completions
155
- async function handleChatCompletion(req, res) {
156
- console.log(
157
- "Request:",
158
- `${req.method} ${req.originalUrl}`,
159
- `${req.body?.messages?.length ?? 0} messages`,
160
- req.body.stream ? "(stream-enabled)" : "(stream-disabled)"
161
- );
162
- try {
163
- let session = await getNewSession();
164
- if (!session) {
165
- res.write(
166
- JSON.stringify({
167
- status: false,
168
- error: {
169
- message: `Error getting a new session, please try again later, if the issue persists, please open an issue on the GitHub repository.`,
170
- type: "invalid_request_error",
171
- },
172
- })
173
- );
174
- return res.end();
175
- }
176
- let proofToken = generateProofToken(
177
- session.proofofwork.seed,
178
- session.proofofwork.difficulty,
179
- userAgent
180
- );
181
- const body = {
182
- action: "next",
183
- messages: req.body.messages.map((message) => ({
184
- author: { role: message.role },
185
- content: { content_type: "text", parts: [message.content] },
186
- })),
187
- parent_message_id: randomUUID(),
188
- model: "text-davinci-002-render-sha",
189
- timezone_offset_min: -180,
190
- suggestions: [],
191
- history_and_training_disabled: true,
192
- conversation_mode: { kind: "primary_assistant" },
193
- websocket_request_id: randomUUID(),
194
- };
195
- let promptTokens = 0;
196
- let completionTokens = 0;
197
- for (let message of req.body.messages) {
198
- promptTokens += encode(message.content).length;
199
- }
200
-
201
- const response = await axiosInstance.post(apiUrl, body, {
202
- responseType: "stream",
203
- headers: {
204
- "oai-device-id": session.deviceId,
205
- "openai-sentinel-chat-requirements-token": session.token,
206
- "openai-sentinel-proof-token": proofToken,
207
- },
208
- });
209
-
210
- // Set the response headers based on the request type
211
- if (req.body.stream) {
212
- res.setHeader("Content-Type", "text/event-stream");
213
- res.setHeader("Cache-Control", "no-cache");
214
- res.setHeader("Connection", "keep-alive");
215
- } else {
216
- res.setHeader("Content-Type", "application/json");
217
- }
218
-
219
- let fullContent = "";
220
- let requestId = GenerateCompletionId("chatcmpl-");
221
- let created = Math.floor(Date.now() / 1000); // Unix timestamp in seconds
222
- let finish_reason = null;
223
- let error;
224
-
225
- for await (const message of StreamCompletion(response.data)) {
226
- // Skip heartbeat detection
227
- if (message.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{6}$/))
228
- continue;
229
-
230
- const parsed = JSON.parse(message);
231
-
232
- if (parsed.error) {
233
- error = `Error message from OpenAI: ${parsed.error}`;
234
- finish_reason = "stop";
235
- break;
236
- }
237
-
238
- let content = parsed?.message?.content?.parts[0] ?? "";
239
- let status = parsed?.message?.status ?? "";
240
-
241
- for (let message of req.body.messages) {
242
- if (message.content === content) {
243
- content = "";
244
- break;
245
- }
246
- }
247
-
248
- switch (status) {
249
- case "in_progress":
250
- finish_reason = null;
251
- break;
252
- case "finished_successfully":
253
- let finish_reason_data =
254
- parsed?.message?.metadata?.finish_details?.type ?? null;
255
- switch (finish_reason_data) {
256
- case "max_tokens":
257
- finish_reason = "length";
258
- break;
259
- case "stop":
260
- default:
261
- finish_reason = "stop";
262
- }
263
- break;
264
- default:
265
- finish_reason = null;
266
- }
267
-
268
- if (content === "") continue;
269
-
270
- let completionChunk = content.replace(fullContent, "");
271
-
272
- completionTokens += encode(completionChunk).length;
273
-
274
- if (req.body.stream) {
275
- let response = {
276
- id: requestId,
277
- created: created,
278
- object: "chat.completion.chunk",
279
- model: "gpt-3.5-turbo",
280
- choices: [
281
- {
282
- delta: {
283
- content: completionChunk,
284
- },
285
- index: 0,
286
- finish_reason: finish_reason,
287
- },
288
- ],
289
- };
290
-
291
- res.write(`data: ${JSON.stringify(response)}\n\n`);
292
- }
293
-
294
- fullContent = content.length > fullContent.length ? content : fullContent;
295
- }
296
-
297
- if (req.body.stream) {
298
- res.write(
299
- `data: ${JSON.stringify({
300
- id: requestId,
301
- created: created,
302
- object: "chat.completion.chunk",
303
- model: "gpt-3.5-turbo",
304
- choices: [
305
- {
306
- delta: {
307
- content: error ?? "",
308
- },
309
- index: 0,
310
- finish_reason: finish_reason,
311
- },
312
- ],
313
- })}\n\n`
314
- );
315
- } else {
316
- res.write(
317
- JSON.stringify({
318
- id: requestId,
319
- created: created,
320
- model: "gpt-3.5-turbo",
321
- object: "chat.completion",
322
- choices: [
323
- {
324
- finish_reason: finish_reason,
325
- index: 0,
326
- message: {
327
- content: error ?? fullContent,
328
- role: "assistant",
329
- },
330
- },
331
- ],
332
- usage: {
333
- prompt_tokens: promptTokens,
334
- completion_tokens: completionTokens,
335
- total_tokens: promptTokens + completionTokens,
336
- },
337
- })
338
- );
339
- }
340
-
341
- res.end();
342
- } catch (error) {
343
- if (!res.headersSent) res.setHeader("Content-Type", "application/json");
344
- res.write(
345
- JSON.stringify({
346
- status: false,
347
- error: {
348
- message:
349
- "An error occurred. Please try again. Additionally, ensure that your request complies with OpenAI's policy.",
350
- type: "invalid_request_error",
351
- },
352
- })
353
- );
354
- res.end();
355
- }
356
- }
357
-
358
- // Initialize Express app and use middlewares
359
- const app = express();
360
- app.use(bodyParser.json());
361
- app.use(enableCORS);
362
-
363
- // Route to handle POST requests for chat completions
364
- app.post("/proxies/v1/chat/completions", handleChatCompletion);
365
-
366
- // 404 handler for unmatched routes
367
- app.use((req, res) =>
368
- res.status(404).send({
369
- status: false,
370
- error: {
371
- message: `The requested endpoint (${req.method.toLocaleUpperCase()} ${req.path}) was not found. https://github.com/missuo/FreeGPT35`,
372
- type: "invalid_request_error",
373
- },
374
- })
375
- );
376
-
377
- // Start the server and the session ID refresh loop
378
- app.listen(port, async () => {
379
- console.log(`💡 Server is running at http://localhost:${port}`);
380
- console.log();
381
- console.log(`🔗 Local Base URL: http://localhost:${port}/v1`);
382
- console.log(`🔗 Local Endpoint: http://localhost:${port}/v1/chat/completions`);
383
- console.log();
384
- console.log("📝 Original TS Source By: Pawan.Krd");
385
- console.log("📝 Modified By: Vincent");
386
- console.log();
387
-
388
- setTimeout(async () => {
389
- while (true) {
390
- try {
391
- await getNewSession();
392
- await wait(refreshInterval);
393
- } catch (error) {
394
- console.error("Error refreshing session ID, retrying in 2 minute...");
395
- console.error("If this error persists, your country may not be supported yet.");
396
- console.error("If your country was the issue, please consider using a U.S. VPN.");
397
- await wait(errorWait);
398
- }
399
- }
400
- }, 0);
401
- });