1+ using System . Runtime . Serialization ;
2+ using Humanizer ;
3+ using Newtonsoft . Json ;
4+ using Newtonsoft . Json . Converters ;
5+ using OpenAI ;
6+ using OpenAI . Images ;
7+ using Slack_GPT_Socket . GptApi ;
8+
9+ namespace Slack_GPT_Socket . Functions ;
10+
11+ [ JsonConverter ( typeof ( StringEnumConverter ) ) ]
12+ public enum QualityEnum
13+ {
14+ [ EnumMember ( Value = "standard" ) ] Standard ,
15+ [ EnumMember ( Value = "hd" ) ] HighDefinition
16+ }
17+
18+ [ JsonConverter ( typeof ( StringEnumConverter ) ) ]
19+ public enum SizeEnum
20+ {
21+ Square ,
22+ Portrait ,
23+ Landscape
24+ }
25+
26+ [ JsonConverter ( typeof ( StringEnumConverter ) ) ]
27+ public enum StyleEnum
28+ {
29+ [ EnumMember ( Value = "vivid" ) ] Vivid ,
30+ [ EnumMember ( Value = "natural" ) ] Natural
31+ }
32+
33+ /// <summary>
34+ /// Generate an image based on the given prompt, returns the URL of the generated image.
35+ /// </summary>
36+ public partial class GenerateImageTool : BaseGptTool , IExpressionGptTool < string , string , QualityEnum ? , SizeEnum ? , StyleEnum ? >
37+ {
38+ private readonly OpenAIClient _api ;
39+
40+ public override string [ ] Aliases { get ; } =
41+ {
42+ "image" ,
43+ "generate-image" ,
44+ } ;
45+
46+ public GenerateImageTool ( OpenAIClient api ) : this ( )
47+ {
48+ _api = api ;
49+ }
50+
51+ /// <summary>
52+ /// Generate an image based on the given prompt, returns the byte array of the generated image, that is then
53+ /// attached AUTOMATICALLY to the response message. Do not mention the image in the response message.
54+ /// </summary>
55+ /// <param name="prompt">
56+ /// Prompt field guides the AI in generating images by providing a clear, concise description of the desired
57+ /// scene or subject, including specific details like the setting, style, and mood. Use descriptive language to specify
58+ /// key elements, context, and artistic styles to ensure the resulting image closely aligns with your vision.
59+ /// </param>
60+ /// <param name="name">
61+ /// Short image name that will be used as file name. Use hyphen and leave out extension format. Use
62+ /// hyphens to mark words
63+ /// </param>
64+ /// <param name="quality">
65+ /// The quality of the image that will be generated. hd creates images with finer details and greater
66+ /// consistency across the image.
67+ /// </param>
68+ /// <param name="size">The size of the generated images, default is square</param>
69+ /// <param name="style">
70+ /// The style of the generated images. Vivid causes the model to lean towards generating hyper-real and
71+ /// dramatic images. Natural causes the model to produce more natural, less hyper-real looking images. Defaults to
72+ /// vivid
73+ /// </param>
74+ /// <returns></returns>
75+ public async Task < CallExpressionResult > CallExpression ( string prompt , string name , QualityEnum ? quality ,
76+ SizeEnum ? size , StyleEnum ? style )
77+ {
78+ var client = _api . GetImageClient ( "dall-e-3" ) ;
79+
80+ GeneratedImageQuality ? generatedImageQuality = quality switch
81+ {
82+ QualityEnum . Standard => GeneratedImageQuality . Standard ,
83+ QualityEnum . HighDefinition => GeneratedImageQuality . High ,
84+ _ => default
85+ } ;
86+
87+ GeneratedImageSize ? generatedImageSize = size switch
88+ {
89+ SizeEnum . Square => GeneratedImageSize . W1024xH1024 ,
90+ SizeEnum . Portrait => GeneratedImageSize . W1024xH1792 ,
91+ SizeEnum . Landscape => GeneratedImageSize . W1792xH1024 ,
92+ _ => default
93+ } ;
94+
95+ GeneratedImageStyle ? generatedImageStyle = style switch
96+ {
97+ StyleEnum . Vivid => GeneratedImageStyle . Vivid ,
98+ StyleEnum . Natural => GeneratedImageStyle . Natural ,
99+ _ => default
100+ } ;
101+
102+ var generateImageAsync = await client . GenerateImageAsync ( prompt , new ImageGenerationOptions
103+ {
104+ Quality = generatedImageQuality ,
105+ Size = generatedImageSize ,
106+ Style = generatedImageStyle ,
107+ ResponseFormat = GeneratedImageFormat . Bytes
108+ } ) ;
109+
110+ var imageBytes = generateImageAsync . Value . ImageBytes ;
111+ var revisedPrompt = generateImageAsync . Value . RevisedPrompt ;
112+
113+ using var memoryStream = new MemoryStream ( ) ;
114+ await imageBytes . ToStream ( ) . CopyToAsync ( memoryStream ) ;
115+ var bytes = memoryStream . ToArray ( ) ;
116+
117+ return new CallExpressionResult
118+ {
119+ TextResponse = "Generated using prompt: " + revisedPrompt + ". Image data is part of the message, do not embed it in the message." ,
120+ Files = new List < FileAttachment >
121+ {
122+ new ( )
123+ {
124+ MimeType = "image/png" ,
125+ Data = bytes ,
126+ Name = $ "{ name } .png",
127+ Title = name . Humanize ( )
128+ }
129+ }
130+ } ;
131+ }
132+ }
0 commit comments