Moonfanz commited on
Commit
ad1fed6
·
verified ·
1 Parent(s): 320d855

Update clewd.js

Browse files
Files changed (1) hide show
  1. clewd.js +561 -559
clewd.js CHANGED
@@ -4,7 +4,7 @@
4
  */
5
  'use strict';
6
 
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, SuperfetchFoldersMk, SuperfetchFoldersRm} = 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, changing, changetime = 0, totaltime, uuidOrgArray = [], model, cookieModel, tokens, apiKey, timestamp, regexLog, isPro, modelList = [];
@@ -32,7 +32,7 @@ const asyncPool = async (poolLimit, array, iteratorFn) => {
32
  return changing = false;
33
  } else {
34
  changeflag = 0, changing = true;
35
- if(!cleanup) {
36
  currentIndex = (currentIndex + 1) % Config.CookieArray.length;
37
  console.log(`Changing Cookie...\n`);
38
  }
@@ -49,22 +49,22 @@ const asyncPool = async (poolLimit, array, iteratorFn) => {
49
  writeSettings(Config);
50
  return CookieChanger(true, true);
51
  }, padtxt = content => {
52
- const {countTokens} = require('@anthropic-ai/tokenizer');
53
  tokens = countTokens(content);
54
  const padtxt = String(Config.Settings.padtxt).split(',').reverse(), maxtokens = parseInt(padtxt[0]), extralimit = parseInt(padtxt[1]) || 1000, minlimit = parseInt(padtxt[2]);
55
  const placeholder = (tokens > maxtokens - extralimit && minlimit ? Config.placeholder_byte : Config.placeholder_token) || randomBytes(randomInt(5, 15)).toString('hex');
56
  const placeholdertokens = countTokens(placeholder.trim());
57
  for (let match; match = content.match(/<\|padtxt.*?(\d+)t.*?\|>/); content = content.replace(match[0], placeholder.repeat(parseInt(match[1]) / placeholdertokens))) tokens += parseInt(match[1]);
58
- if(/<\|padtxt off.*?\|>/.test(content)) return content.replace(/\s*<\|padtxt.*?\|>\s*/g, '\n\n');
59
  const padding = placeholder.repeat(Math.min(maxtokens, (tokens <= maxtokens - extralimit ? maxtokens - tokens : minlimit ? minlimit : extralimit)) / placeholdertokens);
60
  content = /<\|padtxt.*?\|>/.test(content) ? content.replace(/<\|padtxt.*?\|>/, padding).replace(/\s*<\|padtxt.*?\|>\s*/g, '\n\n') : !apiKey ? padding + '\n\n\n' + content.trim() : content;
61
  return content;
62
  }, xmlPlot_merge = (content, mergeTag, nonsys) => {
63
  if (/(\n\n|^\s*)xmlPlot:\s*/.test(content)) {
64
- content = (nonsys ? content : content.replace(/(\n\n|^\s*)(?<!\n\n(Human|Assistant):.*?)xmlPlot:\s*/gs, '$1')).replace(/(\n\n|^\s*)xmlPlot: */g, mergeTag.system && mergeTag.human && mergeTag.all ? '\n\nHuman: ' : '$1' );
65
  }
66
- mergeTag.all && mergeTag.human && (content = content.replace(/(?:\n\n|^\s*)Human:(.*?(?:\n\nAssistant:|$))/gs, function(match, p1) {return '\n\nHuman:' + p1.replace(/\n\nHuman:\s*/g, '\n\n')}));
67
- mergeTag.all && mergeTag.assistant && (content = content.replace(/\n\nAssistant:(.*?(?:\n\nHuman:|$))/gs, function(match, p1) {return '\n\nAssistant:' + p1.replace(/\n\nAssistant:\s*/g, '\n\n')}));
68
  return content;
69
  }, xmlPlot_regex = (content, order) => {
70
  let matches = content.match(new RegExp(`<regex(?: +order *= *${order})${order === 2 ? '?' : ''}> *"(/?)(.*)\\1(.*?)" *: *"(.*?)" *</regex>`, 'gm'));
@@ -117,7 +117,7 @@ const asyncPool = async (poolLimit, array, iteratorFn) => {
117
  .replace(/\s*<\|join\|>\s*/g, '')
118
  .replace(/\s*<\|space\|>\s*/g, ' ')
119
  .replace(/\s*\n\n(H(uman)?|A(ssistant)?): +/g, '\n\n$1: ')
120
- .replace(/<\|(\\.*?)\|>/g, function(match, p1) {
121
  try {
122
  return JSON.parse(`"${p1.replace(/\\?"/g, '\\"')}"`);
123
  } catch { return match }
@@ -125,19 +125,19 @@ const asyncPool = async (poolLimit, array, iteratorFn) => {
125
  //确保格式正确
126
  if (apiKey) {
127
  content = content.replace(/(\n\nHuman:(?!.*?\n\nAssistant:).*?|(?<!\n\nAssistant:.*?))$/s, '$&\n\nAssistant:').replace(/\s*<\|noAssistant\|>\s*(.*?)(?:\n\nAssistant:\s*)?$/s, '\n\n$1');
128
- content.includes('<|reverseHA|>') && (content = content.replace(/\s*<\|reverseHA\|>\s*/g, '\n\n').replace(/Assistant|Human/g, function(match) {return match === 'Human' ? 'Assistant' : 'Human'}).replace(/\n(A|H): /g, function(match, p1) {return p1 === 'A' ? '\nH: ' : '\nA: '}));
129
  return content.replace(Config.Settings.padtxt ? /\s*<\|(?!padtxt).*?\|>\s*/g : /\s*<\|.*?\|>\s*/g, '\n\n').trim().replace(/^.+:/, '\n\n$&').replace(/(?<=\n)\n(?=\n)/g, '');
130
  } else {
131
  return content.replace(Config.Settings.padtxt ? /\s*<\|(?!padtxt).*?\|>\s*/g : /\s*<\|.*?\|>\s*/g, '\n\n').trim().replace(/^Human: *|\n\nAssistant: *$/g, '').replace(/(?<=\n)\n(?=\n)/g, '');
132
  }
133
- }, waitForChange = () => {
134
  return new Promise(resolve => {
135
- const interval = setInterval(() => {
136
- if (!changing) {
137
- clearInterval(interval);
138
- resolve();
139
- }
140
- }, 100);
141
  });
142
  };
143
  /******************************************************* */
@@ -181,7 +181,7 @@ let uuidOrg, curPrompt = {}, prevPrompt = {}, prevMessages = [], prevImpersonate
181
  NoSamples: false,
182
  StripAssistant: false,
183
  StripHuman: false,
184
- PassParams: true,
185
  ClearFlags: true,
186
  PreserveChats: true,
187
  LogMessages: true,
@@ -194,7 +194,7 @@ let uuidOrg, curPrompt = {}, prevPrompt = {}, prevMessages = [], prevImpersonate
194
  }
195
  };
196
 
197
- ServerResponse.prototype.json = async function(body, statusCode = 200, headers) {
198
  body = body instanceof Promise ? await body : body;
199
  this.headersSent || this.writeHead(statusCode, {
200
  'Content-Type': 'application/json',
@@ -204,7 +204,7 @@ ServerResponse.prototype.json = async function(body, statusCode = 200, headers)
204
  return this;
205
  };
206
 
207
- Array.prototype.sample = function() {
208
  return this[Math.floor(Math.random() * this.length)];
209
  };
210
 
@@ -244,7 +244,7 @@ const updateParams = res => {
244
  });
245
  updateParams(res);
246
  }, onListen = async () => {
247
- /***************************** */
248
  if (Firstlogin) {
249
  Firstlogin = false, timestamp = Date.now(), totaltime = Config.CookieArray.length;
250
  console.log(`${Main}\nhttp://${Config.Ip}:${Config.Port}/v1\n\n${Object.keys(Config.Settings).map((setting => UnknownSettings?.includes(setting) ? `??? ${setting}: ${Config.Settings[setting]}` : `${setting}: ${ChangedSettings?.includes(setting) ? '' : ''}${Config.Settings[setting]}`)).sort().join('\n')}\n`); //↓
@@ -271,119 +271,119 @@ const updateParams = res => {
271
  return process.exit();
272
  }
273
  try {
274
- /***************************** */
275
- if ('SET YOUR COOKIE HERE' === Config.Cookie || Config.Cookie?.length < 1) {
276
- return changing = false, console.log(`No cookie available, enter apiKey-only mode.\n`); //throw Error('Set your cookie inside config.js');
277
- }
278
- updateCookies(Config.Cookie);
279
- /**************************** */
280
- const bootstrapRes = await (Config.Settings.Superfetch ? Superfetch : fetch)((Config.rProxy || AI.end()) + `/api/bootstrap`, {
281
- method: 'GET',
282
- headers: {
283
- ...AI.hdr(),
284
- Cookie: getCookies()
285
- }
286
- });
287
- await checkResErr(bootstrapRes);
288
- const bootstrap = await bootstrapRes.json();
289
- if (bootstrap.account === null) {
290
- console.log(`Null!`);
291
- return CookieCleaner('Null', percentage);
292
- }
293
- const bootAccInfo = bootstrap.account.memberships.find(item => item.organization.capabilities.includes('chat')).organization;
294
- cookieModel = bootstrap.statsig.values.layer_configs["HPOHwBLNLQLxkj5Yn4bfSkgCQnBX28kPR7h/BNKdVLw="]?.value?.console_default_model_override?.model || bootstrap.statsig.values.dynamic_configs["6zA9wvTedwkzjLxWy9PVe7yydI00XDQ6L5Fejjq/2o8="]?.value?.model;
295
- isPro = bootAccInfo.capabilities.includes('claude_pro') && 'claude_pro' || bootAccInfo.capabilities.includes('raven') && 'claude_team_pro';
296
- const unknown = cookieModel && !(AI.mdl().includes(cookieModel) || Config.unknownModels.includes(cookieModel));
297
- if (Config.CookieArray?.length > 0 && (isPro || cookieModel) != Config.CookieArray[currentIndex].split('@')[0] || unknown) {
298
- Config.CookieArray[currentIndex] = (isPro || cookieModel) + '@' + Config.Cookie;
299
- unknown && Config.unknownModels.push(cookieModel);
300
- writeSettings(Config);
301
- }
302
- if (!isPro && model && model != cookieModel) return CookieChanger();
303
- console.log(Config.CookieArray?.length > 0 ? `(index: ${currentIndex + 1 || Config.CookieArray.length}) Logged in %o` : 'Logged in %o', { //console.log('Logged in %o', { ↓
304
- name: bootAccInfo.name?.split('@')?.[0],
305
- mail: bootstrap.account.email_address, //
306
- cookieModel, //
307
- capabilities: bootAccInfo.capabilities
308
- }); //↓
309
- if (uuidOrgArray.includes(bootAccInfo.uuid) && percentage <= 100 && Config.CookieArray?.length > 0 || bootAccInfo.api_disabled_reason && !bootAccInfo.api_disabled_until || !bootstrap.account.completed_verification_at) {
310
- const flag = bootAccInfo.api_disabled_reason ? 'Disabled' : !bootstrap.account.completed_verification_at ? 'Unverified' : 'Overlap';
311
- console.log(`${flag}!`);
312
- return CookieCleaner(flag, percentage);
313
- } else uuidOrgArray.push(bootAccInfo.uuid);
314
- if (Config.Cookiecounter < 0) {
315
- console.log(`[progress]: ${percentage.toFixed(2)}%\n[length]: ${Config.CookieArray.length}\n`);
316
- return CookieChanger();
317
- }
318
- /**************************** */
319
- const accRes = await (Config.Settings.Superfetch ? Superfetch : fetch)((Config.rProxy || AI.end()) + '/api/organizations', {
320
- method: 'GET',
321
- headers: {
322
- ...AI.hdr(),
323
- Cookie: getCookies()
324
  }
325
- });
326
- await checkResErr(accRes);
327
- const accInfo = (await accRes.json())?.find(item => item.capabilities.includes('chat')); //const accInfo = (await accRes.json())?.[0];\nif (!accInfo || accInfo.error) {\n throw Error(`Couldn't get account info: "${accInfo?.error?.message || accRes.statusText}"`);\n}\nif (!accInfo?.uuid) {\n throw Error('Invalid account id');\n}
328
- setTitle('ok');
329
- updateParams(accRes);
330
- uuidOrg = accInfo?.uuid;
331
- if (accInfo?.active_flags.length > 0) {
332
- let banned = false; //
333
- const now = new Date, formattedFlags = accInfo.active_flags.map((flag => {
334
- const days = ((new Date(flag.expires_at).getTime() - now.getTime()) / 864e5).toFixed(2);
335
- 'consumer_banned' === flag.type && (banned = true); //
336
- return {
337
- type: flag.type,
338
- remaining_days: days
339
- };
340
- }));
341
- console.warn(`${banned ? '' : ''}Your account has warnings %o`, formattedFlags); //console.warn('Your account has warnings %o', formattedFlags);
342
- await Promise.all(accInfo.active_flags.map((flag => (async type => {
343
- if (!Config.Settings.ClearFlags) {
344
- return;
345
  }
346
- if ('consumer_restricted_mode' === type || 'consumer_banned' === type) { //if ('consumer_restricted_mode' === type) {
347
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
348
  }
349
- const req = await (Config.Settings.Superfetch ? Superfetch : fetch)(`${Config.rProxy || AI.end()}/api/organizations/${uuidOrg}/flags/${type}/dismiss`, {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
350
  headers: {
351
  ...AI.hdr(),
352
  Cookie: getCookies()
353
  },
354
- method: 'POST'
355
  });
356
- updateParams(req);
357
- const json = await req.json();
358
- console.log(`${type}: ${json.error ? json.error.message || json.error.type || json.detail : 'OK'}`);
359
- })(flag.type))));
360
- console.log(`${banned ? 'Banned' : 'Restricted'}!`); //
361
- if (banned) return CookieCleaner('Banned') //
362
- else if (Config.Settings.SkipRestricted) return CookieChanger(); //
363
- }
364
- if (bootstrap.account.settings.preview_feature_uses_artifacts != Config.Settings.Artifacts) {
365
- const settingsRes = await (Config.Settings.Superfetch ? Superfetch : fetch)((Config.rProxy || AI.end()) + `/api/account`, {
366
- method: 'PUT',
367
  headers: {
368
  ...AI.hdr(),
369
  Cookie: getCookies()
370
- },
371
- body: JSON.stringify({ settings: Object.assign(bootstrap.account.settings, { preview_feature_uses_artifacts: Config.Settings.Artifacts }) }),
372
- });
373
- await checkResErr(settingsRes);
374
- updateParams(settingsRes);
375
- }
376
- changing = false;
377
- const convRes = await (Config.Settings.Superfetch ? Superfetch : fetch)(`${Config.rProxy || AI.end()}/api/organizations/${accInfo.uuid}/chat_conversations`, { //const convRes = await fetch(`${Config.rProxy || AI.end()}/api/organizations/${uuidOrg}/chat_conversations`, {
378
- method: 'GET',
379
- headers: {
380
- ...AI.hdr(),
381
- Cookie: getCookies()
382
- }
383
- }), conversations = await convRes.json();
384
- updateParams(convRes);
385
- conversations.length > 0 && await asyncPool(10, conversations, async (conv) => await deleteChat(conv.uuid)); //await Promise.all(conversations.map((conv => deleteChat(conv.uuid))));
386
- /***************************** */
387
  } catch (err) {
388
  if (err.message === 'Invalid authorization') {
389
  console.log(`Invalid!`);
@@ -392,7 +392,7 @@ const updateParams = res => {
392
  console.error('Clewd:\n%o', err);
393
  CookieChanger();
394
  }
395
- /***************************** */
396
  }, writeSettings = async (config, firstRun = false) => {
397
  if (process.env.Cookie || process.env.CookieArray) return; //
398
  write(ConfigPath, `/*\n* https://rentry.org/teralomaniac_clewd\n* https://github.com/teralomaniac/clewd\n*/\n\n// SET YOUR COOKIE BELOW\n\nmodule.exports = ${JSON.stringify(config, null, 4)}\n\n/*\n BufferSize\n * How many characters will be buffered before the AI types once\n * lower = less chance of \`PreventImperson\` working properly\n\n ---\n\n SystemInterval\n * How many messages until \`SystemExperiments alternates\`\n\n ---\n\n Other settings\n * https://gitgud.io/ahsk/clewd/#defaults\n * and\n * https://gitgud.io/ahsk/clewd/-/blob/master/CHANGELOG.md\n */`.trim().replace(/((?<!\r)\n|\r(?!\n))/g, '\r\n'));
@@ -414,144 +414,379 @@ const updateParams = res => {
414
  const api_rProxy = URL.query?.api_rProxy || Config.api_rProxy;
415
  req.url = URL.pathname;
416
  switch (req.url) {
417
- case '/hf/v1/models':
418
- /***************************** */
419
- (async (req, res) => {
420
- let models;
421
- if (/oaiKey:/.test(req.headers.authorization)) {
422
- try {
423
- const modelsRes = await fetch(api_rProxy.replace(/(\/v1)?\/? *$/, '') + '/v1/models', {
424
- method: 'GET',
425
- headers: { authorization: req.headers.authorization.match(/(?<=oaiKey:).*/)?.[0].split(',')[0].trim() }
426
- });
427
- models = await modelsRes.json();
428
- } catch(err) {}
429
- }
430
- res.json({
431
- data: [
432
- ...AI.mdl().concat(Config.unknownModels).map((name => ({ id: name })))
433
- ].concat(models?.data).reduce((acc, current, index) => {
434
- index === 0 && modelList.splice(0);
435
- if (current?.id && acc.every(model => model.id != current.id)) {
436
- acc.push(current);
437
- modelList.push(current.id);
438
- }
439
- return acc;
440
- }, [])
441
- });
442
- })(req, res); //res.json({\n data: AI.mdl().map((name => ({\n id: name\n })))\n});
443
- /***************************** */
444
- break;
445
-
446
- case '/hf/v1/chat/completions':
447
- ((req, res) => {
448
- setTitle('recv...');
449
- let fetchAPI;
450
- const abortControl = new AbortController, {signal} = abortControl;
451
- res.socket.on('close', (async () => {
452
- abortControl.signal.aborted || abortControl.abort();
453
- }));
454
- const buffer = [];
455
- req.on('data', (chunk => {
456
- buffer.push(chunk);
457
- }));
458
- req.on('end', (async () => {
459
- let clewdStream, titleTimer, samePrompt = false, shouldRenew = true, retryRegen = false, exceeded_limit = false, nochange = false; //let clewdStream, titleTimer, samePrompt = false, shouldRenew = true, retryRegen = false;
460
- try {
461
- const body = JSON.parse(Buffer.concat(buffer).toString());
462
- let {temperature} = body;
463
- temperature = typeof temperature === 'number' ? Math.max(.1, Math.min(1, temperature)) : undefined; //temperature = Math.max(.1, Math.min(1, temperature));
464
- let {messages} = body;
465
- /************************* */
466
- const thirdKey = req.headers.authorization?.match(/(?<=(3rd|oai)Key:).*/), oaiAPI = /oaiKey:/.test(req.headers.authorization), forceModel = /--force/.test(body.model);
467
- apiKey = thirdKey?.[0].split(',').map(item => item.trim()) || req.headers.authorization?.match(/sk-ant-api\d\d-[\w-]{86}-[\w-]{6}AA/g);
468
- model = apiKey || forceModel || isPro ? body.model.replace(/--force/, '').trim() : cookieModel;
469
- let max_tokens_to_sample = body.max_tokens, stop_sequences = body.stop, top_p = typeof body.top_p === 'number' ? body.top_p : undefined, top_k = typeof body.top_k === 'number' ? body.top_k : undefined;
470
- if (!apiKey && (Config.ProxyPassword != '' && req.headers.authorization != 'Bearer ' + Config.ProxyPassword || !uuidOrg)) {
471
- throw Error(uuidOrg ? 'ProxyPassword Wrong' : 'No cookie available or apiKey format wrong');
472
- } else if (!changing && !apiKey && (!isPro && model != cookieModel)) CookieChanger();
473
- await waitForChange();
474
- /************************* */
475
- if (messages?.length < 1) {
476
- throw Error('Select OpenAI as completion source');
477
- }
478
- if (!body.stream && 1 === messages.length && JSON.stringify(messages.sort() || []) === JSON.stringify([ {
479
- role: 'user',
480
- content: 'Hi'
481
- } ].sort())) {
482
- return res.json({
483
- choices: [ {
484
- message: {
485
- content: Main
486
- }
487
- } ]
488
  });
489
- }
490
- res.setHeader('Access-Control-Allow-Origin', '*');
491
- body.stream && res.setHeader('Content-Type', 'text/event-stream');
492
- if (!body.stream && messages?.[0]?.content?.startsWith('From the list below, choose a word that best represents a character\'s outfit description, action, or emotion in their dialogue')) {
493
- return res.json({
494
- choices: [ {
495
- message: {
496
- content: 'neutral'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
497
  }
498
- } ]
499
- });
500
- }
501
- if (Config.Settings.AllSamples && Config.Settings.NoSamples) {
502
- console.log('having AllSamples and NoSamples both set to true is not supported');
503
- throw Error('Only one can be used at the same time: AllSamples/NoSamples');
504
- }
505
- //const model = body.model;//if (model === AI.mdl()[0]) {// return;//}
506
- if (!modelList.includes(model) && !/claude-.*/.test(model) && !forceModel) {
507
- throw Error('Invalid model selected: ' + model);
508
- }
509
- curPrompt = {
510
- firstUser: messages.find((message => 'user' === message.role)),
511
- firstSystem: messages.find((message => 'system' === message.role)),
512
- firstAssistant: messages.find((message => 'assistant' === message.role)),
513
- lastUser: messages.findLast((message => 'user' === message.role)),
514
- lastSystem: messages.findLast((message => 'system' === message.role && '[Start a new chat]' !== message.content)),
515
- lastAssistant: messages.findLast((message => 'assistant' === message.role))
516
- };
517
- prevPrompt = {
518
- ...prevMessages.length > 0 && {
519
- firstUser: prevMessages.find((message => 'user' === message.role)),
520
- firstSystem: prevMessages.find((message => 'system' === message.role)),
521
- firstAssistant: prevMessages.find((message => 'assistant' === message.role)),
522
- lastUser: prevMessages.findLast((message => 'user' === message.role)),
523
- lastSystem: prevMessages.find((message => 'system' === message.role && '[Start a new chat]' !== message.content)),
524
- lastAssistant: prevMessages.findLast((message => 'assistant' === message.role))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
525
  }
526
- };
527
- samePrompt = JSON.stringify(messages.filter((message => 'system' !== message.role)).sort()) === JSON.stringify(prevMessages.filter((message => 'system' !== message.role)).sort());
528
- const sameCharDiffChat = !samePrompt && curPrompt.firstSystem?.content === prevPrompt.firstSystem?.content && curPrompt.firstUser?.content !== prevPrompt.firstUser?.content;
529
- shouldRenew = Config.Settings.RenewAlways || !Conversation.uuid || prevImpersonated || !Config.Settings.RenewAlways && samePrompt || sameCharDiffChat;
530
- retryRegen = Config.Settings.RetryRegenerate && samePrompt && null != Conversation.uuid;
531
- samePrompt || (prevMessages = JSON.parse(JSON.stringify(messages)));
532
- let type = '';
533
- if (apiKey) { type = 'api'; } else if (retryRegen) { //if (retryRegen) {
534
- type = 'R';
535
- fetchAPI = await (async (signal, model) => {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
536
  let res;
537
  const body = {
538
- prompt: '',
539
- parent_message_uuid: '',
540
- timezone: AI.zone(),
541
- attachments: [],
542
- files: [],
543
- rendering_mode: 'raw'
 
 
 
 
 
 
 
544
  };
545
  let headers = {
546
  ...AI.hdr(Conversation.uuid || ''),
547
  Accept: 'text/event-stream',
548
  Cookie: getCookies()
549
  };
550
- if (Config.Settings.Superfetch) {
551
- const names = Object.keys(headers), values = Object.values(headers);
552
- headers = names.map(((header, idx) => `${header}: ${values[idx]}`));
553
- }
554
- res = await (Config.Settings.Superfetch ? Superfetch : fetch)((Config.rProxy || AI.end()) + `/api/organizations/${uuidOrg || ''}/chat_conversations/${Conversation.uuid || ''}/retry_completion`, {
555
  stream: true,
556
  signal,
557
  method: 'POST',
@@ -561,323 +796,90 @@ const updateParams = res => {
561
  updateParams(res);
562
  await checkResErr(res);
563
  return res;
564
- })(signal, model);
565
- } else if (shouldRenew) {
566
- Conversation.uuid && await deleteChat(Conversation.uuid);
567
- fetchAPI = await (async signal => {
568
- Conversation.uuid = randomUUID().toString();
569
- Conversation.depth = 0;
570
- const res = await (Config.Settings.Superfetch ? Superfetch : fetch)(`${Config.rProxy || AI.end()}/api/organizations/${uuidOrg}/chat_conversations`, {
571
- signal,
572
- headers: {
573
- ...AI.hdr(),
574
- Cookie: getCookies()
575
- },
576
- method: 'POST',
577
- body: JSON.stringify({
578
- uuid: Conversation.uuid,
579
- name: ''
580
- })
581
- });
582
- updateParams(res);
583
- await checkResErr(res);
584
- return res;
585
- })(signal);
586
- type = 'r';
587
- } else if (samePrompt) {} else {
588
- const systemExperiment = !Config.Settings.RenewAlways && Config.Settings.SystemExperiments;
589
- if (!systemExperiment || systemExperiment && Conversation.depth >= Config.SystemInterval) {
590
- type = 'c-r';
591
- Conversation.depth = 0;
592
- } else {
593
- type = 'c-c';
594
- Conversation.depth++;
595
- }
596
- }
597
- let {prompt, systems} = ((messages, type) => {
598
- const rgxScenario = /^\[Circumstances and context of the dialogue: ([\s\S]+?)\.?\]$/i, rgxPerson = /^\[([\s\S]+?)'s personality: ([\s\S]+?)\]$/i, messagesClone = JSON.parse(JSON.stringify(messages)), realLogs = messagesClone.filter((message => [ 'user', 'assistant' ].includes(message.role))), sampleLogs = messagesClone.filter((message => message.name)), mergedLogs = [ ...sampleLogs, ...realLogs ];
599
- mergedLogs.forEach(((message, idx) => {
600
- const next = mergedLogs[idx + 1];
601
- message.customname = (message => [ 'assistant', 'user' ].includes(message.role) && null != message.name && !(message.name in Replacements))(message);
602
- if (next && !Config.Settings.xmlPlot) { //if (next) {
603
- if ('name' in message && 'name' in next) {
604
- if (message.name === next.name) {
605
- message.content += '\n' + next.content;
606
- next.merged = true;
607
- }
608
- } else if ('system' !== next.role) {
609
- if (next.role === message.role) {
610
- message.content += '\n' + next.content;
611
- next.merged = true;
612
- }
613
- } else {
614
- message.content += '\n' + next.content;
615
- next.merged = true;
616
  }
617
- }
618
- }));
619
- const lastAssistant = realLogs.findLast((message => !message.merged && 'assistant' === message.role));
620
- lastAssistant && Config.Settings.StripAssistant && (lastAssistant.strip = true);
621
- const lastUser = realLogs.findLast((message => !message.merged && 'user' === message.role));
622
- lastUser && Config.Settings.StripHuman && (lastUser.strip = true);
623
- const systemMessages = messagesClone.filter((message => 'system' === message.role && !('name' in message)));
624
- systemMessages.forEach(((message, idx) => {
625
- const scenario = message.content.match(rgxScenario)?.[1], personality = message.content.match(rgxPerson);
626
- if (scenario) {
627
- message.content = Config.ScenarioFormat.replace(/{{scenario}}/gim, scenario);
628
- message.scenario = true;
629
- }
630
- if (3 === personality?.length) {
631
- message.content = Config.PersonalityFormat.replace(/{{char}}/gim, personality[1]).replace(/{{personality}}/gim, personality[2]);
632
- message.personality = true;
633
- }
634
- message.main = 0 === idx;
635
- message.jailbreak = idx === systemMessages.length - 1;
636
- ' ' === message.content && (message.discard = true);
637
- }));
638
- Config.Settings.AllSamples && !Config.Settings.NoSamples && realLogs.forEach((message => {
639
- if (![ lastUser, lastAssistant ].includes(message)) {
640
- if ('user' === message.role) {
641
- message.name = message.customname ? message.name : 'example_user';
642
- message.role = 'system';
643
- } else if ('assistant' === message.role) {
644
- message.name = message.customname ? message.name : 'example_assistant';
645
- message.role = 'system';
646
- } else if (!message.customname) {
647
- throw Error('Invalid role ' + message.name);
648
  }
649
- }
650
- }));
651
- Config.Settings.NoSamples && !Config.Settings.AllSamples && sampleLogs.forEach((message => {
652
- if ('example_user' === message.name) {
653
- message.role = 'user';
654
- } else if ('example_assistant' === message.name) {
655
- message.role = 'assistant';
656
- } else if (!message.customname) {
657
- throw Error('Invalid role ' + message.name);
658
- }
659
- message.customname || delete message.name;
660
- }));
661
- let systems = [];
662
- if (![ 'r', 'R', 'api' ].includes(type)) {
663
- lastUser.strip = true;
664
- systemMessages.forEach((message => message.discard = message.discard || 'c-c' === type ? !message.jailbreak : !message.jailbreak && !message.main));
665
- systems = systemMessages.filter((message => !message.discard)).map((message => `"${message.content.substring(0, 25).replace(/\n/g, '\\n').trim()}..."`));
666
- messagesClone.forEach((message => message.discard = message.discard || mergedLogs.includes(message) && ![ lastUser ].includes(message)));
667
- }
668
- const prompt = messagesClone.map(((message, idx) => {
669
- if (message.merged || message.discard) {
670
- return '';
671
- }
672
- if (message.content.length < 1) {
673
- return message.content;
674
- }
675
- let spacing = '';
676
- /******************************** */
677
- if (Config.Settings.xmlPlot) {
678
- idx > 0 && (spacing = '\n\n');
679
- const prefix = message.customname ? message.role + ': ' + message.name.replaceAll('_', ' ') + ': ' : 'system' !== message.role || message.name ? Replacements[message.name || message.role] + ': ' : 'xmlPlot: ' + Replacements[message.role];
680
- return `${spacing}${message.strip ? '' : prefix}${message.content}`;
681
- } else {
682
- /******************************** */
683
- idx > 0 && (spacing = systemMessages.includes(message) ? '\n' : '\n\n');
684
- const prefix = message.customname ? message.name.replaceAll('_', ' ') + ': ' : 'system' !== message.role || message.name ? Replacements[message.name || message.role] + ': ' : '' + Replacements[message.role];
685
- return `${spacing}${message.strip ? '' : prefix}${'system' === message.role ? message.content : message.content.trim()}`;
686
- } //
687
- }));
688
- return {
689
- prompt: prompt.join(''), //genericFixes(prompt.join('')).trim(),
690
- systems
691
- };
692
- })(messages, type);
693
- /******************************** */
694
- const legacy = /claude-([12]|instant)/i.test(model), messagesAPI = thirdKey || !legacy && !/<\|completeAPI\|>/.test(prompt) || /<\|messagesAPI\|>/.test(prompt), messagesLog = /<\|messagesLog\|>/.test(prompt), fusion = apiKey && messagesAPI && /<\|Fusion Mode\|>/.test(prompt), wedge = '\r';
695
- const stopSet = /<\|stopSet *(\[.*?\]) *\|>/.exec(prompt)?.[1], stopRevoke = /<\|stopRevoke *(\[.*?\]) *\|>/.exec(prompt)?.[1];
696
- if (stop_sequences || stopSet || stopRevoke) stop_sequences = JSON.parse(stopSet || '[]').concat(stop_sequences).concat(['\n\nHuman:', '\n\nAssistant:']).filter(item => !JSON.parse(stopRevoke || '[]').includes(item) && item);
697
- apiKey && (type = oaiAPI ? 'oai_api' : messagesAPI ? 'msg_api' : type);
698
- prompt = Config.Settings.xmlPlot ? xmlPlot(prompt, legacy && !/claude-2\.1/i.test(model)) : apiKey ? `\n\nHuman: ${genericFixes(prompt)}\n\nAssistant:` : genericFixes(prompt).trim();
699
- Config.Settings.FullColon && (prompt = !legacy ?
700
- prompt.replace(fusion ? /\n(?!\nAssistant:\s*$)(?=\n(Human|Assistant):)/gs : apiKey ? /(?<!\n\nHuman:.*)\n(?=\nAssistant:)|\n(?=\nHuman:)(?!.*\n\nAssistant:)/gs : /\n(?=\n(Human|Assistant):)/g, '\n' + wedge) :
701
- prompt.replace(fusion ? /(?<=\n\nAssistant):(?!\s*$)|(?<=\n\nHuman):/gs : apiKey ? /(?<!\n\nHuman:.*)(?<=\n\nAssistant):|(?<=\n\nHuman):(?!.*\n\nAssistant:)/gs : /(?<=\n\n(Human|Assistant)):/g, '﹕'));
702
- prompt = padtxt(prompt);
703
- /******************************** */
704
- console.log(`${model} [${type}]${!retryRegen && systems.length > 0 ? ' ' + systems.join(' / ') : ''}`);
705
- 'R' !== type || prompt || (prompt = '...regen...');
706
- Logger?.write(`\n\n-------\n[${(new Date).toLocaleString()}]\n${Main}\n####### ${model} (${type})\n${JSON.stringify({FusionMode: fusion, PassParams: Config.Settings.PassParams, stop_sequences, temperature, top_k, top_p}, null, 2)}\n\n####### regex:\n${regexLog}\n####### PROMPT ${tokens}t:\n${prompt}\n--\n####### REPLY:\n`); //Logger?.write(`\n\n-------\n[${(new Date).toLocaleString()}]\n####### MODEL: ${model}\n####### PROMPT (${type}):\n${prompt}\n--\n####### REPLY:\n`);
707
- retryRegen || (fetchAPI = await (async (signal, model, prompt, temperature, type) => {
708
- /******************************** */
709
- if (apiKey) {
710
- let messages, system, key = apiKey[Math.floor(Math.random() * apiKey.length)];
711
- if (messagesAPI) {
712
- const rounds = prompt.replace(/^(?!.*\n\nHuman:)/s, '\n\nHuman:').split('\n\nHuman:');
713
- messages = rounds.slice(1).flatMap(round => {
714
- const turns = round.split('\n\nAssistant:');
715
- return [{role: 'user', content: turns[0].trim()}].concat(turns.slice(1).flatMap(turn => [{role: 'assistant', content: turn.trim()}]));
716
- }).reduce((acc, current) => {
717
- if (Config.Settings.FullColon && acc.length > 0 && (acc[acc.length - 1].role === current.role || !acc[acc.length - 1].content)) {
718
- acc[acc.length - 1].content += (current.role === 'user' ? 'Human' : 'Assistant').replace(/.*/, legacy ? '\n$&﹕ ' : '\n' + wedge + '\n$&: ') + current.content;
719
- } else acc.push(current);
720
- return acc;
721
- }, []).filter(message => message.content), oaiAPI ? messages.unshift({role: 'system', content: rounds[0].trim()}) : system = rounds[0].trim();
722
- messagesLog && console.log({system, messages});
723
- }
724
- const res = await fetch((api_rProxy || 'https://api.anthropic.com').replace(/(\/v1)? *$/, thirdKey ? '$1' : '/v1').trim('/') + (oaiAPI ? '/chat/completions' : messagesAPI ? '/messages' : '/complete'), {
725
- method: 'POST',
726
- signal,
727
- headers: {
728
- 'anthropic-version': '2023-06-01',
729
- 'authorization': 'Bearer ' + key,
730
- 'Content-Type': 'application/json',
731
- 'User-Agent': AI.agent(),
732
- 'x-api-key': key,
733
- },
734
- body: JSON.stringify({
735
- ...oaiAPI || messagesAPI ? {
736
- max_tokens : max_tokens_to_sample,
737
- messages,
738
- system
739
- } : {
740
- max_tokens_to_sample,
741
- prompt
742
- },
743
- model,
744
- stop_sequences,
745
- stream: true,
746
- top_k,
747
- top_p
748
- }),
749
- });
750
- await checkResErr(res);
751
- return res;
752
  }
753
- /******************************** */
754
- const attachments = [];
755
- if (Config.Settings.PromptExperiments) {
756
- let splitedprompt = prompt.split('\n\nPlainPrompt:'); //
757
- prompt = splitedprompt[0]; //
758
- attachments.push({
759
- extracted_content: prompt,
760
- file_name: 'paste.txt', //fileName(),
761
- file_type: 'txt', //'text/plain',
762
- file_size: Buffer.from(prompt).byteLength
763
- });
764
- prompt = 'r' === type ? Config.PromptExperimentFirst : Config.PromptExperimentNext;
765
- splitedprompt.length > 1 && (prompt += splitedprompt[1]); //
766
- }
767
- let res;
768
- const body = {
769
- attachments,
770
- files: [],
771
- model: isPro || forceModel ? model : undefined,
772
- rendering_mode: 'raw',
773
- ...Config.Settings.PassParams && {
774
- max_tokens_to_sample, //
775
- //stop_sequences, //
776
- top_k, //
777
- top_p,
778
- },
779
- prompt: prompt || '',
780
- timezone: AI.zone()
781
- };
782
- let headers = {
783
- ...AI.hdr(Conversation.uuid || ''),
784
- Accept: 'text/event-stream',
785
- Cookie: getCookies()
786
- };
787
- res = await (Config.Settings.Superfetch ? Superfetch : fetch)(`${Config.rProxy || AI.end()}/api/organizations/${uuidOrg || ''}/chat_conversations/${Conversation.uuid || ''}/completion`, {
788
- stream: true,
789
- signal,
790
- method: 'POST',
791
- body: JSON.stringify(body),
792
- headers
793
- });
794
- updateParams(res);
795
- await checkResErr(res);
796
- return res;
797
- })(signal, model, prompt, temperature, type));
798
- const response = Writable.toWeb(res);
799
- clewdStream = new ClewdStream({
800
- config: {
801
- ...Config,
802
- Settings: {
803
- ...Config.Settings,
804
- Superfetch: apiKey ? false : Config.Settings.Superfetch
805
- }
806
- }, //config: Config,
807
- version: Main,
808
- minSize: Config.BufferSize,
809
- model,
810
- streaming: true === body.stream,
811
- abortControl,
812
- source: fetchAPI
813
- }, Logger);
814
- titleTimer = setInterval((() => setTitle('recv ' + bytesToSize(clewdStream.size))), 300);
815
- (!apiKey && Config.Settings.Superfetch) ? await Readable.toWeb(fetchAPI.body).pipeThrough(clewdStream).pipeTo(response) : await fetchAPI.body.pipeThrough(clewdStream).pipeTo(response); //Config.Settings.Superfetch ? await Readable.toWeb(fetchAPI.body).pipeThrough(clewdStream).pipeTo(response) : await fetchAPI.body.pipeThrough(clewdStream).pipeTo(response);
816
- } catch (err) {
817
- if ('AbortError' === err.name) {
818
- res.end();
819
- } else {
820
- nochange = true, exceeded_limit = err.exceeded_limit; //
821
- err.planned ? console.log(`${err.status || 'Aborted'}!\n`) : console.error('Clewd:\n%o', err); //err.planned || console.error('Clewd:\n%o', err);
822
- res.json({
823
- error: {
824
- message: 'clewd: ' + (err.message || err.name || err.type),
825
- type: err.type || err.name || err.code,
826
- param: null,
827
- code: err.code || 500
828
- }
829
- }, 500);
830
  }
831
- }
832
- clearInterval(titleTimer);
833
- if (clewdStream) {
834
- clewdStream.censored && console.warn('likely your account is hard-censored');
835
- prevImpersonated = clewdStream.impersonated;
836
- exceeded_limit = clewdStream.error.exceeded_limit; //
837
- clewdStream.error.status < 200 || clewdStream.error.status >= 300 || clewdStream.error.message === 'Overloaded' && (nochange = true); //
838
- setTitle('ok ' + bytesToSize(clewdStream.size));
839
- if (clewdStream.compModel && !(AI.mdl().includes(clewdStream.compModel) || Config.unknownModels.includes(clewdStream.compModel)) && !apiKey) {
840
- Config.unknownModels.push(clewdStream.compModel);
841
- writeSettings(Config);
 
 
842
  }
843
- console.log(`${200 == fetchAPI.status ? '' : ''}${fetchAPI.status}!\n`);
844
- clewdStream.empty();
845
- }
846
- const shouldChange = exceeded_limit || !nochange && Config.Cookiecounter > 0 && changeflag++ >= Config.Cookiecounter - 1; //
847
- if (!apiKey && (shouldChange || prevImpersonated)) { //if (prevImpersonated) {
848
- try {
849
- await deleteChat(Conversation.uuid);
850
- } catch (err) {}
851
- /******************************** */
852
- if (shouldChange) {
853
- exceeded_limit && console.log(`Exceeded limit!\n`);
854
- changeflag = 0;
855
- CookieChanger();
856
  }
857
- /******************************** */
858
- }
859
- }));
860
- })(req, res);
861
- break;
862
 
863
- case '/hf/v1/complete':
864
- res.json({
865
- error: {
866
- message: 'clewd: Set "Chat Completion source" to OpenAI instead of Claude. Enable "External" models aswell',
867
- code: 404
868
- }
869
- }, 404);
870
- break;
871
 
872
- default:
873
- !['/', '/v1', '/favicon.ico'].includes(req.url) && (console.log('unknown request: ' + req.url)); //console.log('unknown request: ' + req.url);
874
- res.writeHead(200, {'Content-Type': 'text/html'}); //
875
- res.write(`<!DOCTYPE html>\n<html>\n<head>\n<meta charset="utf-8">\n</head>\n<body>\n <h1>Hello, World!</h1>\n <p>This is a test HTML file.</p>\n</body>\n</html>`); //
876
- res.end(); //res.json(// {// error: {// message: '404 Not Found',// type: 404,// param: null,// code: 404// }//}, 404);
877
  }
878
  }));
879
 
880
- !async function() {
881
  await (async () => {
882
  if (exists(ConfigPath)) {
883
  const userConfig = require(ConfigPath), validConfigs = Object.keys(Config), parsedConfigs = Object.keys(userConfig), parsedSettings = Object.keys(userConfig.Settings), invalidConfigs = parsedConfigs.filter((config => !validConfigs.includes(config))), validSettings = Object.keys(Config.Settings);
@@ -909,7 +911,7 @@ const updateParams = res => {
909
  writeSettings(Config, true);
910
  }
911
  })();
912
- /***************************** */
913
  for (let key in Config) {
914
  if (key === 'Settings') {
915
  for (let setting in Config.Settings) {
@@ -924,7 +926,7 @@ const updateParams = res => {
924
  Config.unknownModels = Config.unknownModels.reduce((prev, cur) => !cur || prev.includes(cur) || AI.mdl().includes(cur) ? prev : [...prev, cur], []);
925
  writeSettings(Config);
926
  currentIndex = Config.CookieIndex > 0 ? Config.CookieIndex - 1 : Config.Cookiecounter >= 0 ? Math.floor(Math.random() * Config.CookieArray.length) : 0;
927
- /***************************** */
928
  Proxy.listen(Config.Port, Config.Ip, onListen);
929
  Proxy.on('error', (err => {
930
  console.error('Proxy error\n%o', err);
@@ -937,7 +939,7 @@ const cleanup = async () => {
937
  await deleteChat(Conversation.uuid);
938
  SuperfetchFoldersRm();
939
  Logger?.close();
940
- } catch (err) {}
941
  process.exit();
942
  };
943
 
 
4
  */
5
  'use strict';
6
 
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, SuperfetchFoldersMk, SuperfetchFoldersRm } = 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, changing, changetime = 0, totaltime, uuidOrgArray = [], model, cookieModel, tokens, apiKey, timestamp, regexLog, isPro, modelList = [];
 
32
  return changing = false;
33
  } else {
34
  changeflag = 0, changing = true;
35
+ if (!cleanup) {
36
  currentIndex = (currentIndex + 1) % Config.CookieArray.length;
37
  console.log(`Changing Cookie...\n`);
38
  }
 
49
  writeSettings(Config);
50
  return CookieChanger(true, true);
51
  }, padtxt = content => {
52
+ const { countTokens } = require('@anthropic-ai/tokenizer');
53
  tokens = countTokens(content);
54
  const padtxt = String(Config.Settings.padtxt).split(',').reverse(), maxtokens = parseInt(padtxt[0]), extralimit = parseInt(padtxt[1]) || 1000, minlimit = parseInt(padtxt[2]);
55
  const placeholder = (tokens > maxtokens - extralimit && minlimit ? Config.placeholder_byte : Config.placeholder_token) || randomBytes(randomInt(5, 15)).toString('hex');
56
  const placeholdertokens = countTokens(placeholder.trim());
57
  for (let match; match = content.match(/<\|padtxt.*?(\d+)t.*?\|>/); content = content.replace(match[0], placeholder.repeat(parseInt(match[1]) / placeholdertokens))) tokens += parseInt(match[1]);
58
+ if (/<\|padtxt off.*?\|>/.test(content)) return content.replace(/\s*<\|padtxt.*?\|>\s*/g, '\n\n');
59
  const padding = placeholder.repeat(Math.min(maxtokens, (tokens <= maxtokens - extralimit ? maxtokens - tokens : minlimit ? minlimit : extralimit)) / placeholdertokens);
60
  content = /<\|padtxt.*?\|>/.test(content) ? content.replace(/<\|padtxt.*?\|>/, padding).replace(/\s*<\|padtxt.*?\|>\s*/g, '\n\n') : !apiKey ? padding + '\n\n\n' + content.trim() : content;
61
  return content;
62
  }, xmlPlot_merge = (content, mergeTag, nonsys) => {
63
  if (/(\n\n|^\s*)xmlPlot:\s*/.test(content)) {
64
+ content = (nonsys ? content : content.replace(/(\n\n|^\s*)(?<!\n\n(Human|Assistant):.*?)xmlPlot:\s*/gs, '$1')).replace(/(\n\n|^\s*)xmlPlot: */g, mergeTag.system && mergeTag.human && mergeTag.all ? '\n\nHuman: ' : '$1');
65
  }
66
+ mergeTag.all && mergeTag.human && (content = content.replace(/(?:\n\n|^\s*)Human:(.*?(?:\n\nAssistant:|$))/gs, function (match, p1) { return '\n\nHuman:' + p1.replace(/\n\nHuman:\s*/g, '\n\n') }));
67
+ mergeTag.all && mergeTag.assistant && (content = content.replace(/\n\nAssistant:(.*?(?:\n\nHuman:|$))/gs, function (match, p1) { return '\n\nAssistant:' + p1.replace(/\n\nAssistant:\s*/g, '\n\n') }));
68
  return content;
69
  }, xmlPlot_regex = (content, order) => {
70
  let matches = content.match(new RegExp(`<regex(?: +order *= *${order})${order === 2 ? '?' : ''}> *"(/?)(.*)\\1(.*?)" *: *"(.*?)" *</regex>`, 'gm'));
 
117
  .replace(/\s*<\|join\|>\s*/g, '')
118
  .replace(/\s*<\|space\|>\s*/g, ' ')
119
  .replace(/\s*\n\n(H(uman)?|A(ssistant)?): +/g, '\n\n$1: ')
120
+ .replace(/<\|(\\.*?)\|>/g, function (match, p1) {
121
  try {
122
  return JSON.parse(`"${p1.replace(/\\?"/g, '\\"')}"`);
123
  } catch { return match }
 
125
  //确保格式正确
126
  if (apiKey) {
127
  content = content.replace(/(\n\nHuman:(?!.*?\n\nAssistant:).*?|(?<!\n\nAssistant:.*?))$/s, '$&\n\nAssistant:').replace(/\s*<\|noAssistant\|>\s*(.*?)(?:\n\nAssistant:\s*)?$/s, '\n\n$1');
128
+ content.includes('<|reverseHA|>') && (content = content.replace(/\s*<\|reverseHA\|>\s*/g, '\n\n').replace(/Assistant|Human/g, function (match) { return match === 'Human' ? 'Assistant' : 'Human' }).replace(/\n(A|H): /g, function (match, p1) { return p1 === 'A' ? '\nH: ' : '\nA: ' }));
129
  return content.replace(Config.Settings.padtxt ? /\s*<\|(?!padtxt).*?\|>\s*/g : /\s*<\|.*?\|>\s*/g, '\n\n').trim().replace(/^.+:/, '\n\n$&').replace(/(?<=\n)\n(?=\n)/g, '');
130
  } else {
131
  return content.replace(Config.Settings.padtxt ? /\s*<\|(?!padtxt).*?\|>\s*/g : /\s*<\|.*?\|>\s*/g, '\n\n').trim().replace(/^Human: *|\n\nAssistant: *$/g, '').replace(/(?<=\n)\n(?=\n)/g, '');
132
  }
133
+ }, waitForChange = () => {
134
  return new Promise(resolve => {
135
+ const interval = setInterval(() => {
136
+ if (!changing) {
137
+ clearInterval(interval);
138
+ resolve();
139
+ }
140
+ }, 100);
141
  });
142
  };
143
  /******************************************************* */
 
181
  NoSamples: false,
182
  StripAssistant: false,
183
  StripHuman: false,
184
+ PassParams: false,
185
  ClearFlags: true,
186
  PreserveChats: true,
187
  LogMessages: true,
 
194
  }
195
  };
196
 
197
+ ServerResponse.prototype.json = async function (body, statusCode = 200, headers) {
198
  body = body instanceof Promise ? await body : body;
199
  this.headersSent || this.writeHead(statusCode, {
200
  'Content-Type': 'application/json',
 
204
  return this;
205
  };
206
 
207
+ Array.prototype.sample = function () {
208
  return this[Math.floor(Math.random() * this.length)];
209
  };
210
 
 
244
  });
245
  updateParams(res);
246
  }, onListen = async () => {
247
+ /***************************** */
248
  if (Firstlogin) {
249
  Firstlogin = false, timestamp = Date.now(), totaltime = Config.CookieArray.length;
250
  console.log(`${Main}\nhttp://${Config.Ip}:${Config.Port}/v1\n\n${Object.keys(Config.Settings).map((setting => UnknownSettings?.includes(setting) ? `??? ${setting}: ${Config.Settings[setting]}` : `${setting}: ${ChangedSettings?.includes(setting) ? '' : ''}${Config.Settings[setting]}`)).sort().join('\n')}\n`); //↓
 
271
  return process.exit();
272
  }
273
  try {
274
+ /***************************** */
275
+ if ('SET YOUR COOKIE HERE' === Config.Cookie || Config.Cookie?.length < 1) {
276
+ return changing = false, console.log(`No cookie available, enter apiKey-only mode.\n`); //throw Error('Set your cookie inside config.js');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
  }
278
+ updateCookies(Config.Cookie);
279
+ /**************************** */
280
+ const bootstrapRes = await (Config.Settings.Superfetch ? Superfetch : fetch)((Config.rProxy || AI.end()) + `/api/bootstrap`, {
281
+ method: 'GET',
282
+ headers: {
283
+ ...AI.hdr(),
284
+ Cookie: getCookies()
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  }
286
+ });
287
+ await checkResErr(bootstrapRes);
288
+ const bootstrap = await bootstrapRes.json();
289
+ if (bootstrap.account === null) {
290
+ console.log(`Null!`);
291
+ return CookieCleaner('Null', percentage);
292
+ }
293
+ const bootAccInfo = bootstrap.account.memberships.find(item => item.organization.capabilities.includes('chat')).organization;
294
+ cookieModel = bootstrap.statsig.values.layer_configs["HPOHwBLNLQLxkj5Yn4bfSkgCQnBX28kPR7h/BNKdVLw="]?.value?.console_default_model_override?.model || bootstrap.statsig.values.dynamic_configs["6zA9wvTedwkzjLxWy9PVe7yydI00XDQ6L5Fejjq/2o8="]?.value?.model;
295
+ isPro = bootAccInfo.capabilities.includes('claude_pro') && 'claude_pro' || bootAccInfo.capabilities.includes('raven') && 'claude_team_pro';
296
+ const unknown = cookieModel && !(AI.mdl().includes(cookieModel) || Config.unknownModels.includes(cookieModel));
297
+ if (Config.CookieArray?.length > 0 && (isPro || cookieModel) != Config.CookieArray[currentIndex].split('@')[0] || unknown) {
298
+ Config.CookieArray[currentIndex] = (isPro || cookieModel) + '@' + Config.Cookie;
299
+ unknown && Config.unknownModels.push(cookieModel);
300
+ writeSettings(Config);
301
+ }
302
+ if (!isPro && model && model != cookieModel) return CookieChanger();
303
+ console.log(Config.CookieArray?.length > 0 ? `(index: ${currentIndex + 1 || Config.CookieArray.length}) Logged in %o` : 'Logged in %o', { //console.log('Logged in %o', { ↓
304
+ name: bootAccInfo.name?.split('@')?.[0],
305
+ mail: bootstrap.account.email_address, //
306
+ cookieModel, //
307
+ capabilities: bootAccInfo.capabilities
308
+ }); //↓
309
+ if (uuidOrgArray.includes(bootAccInfo.uuid) && percentage <= 100 && Config.CookieArray?.length > 0 || bootAccInfo.api_disabled_reason && !bootAccInfo.api_disabled_until || !bootstrap.account.completed_verification_at) {
310
+ const flag = bootAccInfo.api_disabled_reason ? 'Disabled' : !bootstrap.account.completed_verification_at ? 'Unverified' : 'Overlap';
311
+ console.log(`${flag}!`);
312
+ return CookieCleaner(flag, percentage);
313
+ } else uuidOrgArray.push(bootAccInfo.uuid);
314
+ if (Config.Cookiecounter < 0) {
315
+ console.log(`[progress]: ${percentage.toFixed(2)}%\n[length]: ${Config.CookieArray.length}\n`);
316
+ return CookieChanger();
317
+ }
318
+ /**************************** */
319
+ const accRes = await (Config.Settings.Superfetch ? Superfetch : fetch)((Config.rProxy || AI.end()) + '/api/organizations', {
320
+ method: 'GET',
321
+ headers: {
322
+ ...AI.hdr(),
323
+ Cookie: getCookies()
324
  }
325
+ });
326
+ await checkResErr(accRes);
327
+ const accInfo = (await accRes.json())?.find(item => item.capabilities.includes('chat')); //const accInfo = (await accRes.json())?.[0];\nif (!accInfo || accInfo.error) {\n throw Error(`Couldn't get account info: "${accInfo?.error?.message || accRes.statusText}"`);\n}\nif (!accInfo?.uuid) {\n throw Error('Invalid account id');\n}
328
+ setTitle('ok');
329
+ updateParams(accRes);
330
+ uuidOrg = accInfo?.uuid;
331
+ if (accInfo?.active_flags.length > 0) {
332
+ let banned = false; //
333
+ const now = new Date, formattedFlags = accInfo.active_flags.map((flag => {
334
+ const days = ((new Date(flag.expires_at).getTime() - now.getTime()) / 864e5).toFixed(2);
335
+ 'consumer_banned' === flag.type && (banned = true); //
336
+ return {
337
+ type: flag.type,
338
+ remaining_days: days
339
+ };
340
+ }));
341
+ console.warn(`${banned ? '' : ''}Your account has warnings %o`, formattedFlags); //console.warn('Your account has warnings %o', formattedFlags);
342
+ await Promise.all(accInfo.active_flags.map((flag => (async type => {
343
+ if (!Config.Settings.ClearFlags) {
344
+ return;
345
+ }
346
+ if ('consumer_restricted_mode' === type || 'consumer_banned' === type) { //if ('consumer_restricted_mode' === type) {
347
+ return;
348
+ }
349
+ const req = await (Config.Settings.Superfetch ? Superfetch : fetch)(`${Config.rProxy || AI.end()}/api/organizations/${uuidOrg}/flags/${type}/dismiss`, {
350
+ headers: {
351
+ ...AI.hdr(),
352
+ Cookie: getCookies()
353
+ },
354
+ method: 'POST'
355
+ });
356
+ updateParams(req);
357
+ const json = await req.json();
358
+ console.log(`${type}: ${json.error ? json.error.message || json.error.type || json.detail : 'OK'}`);
359
+ })(flag.type))));
360
+ console.log(`${banned ? 'Banned' : 'Restricted'}!`); //
361
+ if (banned) return CookieCleaner('Banned') //
362
+ else if (Config.Settings.SkipRestricted) return CookieChanger(); //
363
+ }
364
+ if (bootstrap.account.settings.preview_feature_uses_artifacts != Config.Settings.Artifacts) {
365
+ const settingsRes = await (Config.Settings.Superfetch ? Superfetch : fetch)((Config.rProxy || AI.end()) + `/api/account`, {
366
+ method: 'PUT',
367
  headers: {
368
  ...AI.hdr(),
369
  Cookie: getCookies()
370
  },
371
+ body: JSON.stringify({ settings: Object.assign(bootstrap.account.settings, { preview_feature_uses_artifacts: Config.Settings.Artifacts }) }),
372
  });
373
+ await checkResErr(settingsRes);
374
+ updateParams(settingsRes);
375
+ }
376
+ changing = false;
377
+ const convRes = await (Config.Settings.Superfetch ? Superfetch : fetch)(`${Config.rProxy || AI.end()}/api/organizations/${accInfo.uuid}/chat_conversations`, { //const convRes = await fetch(`${Config.rProxy || AI.end()}/api/organizations/${uuidOrg}/chat_conversations`, {
378
+ method: 'GET',
 
 
 
 
 
379
  headers: {
380
  ...AI.hdr(),
381
  Cookie: getCookies()
382
+ }
383
+ }), conversations = await convRes.json();
384
+ updateParams(convRes);
385
+ conversations.length > 0 && await asyncPool(10, conversations, async (conv) => await deleteChat(conv.uuid)); //await Promise.all(conversations.map((conv => deleteChat(conv.uuid))));
386
+ /***************************** */
 
 
 
 
 
 
 
 
 
 
 
 
387
  } catch (err) {
388
  if (err.message === 'Invalid authorization') {
389
  console.log(`Invalid!`);
 
392
  console.error('Clewd:\n%o', err);
393
  CookieChanger();
394
  }
395
+ /***************************** */
396
  }, writeSettings = async (config, firstRun = false) => {
397
  if (process.env.Cookie || process.env.CookieArray) return; //
398
  write(ConfigPath, `/*\n* https://rentry.org/teralomaniac_clewd\n* https://github.com/teralomaniac/clewd\n*/\n\n// SET YOUR COOKIE BELOW\n\nmodule.exports = ${JSON.stringify(config, null, 4)}\n\n/*\n BufferSize\n * How many characters will be buffered before the AI types once\n * lower = less chance of \`PreventImperson\` working properly\n\n ---\n\n SystemInterval\n * How many messages until \`SystemExperiments alternates\`\n\n ---\n\n Other settings\n * https://gitgud.io/ahsk/clewd/#defaults\n * and\n * https://gitgud.io/ahsk/clewd/-/blob/master/CHANGELOG.md\n */`.trim().replace(/((?<!\r)\n|\r(?!\n))/g, '\r\n'));
 
414
  const api_rProxy = URL.query?.api_rProxy || Config.api_rProxy;
415
  req.url = URL.pathname;
416
  switch (req.url) {
417
+ case '/hf/v1/models':
418
+ /***************************** */
419
+ (async (req, res) => {
420
+ let models;
421
+ if (/oaiKey:/.test(req.headers.authorization)) {
422
+ try {
423
+ const modelsRes = await fetch(api_rProxy.replace(/(\/v1)?\/? *$/, '') + '/v1/models', {
424
+ method: 'GET',
425
+ headers: { authorization: req.headers.authorization.match(/(?<=oaiKey:).*/)?.[0].split(',')[0].trim() }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
426
  });
427
+ models = await modelsRes.json();
428
+ } catch (err) { }
429
+ }
430
+ res.json({
431
+ data: [
432
+ ...AI.mdl().concat(Config.unknownModels).map((name => ({ id: name })))
433
+ ].concat(models?.data).reduce((acc, current, index) => {
434
+ index === 0 && modelList.splice(0);
435
+ if (current?.id && acc.every(model => model.id != current.id)) {
436
+ acc.push(current);
437
+ modelList.push(current.id);
438
+ }
439
+ return acc;
440
+ }, [])
441
+ });
442
+ })(req, res); //res.json({\n data: AI.mdl().map((name => ({\n id: name\n })))\n});
443
+ /***************************** */
444
+ break;
445
+
446
+ case '/hf/v1/chat/completions':
447
+ ((req, res) => {
448
+ setTitle('recv...');
449
+ let fetchAPI;
450
+ const abortControl = new AbortController, { signal } = abortControl;
451
+ res.socket.on('close', (async () => {
452
+ abortControl.signal.aborted || abortControl.abort();
453
+ }));
454
+ const buffer = [];
455
+ req.on('data', (chunk => {
456
+ buffer.push(chunk);
457
+ }));
458
+ req.on('end', (async () => {
459
+ let clewdStream, titleTimer, samePrompt = false, shouldRenew = true, retryRegen = false, exceeded_limit = false, nochange = false; //let clewdStream, titleTimer, samePrompt = false, shouldRenew = true, retryRegen = false;
460
+ try {
461
+ const body = JSON.parse(Buffer.concat(buffer).toString());
462
+ let { temperature } = body;
463
+ temperature = typeof temperature === 'number' ? Math.max(.1, Math.min(1, temperature)) : undefined; //temperature = Math.max(.1, Math.min(1, temperature));
464
+ let { messages } = body;
465
+ /************************* */
466
+ const thirdKey = req.headers.authorization?.match(/(?<=(3rd|oai)Key:).*/), oaiAPI = /oaiKey:/.test(req.headers.authorization), forceModel = /--force/.test(body.model);
467
+ apiKey = thirdKey?.[0].split(',').map(item => item.trim()) || req.headers.authorization?.match(/sk-ant-api\d\d-[\w-]{86}-[\w-]{6}AA/g);
468
+ model = apiKey || forceModel || isPro ? body.model.replace(/--force/, '').trim() : cookieModel;
469
+ let max_tokens_to_sample = body.max_tokens, stop_sequences = body.stop, top_p = typeof body.top_p === 'number' ? body.top_p : undefined, top_k = typeof body.top_k === 'number' ? body.top_k : undefined;
470
+ if (!apiKey && (Config.ProxyPassword != '' && req.headers.authorization != 'Bearer ' + Config.ProxyPassword || !uuidOrg)) {
471
+ throw Error(uuidOrg ? 'ProxyPassword Wrong' : 'No cookie available or apiKey format wrong');
472
+ } else if (!changing && !apiKey && (!isPro && model != cookieModel)) CookieChanger();
473
+ await waitForChange();
474
+ /************************* */
475
+ if (messages?.length < 1) {
476
+ throw Error('Select OpenAI as completion source');
477
+ }
478
+ if (!body.stream && 1 === messages.length && JSON.stringify(messages.sort() || []) === JSON.stringify([{
479
+ role: 'user',
480
+ content: 'Hi'
481
+ }].sort())) {
482
+ return res.json({
483
+ choices: [{
484
+ message: {
485
+ content: Main
486
+ }
487
+ }]
488
+ });
489
+ }
490
+ res.setHeader('Access-Control-Allow-Origin', '*');
491
+ body.stream && res.setHeader('Content-Type', 'text/event-stream');
492
+ if (!body.stream && messages?.[0]?.content?.startsWith('From the list below, choose a word that best represents a character\'s outfit description, action, or emotion in their dialogue')) {
493
+ return res.json({
494
+ choices: [{
495
+ message: {
496
+ content: 'neutral'
497
+ }
498
+ }]
499
+ });
500
+ }
501
+ if (Config.Settings.AllSamples && Config.Settings.NoSamples) {
502
+ console.log('having AllSamples and NoSamples both set to true is not supported');
503
+ throw Error('Only one can be used at the same time: AllSamples/NoSamples');
504
+ }
505
+ //const model = body.model;//if (model === AI.mdl()[0]) {// return;//}
506
+ if (!modelList.includes(model) && !/claude-.*/.test(model) && !forceModel) {
507
+ throw Error('Invalid model selected: ' + model);
508
+ }
509
+ curPrompt = {
510
+ firstUser: messages.find((message => 'user' === message.role)),
511
+ firstSystem: messages.find((message => 'system' === message.role)),
512
+ firstAssistant: messages.find((message => 'assistant' === message.role)),
513
+ lastUser: messages.findLast((message => 'user' === message.role)),
514
+ lastSystem: messages.findLast((message => 'system' === message.role && '[Start a new chat]' !== message.content)),
515
+ lastAssistant: messages.findLast((message => 'assistant' === message.role))
516
+ };
517
+ prevPrompt = {
518
+ ...prevMessages.length > 0 && {
519
+ firstUser: prevMessages.find((message => 'user' === message.role)),
520
+ firstSystem: prevMessages.find((message => 'system' === message.role)),
521
+ firstAssistant: prevMessages.find((message => 'assistant' === message.role)),
522
+ lastUser: prevMessages.findLast((message => 'user' === message.role)),
523
+ lastSystem: prevMessages.find((message => 'system' === message.role && '[Start a new chat]' !== message.content)),
524
+ lastAssistant: prevMessages.findLast((message => 'assistant' === message.role))
525
+ }
526
+ };
527
+ samePrompt = JSON.stringify(messages.filter((message => 'system' !== message.role)).sort()) === JSON.stringify(prevMessages.filter((message => 'system' !== message.role)).sort());
528
+ const sameCharDiffChat = !samePrompt && curPrompt.firstSystem?.content === prevPrompt.firstSystem?.content && curPrompt.firstUser?.content !== prevPrompt.firstUser?.content;
529
+ shouldRenew = Config.Settings.RenewAlways || !Conversation.uuid || prevImpersonated || !Config.Settings.RenewAlways && samePrompt || sameCharDiffChat;
530
+ retryRegen = Config.Settings.RetryRegenerate && samePrompt && null != Conversation.uuid;
531
+ samePrompt || (prevMessages = JSON.parse(JSON.stringify(messages)));
532
+ let type = '';
533
+ if (apiKey) { type = 'api'; } else if (retryRegen) { //if (retryRegen) {
534
+ type = 'R';
535
+ fetchAPI = await (async (signal, model) => {
536
+ let res;
537
+ const body = {
538
+ prompt: '',
539
+ parent_message_uuid: '',
540
+ timezone: AI.zone(),
541
+ attachments: [],
542
+ files: [],
543
+ rendering_mode: 'raw'
544
+ };
545
+ let headers = {
546
+ ...AI.hdr(Conversation.uuid || ''),
547
+ Accept: 'text/event-stream',
548
+ Cookie: getCookies()
549
+ };
550
+ if (Config.Settings.Superfetch) {
551
+ const names = Object.keys(headers), values = Object.values(headers);
552
+ headers = names.map(((header, idx) => `${header}: ${values[idx]}`));
553
  }
554
+ res = await (Config.Settings.Superfetch ? Superfetch : fetch)((Config.rProxy || AI.end()) + `/api/organizations/${uuidOrg || ''}/chat_conversations/${Conversation.uuid || ''}/retry_completion`, {
555
+ stream: true,
556
+ signal,
557
+ method: 'POST',
558
+ body: JSON.stringify(body),
559
+ headers
560
+ });
561
+ updateParams(res);
562
+ await checkResErr(res);
563
+ return res;
564
+ })(signal, model);
565
+ } else if (shouldRenew) {
566
+ Conversation.uuid && await deleteChat(Conversation.uuid);
567
+ fetchAPI = await (async signal => {
568
+ Conversation.uuid = randomUUID().toString();
569
+ Conversation.depth = 0;
570
+ const res = await (Config.Settings.Superfetch ? Superfetch : fetch)(`${Config.rProxy || AI.end()}/api/organizations/${uuidOrg}/chat_conversations`, {
571
+ signal,
572
+ headers: {
573
+ ...AI.hdr(),
574
+ Cookie: getCookies()
575
+ },
576
+ method: 'POST',
577
+ body: JSON.stringify({
578
+ uuid: Conversation.uuid,
579
+ name: ''
580
+ })
581
+ });
582
+ updateParams(res);
583
+ await checkResErr(res);
584
+ return res;
585
+ })(signal);
586
+ type = 'r';
587
+ } else if (samePrompt) { } else {
588
+ const systemExperiment = !Config.Settings.RenewAlways && Config.Settings.SystemExperiments;
589
+ if (!systemExperiment || systemExperiment && Conversation.depth >= Config.SystemInterval) {
590
+ type = 'c-r';
591
+ Conversation.depth = 0;
592
+ } else {
593
+ type = 'c-c';
594
+ Conversation.depth++;
595
+ }
596
  }
597
+ let { prompt, systems } = ((messages, type) => {
598
+ const rgxScenario = /^\[Circumstances and context of the dialogue: ([\s\S]+?)\.?\]$/i, rgxPerson = /^\[([\s\S]+?)'s personality: ([\s\S]+?)\]$/i, messagesClone = JSON.parse(JSON.stringify(messages)), realLogs = messagesClone.filter((message => ['user', 'assistant'].includes(message.role))), sampleLogs = messagesClone.filter((message => message.name)), mergedLogs = [...sampleLogs, ...realLogs];
599
+ mergedLogs.forEach(((message, idx) => {
600
+ const next = mergedLogs[idx + 1];
601
+ message.customname = (message => ['assistant', 'user'].includes(message.role) && null != message.name && !(message.name in Replacements))(message);
602
+ if (next && !Config.Settings.xmlPlot) { //if (next) {
603
+ if ('name' in message && 'name' in next) {
604
+ if (message.name === next.name) {
605
+ message.content += '\n' + next.content;
606
+ next.merged = true;
607
+ }
608
+ } else if ('system' !== next.role) {
609
+ if (next.role === message.role) {
610
+ message.content += '\n' + next.content;
611
+ next.merged = true;
612
+ }
613
+ } else {
614
+ message.content += '\n' + next.content;
615
+ next.merged = true;
616
+ }
617
+ }
618
+ }));
619
+ const lastAssistant = realLogs.findLast((message => !message.merged && 'assistant' === message.role));
620
+ lastAssistant && Config.Settings.StripAssistant && (lastAssistant.strip = true);
621
+ const lastUser = realLogs.findLast((message => !message.merged && 'user' === message.role));
622
+ lastUser && Config.Settings.StripHuman && (lastUser.strip = true);
623
+ const systemMessages = messagesClone.filter((message => 'system' === message.role && !('name' in message)));
624
+ systemMessages.forEach(((message, idx) => {
625
+ const scenario = message.content.match(rgxScenario)?.[1], personality = message.content.match(rgxPerson);
626
+ if (scenario) {
627
+ message.content = Config.ScenarioFormat.replace(/{{scenario}}/gim, scenario);
628
+ message.scenario = true;
629
+ }
630
+ if (3 === personality?.length) {
631
+ message.content = Config.PersonalityFormat.replace(/{{char}}/gim, personality[1]).replace(/{{personality}}/gim, personality[2]);
632
+ message.personality = true;
633
+ }
634
+ message.main = 0 === idx;
635
+ message.jailbreak = idx === systemMessages.length - 1;
636
+ ' ' === message.content && (message.discard = true);
637
+ }));
638
+ Config.Settings.AllSamples && !Config.Settings.NoSamples && realLogs.forEach((message => {
639
+ if (![lastUser, lastAssistant].includes(message)) {
640
+ if ('user' === message.role) {
641
+ message.name = message.customname ? message.name : 'example_user';
642
+ message.role = 'system';
643
+ } else if ('assistant' === message.role) {
644
+ message.name = message.customname ? message.name : 'example_assistant';
645
+ message.role = 'system';
646
+ } else if (!message.customname) {
647
+ throw Error('Invalid role ' + message.name);
648
+ }
649
+ }
650
+ }));
651
+ Config.Settings.NoSamples && !Config.Settings.AllSamples && sampleLogs.forEach((message => {
652
+ if ('example_user' === message.name) {
653
+ message.role = 'user';
654
+ } else if ('example_assistant' === message.name) {
655
+ message.role = 'assistant';
656
+ } else if (!message.customname) {
657
+ throw Error('Invalid role ' + message.name);
658
+ }
659
+ message.customname || delete message.name;
660
+ }));
661
+ let systems = [];
662
+ if (!['r', 'R', 'api'].includes(type)) {
663
+ lastUser.strip = true;
664
+ systemMessages.forEach((message => message.discard = message.discard || 'c-c' === type ? !message.jailbreak : !message.jailbreak && !message.main));
665
+ systems = systemMessages.filter((message => !message.discard)).map((message => `"${message.content.substring(0, 25).replace(/\n/g, '\\n').trim()}..."`));
666
+ messagesClone.forEach((message => message.discard = message.discard || mergedLogs.includes(message) && ![lastUser].includes(message)));
667
+ }
668
+ const prompt = messagesClone.map(((message, idx) => {
669
+ if (message.merged || message.discard) {
670
+ return '';
671
+ }
672
+ if (message.content.length < 1) {
673
+ return message.content;
674
+ }
675
+ let spacing = '';
676
+ /******************************** */
677
+ if (Config.Settings.xmlPlot) {
678
+ idx > 0 && (spacing = '\n\n');
679
+ const prefix = message.customname ? message.role + ': ' + message.name.replaceAll('_', ' ') + ': ' : 'system' !== message.role || message.name ? Replacements[message.name || message.role] + ': ' : 'xmlPlot: ' + Replacements[message.role];
680
+ return `${spacing}${message.strip ? '' : prefix}${message.content}`;
681
+ } else {
682
+ /******************************** */
683
+ idx > 0 && (spacing = systemMessages.includes(message) ? '\n' : '\n\n');
684
+ const prefix = message.customname ? message.name.replaceAll('_', ' ') + ': ' : 'system' !== message.role || message.name ? Replacements[message.name || message.role] + ': ' : '' + Replacements[message.role];
685
+ return `${spacing}${message.strip ? '' : prefix}${'system' === message.role ? message.content : message.content.trim()}`;
686
+ } //
687
+ }));
688
+ return {
689
+ prompt: prompt.join(''), //genericFixes(prompt.join('')).trim(),
690
+ systems
691
+ };
692
+ })(messages, type);
693
+ /******************************** */
694
+ const legacy = /claude-([12]|instant)/i.test(model), messagesAPI = thirdKey || !legacy && !/<\|completeAPI\|>/.test(prompt) || /<\|messagesAPI\|>/.test(prompt), messagesLog = /<\|messagesLog\|>/.test(prompt), fusion = apiKey && messagesAPI && /<\|Fusion Mode\|>/.test(prompt), wedge = '\r';
695
+ const stopSet = /<\|stopSet *(\[.*?\]) *\|>/.exec(prompt)?.[1], stopRevoke = /<\|stopRevoke *(\[.*?\]) *\|>/.exec(prompt)?.[1];
696
+ if (stop_sequences || stopSet || stopRevoke) stop_sequences = JSON.parse(stopSet || '[]').concat(stop_sequences).concat(['\n\nHuman:', '\n\nAssistant:']).filter(item => !JSON.parse(stopRevoke || '[]').includes(item) && item);
697
+ apiKey && (type = oaiAPI ? 'oai_api' : messagesAPI ? 'msg_api' : type);
698
+ prompt = Config.Settings.xmlPlot ? xmlPlot(prompt, legacy && !/claude-2\.1/i.test(model)) : apiKey ? `\n\nHuman: ${genericFixes(prompt)}\n\nAssistant:` : genericFixes(prompt).trim();
699
+ Config.Settings.FullColon && (prompt = !legacy ?
700
+ prompt.replace(fusion ? /\n(?!\nAssistant:\s*$)(?=\n(Human|Assistant):)/gs : apiKey ? /(?<!\n\nHuman:.*)\n(?=\nAssistant:)|\n(?=\nHuman:)(?!.*\n\nAssistant:)/gs : /\n(?=\n(Human|Assistant):)/g, '\n' + wedge) :
701
+ prompt.replace(fusion ? /(?<=\n\nAssistant):(?!\s*$)|(?<=\n\nHuman):/gs : apiKey ? /(?<!\n\nHuman:.*)(?<=\n\nAssistant):|(?<=\n\nHuman):(?!.*\n\nAssistant:)/gs : /(?<=\n\n(Human|Assistant)):/g, '﹕'));
702
+ prompt = padtxt(prompt);
703
+ /******************************** */
704
+ console.log(`${model} [${type}]${!retryRegen && systems.length > 0 ? ' ' + systems.join(' / ') : ''}`);
705
+ 'R' !== type || prompt || (prompt = '...regen...');
706
+ Logger?.write(`\n\n-------\n[${(new Date).toLocaleString()}]\n${Main}\n####### ${model} (${type})\n${JSON.stringify({ FusionMode: fusion, PassParams: Config.Settings.PassParams, stop_sequences, temperature, top_k, top_p }, null, 2)}\n\n####### regex:\n${regexLog}\n####### PROMPT ${tokens}t:\n${prompt}\n--\n####### REPLY:\n`); //Logger?.write(`\n\n-------\n[${(new Date).toLocaleString()}]\n####### MODEL: ${model}\n####### PROMPT (${type}):\n${prompt}\n--\n####### REPLY:\n`);
707
+ retryRegen || (fetchAPI = await (async (signal, model, prompt, temperature, type) => {
708
+ /******************************** */
709
+ if (apiKey) {
710
+ let messages, system, key = apiKey[Math.floor(Math.random() * apiKey.length)];
711
+ if (messagesAPI) {
712
+ const rounds = prompt.replace(/^(?!.*\n\nHuman:)/s, '\n\nHuman:').split('\n\nHuman:');
713
+ messages = rounds.slice(1).flatMap(round => {
714
+ const turns = round.split('\n\nAssistant:');
715
+ return [{ role: 'user', content: turns[0].trim() }].concat(turns.slice(1).flatMap(turn => [{ role: 'assistant', content: turn.trim() }]));
716
+ }).reduce((acc, current) => {
717
+ if (Config.Settings.FullColon && acc.length > 0 && (acc[acc.length - 1].role === current.role || !acc[acc.length - 1].content)) {
718
+ acc[acc.length - 1].content += (current.role === 'user' ? 'Human' : 'Assistant').replace(/.*/, legacy ? '\n$&﹕ ' : '\n' + wedge + '\n$&: ') + current.content;
719
+ } else acc.push(current);
720
+ return acc;
721
+ }, []).filter(message => message.content), oaiAPI ? messages.unshift({ role: 'system', content: rounds[0].trim() }) : system = rounds[0].trim();
722
+ messagesLog && console.log({ system, messages });
723
+ }
724
+ const res = await fetch((api_rProxy || 'https://api.anthropic.com').replace(/(\/v1)? *$/, thirdKey ? '$1' : '/v1').trim('/') + (oaiAPI ? '/chat/completions' : messagesAPI ? '/messages' : '/complete'), {
725
+ method: 'POST',
726
+ signal,
727
+ headers: {
728
+ 'anthropic-version': '2023-06-01',
729
+ 'authorization': 'Bearer ' + key,
730
+ 'Content-Type': 'application/json',
731
+ 'User-Agent': AI.agent(),
732
+ 'x-api-key': key,
733
+ },
734
+ body: JSON.stringify({
735
+ ...oaiAPI || messagesAPI ? {
736
+ max_tokens: max_tokens_to_sample,
737
+ messages,
738
+ system
739
+ } : {
740
+ max_tokens_to_sample,
741
+ prompt
742
+ },
743
+ model,
744
+ stop_sequences,
745
+ stream: true,
746
+ temperature,
747
+ top_k,
748
+ top_p
749
+ }),
750
+ });
751
+ await checkResErr(res);
752
+ return res;
753
+ }
754
+ /******************************** */
755
+ const attachments = [];
756
+ if (Config.Settings.PromptExperiments) {
757
+ let splitedprompt = prompt.split('\n\nPlainPrompt:'); //
758
+ prompt = splitedprompt[0]; //
759
+ attachments.push({
760
+ extracted_content: prompt,
761
+ file_name: 'paste.txt', //fileName(),
762
+ file_type: 'txt', //'text/plain',
763
+ file_size: Buffer.from(prompt).byteLength
764
+ });
765
+ prompt = 'r' === type ? Config.PromptExperimentFirst : Config.PromptExperimentNext;
766
+ splitedprompt.length > 1 && (prompt += splitedprompt[1]); //
767
+ }
768
  let res;
769
  const body = {
770
+ attachments,
771
+ files: [],
772
+ model: isPro || forceModel ? model : undefined,
773
+ rendering_mode: 'raw',
774
+ ...Config.Settings.PassParams && {
775
+ max_tokens_to_sample, //
776
+ //stop_sequences, //
777
+ top_k, //
778
+ top_p, //
779
+ temperature
780
+ },
781
+ prompt: prompt || '',
782
+ timezone: AI.zone()
783
  };
784
  let headers = {
785
  ...AI.hdr(Conversation.uuid || ''),
786
  Accept: 'text/event-stream',
787
  Cookie: getCookies()
788
  };
789
+ res = await (Config.Settings.Superfetch ? Superfetch : fetch)(`${Config.rProxy || AI.end()}/api/organizations/${uuidOrg || ''}/chat_conversations/${Conversation.uuid || ''}/completion`, {
 
 
 
 
790
  stream: true,
791
  signal,
792
  method: 'POST',
 
796
  updateParams(res);
797
  await checkResErr(res);
798
  return res;
799
+ })(signal, model, prompt, temperature, type));
800
+ const response = Writable.toWeb(res);
801
+ clewdStream = new ClewdStream({
802
+ config: {
803
+ ...Config,
804
+ Settings: {
805
+ ...Config.Settings,
806
+ Superfetch: apiKey ? false : Config.Settings.Superfetch
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
807
  }
808
+ }, //config: Config,
809
+ version: Main,
810
+ minSize: Config.BufferSize,
811
+ model,
812
+ streaming: true === body.stream,
813
+ abortControl,
814
+ source: fetchAPI
815
+ }, Logger);
816
+ titleTimer = setInterval((() => setTitle('recv ' + bytesToSize(clewdStream.size))), 300);
817
+ (!apiKey && Config.Settings.Superfetch) ? await Readable.toWeb(fetchAPI.body).pipeThrough(clewdStream).pipeTo(response) : await fetchAPI.body.pipeThrough(clewdStream).pipeTo(response); //Config.Settings.Superfetch ? await Readable.toWeb(fetchAPI.body).pipeThrough(clewdStream).pipeTo(response) : await fetchAPI.body.pipeThrough(clewdStream).pipeTo(response);
818
+ } catch (err) {
819
+ if ('AbortError' === err.name) {
820
+ res.end();
821
+ } else {
822
+ nochange = true, exceeded_limit = err.exceeded_limit; //
823
+ err.planned ? console.log(`${err.status || 'Aborted'}!\n`) : console.error('Clewd:\n%o', err); //err.planned || console.error('Clewd:\n%o', err);
824
+ res.json({
825
+ error: {
826
+ message: 'clewd: ' + (err.message || err.name || err.type),
827
+ type: err.type || err.name || err.code,
828
+ param: null,
829
+ code: err.code || 500
 
 
 
 
 
 
 
 
 
830
  }
831
+ }, 500);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
832
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
833
  }
834
+ clearInterval(titleTimer);
835
+ if (clewdStream) {
836
+ clewdStream.censored && console.warn('likely your account is hard-censored');
837
+ prevImpersonated = clewdStream.impersonated;
838
+ exceeded_limit = clewdStream.error.exceeded_limit; //
839
+ clewdStream.error.status < 200 || clewdStream.error.status >= 300 || clewdStream.error.message === 'Overloaded' && (nochange = true); //
840
+ setTitle('ok ' + bytesToSize(clewdStream.size));
841
+ if (clewdStream.compModel && !(AI.mdl().includes(clewdStream.compModel) || Config.unknownModels.includes(clewdStream.compModel)) && !apiKey) {
842
+ Config.unknownModels.push(clewdStream.compModel);
843
+ writeSettings(Config);
844
+ }
845
+ console.log(`${200 == fetchAPI.status ? '' : ''}${fetchAPI.status}!\n`);
846
+ clewdStream.empty();
847
  }
848
+ const shouldChange = exceeded_limit || !nochange && Config.Cookiecounter > 0 && changeflag++ >= Config.Cookiecounter - 1; //
849
+ if (!apiKey && (shouldChange || prevImpersonated)) { //if (prevImpersonated) {
850
+ try {
851
+ await deleteChat(Conversation.uuid);
852
+ } catch (err) { }
853
+ /******************************** */
854
+ if (shouldChange) {
855
+ exceeded_limit && console.log(`Exceeded limit!\n`);
856
+ changeflag = 0;
857
+ CookieChanger();
858
+ }
859
+ /******************************** */
 
860
  }
861
+ }));
862
+ })(req, res);
863
+ break;
 
 
864
 
865
+ case '/hf/v1/complete':
866
+ res.json({
867
+ error: {
868
+ message: 'clewd: Set "Chat Completion source" to OpenAI instead of Claude. Enable "External" models aswell',
869
+ code: 404
870
+ }
871
+ }, 404);
872
+ break;
873
 
874
+ default:
875
+ !['/', '/v1', '/favicon.ico'].includes(req.url) && (console.log('unknown request: ' + req.url)); //console.log('unknown request: ' + req.url);
876
+ res.writeHead(200, { 'Content-Type': 'text/html' }); //
877
+ res.write(`<!DOCTYPE html>\n<html>\n<head>\n<meta charset="utf-8">\n</head>\n<body>\n <h1>Hello, World!</h1>\n <p>This is a test HTML file.</p>\n</body>\n</html>`); //
878
+ res.end(); //res.json(// {// error: {// message: '404 Not Found',// type: 404,// param: null,// code: 404// }//}, 404);
879
  }
880
  }));
881
 
882
+ !async function () {
883
  await (async () => {
884
  if (exists(ConfigPath)) {
885
  const userConfig = require(ConfigPath), validConfigs = Object.keys(Config), parsedConfigs = Object.keys(userConfig), parsedSettings = Object.keys(userConfig.Settings), invalidConfigs = parsedConfigs.filter((config => !validConfigs.includes(config))), validSettings = Object.keys(Config.Settings);
 
911
  writeSettings(Config, true);
912
  }
913
  })();
914
+ /***************************** */
915
  for (let key in Config) {
916
  if (key === 'Settings') {
917
  for (let setting in Config.Settings) {
 
926
  Config.unknownModels = Config.unknownModels.reduce((prev, cur) => !cur || prev.includes(cur) || AI.mdl().includes(cur) ? prev : [...prev, cur], []);
927
  writeSettings(Config);
928
  currentIndex = Config.CookieIndex > 0 ? Config.CookieIndex - 1 : Config.Cookiecounter >= 0 ? Math.floor(Math.random() * Config.CookieArray.length) : 0;
929
+ /***************************** */
930
  Proxy.listen(Config.Port, Config.Ip, onListen);
931
  Proxy.on('error', (err => {
932
  console.error('Proxy error\n%o', err);
 
939
  await deleteChat(Conversation.uuid);
940
  SuperfetchFoldersRm();
941
  Logger?.close();
942
+ } catch (err) { }
943
  process.exit();
944
  };
945