Skip to content

Commit

Permalink
Add: Generate Image by DALL·E 3 (#493)
Browse files Browse the repository at this point in the history
* add generateImage function

* remove debug comment

* change command to image

* add image command instructions

* add n parameter instructions

* use the currentProvider.createClient method

* display no supported models error

* refactor for same key value names
  • Loading branch information
mingming-ma authored Mar 15, 2024
1 parent b12cd30 commit d09c947
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/components/Message/AppMessage/Help.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ Some commands accept arguments as well.
| /new | Creates a new chat. |
| /clear | Erases all messages in the current chat. |
| /summary [max-length] | Uses ChatGPT to create a summary of the current chat. Optionally takes a maximum word length (defaults to 500). |
| /import&nbsp;<url> | Loads the provided URL and imports the text. Where possible, ChatCraft will try to get raw text vs. HTML from sites like GitHub. NOTE: to prevent abuse, you must be logged into use the import command. |`;
| /import&nbsp;<url> | Loads the provided URL and imports the text. Where possible, ChatCraft will try to get raw text vs. HTML from sites like GitHub. NOTE: to prevent abuse, you must be logged into use the import command. |
| /image&nbsp;<prompt> | Creates an image using the provided prompt.|
`;

const helpText = `## ChatCraft.org Help
Expand Down
48 changes: 48 additions & 0 deletions src/lib/ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -396,3 +396,51 @@ export const textToSpeech = async (message: string): Promise<string> => {

return objectUrl;
};

/**
* Only meant to be used outside components or hooks
* where useModels cannot be used.
*/
export async function isGenerateImageSupported() {
const { currentProvider } = getSettings();
if (!currentProvider.apiKey) {
throw new Error("Missing API Key");
}

return (
(await currentProvider.queryModels(currentProvider.apiKey)).filter((model: string) =>
model.includes("dall-e-3")
)?.length > 0
);
}

type dalle3ImageSize = "1024x1024" | "1792x1024" | "1024x1792";

export const generateImage = async (
prompt: string,
//You can request 1 image at a time with DALL·E 3 (request more by making parallel requests) or up to 10 images at a time using DALL·E 2 with the n parameter.
//https://platform.openai.com/docs/guides/images/generations
n: number = 1,
size: dalle3ImageSize = "1024x1024"
): Promise<string[]> => {
const { currentProvider } = getSettings();
if (!currentProvider.apiKey) {
throw new Error("Missing OpenAI API Key");
}

const { openai } = currentProvider.createClient(currentProvider.apiKey);

try {
const response = await openai.images.generate({
model: "dall-e-3",
prompt,
n,
size,
});

const imageUrls = response.data.map((img: any) => img.url);
return imageUrls;
} catch (error: any) {
throw new Error(error);
}
};
30 changes: 30 additions & 0 deletions src/lib/commands/ImageCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { ChatCraftCommand } from "../ChatCraftCommand";
import { ChatCraftChat } from "../ChatCraftChat";
import { ChatCraftHumanMessage } from "../ChatCraftMessage";
import { generateImage, isGenerateImageSupported } from "../../lib/ai";

export class ImageCommand extends ChatCraftCommand {
constructor() {
super("image");
}

async execute(chat: ChatCraftChat, user: User | undefined, args?: string[]) {
if (!(await isGenerateImageSupported())) {
throw new Error("Failed to generate image, no image generation models available");
}
if (!(args && args[0])) {
throw new Error("must include a prompt");
}
const prompt = args.join(" ");
let imageUrls: string[] = [];
const text = `(DALL·E 3 result of the prompt: ${prompt})`;

try {
imageUrls = await generateImage(prompt);
} catch (error: any) {
console.error(`Failed to generate image: ${error.message}`);
throw new Error(`Failed to generate image: ${error.message}`);
}
return chat.addMessage(new ChatCraftHumanMessage({ user, text, imageUrls }));
}
}
2 changes: 2 additions & 0 deletions src/lib/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { SummaryCommand } from "./SummaryCommand";
import { HelpCommand } from "./HelpCommand";
import { ImportCommand } from "./ImportCommand";
import { CommandsHelpCommand } from "./CommandsHelpCommand";
import { ImageCommand } from "./ImageCommand";

// Register all our commands
ChatCraftCommandRegistry.registerCommand(new NewCommand());
Expand All @@ -15,3 +16,4 @@ ChatCraftCommandRegistry.registerCommand(new SummaryCommand());
ChatCraftCommandRegistry.registerCommand(new HelpCommand());
ChatCraftCommandRegistry.registerCommand(new CommandsHelpCommand());
ChatCraftCommandRegistry.registerCommand(new ImportCommand());
ChatCraftCommandRegistry.registerCommand(new ImageCommand());

0 comments on commit d09c947

Please sign in to comment.