mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-09-22 08:12:00 +02:00
86 lines
3.3 KiB
JavaScript
86 lines
3.3 KiB
JavaScript
![]() |
// Generates image using stable diffusion webui's api (automatic1111)
|
||
|
const fs = require('fs');
|
||
|
const { Tool } = require('langchain/tools');
|
||
|
const path = require('path');
|
||
|
const axios = require('axios');
|
||
|
const sharp = require('sharp');
|
||
|
|
||
|
class StableDiffusionAPI extends Tool {
|
||
|
constructor(fields) {
|
||
|
super();
|
||
|
this.name = 'stable-diffusion';
|
||
|
this.url = fields.SD_WEBUI_URL || this.getServerURL();
|
||
|
this.description = `You can generate images with 'stable-diffusion'. This tool is exclusively for visual content.
|
||
|
Guidelines:
|
||
|
- Visually describe the moods, details, structures, styles, and/or proportions of the image. Remember, the focus is on visual attributes.
|
||
|
- Craft your input by "showing" and not "telling" the imagery. Think in terms of what you'd want to see in a photograph or a painting.
|
||
|
- It's best to follow this format for image creation:
|
||
|
"detailed keywords to describe the subject, separated by comma | keywords we want to exclude from the final image"
|
||
|
- Here's an example prompt for generating a realistic portrait photo of a man:
|
||
|
"photo of a man in black clothes, half body, high detailed skin, coastline, overcast weather, wind, waves, 8k uhd, dslr, soft lighting, high quality, film grain, Fujifilm XT3 | semi-realistic, cgi, 3d, render, sketch, cartoon, drawing, anime, out of frame, low quality, ugly, mutation, deformed"
|
||
|
- Generate images only once per human query unless explicitly requested by the user`;
|
||
|
}
|
||
|
|
||
|
replaceNewLinesWithSpaces(inputString) {
|
||
|
return inputString.replace(/\r\n|\r|\n/g, ' ');
|
||
|
}
|
||
|
|
||
|
getMarkdownImageUrl(imageName) {
|
||
|
const imageUrl = path.join(this.relativeImageUrl, imageName).replace(/\\/g, '/').replace('public/', '');
|
||
|
return ``;
|
||
|
}
|
||
|
|
||
|
getServerURL() {
|
||
|
const url = process.env.SD_WEBUI_URL || '';
|
||
|
if (!url) {
|
||
|
throw new Error('Missing SD_WEBUI_URL environment variable.');
|
||
|
}
|
||
|
return url;
|
||
|
}
|
||
|
|
||
|
async _call(input) {
|
||
|
const url = this.url;
|
||
|
const payload = {
|
||
|
prompt: input.split('|')[0],
|
||
|
negative_prompt: input.split('|')[1],
|
||
|
steps: 20
|
||
|
};
|
||
|
const response = await axios.post(`${url}/sdapi/v1/txt2img`, payload);
|
||
|
const image = response.data.images[0];
|
||
|
|
||
|
const pngPayload = { image: `data:image/png;base64,${image}` };
|
||
|
const response2 = await axios.post(`${url}/sdapi/v1/png-info`, pngPayload);
|
||
|
const info = response2.data.info;
|
||
|
|
||
|
// Generate unique name
|
||
|
const imageName = `${Date.now()}.png`;
|
||
|
this.outputPath = path.resolve(__dirname, '..', '..', '..', '..', 'client', 'public', 'images');
|
||
|
const appRoot = path.resolve(__dirname, '..', '..', '..', '..', 'client');
|
||
|
this.relativeImageUrl = path.relative(appRoot, this.outputPath);
|
||
|
|
||
|
// Check if directory exists, if not create it
|
||
|
if (!fs.existsSync(this.outputPath)) {
|
||
|
fs.mkdirSync(this.outputPath, { recursive: true });
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
const buffer = Buffer.from(image.split(',', 1)[0], 'base64');
|
||
|
await sharp(buffer)
|
||
|
.withMetadata({
|
||
|
iptcpng: {
|
||
|
parameters: info
|
||
|
}
|
||
|
})
|
||
|
.toFile(this.outputPath + '/' + imageName);
|
||
|
this.result = this.getMarkdownImageUrl(imageName);
|
||
|
} catch (error) {
|
||
|
console.error('Error while saving the image:', error);
|
||
|
// this.result = theImageUrl;
|
||
|
}
|
||
|
|
||
|
return this.result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module.exports = StableDiffusionAPI;
|