mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 17:00:15 +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
120 lines
4.3 KiB
JavaScript
120 lines
4.3 KiB
JavaScript
// From https://platform.openai.com/docs/api-reference/images/create
|
|
// To use this tool, you must pass in a configured OpenAIApi object.
|
|
const fs = require('fs');
|
|
const { Configuration, OpenAIApi } = require('openai');
|
|
// const { genAzureEndpoint } = require('../../../utils/genAzureEndpoints');
|
|
const { Tool } = require('langchain/tools');
|
|
const saveImageFromUrl = require('./saveImageFromUrl');
|
|
const path = require('path');
|
|
|
|
class OpenAICreateImage extends Tool {
|
|
constructor(fields = {}) {
|
|
super();
|
|
|
|
let apiKey = fields.DALLE_API_KEY || this.getApiKey();
|
|
// let azureKey = fields.AZURE_API_KEY || process.env.AZURE_API_KEY;
|
|
let config = { apiKey };
|
|
|
|
// if (azureKey) {
|
|
// apiKey = azureKey;
|
|
// const azureConfig = {
|
|
// apiKey,
|
|
// azureOpenAIApiInstanceName: process.env.AZURE_OPENAI_API_INSTANCE_NAME || fields.azureOpenAIApiInstanceName,
|
|
// azureOpenAIApiDeploymentName: process.env.AZURE_OPENAI_API_DEPLOYMENT_NAME || fields.azureOpenAIApiDeploymentName,
|
|
// azureOpenAIApiVersion: process.env.AZURE_OPENAI_API_VERSION || fields.azureOpenAIApiVersion
|
|
// };
|
|
// config = {
|
|
// apiKey,
|
|
// basePath: genAzureEndpoint({
|
|
// ...azureConfig,
|
|
// }),
|
|
// baseOptions: {
|
|
// headers: { 'api-key': apiKey },
|
|
// params: {
|
|
// 'api-version': azureConfig.azureOpenAIApiVersion // this might change. I got the current value from the sample code at https://oai.azure.com/portal/chat
|
|
// }
|
|
// }
|
|
// };
|
|
// }
|
|
this.openaiApi = new OpenAIApi(new Configuration(config));
|
|
this.name = 'dall-e';
|
|
this.description = `You can generate images with 'dall-e'. 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. Come up with the optional inputs yourself if none are given:
|
|
"Subject: [subject], Style: [style], Color: [color], Details: [details], Emotion: [emotion]"
|
|
- Generate images only once per human query unless explicitly requested by the user`;
|
|
}
|
|
|
|
getApiKey() {
|
|
const apiKey = process.env.DALLE_API_KEY || '';
|
|
if (!apiKey) {
|
|
throw new Error('Missing DALLE_API_KEY environment variable.');
|
|
}
|
|
return apiKey;
|
|
}
|
|
|
|
replaceUnwantedChars(inputString) {
|
|
return inputString
|
|
.replace(/\r\n|\r|\n/g, ' ')
|
|
.replace('"', '')
|
|
.trim();
|
|
}
|
|
|
|
getMarkdownImageUrl(imageName) {
|
|
const imageUrl = path
|
|
.join(this.relativeImageUrl, imageName)
|
|
.replace(/\\/g, '/')
|
|
.replace('public/', '');
|
|
return ``;
|
|
}
|
|
|
|
async _call(input) {
|
|
const resp = await this.openaiApi.createImage({
|
|
prompt: this.replaceUnwantedChars(input),
|
|
// TODO: Future idea -- could we ask an LLM to extract these arguments from an input that might contain them?
|
|
n: 1,
|
|
// size: '1024x1024'
|
|
size: '512x512',
|
|
});
|
|
|
|
const theImageUrl = resp.data.data[0].url;
|
|
|
|
if (!theImageUrl) {
|
|
throw new Error('No image URL returned from OpenAI API.');
|
|
}
|
|
|
|
const regex = /img-[\w\d]+.png/;
|
|
const match = theImageUrl.match(regex);
|
|
let imageName = '1.png';
|
|
|
|
if (match) {
|
|
imageName = match[0];
|
|
console.log(imageName); // Output: img-lgCf7ppcbhqQrz6a5ear6FOb.png
|
|
} else {
|
|
console.log('No image name found in the string.');
|
|
}
|
|
|
|
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 {
|
|
await saveImageFromUrl(theImageUrl, 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 = OpenAICreateImage;
|