mrloler/oai-claude
1
1const FormData = require('form-data');2 3const wait = (duration) => {4 return new Promise((resolve) => {5 setTimeout(() => {6 resolve();7 }, duration);8 });9};10 11function buildPrompt(messages) {12 prompt = "\n\n" + preparePrompt(messages);13 return prompt;14 //do not escape for now15 const escapedPrompt = prompt.replace(/\r?\n|\r/g, '\\n').replace(/"/g, '\\"');16 return escapedPrompt;17};18 19const readBody = (res, json) => new Promise((resolve, reject) => {20 let buffer = '';21 22 res.on('data', chunk => {23 buffer += chunk;24 });25 26 res.on('end', () => {27 try {28 if (json) buffer = JSON.parse(buffer);29 resolve(buffer);30 } catch (e) {31 console.error(buffer);32 reject(e);33 }34 });35})36 37function preparePrompt(messages) {38 return messages.filter(m => m.content?.trim()).map(m => {39 let author = '';40 switch (m.role) {41 case 'user': author = 'Human'; break;42 case 'assistant': author = 'Assistant'; break;43 case 'system': author = 'System Note'; break;44 default: author = m.role; break;45 }46 47 return `${author}: ${m.content.trim()}`;48 }).join('\n\n');49}50 51const currentTime = () => {52 const date = new Date();53 const year = date.getFullYear();54 const month = String(date.getMonth() + 1).padStart(2, '0');55 const day = String(date.getDate()).padStart(2, '0');56 const hours = String(date.getHours()).padStart(2, '0');57 const minutes = String(date.getMinutes()).padStart(2, '0');58 const seconds = String(date.getSeconds()).padStart(2, '0');59 const milliseconds = String(date.getMilliseconds()).padStart(3, '0');60 61 return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`;62};63 64const genHeaders = (config) => {65 return {66 'Cookie': `d=${config.cookie};`,67 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0',68 }69}70 71function splitJsonArray(jsonArray, maxLength) {72 let result = [];73 let currentChunk = [];74 let currentLength = 2; // Accounts for the opening and closing square brackets in the JSON array75 76 const jail = '(OOC: This is just a part of the context, reply only with "OOC: understood")';77 const assistant = "\n\nAssistant: ";78 79 const addObjectToChunk = (object, chunk) => {80 chunk.push(object);81 return currentLength + JSON.stringify(object).length + 1;82 };83 84 const appendTextToContent = (object, text) => {85 const newObj = JSON.parse(JSON.stringify(object));86 newObj.content += text;87 return newObj;88 };89 90 for (const obj of jsonArray) {91 const objLength = JSON.stringify(obj).length + 1;92 93 if (currentLength + objLength <= maxLength) {94 currentLength = addObjectToChunk(obj, currentChunk);95 } else {96 const lastObjectInChunk = currentChunk[currentChunk.length - 1];97 if (!lastObjectInChunk) continue;98 const lastObjectWithJail = appendTextToContent(lastObjectInChunk, ` ${jail}`);99 const lastObjectWithJailLength = JSON.stringify(lastObjectWithJail).length + 1;100 101 if (currentLength - JSON.stringify(lastObjectInChunk).length - 1 + lastObjectWithJailLength <= maxLength) {102 currentChunk[currentChunk.length - 1] = lastObjectWithJail;103 }104 105 result.push(currentChunk);106 currentChunk = [obj];107 currentLength = 2 + objLength;108 }109 }110 111 if (currentChunk.length > 0) {112 result.push(currentChunk);113 }114 115 const lastChunk = result[result.length - 1];116 const lastObjectInLastChunk = lastChunk[lastChunk.length - 1];117 const lastObjectWithAssistant = appendTextToContent(lastObjectInLastChunk, assistant);118 const lastObjectWithAssistantLength = JSON.stringify(lastObjectWithAssistant).length + 1;119 120 if (currentLength - JSON.stringify(lastObjectInLastChunk).length - 1 + lastObjectWithAssistantLength <= maxLength) {121 lastChunk[lastChunk.length - 1] = lastObjectWithAssistant;122 }123 124 return result;125}126 127function convertToUnixTime(date) {128 const unixTime = Math.floor(date.getTime() / 1000);129 const randomDigit = Math.floor(Math.random() * 10);130 return `${unixTime}.xxxxx${randomDigit}`;131}132 133function createBaseForm(config) {134 const form = new FormData();135 form.append('token', config.token);136 form.append('channel', `${config.claudeId}`);137 form.append('_x_mode', 'online');138 form.append('_x_sonic', 'true');139 return form;140}141 142// Add the utility functions here143// e.g. escapePrompt, readBody, preparePrompt, currentTime, headers, convertToUnixTime, createBaseForm144 145const dataToResponse = (146 data,147 promptTokens,148 completionTokens,149 stream = false,150 reason = null151) => {152 const currDate = new Date();153 const contentData = { content: data, role: 'assistant' };154 const contentName = stream ? 'delta' : 'message';155 156 return {157 choices: [158 {159 [contentName]: !!data ? contentData : {},160 finish_reason: reason,161 index: 0,162 },163 ],164 created: currDate.getTime(),165 id: `chatcmpl-${(Math.random().toString(36).slice(2))}`,166 object: 'chat.completion.chunk',167 usage: {168 prompt_tokens: promptTokens,169 completion_tokens: completionTokens,170 total_tokens: promptTokens + completionTokens,171 },172 };173};174 175const stats = {176 prompts: []177}178 179module.exports = {180 buildPrompt,181 readBody,182 preparePrompt,183 currentTime,184 genHeaders,185 convertToUnixTime,186 createBaseForm,187 splitJsonArray,188 wait,189 dataToResponse,190 stats,191};