mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-18 01:10:14 +01:00
* ci(backend-review.yml): add linter step to the backend review workflow * chore(backend-review.yml): remove prettier from lint-action configuration * chore: apply new linting workflow * chore(lint-staged.config.js): reorder lint-staged tasks for JavaScript and TypeScript files * chore(eslint): update ignorePatterns in .eslintrc.js chore(lint-action): remove prettier option in backend-review.yml chore(package.json): add lint and lint:fix scripts * chore(lint-staged.config.js): remove prettier --write command for js, jsx, ts, tsx files * chore(titleConvo.js): remove unnecessary console.log statement chore(titleConvo.js): add missing comma in options object * chore: apply linting to all files * chore(lint-staged.config.js): update lint-staged configuration to include prettier formatting
88 lines
3.3 KiB
JavaScript
88 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;
|