mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Add AI Horde client library
This commit is contained in:
30
package-lock.json
generated
30
package-lock.json
generated
@ -10,6 +10,7 @@
|
|||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dqbd/tiktoken": "^1.0.2",
|
"@dqbd/tiktoken": "^1.0.2",
|
||||||
|
"@zeldafan0225/ai_horde": "^4.0.1",
|
||||||
"axios": "^1.3.4",
|
"axios": "^1.3.4",
|
||||||
"command-exists": "^1.2.9",
|
"command-exists": "^1.2.9",
|
||||||
"compression": "^1",
|
"compression": "^1",
|
||||||
@ -418,6 +419,11 @@
|
|||||||
"regenerator-runtime": "^0.13.3"
|
"regenerator-runtime": "^0.13.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@thunder04/supermap": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@thunder04/supermap/-/supermap-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-SjlUrfe45mwiAgKZHRRhh+oHRwXsjrCg6NI2HJxymTJt+9SwJw422yse/A5lr5WBpTky6qEce+H6Ec1sytm93A=="
|
||||||
|
},
|
||||||
"node_modules/@tokenizer/token": {
|
"node_modules/@tokenizer/token": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
@ -434,6 +440,16 @@
|
|||||||
"node": ">=10.0.0"
|
"node": ">=10.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@zeldafan0225/ai_horde": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@zeldafan0225/ai_horde/-/ai_horde-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-mf1cknnBYzKCvgH4KAkdVY3J7sLkR2b79W6I9ZEA2aJCyua28bpZzNaCDSHKKyaNj+0wyHViC+L53X32jw9pMg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@thunder04/supermap": "^3.0.2",
|
||||||
|
"centra": "^2.5.0",
|
||||||
|
"esbuild": "^0.12.28"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/accepts": {
|
"node_modules/accepts": {
|
||||||
"version": "1.3.8",
|
"version": "1.3.8",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -621,6 +637,11 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/centra": {
|
||||||
|
"version": "2.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/centra/-/centra-2.6.0.tgz",
|
||||||
|
"integrity": "sha512-dgh+YleemrT8u85QL11Z6tYhegAs3MMxsaWAq/oXeAmYJ7VxL3SI9TZtnfaEvNDMAPolj25FXIb3S+HCI4wQaQ=="
|
||||||
|
},
|
||||||
"node_modules/cliui": {
|
"node_modules/cliui": {
|
||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
@ -872,6 +893,15 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/esbuild": {
|
||||||
|
"version": "0.12.29",
|
||||||
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.12.29.tgz",
|
||||||
|
"integrity": "sha512-w/XuoBCSwepyiZtIRsKsetiLDUVGPVw1E/R3VTFSecIy8UR7Cq3SOtwKHJMFoVqqVG36aGkzh4e8BvpO1Fdc7g==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"bin": {
|
||||||
|
"esbuild": "bin/esbuild"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/escalade": {
|
"node_modules/escalade": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dqbd/tiktoken": "^1.0.2",
|
"@dqbd/tiktoken": "^1.0.2",
|
||||||
|
"@zeldafan0225/ai_horde": "^4.0.1",
|
||||||
"axios": "^1.3.4",
|
"axios": "^1.3.4",
|
||||||
"command-exists": "^1.2.9",
|
"command-exists": "^1.2.9",
|
||||||
"compression": "^1",
|
"compression": "^1",
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"display_name": "Stable Diffusion",
|
"display_name": "Stable Diffusion",
|
||||||
"loading_order": 10,
|
"loading_order": 10,
|
||||||
"requires": [
|
"requires": [],
|
||||||
|
"optional": [
|
||||||
"sd"
|
"sd"
|
||||||
],
|
],
|
||||||
"optional": [],
|
|
||||||
"js": "index.js",
|
"js": "index.js",
|
||||||
"css": "style.css",
|
"css": "style.css",
|
||||||
"author": "Cohee#1207",
|
"author": "Cohee#1207",
|
||||||
|
94
server.js
94
server.js
@ -82,6 +82,10 @@ const allowKeysExposure = config.allowKeysExposure;
|
|||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
const tiktoken = require('@dqbd/tiktoken');
|
const tiktoken = require('@dqbd/tiktoken');
|
||||||
const WebSocket = require('ws');
|
const WebSocket = require('ws');
|
||||||
|
const AIHorde = require("@zeldafan0225/ai_horde");
|
||||||
|
const ai_horde = new AIHorde({
|
||||||
|
client_agent: getVersion()?.agent || 'SillyTavern:UNKNOWN:Cohee#1207',
|
||||||
|
});
|
||||||
|
|
||||||
var Client = require('node-rest-client').Client;
|
var Client = require('node-rest-client').Client;
|
||||||
var client = new Client();
|
var client = new Client();
|
||||||
@ -309,27 +313,8 @@ app.get('/deviceinfo', function (request, response) {
|
|||||||
return response.send(deviceInfo);
|
return response.send(deviceInfo);
|
||||||
});
|
});
|
||||||
app.get('/version', function (_, response) {
|
app.get('/version', function (_, response) {
|
||||||
let pkgVersion, gitRevision, gitBranch;
|
const data = getVersion();
|
||||||
try {
|
response.send(data);
|
||||||
const pkgJson = require('./package.json');
|
|
||||||
pkgVersion = pkgJson.version;
|
|
||||||
if (commandExistsSync('git')) {
|
|
||||||
gitRevision = require('child_process')
|
|
||||||
.execSync('git rev-parse --short HEAD', { cwd: __dirname })
|
|
||||||
.toString().trim();
|
|
||||||
|
|
||||||
gitBranch = require('child_process')
|
|
||||||
.execSync('git rev-parse --abbrev-ref HEAD', { cwd: __dirname })
|
|
||||||
.toString().trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
// suppress exception
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
const agent = `SillyTavern:${gitRevision || pkgVersion}:Cohee#1207`;
|
|
||||||
response.send({ agent, pkgVersion, gitRevision, gitBranch });
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
//**************Kobold api
|
//**************Kobold api
|
||||||
@ -665,6 +650,31 @@ app.post("/setsoftprompt", jsonParser, async function (request, response) {
|
|||||||
return response.sendStatus(200);
|
return response.sendStatus(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function getVersion() {
|
||||||
|
let pkgVersion = 'UNKNOWN';
|
||||||
|
let gitRevision = null;
|
||||||
|
let gitBranch = null;
|
||||||
|
try {
|
||||||
|
const pkgJson = require('./package.json');
|
||||||
|
pkgVersion = pkgJson.version;
|
||||||
|
if (commandExistsSync('git')) {
|
||||||
|
gitRevision = require('child_process')
|
||||||
|
.execSync('git rev-parse --short HEAD', { cwd: __dirname })
|
||||||
|
.toString().trim();
|
||||||
|
|
||||||
|
gitBranch = require('child_process')
|
||||||
|
.execSync('git rev-parse --abbrev-ref HEAD', { cwd: __dirname })
|
||||||
|
.toString().trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
// suppress exception
|
||||||
|
}
|
||||||
|
|
||||||
|
const agent = `SillyTavern:${pkgVersion}:Cohee#1207`;
|
||||||
|
return { agent, pkgVersion, gitRevision, gitBranch };
|
||||||
|
}
|
||||||
|
|
||||||
function tryParse(str) {
|
function tryParse(str) {
|
||||||
try {
|
try {
|
||||||
return json5.parse(str);
|
return json5.parse(str);
|
||||||
@ -2870,8 +2880,9 @@ app.post('/readsecretstate', jsonParser, (_, response) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const ANONYMOUS_KEY = "0000000000";
|
||||||
|
|
||||||
app.post('/generate_horde', jsonParser, async (request, response) => {
|
app.post('/generate_horde', jsonParser, async (request, response) => {
|
||||||
const ANONYMOUS_KEY = "0000000000";
|
|
||||||
const api_key_horde = readSecret(SECRET_KEYS.HORDE) || ANONYMOUS_KEY;
|
const api_key_horde = readSecret(SECRET_KEYS.HORDE) || ANONYMOUS_KEY;
|
||||||
const url = 'https://horde.koboldai.net/api/v2/generate/text/async';
|
const url = 'https://horde.koboldai.net/api/v2/generate/text/async';
|
||||||
|
|
||||||
@ -2914,6 +2925,45 @@ app.post('/viewsecrets', jsonParser, async (_, response) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.post('/horde_generateimage', async (request, response) => {
|
||||||
|
const MAX_ATTEMPTS = 100;
|
||||||
|
const CHECK_INTERVAL = 3000;
|
||||||
|
const api_key_horde = readSecret(SECRET_KEYS.HORDE) || ANONYMOUS_KEY;
|
||||||
|
const generation = await ai_horde.postAsyncImageGenerate(
|
||||||
|
{
|
||||||
|
prompt: `${request.body.prompt_prefix} ${request.body.prompt} ### ${request.body.negative_prompt}`,
|
||||||
|
params:
|
||||||
|
{
|
||||||
|
sampler_name: request.body.sampler,
|
||||||
|
cfg_scale: request.body.scale,
|
||||||
|
steps: request.body.steps,
|
||||||
|
width: request.body.width,
|
||||||
|
height: request.body.height,
|
||||||
|
n: 1,
|
||||||
|
},
|
||||||
|
r2: false,
|
||||||
|
nsfw: request.body.nfsw,
|
||||||
|
models: [request.body.model],
|
||||||
|
},
|
||||||
|
{ token: api_key_horde });
|
||||||
|
|
||||||
|
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
|
||||||
|
await delay(CHECK_INTERVAL);
|
||||||
|
const check = await ai_horde.getImageGenerationCheck(generation.id);
|
||||||
|
|
||||||
|
if (check.done) {
|
||||||
|
const result = await ai_horde.getImageGenerationStatus(generation.id);
|
||||||
|
return response.send(result.generations[0].img);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check.faulted) {
|
||||||
|
return response.sendStatus(500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.sendStatus(504);
|
||||||
|
});
|
||||||
|
|
||||||
function writeSecret(key, value) {
|
function writeSecret(key, value) {
|
||||||
if (!fs.existsSync(SECRETS_FILE)) {
|
if (!fs.existsSync(SECRETS_FILE)) {
|
||||||
const emptyFile = JSON.stringify({});
|
const emptyFile = JSON.stringify({});
|
||||||
|
Reference in New Issue
Block a user