Commit ·
10a7711
1
Parent(s): 85fad92
Upload 12 files
Browse files- .gitignore +3 -0
- clewd.js +182 -167
- lib/clewd-stream.js +3 -5
- lib/clewd-utils.js +10 -4
- package.json +5 -2
.gitignore
CHANGED
|
@@ -13,6 +13,9 @@ yarn-error.log*
|
|
| 13 |
cookies.json
|
| 14 |
cookies.js
|
| 15 |
cookies.ini
|
|
|
|
|
|
|
|
|
|
| 16 |
config.js
|
| 17 |
log.txt
|
| 18 |
|
|
|
|
| 13 |
cookies.json
|
| 14 |
cookies.js
|
| 15 |
cookies.ini
|
| 16 |
+
lib/bin/cfg
|
| 17 |
+
lib/bin/hdr
|
| 18 |
+
lib/bin/pyld
|
| 19 |
config.js
|
| 20 |
log.txt
|
| 21 |
|
clewd.js
CHANGED
|
@@ -7,12 +7,13 @@
|
|
| 7 |
const {createServer: Server, IncomingMessage, ServerResponse} = require('node:http'), {createHash: Hash, randomUUID, randomInt, randomBytes} = require('node:crypto'), {TransformStream, ReadableStream} = require('node:stream/web'), {Readable, Writable} = require('node:stream'), {Blob} = require('node:buffer'), {existsSync: exists, writeFileSync: write, createWriteStream} = require('node:fs'), {join: joinP} = require('node:path'), {ClewdSuperfetch: Superfetch, SuperfetchAvailable} = require('./lib/clewd-superfetch'), {AI, fileName, genericFixes, bytesToSize, setTitle, checkResErr, Replacements, Main} = require('./lib/clewd-utils'), ClewdStream = require('./lib/clewd-stream');
|
| 8 |
|
| 9 |
/******************************************************* */
|
| 10 |
-
let currentIndex, Firstlogin = true, changeflag = 0, changetime = 0, totaltime, uuidOrgArray = [];
|
| 11 |
|
| 12 |
const events = require('events'), CookieChanger = new events.EventEmitter();
|
| 13 |
require('events').EventEmitter.defaultMaxListeners = 0;
|
| 14 |
|
| 15 |
CookieChanger.on('ChangeCookie', () => {
|
|
|
|
| 16 |
Proxy && Proxy.close();
|
| 17 |
console.log(`Changing Cookie...\n`);
|
| 18 |
Proxy.listen(Config.Port, Config.Ip, onListen);
|
|
@@ -21,117 +22,114 @@ CookieChanger.on('ChangeCookie', () => {
|
|
| 21 |
}));
|
| 22 |
});
|
| 23 |
|
| 24 |
-
const
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
} else {
|
| 33 |
-
byteLength += 1.5;
|
| 34 |
-
}
|
| 35 |
-
}
|
| 36 |
-
return byteLength;
|
| 37 |
-
}, padtxt = (content) => {
|
| 38 |
-
if (Config.padtxt_placeholder.length > 0) {
|
| 39 |
-
var placeholder = Config.padtxt_placeholder;
|
| 40 |
-
} else {
|
| 41 |
-
const bytes = randomInt(5, 15);
|
| 42 |
-
var placeholder = randomBytes(bytes).toString('hex');
|
| 43 |
-
}
|
| 44 |
-
let count = Math.floor((Config.Settings.padtxt - simpletokenizer(content)) / simpletokenizer(placeholder));
|
| 45 |
-
|
| 46 |
-
// 生成占位符字符串
|
| 47 |
let padding = '';
|
| 48 |
for (let i = 0; i < count; i++) {
|
| 49 |
padding += placeholder;
|
| 50 |
}
|
| 51 |
-
|
| 52 |
-
// 在prompt前面添加占位符, 在末尾增加空行然后添加prompt
|
| 53 |
content = padding + '\n\n\n' + content;
|
| 54 |
-
|
| 55 |
return content.trim();
|
| 56 |
-
}, xmlPlot =
|
| 57 |
// 检查内容中是否包含"<card>"
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
}
|
| 63 |
-
|
| 64 |
-
//群组
|
| 65 |
-
content = content.replace(/(<reply>\n|\n<\/reply>)\1*/g, '$1');
|
| 66 |
-
content = content.replace(/<customname>(.*?)<\/customname>:/gm, '$1:\n');
|
| 67 |
-
|
| 68 |
//role合并
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
content = content.replace(/^\s*Human:\s*/, '');
|
| 74 |
}
|
| 75 |
-
if (!
|
| 76 |
content = content.replace(/\n\nAssistant:(.*?(?:\n\nHuman:|$))/gs, function(match, p1) {return '\n\nAssistant:' + p1.replace(/\n\nAssistant:\s*/g, '\n\n')});
|
| 77 |
}
|
| 78 |
}
|
| 79 |
-
content = content.replace(/(\n\n|^)xmlPlot:\s*/gm, '$1');
|
| 80 |
content = content.replace(/<\!-- Merge.*?Disable -->/gm, '');
|
| 81 |
-
|
| 82 |
-
//
|
| 83 |
-
content = content.replace(/
|
| 84 |
-
let
|
| 85 |
-
let
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
const seglength = segcontentHuman.length;
|
| 91 |
-
for (let i = 1; i < seglength; i++) {
|
| 92 |
-
const match = segcontentHuman[i].match(/<PrevHuman>.*?<\/PrevHuman>/s);
|
| 93 |
-
if (match) {
|
| 94 |
-
segcontentHuman[i - 1] += match[0].replace(/<PrevHuman>(.*?)<\/PrevHuman>/s, '\n\n$1');
|
| 95 |
-
segcontentHuman[i] = segcontentHuman[i].replace(match[0], '');
|
| 96 |
}
|
|
|
|
| 97 |
}
|
| 98 |
-
|
| 99 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
}
|
| 101 |
-
content =
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
const cardtag = content.match(/(?=\n\n<\/card>)/) || '</card>';
|
| 110 |
const exampletag = content.match(/(?=\n\n<\/example>)/) || '</example>';
|
| 111 |
const plot = content.includes('</plot>') ? '<plot>' : '';
|
| 112 |
-
content = content.replace(/<example-note>.*<\/example-note>/, '');
|
| 113 |
const firstChatStart = content.indexOf('\n\n[Start a new');
|
| 114 |
const lastChatStart = content.lastIndexOf('\n\n[Start a new');
|
| 115 |
firstChatStart != -1 && firstChatStart === lastChatStart && (content = content.slice(0, firstChatStart) + `\n\n${cardtag}` + content.slice(firstChatStart));
|
| 116 |
-
firstChatStart != lastChatStart && (content = content.slice(0, firstChatStart) + `\n\n${cardtag}\n
|
| 117 |
-
|
| 118 |
-
//
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
if (segcontentlastIndex >= 2 && segcontentHuman[segcontentlastIndex].includes('<!-- Plain Prompt Enable -->') && !content.includes('\n\nPlainPrompt:')) {
|
| 122 |
-
content = segcontentHuman.slice(0, segcontentlastIndex).join('\n\nHuman:') + '\n\nPlainPrompt:' + segcontentHuman.slice(segcontentlastIndex).join('\n\nHuman:');
|
| 123 |
-
}
|
| 124 |
-
content = content.replace(/<\!-- Plain Prompt Enable -->/, '');
|
| 125 |
-
content = content.replace(/\n\nHuman:.*PlainPrompt:/, '\n\nPlainPrompt:');
|
| 126 |
-
|
| 127 |
-
//消除空XML tags或多余的\n
|
| 128 |
-
content = content.replace(/\n<\/(hidden|META)>\s+?<\1>\n/g, '');
|
| 129 |
-
content = content.replace(/\n<(card|example|hidden|plot|META)>\s+?<\1>/g, '\n<$1>');
|
| 130 |
content = content.replace(/(?:<!--.*?-->)?\n<(card|example|hidden|plot|META)>\s+?<\/\1>/g, '');
|
| 131 |
-
content = content.replace(/(?<=(: |\n)<(card|hidden|example|plot|META)>\n)\s*/g, '');
|
| 132 |
-
content = content.replace(/\s*(?=\n<\/(card|hidden|example|plot|META)>(\n|$))/g, '');
|
| 133 |
content = content.replace(/(?<=\n)\n(?=\n)/g, '');
|
| 134 |
-
|
| 135 |
return content.trim();
|
| 136 |
};
|
| 137 |
/******************************************************* */
|
|
@@ -147,8 +145,9 @@ const ConfigPath = joinP(__dirname, './config.js'), LogPath = joinP(__dirname, '
|
|
| 147 |
let uuidOrg, curPrompt = {}, prevPrompt = {}, prevMessages = [], prevImpersonated = false, Config = {
|
| 148 |
Cookie: '',
|
| 149 |
CookieArray: [],
|
| 150 |
-
Cookiecounter:
|
| 151 |
CookieIndex: 0,
|
|
|
|
| 152 |
Ip: (process.env.Cookie || process.env.CookieArray) ? '0.0.0.0' : '127.0.0.1',
|
| 153 |
Port: process.env.PORT || 8444,
|
| 154 |
localtunnel: false,
|
|
@@ -172,10 +171,10 @@ let uuidOrg, curPrompt = {}, prevPrompt = {}, prevMessages = [], prevImpersonate
|
|
| 172 |
StripHuman: false,
|
| 173 |
PassParams: false,
|
| 174 |
ClearFlags: true,
|
| 175 |
-
PreserveChats:
|
| 176 |
LogMessages: true,
|
| 177 |
FullColon: true,
|
| 178 |
-
padtxt:
|
| 179 |
xmlPlot: true,
|
| 180 |
Superfetch: true
|
| 181 |
}
|
|
@@ -222,14 +221,18 @@ const updateParams = res => {
|
|
| 222 |
if (Config.Settings.PreserveChats) {
|
| 223 |
return;
|
| 224 |
}
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 233 |
}, onListen = async () => {
|
| 234 |
/***************************** */
|
| 235 |
if (Firstlogin) {
|
|
@@ -250,7 +253,7 @@ const updateParams = res => {
|
|
| 250 |
currentIndex = (currentIndex + 1) % Config.CookieArray.length;
|
| 251 |
changetime += 1;
|
| 252 |
}
|
| 253 |
-
let percentage = ((changetime + Config.CookieIndex) / totaltime) * 100
|
| 254 |
if (Config.Cookiecounter < 0 && percentage > 100) {
|
| 255 |
console.log(`\n※※※Cookie cleanup completed※※※\n\n`);
|
| 256 |
return process.exit();
|
|
@@ -259,6 +262,7 @@ const updateParams = res => {
|
|
| 259 |
if ('SET YOUR COOKIE HERE' === Config.Cookie || Config.Cookie?.length < 1) {
|
| 260 |
throw Error('Set your cookie inside config.js');
|
| 261 |
}
|
|
|
|
| 262 |
updateCookies(Config.Cookie);
|
| 263 |
//console.log(`[2m${Main}[0m\n[33mhttp://${Config.Ip}:${Config.Port}/v1[0m\n\n${Object.keys(Config.Settings).map((setting => UnknownSettings.includes(setting) ? `??? [31m${setting}: ${Config.Settings[setting]}[0m` : `[1m${setting}:[0m ${ChangedSettings.includes(setting) ? '[33m' : '[36m'}${Config.Settings[setting]}[0m`)).sort().join('\n')}\n`);
|
| 264 |
//Config.Settings.Superfetch && SuperfetchAvailable(true);
|
|
@@ -271,9 +275,7 @@ const updateParams = res => {
|
|
| 271 |
});
|
| 272 |
/**************************** */
|
| 273 |
if (accRes.statusText === 'Forbidden' && Config.CookieArray?.length > 0) {
|
| 274 |
-
|
| 275 |
-
!process.env.Cookie && !process.env.CookieArray && writeSettings(Config);
|
| 276 |
-
currentIndex = (currentIndex - 1 + Config.CookieArray.length) % Config.CookieArray.length;
|
| 277 |
console.log(`[31mExpired![0m`);
|
| 278 |
Config.Cookiecounter < 0 && console.log(`[progress]: [32m${percentage.toFixed(2)}%[0m\n[length]: [33m${Config.CookieArray.length}[0m\n`);
|
| 279 |
CookieChanger.emit('ChangeCookie');
|
|
@@ -290,38 +292,64 @@ const updateParams = res => {
|
|
| 290 |
}
|
| 291 |
setTitle('ok');
|
| 292 |
updateParams(accRes);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 293 |
console.log(Config.CookieArray?.length > 0 ? `(index: [36m${currentIndex || Config.CookieArray.length}[0m) Logged in %o` : 'Logged in %o', { //console.log('Logged in %o', {
|
| 294 |
name: accInfo.name?.split('@')?.[0],
|
|
|
|
| 295 |
capabilities: accInfo.capabilities,
|
| 296 |
});
|
| 297 |
uuidOrg = accInfo?.uuid;
|
| 298 |
/************************* */
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 302 |
Config.Cookiecounter < 0 && console.log(`[progress]: [32m${percentage.toFixed(2)}%[0m\n[length]: [33m${Config.CookieArray.length}[0m\n`);
|
| 303 |
-
|
| 304 |
-
!process.env.Cookie && !process.env.CookieArray && writeSettings(Config);
|
| 305 |
-
CookieChanger.emit('ChangeCookie');
|
| 306 |
-
return;
|
| 307 |
-
} else {
|
| 308 |
-
uuidOrgArray.push(uuidOrg);
|
| 309 |
}
|
| 310 |
/************************* */
|
| 311 |
if (accInfo?.active_flags.length > 0) {
|
|
|
|
| 312 |
const now = new Date, formattedFlags = accInfo.active_flags.map((flag => {
|
| 313 |
const days = ((new Date(flag.expires_at).getTime() - now.getTime()) / 864e5).toFixed(2);
|
|
|
|
| 314 |
return {
|
| 315 |
type: flag.type,
|
| 316 |
remaining_days: days
|
| 317 |
};
|
| 318 |
}));
|
| 319 |
-
console.warn('[
|
| 320 |
await Promise.all(accInfo.active_flags.map((flag => (async type => {
|
| 321 |
if (!Config.Settings.ClearFlags) {
|
| 322 |
return;
|
| 323 |
}
|
| 324 |
-
if ('consumer_restricted_mode' === type) {
|
| 325 |
return;
|
| 326 |
}
|
| 327 |
const req = await (Config.Settings.Superfetch ? Superfetch : fetch)(`${Config.rProxy}/api/organizations/${uuidOrg}/flags/${type}/dismiss`, {
|
|
@@ -337,40 +365,18 @@ const updateParams = res => {
|
|
| 337 |
})(flag.type))));
|
| 338 |
/***************************** */
|
| 339 |
if (Config.CookieArray?.length > 0) {
|
| 340 |
-
console.log(`[35mRestricted![0m`);
|
|
|
|
| 341 |
Config.Cookiecounter < 0 && console.log(`[progress]: [32m${percentage.toFixed(2)}%[0m\n[length]: [33m${Config.CookieArray.length}[0m\n`);
|
| 342 |
-
CookieChanger.emit('ChangeCookie');
|
| 343 |
-
return;
|
| 344 |
}
|
| 345 |
}
|
| 346 |
-
if (Config.
|
| 347 |
-
|
| 348 |
-
|
| 349 |
-
|
| 350 |
-
|
| 351 |
-
|
| 352 |
-
method: 'GET'
|
| 353 |
-
}), accountinfo = await allres.text();
|
| 354 |
-
updateParams(allres);
|
| 355 |
-
const Unverified = accountinfo.includes('\\"completed_verification_at\\":null');
|
| 356 |
-
const Banned = accountinfo.includes('\\"gate\":\\"segment:abuse\\",\\"gateValue\\":\\"true\\",');
|
| 357 |
-
const Exceededlimit = /\\"messageLimit\\":{\\"type\\":\\"(approaching_limit\\",\\"remaining\\":0|exceeded_limit)\\",/.test(accountinfo);
|
| 358 |
-
const Remain = /\\"messageLimit\\":{\\"type\\":\\"approaching_limit\\",\\"remaining\\":\d+\\",/.exec(accountinfo);
|
| 359 |
-
Remain && (changeflag = Math.max(Config.Cookiecounter - Remain[0], changeflag));
|
| 360 |
-
if (Unverified || Banned) {
|
| 361 |
-
Config.CookieArray = Config.CookieArray.filter(item => item !== Config.Cookie);
|
| 362 |
-
!process.env.Cookie && !process.env.CookieArray && writeSettings(Config);
|
| 363 |
-
currentIndex = (currentIndex - 1 + Config.CookieArray.length) % Config.CookieArray.length;
|
| 364 |
-
}
|
| 365 |
-
Unverified && console.log(`[31mUnverified![0m`);
|
| 366 |
-
Banned && console.log(`[31mBanned![0m`);
|
| 367 |
-
Exceededlimit && console.log(`[35mExceeded limit![0m`);
|
| 368 |
-
Config.Cookiecounter < 0 && console.log(`[progress]: [32m${percentage.toFixed(2)}%[0m\n[length]: [33m${Config.CookieArray.length}[0m`);
|
| 369 |
-
if (Unverified || Banned || Exceededlimit || Config.Cookiecounter < 0) {
|
| 370 |
-
console.log('');
|
| 371 |
-
CookieChanger.emit('ChangeCookie');
|
| 372 |
-
return;
|
| 373 |
-
}
|
| 374 |
/***************************** */
|
| 375 |
}
|
| 376 |
const convRes = await fetch(`${Config.rProxy}/api/organizations/${uuidOrg}/chat_conversations`, {
|
|
@@ -424,6 +430,12 @@ const updateParams = res => {
|
|
| 424 |
try {
|
| 425 |
const body = JSON.parse(Buffer.concat(buffer).toString()), temperature = Math.max(.1, Math.min(1, body.temperature));
|
| 426 |
let {messages} = body;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 427 |
if (messages?.length < 1) {
|
| 428 |
throw Error('Select OpenAI as completion source');
|
| 429 |
}
|
|
@@ -454,7 +466,7 @@ const updateParams = res => {
|
|
| 454 |
console.log('[33mhaving[0m [1mAllSamples[0m and [1mNoSamples[0m both set to true is not supported');
|
| 455 |
throw Error('Only one can be used at the same time: AllSamples/NoSamples');
|
| 456 |
}
|
| 457 |
-
const model = AI.mdl();
|
| 458 |
curPrompt = {
|
| 459 |
firstUser: messages.find((message => 'user' === message.role)),
|
| 460 |
firstSystem: messages.find((message => 'system' === message.role)),
|
|
@@ -624,38 +636,38 @@ const updateParams = res => {
|
|
| 624 |
return message.content;
|
| 625 |
}
|
| 626 |
let spacing = '';
|
| 627 |
-
/*********************************
|
| 628 |
if (Config.Settings.xmlPlot) {
|
| 629 |
idx > 0 && (spacing = '\n\n');
|
| 630 |
const prefix = message.customname ? message.role + ': <customname>' + message.name + '</customname>: ' : 'system' !== message.role || message.name ? Replacements[message.name || message.role] + ': ' : 'xmlPlot: ' + Replacements[message.role];
|
| 631 |
return `${spacing}${prefix}${message.customname ? '<reply>\n' + message.content.trim() + '\n</reply>' : message.content}`;
|
| 632 |
} else {
|
| 633 |
-
/*********************************
|
| 634 |
idx > 0 && (spacing = systemMessages.includes(message) ? '\n' : '\n\n');
|
| 635 |
const prefix = message.customname ? message.name + ': ' : 'system' !== message.role || message.name ? Replacements[message.name || message.role] + ': ' : '' + Replacements[message.role];
|
| 636 |
return `${spacing}${message.strip ? '' : prefix}${'system' === message.role ? message.content : message.content.trim()}`;
|
| 637 |
} //
|
| 638 |
}));
|
| 639 |
return {
|
| 640 |
-
prompt: genericFixes(prompt.join('')).trim(),
|
| 641 |
systems
|
| 642 |
};
|
| 643 |
})(messages, type);
|
| 644 |
console.log(`${model} [[2m${type}[0m]${!retryRegen && systems.length > 0 ? ' ' + systems.join(' [33m/[0m ') : ''}`);
|
| 645 |
'R' !== type || prompt || (prompt = '...regen...');
|
| 646 |
-
/*********************************
|
| 647 |
-
Config.Settings.xmlPlot
|
| 648 |
Config.Settings.FullColon && (prompt = prompt.replace(/(?<=\n\n(H(?:uman)?|A(?:ssistant)?)):[ ]?/g, ': '));
|
| 649 |
Config.Settings.padtxt && (prompt = padtxt(prompt));
|
| 650 |
-
/*********************************
|
| 651 |
Logger?.write(`\n\n-------\n[${(new Date).toLocaleString()}]\n####### PROMPT (${type}):\n${prompt}\n--\n####### REPLY:\n`);
|
| 652 |
retryRegen || (fetchAPI = await (async (signal, model, prompt, temperature, type) => {
|
| 653 |
const attachments = [];
|
| 654 |
if (Config.Settings.PromptExperiments) {
|
| 655 |
-
/*********************************
|
| 656 |
let splitedprompt = prompt.split('\n\nPlainPrompt:');
|
| 657 |
prompt = splitedprompt[0];
|
| 658 |
-
/*********************************
|
| 659 |
attachments.push({
|
| 660 |
extracted_content: (prompt),
|
| 661 |
file_name: 'paste.txt', //fileName(),
|
|
@@ -663,9 +675,9 @@ const updateParams = res => {
|
|
| 663 |
file_type: 'txt' //'text/plain'
|
| 664 |
});
|
| 665 |
prompt = 'r' === type ? Config.PromptExperimentFirst : Config.PromptExperimentNext;
|
| 666 |
-
/*********************************
|
| 667 |
splitedprompt.length > 1 && (prompt = prompt + splitedprompt[1]);
|
| 668 |
-
/*********************************
|
| 669 |
}
|
| 670 |
let res;
|
| 671 |
const body = {
|
|
@@ -695,7 +707,7 @@ const updateParams = res => {
|
|
| 695 |
headers
|
| 696 |
});
|
| 697 |
updateParams(res);
|
| 698 |
-
await checkResErr(res);
|
| 699 |
return res;
|
| 700 |
})(signal, model, prompt, temperature, type));
|
| 701 |
const response = Writable.toWeb(res);
|
|
@@ -725,14 +737,13 @@ const updateParams = res => {
|
|
| 725 |
});
|
| 726 |
}
|
| 727 |
}
|
| 728 |
-
clearInterval(titleTimer);
|
| 729 |
if (clewdStream) {
|
| 730 |
clewdStream.censored && console.warn('[33mlikely your account is hard-censored[0m');
|
| 731 |
prevImpersonated = clewdStream.impersonated;
|
| 732 |
setTitle('ok ' + bytesToSize(clewdStream.size));
|
| 733 |
-
//console.log(`${200 == fetchAPI.status ? '[32m' : '[33m'}${fetchAPI.status}![0m\n`);
|
| 734 |
-
/******************************** */
|
| 735 |
-
429 == fetchAPI.status ? console.log(`[35mExceeded limit![0m\n`) : console.log(`${200 == fetchAPI.status ? '[32m' : '[33m'}${fetchAPI.status}![0m\n`);
|
| 736 |
changeflag += 1;
|
| 737 |
if (Config.CookieArray?.length > 0 && (429 == fetchAPI.status || (Config.Cookiecounter && changeflag >= Config.Cookiecounter))) {
|
| 738 |
changeflag = 0;
|
|
@@ -741,12 +752,11 @@ const updateParams = res => {
|
|
| 741 |
/******************************** */
|
| 742 |
clewdStream.empty();
|
| 743 |
}
|
| 744 |
-
if (prevImpersonated) {
|
| 745 |
-
|
| 746 |
-
|
| 747 |
-
} catch (err) {}
|
| 748 |
-
}
|
| 749 |
/******************************** */
|
|
|
|
| 750 |
changer && CookieChanger.emit('ChangeCookie');
|
| 751 |
/******************************** */
|
| 752 |
}));
|
|
@@ -762,15 +772,19 @@ const updateParams = res => {
|
|
| 762 |
break;
|
| 763 |
|
| 764 |
default:
|
| 765 |
-
|
| 766 |
-
res.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 767 |
error: {
|
| 768 |
message: '404 Not Found',
|
| 769 |
type: 404,
|
| 770 |
param: null,
|
| 771 |
code: 404
|
| 772 |
}
|
| 773 |
-
},
|
| 774 |
}
|
| 775 |
}));
|
| 776 |
|
|
@@ -828,6 +842,7 @@ const updateParams = res => {
|
|
| 828 |
Config.rProxy.endsWith('/') && (Config.rProxy = Config.rProxy.slice(0, -1));
|
| 829 |
let uniqueArr = [], seen = new Set();
|
| 830 |
for (let Cookie of Config.CookieArray) {
|
|
|
|
| 831 |
if (!seen.has(Cookie)) {
|
| 832 |
uniqueArr.push(Cookie);
|
| 833 |
seen.add(Cookie);
|
|
|
|
| 7 |
const {createServer: Server, IncomingMessage, ServerResponse} = require('node:http'), {createHash: Hash, randomUUID, randomInt, randomBytes} = require('node:crypto'), {TransformStream, ReadableStream} = require('node:stream/web'), {Readable, Writable} = require('node:stream'), {Blob} = require('node:buffer'), {existsSync: exists, writeFileSync: write, createWriteStream} = require('node:fs'), {join: joinP} = require('node:path'), {ClewdSuperfetch: Superfetch, SuperfetchAvailable} = require('./lib/clewd-superfetch'), {AI, fileName, genericFixes, bytesToSize, setTitle, checkResErr, Replacements, Main} = require('./lib/clewd-utils'), ClewdStream = require('./lib/clewd-stream');
|
| 8 |
|
| 9 |
/******************************************************* */
|
| 10 |
+
let currentIndex, Firstlogin = true, changeflag = 0, changetime = 0, totaltime, uuidOrgArray = [], model;
|
| 11 |
|
| 12 |
const events = require('events'), CookieChanger = new events.EventEmitter();
|
| 13 |
require('events').EventEmitter.defaultMaxListeners = 0;
|
| 14 |
|
| 15 |
CookieChanger.on('ChangeCookie', () => {
|
| 16 |
+
changeflag = 0;
|
| 17 |
Proxy && Proxy.close();
|
| 18 |
console.log(`Changing Cookie...\n`);
|
| 19 |
Proxy.listen(Config.Port, Config.Ip, onListen);
|
|
|
|
| 22 |
}));
|
| 23 |
});
|
| 24 |
|
| 25 |
+
const CookieCleaner = () => {
|
| 26 |
+
Config.CookieArray = Config.CookieArray.filter(item => item !== Config.Cookie);
|
| 27 |
+
!process.env.Cookie && !process.env.CookieArray && writeSettings(Config);
|
| 28 |
+
currentIndex = (currentIndex - 1 + Config.CookieArray.length) % Config.CookieArray.length;
|
| 29 |
+
}, padtxt = content => {
|
| 30 |
+
const {encode} = require('gpt-tokenizer');
|
| 31 |
+
const placeholder = Config.padtxt_placeholder || randomBytes(randomInt(5, 15)).toString('hex');
|
| 32 |
+
let count = Math.floor(Math.max(1000, Config.Settings.padtxt - encode(content).length) / encode(placeholder).length);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
let padding = '';
|
| 34 |
for (let i = 0; i < count; i++) {
|
| 35 |
padding += placeholder;
|
| 36 |
}
|
|
|
|
|
|
|
| 37 |
content = padding + '\n\n\n' + content;
|
|
|
|
| 38 |
return content.trim();
|
| 39 |
+
}, xmlPlot = content => {
|
| 40 |
// 检查内容中是否包含"<card>"
|
| 41 |
+
const card = content.includes('<card>');
|
| 42 |
+
//<card>越狱倒置
|
| 43 |
+
if (card) {
|
| 44 |
+
let segcontentHuman = content.split('\n\nHuman:');
|
| 45 |
+
const seglength = segcontentHuman.length;
|
| 46 |
+
if (/Assistant: *.$/.test(content) && seglength > 1 && !segcontentHuman[seglength - 2].includes('\n\nAssistant:')) {
|
| 47 |
+
segcontentHuman[seglength - 2] = segcontentHuman.splice(seglength - 1, 1, segcontentHuman[seglength - 2])[0];
|
| 48 |
+
}
|
| 49 |
+
content = segcontentHuman.join('\n\nHuman:');
|
| 50 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
//role合并
|
| 52 |
+
const MergeDisable = content.includes('<\!-- Merge Disable -->');
|
| 53 |
+
const MergeHumanDisable = content.includes('<\!-- Merge Human Disable -->');
|
| 54 |
+
const MergeAssistantDisable = content.includes('<\!-- Merge Assistant Disable -->');
|
| 55 |
+
if (!MergeDisable) {
|
| 56 |
+
if (content.includes('<\!-- Merge System Disable -->') || !card) {
|
| 57 |
+
content = content.replace(/(\n\n|^\s*)xmlPlot:\s*/gm, '$1');
|
| 58 |
+
}
|
| 59 |
+
if (!MergeHumanDisable) {
|
| 60 |
+
content = content.replace(/(\n\n|^\s*)xmlPlot:/g, '$1Human:');
|
| 61 |
+
content = content.replace(/(?:\n\n|^\s*)Human:(.*?(?:\n\nAssistant:|$))/gs, function(match, p1) {return '\n\nHuman:' + p1.replace(/\n\nHuman:\s*/g, '\n\n')});
|
| 62 |
content = content.replace(/^\s*Human:\s*/, '');
|
| 63 |
}
|
| 64 |
+
if (!MergeAssistantDisable) {
|
| 65 |
content = content.replace(/\n\nAssistant:(.*?(?:\n\nHuman:|$))/gs, function(match, p1) {return '\n\nAssistant:' + p1.replace(/\n\nAssistant:\s*/g, '\n\n')});
|
| 66 |
}
|
| 67 |
}
|
| 68 |
+
content = content.replace(/(\n\n|^\s*)xmlPlot:\s*/gm, '$1');
|
| 69 |
content = content.replace(/<\!-- Merge.*?Disable -->/gm, '');
|
| 70 |
+
//自定义插入
|
| 71 |
+
content = content.replace(/(<\/?)PrevAssistant>/gm, '$1@1>');
|
| 72 |
+
content = content.replace(/(<\/?)PrevHuman>/gm, '$1@2>');
|
| 73 |
+
let splitContent = content.split(/\n\n(?=Assistant:|Human:)/g);
|
| 74 |
+
let match;
|
| 75 |
+
while ((match = /<@(\d+)>(.*?)<\/@\1>/gs.exec(content)) !== null) {
|
| 76 |
+
let index = splitContent.length - parseInt(match[1]) - 1;
|
| 77 |
+
if (index >= 0) {
|
| 78 |
+
splitContent[index] += '\n\n' + match[2];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
}
|
| 80 |
+
content = content.replace(match[0], '');
|
| 81 |
}
|
| 82 |
+
content = splitContent.join('\n\n');
|
| 83 |
+
content = content.replace(/<@(\d+)>.*?<\/@\1>/gs, '');
|
| 84 |
+
//正则
|
| 85 |
+
while ((match = /<regex>"(\/?)(.*)\1(.*)" *: *"(.*?)"<\/regex>/gm.exec(content)) !== null) {
|
| 86 |
+
try {
|
| 87 |
+
content = content.replace(new RegExp(match[2], match[3]), match[4]);
|
| 88 |
+
} catch (error) {}
|
| 89 |
+
content = content.replace(match[0], '');
|
| 90 |
}
|
| 91 |
+
content = content.replace(/(\r\n|\r|\\n)/gm, '\n');
|
| 92 |
+
//二次role合并
|
| 93 |
+
if (!MergeDisable) {
|
| 94 |
+
if (!MergeHumanDisable) {
|
| 95 |
+
content = content.replace(/(?:\n\n|^\s*)Human:(.*?(?:\n\nAssistant:|$))/gs, function(match, p1) {return '\n\nHuman:' + p1.replace(/\n\nHuman:\s*/g, '\n\n')});
|
| 96 |
+
}
|
| 97 |
+
if (!MergeAssistantDisable) {
|
| 98 |
+
content = content.replace(/\n\nAssistant:(.*?(?:\n\nHuman:|$))/gs, function(match, p1) {return '\n\nAssistant:' + p1.replace(/\n\nAssistant:\s*/g, '\n\n')});
|
| 99 |
+
}
|
| 100 |
+
}
|
| 101 |
+
//Plain Prompt
|
| 102 |
+
let segcontentHuman = content.split('\n\nHuman:');
|
| 103 |
+
let segcontentlastIndex = segcontentHuman.length - 1;
|
| 104 |
+
if (segcontentlastIndex >= 2 && segcontentHuman[segcontentlastIndex].includes('<!-- Plain Prompt Enable -->') && !content.includes('\n\nPlainPrompt:')) {
|
| 105 |
+
content = segcontentHuman.slice(0, segcontentlastIndex).join('\n\nHuman:') + '\n\nPlainPrompt:' + segcontentHuman.slice(segcontentlastIndex).join('\n\nHuman:');
|
| 106 |
+
}
|
| 107 |
+
content = content.replace(/<\!-- Plain Prompt Enable -->/gm, '');
|
| 108 |
+
content = content.replace(/\n\nHuman: *PlainPrompt:/, '\n\nPlainPrompt:');
|
| 109 |
+
//<card>群组
|
| 110 |
+
if (!card) {
|
| 111 |
+
content = content.replace(/(<reply>\n|\n<\/reply>)/g, '');
|
| 112 |
+
return content.replace(/<customname>(.*?)<\/customname>/gm, '$1');
|
| 113 |
+
} else {
|
| 114 |
+
content = content.replace(/(<reply>\n|\n<\/reply>)\1*/g, '$1');
|
| 115 |
+
content = content.replace(/<customname>(.*?)<\/customname>:/gm, '$1:\n');
|
| 116 |
+
}
|
| 117 |
+
//<card>在第一个"[Start a new"前面加上"<example>",在最后一个"[Start a new"前面加上"</example>\n\n<plot>\n\n"
|
| 118 |
const cardtag = content.match(/(?=\n\n<\/card>)/) || '</card>';
|
| 119 |
const exampletag = content.match(/(?=\n\n<\/example>)/) || '</example>';
|
| 120 |
const plot = content.includes('</plot>') ? '<plot>' : '';
|
|
|
|
| 121 |
const firstChatStart = content.indexOf('\n\n[Start a new');
|
| 122 |
const lastChatStart = content.lastIndexOf('\n\n[Start a new');
|
| 123 |
firstChatStart != -1 && firstChatStart === lastChatStart && (content = content.slice(0, firstChatStart) + `\n\n${cardtag}` + content.slice(firstChatStart));
|
| 124 |
+
firstChatStart != lastChatStart && (content = content.slice(0, firstChatStart) + `\n\n${cardtag}\n<example>` + content.slice(firstChatStart, lastChatStart) + `\n\n${exampletag}\n\n${plot}` + content.slice(lastChatStart));
|
| 125 |
+
//<card>消除空XML tags、两端空白符和多余的\n
|
| 126 |
+
content = content.replace(/\s*<\|curtail\|>\s*/g, '\n');
|
| 127 |
+
content = content.replace(/\n<\/(card|hidden|META)>\s+?<\1>\n/g, '\n');
|
| 128 |
+
content = content.replace(/\n<(\/?card|example|hidden|plot|META)>\s+?<\1>/g, '\n<$1>');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
content = content.replace(/(?:<!--.*?-->)?\n<(card|example|hidden|plot|META)>\s+?<\/\1>/g, '');
|
| 130 |
+
content = content.replace(/(?<=(: |\n)<(card|hidden|example|plot|META|EOT)>\n)\s*/g, '');
|
| 131 |
+
content = content.replace(/\s*(?=\n<\/(card|hidden|example|plot|META|EOT)>(\n|$))/g, '');
|
| 132 |
content = content.replace(/(?<=\n)\n(?=\n)/g, '');
|
|
|
|
| 133 |
return content.trim();
|
| 134 |
};
|
| 135 |
/******************************************************* */
|
|
|
|
| 145 |
let uuidOrg, curPrompt = {}, prevPrompt = {}, prevMessages = [], prevImpersonated = false, Config = {
|
| 146 |
Cookie: '',
|
| 147 |
CookieArray: [],
|
| 148 |
+
Cookiecounter: 3,
|
| 149 |
CookieIndex: 0,
|
| 150 |
+
ProxyPassword: '',
|
| 151 |
Ip: (process.env.Cookie || process.env.CookieArray) ? '0.0.0.0' : '127.0.0.1',
|
| 152 |
Port: process.env.PORT || 8444,
|
| 153 |
localtunnel: false,
|
|
|
|
| 171 |
StripHuman: false,
|
| 172 |
PassParams: false,
|
| 173 |
ClearFlags: true,
|
| 174 |
+
PreserveChats: false,
|
| 175 |
LogMessages: true,
|
| 176 |
FullColon: true,
|
| 177 |
+
padtxt: 15000,
|
| 178 |
xmlPlot: true,
|
| 179 |
Superfetch: true
|
| 180 |
}
|
|
|
|
| 221 |
if (Config.Settings.PreserveChats) {
|
| 222 |
return;
|
| 223 |
}
|
| 224 |
+
try { //
|
| 225 |
+
const res = await fetch(`${Config.rProxy}/api/organizations/${uuidOrg}/chat_conversations/${uuid}`, {
|
| 226 |
+
headers: {
|
| 227 |
+
...AI.hdr(),
|
| 228 |
+
Cookie: getCookies()
|
| 229 |
+
},
|
| 230 |
+
method: 'DELETE'
|
| 231 |
+
});
|
| 232 |
+
updateParams(res);
|
| 233 |
+
} catch (err) { //
|
| 234 |
+
console.log(`[33mdeleteChat failed[0m`); //
|
| 235 |
+
} //
|
| 236 |
}, onListen = async () => {
|
| 237 |
/***************************** */
|
| 238 |
if (Firstlogin) {
|
|
|
|
| 253 |
currentIndex = (currentIndex + 1) % Config.CookieArray.length;
|
| 254 |
changetime += 1;
|
| 255 |
}
|
| 256 |
+
let percentage = ((changetime + Math.max(Config.CookieIndex - 1, 0)) / totaltime) * 100
|
| 257 |
if (Config.Cookiecounter < 0 && percentage > 100) {
|
| 258 |
console.log(`\n※※※Cookie cleanup completed※※※\n\n`);
|
| 259 |
return process.exit();
|
|
|
|
| 262 |
if ('SET YOUR COOKIE HERE' === Config.Cookie || Config.Cookie?.length < 1) {
|
| 263 |
throw Error('Set your cookie inside config.js');
|
| 264 |
}
|
| 265 |
+
!/^sessionKey=/.test(Config.Cookie) && (Config.Cookie += 'sessionKey='); //
|
| 266 |
updateCookies(Config.Cookie);
|
| 267 |
//console.log(`[2m${Main}[0m\n[33mhttp://${Config.Ip}:${Config.Port}/v1[0m\n\n${Object.keys(Config.Settings).map((setting => UnknownSettings.includes(setting) ? `??? [31m${setting}: ${Config.Settings[setting]}[0m` : `[1m${setting}:[0m ${ChangedSettings.includes(setting) ? '[33m' : '[36m'}${Config.Settings[setting]}[0m`)).sort().join('\n')}\n`);
|
| 268 |
//Config.Settings.Superfetch && SuperfetchAvailable(true);
|
|
|
|
| 275 |
});
|
| 276 |
/**************************** */
|
| 277 |
if (accRes.statusText === 'Forbidden' && Config.CookieArray?.length > 0) {
|
| 278 |
+
CookieCleaner();
|
|
|
|
|
|
|
| 279 |
console.log(`[31mExpired![0m`);
|
| 280 |
Config.Cookiecounter < 0 && console.log(`[progress]: [32m${percentage.toFixed(2)}%[0m\n[length]: [33m${Config.CookieArray.length}[0m\n`);
|
| 281 |
CookieChanger.emit('ChangeCookie');
|
|
|
|
| 292 |
}
|
| 293 |
setTitle('ok');
|
| 294 |
updateParams(accRes);
|
| 295 |
+
/**************************** */
|
| 296 |
+
const accountRes = await fetch(Config.rProxy + '/api/auth/current_account', {
|
| 297 |
+
method: 'GET',
|
| 298 |
+
headers: {
|
| 299 |
+
...AI.hdr(),
|
| 300 |
+
Cookie: getCookies()
|
| 301 |
+
}
|
| 302 |
+
});
|
| 303 |
+
await checkResErr(accountRes);
|
| 304 |
+
const accountInfo = (await accountRes.json());
|
| 305 |
+
/**************************** */
|
| 306 |
console.log(Config.CookieArray?.length > 0 ? `(index: [36m${currentIndex || Config.CookieArray.length}[0m) Logged in %o` : 'Logged in %o', { //console.log('Logged in %o', {
|
| 307 |
name: accInfo.name?.split('@')?.[0],
|
| 308 |
+
mail: accountInfo.account.email_address, //
|
| 309 |
capabilities: accInfo.capabilities,
|
| 310 |
});
|
| 311 |
uuidOrg = accInfo?.uuid;
|
| 312 |
/************************* */
|
| 313 |
+
model = accountInfo.account.statsig.values.dynamic_configs["6zA9wvTedwkzjLxWy9PVe7yydI00XDQ6L5Fejjq/2o8="]?.value?.model;
|
| 314 |
+
model != AI.mdl() && console.log(`[33m${model}[0m`);
|
| 315 |
+
if (model != AI.mdl() && Config.Cookiecounter === -2) {
|
| 316 |
+
CookieCleaner();
|
| 317 |
+
return CookieChanger.emit('ChangeCookie');
|
| 318 |
+
}
|
| 319 |
+
const Overlap = uuidOrgArray.includes(uuidOrg) && percentage <= 100 && Config.CookieArray?.length > 0;
|
| 320 |
+
!Overlap && uuidOrgArray.push(uuidOrg);
|
| 321 |
+
const Unverified = !accountInfo.account.completed_verification_at;
|
| 322 |
+
const abuseTag = accountInfo.account.statsig.values.feature_gates["4fDxNAVXgvks8yzKUoU+T+w3Qr3oYVqoJJVNYh04Mik="]?.secondary_exposures[0];
|
| 323 |
+
const Banned = abuseTag.gateValue === 'true' && abuseTag.gate === 'segment:abuse';
|
| 324 |
+
const Remain = accountInfo.messageLimit?.remaining;
|
| 325 |
+
const Exceededlimit = (accountInfo.messageLimit?.type === 'approaching_limit' && Remain === 0) || accountInfo.messageLimit?.type === 'exceeded_limit';
|
| 326 |
+
if (Remain) {
|
| 327 |
+
changeflag = Math.max(Config.Cookiecounter - Remain, changeflag);
|
| 328 |
+
console.log(`[33mApproachingLimit!: Remain ${Remain}[0m`);
|
| 329 |
+
}
|
| 330 |
+
if ((Overlap || Unverified || Banned) && Config.CookieArray?.length > 0) {
|
| 331 |
+
Overlap ? console.log(`[31mOverlap![0m`) : Unverified ? console.log(`[31mUnverified![0m`) : Banned && console.log(`[31mBanned![0m`);
|
| 332 |
+
CookieCleaner();
|
| 333 |
Config.Cookiecounter < 0 && console.log(`[progress]: [32m${percentage.toFixed(2)}%[0m\n[length]: [33m${Config.CookieArray.length}[0m\n`);
|
| 334 |
+
return CookieChanger.emit('ChangeCookie');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 335 |
}
|
| 336 |
/************************* */
|
| 337 |
if (accInfo?.active_flags.length > 0) {
|
| 338 |
+
let flagtype; //
|
| 339 |
const now = new Date, formattedFlags = accInfo.active_flags.map((flag => {
|
| 340 |
const days = ((new Date(flag.expires_at).getTime() - now.getTime()) / 864e5).toFixed(2);
|
| 341 |
+
flagtype = flag.type; //
|
| 342 |
return {
|
| 343 |
type: flag.type,
|
| 344 |
remaining_days: days
|
| 345 |
};
|
| 346 |
}));
|
| 347 |
+
console.warn(`${'consumer_banned' === flagtype ? '[31m' : '[35m'}Your account has warnings[0m %o`, formattedFlags); //console.warn('[31mYour account has warnings[0m %o', formattedFlags);
|
| 348 |
await Promise.all(accInfo.active_flags.map((flag => (async type => {
|
| 349 |
if (!Config.Settings.ClearFlags) {
|
| 350 |
return;
|
| 351 |
}
|
| 352 |
+
if ('consumer_restricted_mode' === type || 'consumer_banned' === type) { //if ('consumer_restricted_mode' === type) {
|
| 353 |
return;
|
| 354 |
}
|
| 355 |
const req = await (Config.Settings.Superfetch ? Superfetch : fetch)(`${Config.rProxy}/api/organizations/${uuidOrg}/flags/${type}/dismiss`, {
|
|
|
|
| 365 |
})(flag.type))));
|
| 366 |
/***************************** */
|
| 367 |
if (Config.CookieArray?.length > 0) {
|
| 368 |
+
console.log(`${'consumer_banned' === flagtype ? '[31mBanned' : '[35mRestricted'}![0m`);
|
| 369 |
+
'consumer_banned' === flagtype && CookieCleaner();
|
| 370 |
Config.Cookiecounter < 0 && console.log(`[progress]: [32m${percentage.toFixed(2)}%[0m\n[length]: [33m${Config.CookieArray.length}[0m\n`);
|
| 371 |
+
return CookieChanger.emit('ChangeCookie');
|
|
|
|
| 372 |
}
|
| 373 |
}
|
| 374 |
+
if (Config.Cookiecounter < 0) {
|
| 375 |
+
console.log(`[progress]: [32m${percentage.toFixed(2)}%[0m\n[length]: [33m${Config.CookieArray.length}[0m\n`);
|
| 376 |
+
return CookieChanger.emit('ChangeCookie');
|
| 377 |
+
} else if (Exceededlimit) {
|
| 378 |
+
console.log(`[35mExceeded limit![0m\n`);
|
| 379 |
+
return CookieChanger.emit('ChangeCookie');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 380 |
/***************************** */
|
| 381 |
}
|
| 382 |
const convRes = await fetch(`${Config.rProxy}/api/organizations/${uuidOrg}/chat_conversations`, {
|
|
|
|
| 430 |
try {
|
| 431 |
const body = JSON.parse(Buffer.concat(buffer).toString()), temperature = Math.max(.1, Math.min(1, body.temperature));
|
| 432 |
let {messages} = body;
|
| 433 |
+
/************************* */
|
| 434 |
+
const authorization = Object.fromEntries(Object.entries(req.headers).map(([key, value]) => [key, value])).authorization;
|
| 435 |
+
if (Config.ProxyPassword != '' && authorization != 'Bearer ' + Config.ProxyPassword) {
|
| 436 |
+
throw Error('ProxyPassword Wrong');
|
| 437 |
+
}
|
| 438 |
+
/************************* */
|
| 439 |
if (messages?.length < 1) {
|
| 440 |
throw Error('Select OpenAI as completion source');
|
| 441 |
}
|
|
|
|
| 466 |
console.log('[33mhaving[0m [1mAllSamples[0m and [1mNoSamples[0m both set to true is not supported');
|
| 467 |
throw Error('Only one can be used at the same time: AllSamples/NoSamples');
|
| 468 |
}
|
| 469 |
+
//const model = AI.mdl();
|
| 470 |
curPrompt = {
|
| 471 |
firstUser: messages.find((message => 'user' === message.role)),
|
| 472 |
firstSystem: messages.find((message => 'system' === message.role)),
|
|
|
|
| 636 |
return message.content;
|
| 637 |
}
|
| 638 |
let spacing = '';
|
| 639 |
+
/******************************** */
|
| 640 |
if (Config.Settings.xmlPlot) {
|
| 641 |
idx > 0 && (spacing = '\n\n');
|
| 642 |
const prefix = message.customname ? message.role + ': <customname>' + message.name + '</customname>: ' : 'system' !== message.role || message.name ? Replacements[message.name || message.role] + ': ' : 'xmlPlot: ' + Replacements[message.role];
|
| 643 |
return `${spacing}${prefix}${message.customname ? '<reply>\n' + message.content.trim() + '\n</reply>' : message.content}`;
|
| 644 |
} else {
|
| 645 |
+
/******************************** */
|
| 646 |
idx > 0 && (spacing = systemMessages.includes(message) ? '\n' : '\n\n');
|
| 647 |
const prefix = message.customname ? message.name + ': ' : 'system' !== message.role || message.name ? Replacements[message.name || message.role] + ': ' : '' + Replacements[message.role];
|
| 648 |
return `${spacing}${message.strip ? '' : prefix}${'system' === message.role ? message.content : message.content.trim()}`;
|
| 649 |
} //
|
| 650 |
}));
|
| 651 |
return {
|
| 652 |
+
prompt: prompt.join('').trim(),//genericFixes(prompt.join('')).trim(),
|
| 653 |
systems
|
| 654 |
};
|
| 655 |
})(messages, type);
|
| 656 |
console.log(`${model} [[2m${type}[0m]${!retryRegen && systems.length > 0 ? ' ' + systems.join(' [33m/[0m ') : ''}`);
|
| 657 |
'R' !== type || prompt || (prompt = '...regen...');
|
| 658 |
+
/******************************** */
|
| 659 |
+
prompt = Config.Settings.xmlPlot ? xmlPlot(prompt) : genericFixes(prompt);
|
| 660 |
Config.Settings.FullColon && (prompt = prompt.replace(/(?<=\n\n(H(?:uman)?|A(?:ssistant)?)):[ ]?/g, ': '));
|
| 661 |
Config.Settings.padtxt && (prompt = padtxt(prompt));
|
| 662 |
+
/******************************** */
|
| 663 |
Logger?.write(`\n\n-------\n[${(new Date).toLocaleString()}]\n####### PROMPT (${type}):\n${prompt}\n--\n####### REPLY:\n`);
|
| 664 |
retryRegen || (fetchAPI = await (async (signal, model, prompt, temperature, type) => {
|
| 665 |
const attachments = [];
|
| 666 |
if (Config.Settings.PromptExperiments) {
|
| 667 |
+
/******************************** */
|
| 668 |
let splitedprompt = prompt.split('\n\nPlainPrompt:');
|
| 669 |
prompt = splitedprompt[0];
|
| 670 |
+
/******************************** */
|
| 671 |
attachments.push({
|
| 672 |
extracted_content: (prompt),
|
| 673 |
file_name: 'paste.txt', //fileName(),
|
|
|
|
| 675 |
file_type: 'txt' //'text/plain'
|
| 676 |
});
|
| 677 |
prompt = 'r' === type ? Config.PromptExperimentFirst : Config.PromptExperimentNext;
|
| 678 |
+
/******************************** */
|
| 679 |
splitedprompt.length > 1 && (prompt = prompt + splitedprompt[1]);
|
| 680 |
+
/******************************** */
|
| 681 |
}
|
| 682 |
let res;
|
| 683 |
const body = {
|
|
|
|
| 707 |
headers
|
| 708 |
});
|
| 709 |
updateParams(res);
|
| 710 |
+
await checkResErr(res, CookieChanger); //await checkResErr(res);
|
| 711 |
return res;
|
| 712 |
})(signal, model, prompt, temperature, type));
|
| 713 |
const response = Writable.toWeb(res);
|
|
|
|
| 737 |
});
|
| 738 |
}
|
| 739 |
}
|
| 740 |
+
clearInterval(titleTimer);
|
| 741 |
if (clewdStream) {
|
| 742 |
clewdStream.censored && console.warn('[33mlikely your account is hard-censored[0m');
|
| 743 |
prevImpersonated = clewdStream.impersonated;
|
| 744 |
setTitle('ok ' + bytesToSize(clewdStream.size));
|
| 745 |
+
429 == fetchAPI.status ? console.log(`[35mExceeded limit![0m\n`) : console.log(`${200 == fetchAPI.status ? '[32m' : '[33m'}${fetchAPI.status}![0m\n`); //console.log(`${200 == fetchAPI.status ? '[32m' : '[33m'}${fetchAPI.status}![0m\n`);
|
| 746 |
+
/******************************** */
|
|
|
|
| 747 |
changeflag += 1;
|
| 748 |
if (Config.CookieArray?.length > 0 && (429 == fetchAPI.status || (Config.Cookiecounter && changeflag >= Config.Cookiecounter))) {
|
| 749 |
changeflag = 0;
|
|
|
|
| 752 |
/******************************** */
|
| 753 |
clewdStream.empty();
|
| 754 |
}
|
| 755 |
+
/*if (prevImpersonated) {
|
| 756 |
+
await deleteChat(Conversation.uuid);
|
| 757 |
+
}*/
|
|
|
|
|
|
|
| 758 |
/******************************** */
|
| 759 |
+
await deleteChat(Conversation.uuid);
|
| 760 |
changer && CookieChanger.emit('ChangeCookie');
|
| 761 |
/******************************** */
|
| 762 |
}));
|
|
|
|
| 772 |
break;
|
| 773 |
|
| 774 |
default:
|
| 775 |
+
!['/', '/v1', '/favicon.ico'].includes(req.url) && (console.log('unknown request: ' + req.url)); //console.log('unknown request: ' + req.url);
|
| 776 |
+
res.writeHead(200, {'Content-Type': 'text/html'});
|
| 777 |
+
res.write(`<!DOCTYPE html>\n<html>\n<head>\n<meta charset="utf-8">\n<script>\nfunction copyToClipboard(text) {\n var textarea = document.createElement("textarea");\n textarea.textContent = text;\n textarea.style.position = "fixed";\n document.body.appendChild(textarea);\n textarea.select();\n try {\n return document.execCommand("copy");\n } catch (ex) {\n console.warn("Copy to clipboard failed.", ex);\n return false;\n } finally {\n document.body.removeChild(textarea);\n }\n}\nfunction copyLink(event) {\n event.preventDefault();\n const url = new URL(window.location.href);\n const link = url.protocol + '//' + url.host + '/v1';\n copyToClipboard(link);\n alert('链接已复制: ' + link);\n}\n</script>\n</head>\n<body>\n${Main}<br/><br/>完全开源、免费且禁止商用<br/><br/>反向代理: <a href="v1" onclick="copyLink(event)">点击复制链接</a><br/>填入OpenAI API反向代理并选择OpenAI分类中的claude-2模型(酒馆需打开Show "External" models)<br/><br/>教程与FAQ: <a href="https://rentry.org/teralomaniac_clewd" target="FAQ">https://rentry.org/teralomaniac_clewd</a>\n</body>\n</html>`);
|
| 778 |
+
res.end();
|
| 779 |
+
/*res.json(
|
| 780 |
+
{
|
| 781 |
error: {
|
| 782 |
message: '404 Not Found',
|
| 783 |
type: 404,
|
| 784 |
param: null,
|
| 785 |
code: 404
|
| 786 |
}
|
| 787 |
+
}, 404);*/
|
| 788 |
}
|
| 789 |
}));
|
| 790 |
|
|
|
|
| 842 |
Config.rProxy.endsWith('/') && (Config.rProxy = Config.rProxy.slice(0, -1));
|
| 843 |
let uniqueArr = [], seen = new Set();
|
| 844 |
for (let Cookie of Config.CookieArray) {
|
| 845 |
+
!/^sessionKey=/.test(Cookie) && (Cookie += 'sessionKey=');
|
| 846 |
if (!seen.has(Cookie)) {
|
| 847 |
uniqueArr.push(Cookie);
|
| 848 |
seen.add(Cookie);
|
lib/clewd-stream.js
CHANGED
|
@@ -42,8 +42,6 @@ class ClewdStream extends TransformStream {
|
|
| 42 |
#stopReason=void 0;
|
| 43 |
#hardCensor=false;
|
| 44 |
#impersonated=false;
|
| 45 |
-
#cookiechange=false;
|
| 46 |
-
#readonly=false;
|
| 47 |
get size() {
|
| 48 |
return this.#recvLength;
|
| 49 |
}
|
|
@@ -68,7 +66,7 @@ class ClewdStream extends TransformStream {
|
|
| 68 |
}
|
| 69 |
#err(err, controller) {
|
| 70 |
this.#logger?.write(JSON.stringify(err, null, 4));
|
| 71 |
-
const message = `## ${this.#version}\n**${AI.mdl()} error**:\n${err.status || err.code || err.type}\n\n\`\`\`${err.message}\`\`\``;
|
| 72 |
this.#enqueue(this.#build(message), controller);
|
| 73 |
return this.#endEarly(controller);
|
| 74 |
}
|
|
@@ -98,7 +96,7 @@ class ClewdStream extends TransformStream {
|
|
| 98 |
this.#streaming ? this.#compOK.length > 0 && this.#enqueue(this.#build(this.#compOK), controller) : this.#enqueue(this.#build(this.#compAll.join('')), controller);
|
| 99 |
this.#compAll?.[0] === Buffer.from([ 73, 32, 97, 112, 111, 108, 111, 103, 105, 122, 101, 44, 32, 98, 117, 116, 32, 73, 32, 119, 105, 108, 108, 32, 110, 111, 116, 32, 112, 114, 111, 118, 105, 100, 101, 32, 97, 110, 121, 32, 114, 101, 115, 112, 111, 110, 115, 101, 115, 32, 116, 104, 97, 116, 32, 118, 105, 111, 108, 97, 116, 101, 32, 65, 110, 116, 104, 114, 111, 112, 105, 99, 39, 115, 32, 65, 99, 99, 101, 112, 116, 97, 98, 108, 101, 32, 85, 115, 101, 32, 80, 111, 108, 105, 99, 121, 32, 111, 114, 32, 99, 111, 117, 108, 100, 32, 112, 114, 111, 109, 111, 116, 101, 32, 104, 97, 114, 109, 46 ]).toString() && (this.#hardCensor = true);
|
| 100 |
if (!this.#ended && 0 === this.total) {
|
| 101 |
-
const err = `## ${this.#version}\n**error**:\n\n\`\`\`Received no valid replies at all\`\`\``;
|
| 102 |
this.#enqueue(this.#build(err), controller);
|
| 103 |
}
|
| 104 |
this.#streaming && this.#enqueue('data: [DONE]\n\n', controller);
|
|
@@ -157,7 +155,7 @@ class ClewdStream extends TransformStream {
|
|
| 157 |
},
|
| 158 |
status: this.#source.status,
|
| 159 |
superfetch: this.#source.superfetch
|
| 160 |
-
}), false);
|
| 161 |
delete err.stack;
|
| 162 |
return this.#err(err, controller);
|
| 163 |
}
|
|
|
|
| 42 |
#stopReason=void 0;
|
| 43 |
#hardCensor=false;
|
| 44 |
#impersonated=false;
|
|
|
|
|
|
|
| 45 |
get size() {
|
| 46 |
return this.#recvLength;
|
| 47 |
}
|
|
|
|
| 66 |
}
|
| 67 |
#err(err, controller) {
|
| 68 |
this.#logger?.write(JSON.stringify(err, null, 4));
|
| 69 |
+
const message = `## ${this.#version}\n**${AI.mdl()} error**:\n${err.status || err.code || err.type}\n\n\`\`\`${err.message}\`\`\`\n\nFAQ: https://rentry.org/teralomaniac_clewd`;
|
| 70 |
this.#enqueue(this.#build(message), controller);
|
| 71 |
return this.#endEarly(controller);
|
| 72 |
}
|
|
|
|
| 96 |
this.#streaming ? this.#compOK.length > 0 && this.#enqueue(this.#build(this.#compOK), controller) : this.#enqueue(this.#build(this.#compAll.join('')), controller);
|
| 97 |
this.#compAll?.[0] === Buffer.from([ 73, 32, 97, 112, 111, 108, 111, 103, 105, 122, 101, 44, 32, 98, 117, 116, 32, 73, 32, 119, 105, 108, 108, 32, 110, 111, 116, 32, 112, 114, 111, 118, 105, 100, 101, 32, 97, 110, 121, 32, 114, 101, 115, 112, 111, 110, 115, 101, 115, 32, 116, 104, 97, 116, 32, 118, 105, 111, 108, 97, 116, 101, 32, 65, 110, 116, 104, 114, 111, 112, 105, 99, 39, 115, 32, 65, 99, 99, 101, 112, 116, 97, 98, 108, 101, 32, 85, 115, 101, 32, 80, 111, 108, 105, 99, 121, 32, 111, 114, 32, 99, 111, 117, 108, 100, 32, 112, 114, 111, 109, 111, 116, 101, 32, 104, 97, 114, 109, 46 ]).toString() && (this.#hardCensor = true);
|
| 98 |
if (!this.#ended && 0 === this.total) {
|
| 99 |
+
const err = `## ${this.#version}\n**error**:\n\n\`\`\`Received no valid replies at all\`\`\`\n\nFAQ: https://rentry.org/teralomaniac_clewd`;
|
| 100 |
this.#enqueue(this.#build(err), controller);
|
| 101 |
}
|
| 102 |
this.#streaming && this.#enqueue('data: [DONE]\n\n', controller);
|
|
|
|
| 155 |
},
|
| 156 |
status: this.#source.status,
|
| 157 |
superfetch: this.#source.superfetch
|
| 158 |
+
}), false, false); //}), false);
|
| 159 |
delete err.stack;
|
| 160 |
return this.#err(err, controller);
|
| 161 |
}
|
lib/clewd-utils.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
| 5 |
'use strict';
|
| 6 |
|
| 7 |
const {randomInt, randomBytes} = require('node:crypto'), {version: Version} = require('../package.json'), Encoder = (new TextDecoder,
|
| 8 |
-
new TextEncoder), Main = 'clewd v' + Version + '
|
| 9 |
user: 'Human',
|
| 10 |
assistant: 'Assistant',
|
| 11 |
system: '',
|
|
@@ -13,8 +13,8 @@ new TextEncoder), Main = 'clewd v' + Version + '修改版 by tera', Replacements
|
|
| 13 |
example_assistant: 'A'
|
| 14 |
}, DangerChars = [ ...new Set([ ...Object.values(Replacements).join(''), ...'\n', ...':', ...'\\n' ]) ].filter((char => ' ' !== char)).sort(), AI = {
|
| 15 |
end: () => Buffer.from([ 104, 116, 116, 112, 115, 58, 47, 47, 99, 108, 97, 117, 100, 101, 46, 97, 105 ]).toString(),
|
| 16 |
-
mdl: () => Buffer.from([ 99, 108, 97, 117, 100, 101, 45, 50 ]).toString(),
|
| 17 |
-
zone: () => Buffer.from([ 65, 109, 101, 114, 105, 99, 97, 47, 78, 101, 119, 95, 89, 111, 114, 107 ]).toString(),
|
| 18 |
agent: () => Buffer.from([ 77, 111, 122, 105, 108, 108, 97, 47, 53, 46, 48, 32, 40, 77, 97, 99, 105, 110, 116, 111, 115, 104, 59, 32, 73, 110, 116, 101, 108, 32, 77, 97, 99, 32, 79, 83, 32, 88, 32, 49, 48, 95, 49, 53, 95, 55, 41, 32, 65, 112, 112, 108, 101, 87, 101, 98, 75, 105, 116, 47, 53, 51, 55, 46, 51, 54, 32, 40, 75, 72, 84, 77, 76, 44, 32, 108, 105, 107, 101, 32, 71, 101, 99, 107, 111, 41, 32, 67, 104, 114, 111, 109, 101, 47, 49, 49, 52, 46, 48, 46, 48, 46, 48, 32, 83, 97, 102, 97, 114, 105, 47, 53, 51, 55, 46, 51, 54, 32, 69, 100, 103, 47, 49, 49, 52, 46, 48, 46, 49, 56, 50, 51, 46, 55, 57 ]).toString(),
|
| 19 |
cp: () => Buffer.from([ 55, 55, 49, 44, 52, 56, 54, 53, 45, 52, 56, 54, 54, 45, 52, 56, 54, 55, 45, 52, 57, 49, 57, 53, 45, 52, 57, 49, 57, 57, 45, 52, 57, 49, 57, 54, 45, 52, 57, 50, 48, 48, 45, 53, 50, 51, 57, 51, 45, 53, 50, 51, 57, 50, 45, 52, 57, 49, 55, 49, 45, 52, 57, 49, 55, 50, 45, 49, 53, 54, 45, 49, 53, 55, 45, 52, 55, 45, 53, 51, 44, 48, 45, 50, 51, 45, 54, 53, 50, 56, 49, 45, 49, 48, 45, 49, 49, 45, 51, 53, 45, 49, 54, 45, 53, 45, 49, 51, 45, 49, 56, 45, 53, 49, 45, 52, 53, 45, 52, 51, 45, 50, 55, 45, 49, 55, 53, 49, 51, 45, 50, 49, 44, 50, 57, 45, 50, 51, 45, 50, 52, 44, 48 ]).toString(),
|
| 20 |
hdr: refPath => ({
|
|
@@ -42,7 +42,7 @@ module.exports.Replacements = Replacements;
|
|
| 42 |
|
| 43 |
module.exports.DangerChars = DangerChars;
|
| 44 |
|
| 45 |
-
module.exports.checkResErr = async (res, throwIt = true) => {
|
| 46 |
let err, json, errAPI;
|
| 47 |
if ('string' == typeof res) {
|
| 48 |
json = JSON.parse(res);
|
|
@@ -61,6 +61,12 @@ module.exports.checkResErr = async (res, throwIt = true) => {
|
|
| 61 |
if ((429 === res.status || 429 === json.status) && errAPI.resets_at) {
|
| 62 |
const hours = ((new Date(1e3 * errAPI.resets_at).getTime() - Date.now()) / 1e3 / 60 / 60).toFixed(1);
|
| 63 |
err.message += `, expires in ${hours} hours`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
}
|
| 65 |
if (throwIt) {
|
| 66 |
throw err;
|
|
|
|
| 5 |
'use strict';
|
| 6 |
|
| 7 |
const {randomInt, randomBytes} = require('node:crypto'), {version: Version} = require('../package.json'), Encoder = (new TextDecoder,
|
| 8 |
+
new TextEncoder), Main = 'clewd修改版 v' + Version + '(10) by tera', Replacements = {
|
| 9 |
user: 'Human',
|
| 10 |
assistant: 'Assistant',
|
| 11 |
system: '',
|
|
|
|
| 13 |
example_assistant: 'A'
|
| 14 |
}, DangerChars = [ ...new Set([ ...Object.values(Replacements).join(''), ...'\n', ...':', ...'\\n' ]) ].filter((char => ' ' !== char)).sort(), AI = {
|
| 15 |
end: () => Buffer.from([ 104, 116, 116, 112, 115, 58, 47, 47, 99, 108, 97, 117, 100, 101, 46, 97, 105 ]).toString(),
|
| 16 |
+
mdl: () => Buffer.from([ 99, 108, 97, 117, 100, 101, 45, 50, 46, 49 ]).toString(),
|
| 17 |
+
zone: () => Buffer.from([ 65, 115, 105, 97, 47, 83, 104, 97, 110, 103, 104, 97, 105 ]).toString(), //Buffer.from([ 65, 109, 101, 114, 105, 99, 97, 47, 78, 101, 119, 95, 89, 111, 114, 107 ]).toString(),
|
| 18 |
agent: () => Buffer.from([ 77, 111, 122, 105, 108, 108, 97, 47, 53, 46, 48, 32, 40, 77, 97, 99, 105, 110, 116, 111, 115, 104, 59, 32, 73, 110, 116, 101, 108, 32, 77, 97, 99, 32, 79, 83, 32, 88, 32, 49, 48, 95, 49, 53, 95, 55, 41, 32, 65, 112, 112, 108, 101, 87, 101, 98, 75, 105, 116, 47, 53, 51, 55, 46, 51, 54, 32, 40, 75, 72, 84, 77, 76, 44, 32, 108, 105, 107, 101, 32, 71, 101, 99, 107, 111, 41, 32, 67, 104, 114, 111, 109, 101, 47, 49, 49, 52, 46, 48, 46, 48, 46, 48, 32, 83, 97, 102, 97, 114, 105, 47, 53, 51, 55, 46, 51, 54, 32, 69, 100, 103, 47, 49, 49, 52, 46, 48, 46, 49, 56, 50, 51, 46, 55, 57 ]).toString(),
|
| 19 |
cp: () => Buffer.from([ 55, 55, 49, 44, 52, 56, 54, 53, 45, 52, 56, 54, 54, 45, 52, 56, 54, 55, 45, 52, 57, 49, 57, 53, 45, 52, 57, 49, 57, 57, 45, 52, 57, 49, 57, 54, 45, 52, 57, 50, 48, 48, 45, 53, 50, 51, 57, 51, 45, 53, 50, 51, 57, 50, 45, 52, 57, 49, 55, 49, 45, 52, 57, 49, 55, 50, 45, 49, 53, 54, 45, 49, 53, 55, 45, 52, 55, 45, 53, 51, 44, 48, 45, 50, 51, 45, 54, 53, 50, 56, 49, 45, 49, 48, 45, 49, 49, 45, 51, 53, 45, 49, 54, 45, 53, 45, 49, 51, 45, 49, 56, 45, 53, 49, 45, 52, 53, 45, 52, 51, 45, 50, 55, 45, 49, 55, 53, 49, 51, 45, 50, 49, 44, 50, 57, 45, 50, 51, 45, 50, 52, 44, 48 ]).toString(),
|
| 20 |
hdr: refPath => ({
|
|
|
|
| 42 |
|
| 43 |
module.exports.DangerChars = DangerChars;
|
| 44 |
|
| 45 |
+
module.exports.checkResErr = async (res, CookieChanger, throwIt = true) => { //module.exports.checkResErr = async (res, throwIt = true) => {
|
| 46 |
let err, json, errAPI;
|
| 47 |
if ('string' == typeof res) {
|
| 48 |
json = JSON.parse(res);
|
|
|
|
| 61 |
if ((429 === res.status || 429 === json.status) && errAPI.resets_at) {
|
| 62 |
const hours = ((new Date(1e3 * errAPI.resets_at).getTime() - Date.now()) / 1e3 / 60 / 60).toFixed(1);
|
| 63 |
err.message += `, expires in ${hours} hours`;
|
| 64 |
+
/************************** */
|
| 65 |
+
if (CookieChanger) {
|
| 66 |
+
console.log(`[35mExceeded limit![0m\n`);
|
| 67 |
+
CookieChanger && CookieChanger.emit('ChangeCookie');
|
| 68 |
+
}
|
| 69 |
+
/************************** */
|
| 70 |
}
|
| 71 |
if (throwIt) {
|
| 72 |
throw err;
|
package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
{
|
| 2 |
"name": "clewd",
|
| 3 |
"version": "4.6",
|
| 4 |
-
"description": ":
|
| 5 |
"main": "clewd.js",
|
| 6 |
"engines": {
|
| 7 |
"node": ">=20.4.0"
|
|
@@ -35,5 +35,8 @@
|
|
| 35 |
"bugs": {
|
| 36 |
"url": "https://gitgud.io/ahsk/clewd/-/issues"
|
| 37 |
},
|
| 38 |
-
"dependencies": {
|
|
|
|
|
|
|
|
|
|
| 39 |
}
|
|
|
|
| 1 |
{
|
| 2 |
"name": "clewd",
|
| 3 |
"version": "4.6",
|
| 4 |
+
"description": "<div align=\"center\"> <a href=\"https://github.com/teralomaniac/clewd\"> <h1>Clewd</h1> <img height=\"120\" width=\"120\" alt=\"Clewd\" title=\"Clewd\" src=\"https://gitgud.io/ahsk/clewd/-/raw/master/media/logo.png\" align=\"left\" />",
|
| 5 |
"main": "clewd.js",
|
| 6 |
"engines": {
|
| 7 |
"node": ">=20.4.0"
|
|
|
|
| 35 |
"bugs": {
|
| 36 |
"url": "https://gitgud.io/ahsk/clewd/-/issues"
|
| 37 |
},
|
| 38 |
+
"dependencies": {
|
| 39 |
+
"localtunnel": "^2.0.2",
|
| 40 |
+
"gpt-tokenizer": "^2.1.2"
|
| 41 |
+
}
|
| 42 |
}
|