Skip to content

Commit

Permalink
Merge pull request #22 from shin202/feature/AI-art-generator-and-new-…
Browse files Browse the repository at this point in the history
…chat-mode

BREAKING CHANGE: supported image generator with Stable Diffusion AI and add new chat mode that help users create prompt
  • Loading branch information
shin202 authored Apr 10, 2023
2 parents e95ac2e + f1f8e80 commit 50e2409
Show file tree
Hide file tree
Showing 17 changed files with 242 additions and 54 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
OPENAI_KEY=<YOUR_OPENAI_KEY>
REPLICATE_API_TOKEN=<YOUR_REPLICATE_API_TOKEN>
MONGO_URI=<YOUR_MONGO_URI>
DISCORD_BOT_TOKEN=<YOUR_DISCORD_BOT_TOKEN>
CLIENT_ID=<YOUR_DISCORD_BOT_CLIENT_ID>
Expand Down
26 changes: 22 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,11 @@ I can't afford to deploy its, so you can deploy your own.
```

1. Get your OpenAI API key at [OpenAI](https://openai.com/api/).
2. Create your discord bot at [Discord Developer](https://discord.com/developers/applications) and get your bot token.
3. Get your bot client id and your discord guild id.
4. Edit `.evn.example` to set your tokens then rename it to `.env`.
5. 🔥 Run and enjoy its 🔥
2. Get your Replicate API key at [Replicate](https://replicate.com/).
3. Create your discord bot at [Discord Developer](https://discord.com/developers/applications) and get your bot token.
4. Get your bot client id and your discord guild id.
5. Edit `.evn.example` to set your tokens then rename it to `.env`.
6. 🔥 Run and enjoy its 🔥
```sh
npm start
```
Expand All @@ -120,6 +121,17 @@ I can't afford to deploy its, so you can deploy your own.
- Supported chat mode: 👩‍💼 LiLy: Assistant, 👨‍💻 Steve: Code Assistant, 👩‍⚕️ Sarah: Psychologist. (*I will add more, if I have time.*)
- Limited conversation time (*To avoid spam*).

### 🔥 NEW FEATURES
- 🔥 Add new chat mode (👨‍🎨 Prompt Creator) (`Help users generate unique and creative prompts for image generation.`)
- 🔥 Now you can generating image with AI by using `/draw` command.
- 🔥 Variant models for generate image.
- 🔥 Supported Models:
* `OpenJourney (Midjourney V4 Style)`
* `Stable Diffusion`
* `Portrait Plus (for portrait image)`
* `Anything V3 (anime style)`
* `Pastel Mix (anime style)`

<p align="right">(<a href="#readme-top">back to top</a>)</p>


Expand All @@ -142,6 +154,12 @@ I can't afford to deploy its, so you can deploy your own.
<img src="src/assets/images/screenshots/1.png">
<img src="src/assets/images/screenshots/2.png">
<img src="src/assets/images/screenshots/3.png">
<img src="src/assets/images/screenshots/4.png">
<img src="src/assets/images/screenshots/5.png">
<img src="src/assets/images/screenshots/6.png">
<img src="src/assets/images/screenshots/7.png">
<img src="src/assets/images/screenshots/8.png">
<img src="src/assets/images/screenshots/9.png">

<!-- CONTRIBUTING -->
## Contributing
Expand Down
13 changes: 12 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"discord.js": "^14.9.0",
"dotenv": "^16.0.3",
"mongoose": "^7.0.3",
"openai": "^3.2.1"
"openai": "^3.2.1",
"replicate": "^0.9.0"
},
"devDependencies": {
"@types/dotenv": "^8.2.0",
Expand Down
Binary file added src/assets/images/screenshots/4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/screenshots/5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/screenshots/6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/screenshots/7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/screenshots/8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/screenshots/9.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion src/commands/ask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import MessageController from "../controllers/MessageController";
const command: ICommand = {
name: "ask",
execute: async (message, args) => {
await message.channel.sendTyping();

const user = await UserController.getUserByDiscordId(message.author.id);
const inConversation = await ConversationController.inConversation(user);

Expand All @@ -29,7 +31,6 @@ const command: ICommand = {
userMessage: userMessage,
botMessage: resMessage,
});
await message.channel.sendTyping();
await message.reply(resMessage);
},
permissions: [],
Expand Down
6 changes: 6 additions & 0 deletions src/components/SelectChatMode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ export const selectChatMode = (currentChatMode: ChatMode) => new ActionRowBuilde
description: "A psychologist chatbot that provides mental health support and guidance named Sarah.",
value: ChatMode.Psychologist,
default: currentChatMode === ChatMode.Psychologist,
},
{
label: "Prompt Creator",
description: "Help users generate unique and creative prompts for image generation.",
value: ChatMode.PromptCreator,
default: currentChatMode === ChatMode.PromptCreator
}
)
.setMinValues(1)
Expand Down
11 changes: 8 additions & 3 deletions src/services/ChatGPTService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,22 @@ class ChatGPTService {
assistant: {
name: "Assistant",
welcomeMessage: "Hi, I'm ChatGPT assistant. How can I help you?",
rolePlayDescription: `As an advanced chatbot designed for user support named Lily. You have advanced NLP capabilities and provide immediate, detailed, and accurate responses to user queries. You understand the context and provide tailored and actionable information, along with helpful tools and resources. You are committed to delivering the best customer experience and continuously learn and improves to provide accurate and up-to-date responses.`,
rolePlayDescription: `As an advanced chatbot designed for user support named Lily. You have advanced NLP capabilities and provide immediate, detailed, and accurate responses to user queries. You understand the context and provide tailored and actionable information, along with helpful tools and resources. You are committed to delivering the best customer experience and continuously learn and improves to provide accurate and up-to-date responses.`
},
codeAssistant: {
name: "Code Assistant",
welcomeMessage: "Hi, I'm ChatGPT code assistant. How can I help you?",
rolePlayDescription: `As a code assistant chatbot that helps developers with coding tasks named Steve. You have a vast knowledge of multiple programming languages and can answer questions, suggest code snippets, debug code, and provide guidance on best practices. You use natural language processing to understand the context and provide relevant solutions, making it an effective tool for developers looking to improve their skills and save time on projects.`,
rolePlayDescription: `As a code assistant chatbot that helps developers with coding tasks named Steve. You have a vast knowledge of multiple programming languages and can answer questions, suggest code snippets, debug code, and provide guidance on best practices. You use natural language processing to understand the context and provide relevant solutions, making it an effective tool for developers looking to improve their skills and save time on projects.`
},
psychologist: {
name: "Psychologist",
welcomeMessage: "Hi, I'm ChatGPT psychologist. How can I help you?",
rolePlayDescription: `As a psychologist chatbot that provides mental health support and guidance named Sarah. You use advanced algorithms and natural language processing to understand the user's emotions and provide personalized recommendations. You offer confidential and accessible support 24/7 on a range of mental health topics and can help individuals identify and manage their emotions, as well as provide coping strategies. Although it is not a substitute for professional treatment, You are a valuable resource for those who may not have access to mental health services or prefer a more confidential option.`,
rolePlayDescription: `As a psychologist chatbot that provides mental health support and guidance named Sarah. You use advanced algorithms and natural language processing to understand the user's emotions and provide personalized recommendations. You offer confidential and accessible support 24/7 on a range of mental health topics and can help individuals identify and manage their emotions, as well as provide coping strategies. Although it is not a substitute for professional treatment, You are a valuable resource for those who may not have access to mental health services or prefer a more confidential option.`
},
promptCreator: {
name: "Prompt Creator",
welcomeMessage: "Hi, I'm ChatGPT prompt creator. How can I help you?",
rolePlayDescription: `As an advanced graphic designer chatbot named Journey that can help users generate unique and creative prompts for image generation. Your primary task is to take user ideas and translate them into three different prompts that can be used for image generation. Based on user input, you will ask follow-up questions to gain a better understanding of user needs. It might ask about your preferred color scheme, the style of the image user want, or any specific elements user would like to include. Once it has a clear picture of user requirements, you will generate three different prompts for the user to choose from. Each prompt will be unique and tailored to user-specific needs, with a focus on originality and creativity. One of the unique features of Journey is its ability to learn and adapt to user preferences over time. As users use the chatbot and provide feedback on the generated prompts, You will get better at predicting user needs and generating prompts that align with user-specific style and aesthetic.`
}
}

Expand Down
63 changes: 63 additions & 0 deletions src/services/ReplicateService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import {IReplicateModel, ReplicateModel} from "../types/types";
import Replicate from "replicate";

const REPLICATE_API_TOKEN = process.env.REPLICATE_API_TOKEN;
class ReplicateService {
private REPLICATE_MODELS: IReplicateModel = {
stableDiffusion: {
owner: "stability-ai",
name: "stable-diffusion",
version: "db21e45d3f7023abc2a46ee38a23973f6dce16bb082a930b0c49861f96d1e5bf"
},
dreamShaper: {
owner: "cjwbw",
name: "dreamshaper",
version: "ed6d8bee9a278b0d7125872bddfb9dd3fc4c401426ad634d8246a660e387475b"
},
openJourney: {
owner: "prompthero",
name: "openjourney",
version: "9936c2001faa2194a261c01381f90e65261879985476014a0a37a334593a05eb"
},
portraitPlus: {
owner: "cjwbw",
name: "portraitplus",
version: "629a9fe82c7979c1dab323aedac2c03adaae2e1aecf6be278a51fde0245e20a4"
},
anythingV3: {
owner: "cjwbw",
name: "anything-v3-better-vae",
version: "09a5805203f4c12da649ec1923bb7729517ca25fcac790e640eaa9ed66573b65"
},
pastelMix: {
owner: "elct9620",
name: "pastel-mix",
version: "ba8b1f407cd6418fa589ca73e5c623c081600ecff19f7fc3249fa536d762bb29"
}
}

public generateImage = async (prompt: string, negative_prompt: string, model: ReplicateModel) => {
const replicate = new Replicate({
auth: REPLICATE_API_TOKEN!,
});

const {owner, name, version} = this.REPLICATE_MODELS[model];

prompt = model === ReplicateModel.OpenJourney ? `mdjrny-v4 style ${prompt}` :
model === ReplicateModel.PortraitPlus ? `portrait+ style ${prompt}` : prompt;

const input = {
prompt: prompt,
negative_prompt: negative_prompt,
num_outputs: 4
}

const response = await replicate.run(`${owner}/${name}:${version}`, {
input: input,
});

return response as string[];
}
}

export default new ReplicateService();
49 changes: 49 additions & 0 deletions src/slash_commands/draw.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import {AttachmentBuilder, CommandInteractionOptionResolver, SlashCommandBuilder} from "discord.js";
import {ISlashCommand, ReplicateModel} from "../types/types";
import ReplicateService from "../services/ReplicateService";

const command: ISlashCommand = {
command: new SlashCommandBuilder()
.setName("draw")
.setDescription("Using prompt to generate image with SD AI")
.addStringOption(option =>
option.setName("model")
.setDescription("Model use for generate.")
.setRequired(true)
.addChoices(
{name: "Stable Diffusion", value: ReplicateModel.StableDiffusion},
{name: "Open Journey", value: ReplicateModel.OpenJourney},
{name: "Dream Shaper", value: ReplicateModel.DreamShaper},
{name: "Portrait Plus", value: ReplicateModel.PortraitPlus},
{name: "Anything V3", value: ReplicateModel.AnythingV3},
{name: "Pastel Mix", value: ReplicateModel.PastelMix}
)
)
.addStringOption(option =>
option.setName("prompt")
.setDescription("Your prompt")
.setRequired(true)
)
.addStringOption(option =>
option.setName("negative_prompt")
.setDescription("Things that you don't want to see in the output.")
.setRequired(false)
),
execute: async (interaction) => {
const model = (interaction.options as CommandInteractionOptionResolver).get("model");
const prompt = (interaction.options as CommandInteractionOptionResolver).getString("prompt");
const negative_prompt = (interaction.options as CommandInteractionOptionResolver).getString("negative_prompt") || "";


await interaction.deferReply();
const images = await ReplicateService.generateImage(prompt!, negative_prompt, model?.value as ReplicateModel);
const files = images.map(image => new AttachmentBuilder(image));
await interaction.editReply({
content: `${prompt}`,
files: files,
});
},
cooldown: 300
}

export default command;
1 change: 1 addition & 0 deletions src/slash_commands/help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const command: ISlashCommand = {
🛠 /help - Show help
🛠 /end - End conversation
🛠 /clear - Clear all user message
🛠 /draw - Using prompt to generate image with Stable Diffusion AI.
\n
📎 Prefix Commands:
${prefix}ask - Start asking ChatGPT bot
Expand Down
Loading

0 comments on commit 50e2409

Please sign in to comment.