Skip to content

Commit

Permalink
Add DALL-E 3 Support to /render (#148)
Browse files Browse the repository at this point in the history
* Updated dependencies

* Updated dalle2 opt variable names for consistency

* Stubbed out handleDalle3SubCmd

* Added dalle3 subcommand to /render

* Updated render.go to no longer use deprecated constants
  • Loading branch information
Kardbord authored Nov 7, 2023
1 parent 013df7f commit 47bb7de
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 17 deletions.
14 changes: 7 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/TannerKvarfordt/Kard-bot
go 1.18

require (
github.com/TannerKvarfordt/gopenai v0.1.4-beta
github.com/TannerKvarfordt/gopenai v0.1.5-beta
github.com/TannerKvarfordt/hfapigo v1.3.1
github.com/TannerKvarfordt/imgflipgo v1.0.8
github.com/TannerKvarfordt/ubiquity v0.2.3
Expand All @@ -25,15 +25,15 @@ require (
github.com/fatih/structtag v1.2.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/gorilla/schema v1.2.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/gorilla/schema v1.2.1 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/oauth2 v0.10.0 // indirect
golang.org/x/sys v0.13.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
golang.org/x/oauth2 v0.13.0 // indirect
golang.org/x/sys v0.14.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/protobuf v1.31.0 // indirect
)
31 changes: 31 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/TannerKvarfordt/gopenai v0.1.4-beta h1:Xkizsqt8hRXnfj2igDM9uFDjJMeFv/lr5QYmJC4wrW8=
github.com/TannerKvarfordt/gopenai v0.1.4-beta/go.mod h1:X42mdDQIih6TLzctpf8Wp/cIGpHaMiImMWZ+BQz7nT0=
github.com/TannerKvarfordt/gopenai v0.1.5-beta h1:7vbtwn3fqDrPUsjCz2SP0s+ivIeNbFAP6ACDfklARhc=
github.com/TannerKvarfordt/gopenai v0.1.5-beta/go.mod h1:X42mdDQIih6TLzctpf8Wp/cIGpHaMiImMWZ+BQz7nT0=
github.com/TannerKvarfordt/hfapigo v1.3.1 h1:Q0nGBLI3p6kbY/PHdjWFKsXN9HDulPQPSIlACtiZ0rE=
github.com/TannerKvarfordt/hfapigo v1.3.1/go.mod h1:QvdRtU6q3i/VURfTwUu/akYX6HtdIGn25t62zFLoXX4=
github.com/TannerKvarfordt/imgflipgo v1.0.8 h1:n6MPCZYGY51EL+H85UGV71LRiTiWIyoEprawYlu2Tr0=
Expand All @@ -26,6 +28,7 @@ github.com/go-co-op/gocron v1.35.3/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISk
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
Expand All @@ -38,9 +41,13 @@ github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc=
github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
github.com/gorilla/schema v1.2.1 h1:tjDxcmdb+siIqkTNoV+qRH2mjYdr2hHe5MKXbp61ziM=
github.com/gorilla/schema v1.2.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
Expand Down Expand Up @@ -76,39 +83,63 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/vartanbeno/go-reddit/v2 v2.0.1 h1:P6ITpf5YHjdy7DHZIbUIDn/iNAoGcEoDQnMa+L4vutw=
github.com/vartanbeno/go-reddit/v2 v2.0.1/go.mod h1:758/S10hwZSLm43NPtwoNQdZFSg3sjB5745Mwjb0ANI=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY=
golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
Expand Down
6 changes: 6 additions & 0 deletions kardbot/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,12 @@ func getCommands() []*discordgo.ApplicationCommand {
Type: discordgo.ApplicationCommandOptionSubCommand,
Options: dalle2Opts(),
},
{
Name: dalle3SubCmd,
Description: "Ask Open AI's DALL·E 3 model to generate an image from a prompt.",
Type: discordgo.ApplicationCommandOptionSubCommand,
Options: dalle3Opts(),
},
{
Name: hfSubCmd,
Description: "Ask a HuggingFace model to generate an image from a prompt.",
Expand Down
169 changes: 159 additions & 10 deletions kardbot/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,14 @@ const (
hfModelsFilepath = "config/hugging-face-models.json"

dalle2SubCmd = "dalle2"
dalle2PromptOpt = "prompt"
dalle2SizeOpt = "size"
dalle2OptPrompt = "prompt"
dalle2OptSize = "size"

dalle3SubCmd = "dalle3"
dalle3OptPrompt = "prompt"
dalle3OptSize = "size"
dalle3OptQuality = "quality"
dalle3OptStyle = "style"
)

func handleRenderCmd(s *discordgo.Session, i *discordgo.InteractionCreate) {
Expand All @@ -55,6 +61,8 @@ func handleRenderCmd(s *discordgo.Session, i *discordgo.InteractionCreate) {
handleHfSubCmd(s, i, i.ApplicationCommandData().Options[0].Options)
case dalle2SubCmd:
handleDalle2SubCmd(s, i, i.ApplicationCommandData().Options[0].Options)
case dalle3SubCmd:
handleDalle3SubCmd(s, i, i.ApplicationCommandData().Options[0].Options)
default:
err = fmt.Errorf("reached unreachable case")
log.Error(err)
Expand Down Expand Up @@ -246,27 +254,27 @@ func dalle2Opts() []*discordgo.ApplicationCommandOption {
return []*discordgo.ApplicationCommandOption{
{
Type: discordgo.ApplicationCommandOptionString,
Name: dalle2PromptOpt,
Name: dalle2OptPrompt,
Description: "A prompt to generate an image from. This can be very specific.",
Required: true,
},
{
Type: discordgo.ApplicationCommandOptionString,
Name: dalle2SizeOpt,
Name: dalle2OptSize,
Description: "The size of the image to be generated",
Required: true,
Choices: []*discordgo.ApplicationCommandOptionChoice{
{
Name: images.SmallImage,
Value: images.SmallImage,
Name: images.Dalle2SmallImage,
Value: images.Dalle2SmallImage,
},
{
Name: images.MediumImage,
Value: images.MediumImage,
Name: images.Dalle2MediumImage,
Value: images.Dalle2MediumImage,
},
{
Name: images.LargeImage,
Value: images.LargeImage,
Name: images.Dalle2LargeImage,
Value: images.Dalle2LargeImage,
},
},
},
Expand Down Expand Up @@ -300,6 +308,8 @@ func handleDalle2SubCmd(s *discordgo.Session, i *discordgo.InteractionCreate, op
contentFlags = []byte("Whoops, couldn't retrieve the details of your violation.")
}
interactionFollowUpEphemeralError(s, i, false, fmt.Errorf("sorry! Your prompt does not appear to conform to [Open AI's Usage Policies](<https://beta.openai.com/docs/usage-policies>)\n```JSON\n%s\n```", contentFlags))
} else if strings.Contains(err.Error(), "safety system") {
interactionFollowUpEphemeralError(s, i, false, err)
} else {
log.Error(err)
interactionFollowUpEphemeralError(s, i, true, err)
Expand Down Expand Up @@ -333,3 +343,142 @@ func handleDalle2SubCmd(s *discordgo.Session, i *discordgo.InteractionCreate, op
interactionFollowUpEphemeralError(s, i, true, err)
}
}

func dalle3Opts() []*discordgo.ApplicationCommandOption {
return []*discordgo.ApplicationCommandOption{
{
Type: discordgo.ApplicationCommandOptionString,
Name: dalle3OptPrompt,
Description: "A prompt to generate an image from. This can be very detailed.",
Required: true,
},
{
Type: discordgo.ApplicationCommandOptionString,
Name: dalle3OptSize,
Description: "The size of the image to be generated.",
Required: true,
Choices: []*discordgo.ApplicationCommandOptionChoice{
{
Name: images.Dalle3SquareImage,
Value: images.Dalle3SquareImage,
},
{
Name: images.Dalle3LandscapeImage,
Value: images.Dalle3LandscapeImage,
},
{
Name: images.Dalle3PortraitImage,
Value: images.Dalle3PortraitImage,
},
},
},
{
Type: discordgo.ApplicationCommandOptionString,
Name: dalle3OptQuality,
Description: "The quality of the image that will be generated.",
Required: false,
Choices: []*discordgo.ApplicationCommandOptionChoice{
{
Name: images.QualityStandard,
Value: images.QualityStandard,
},
{
Name: images.QualityHD,
Value: images.QualityHD,
},
},
},
{
Type: discordgo.ApplicationCommandOptionString,
Name: dalle3OptStyle,
Description: "Vivid produces more hyper-real images, natural produces less hyper-real images.",
Required: false,
Choices: []*discordgo.ApplicationCommandOptionChoice{
{
Name: images.StyleVivid,
Value: images.StyleVivid,
},
{
Name: images.StyleNatural,
Value: images.StyleNatural,
},
},
},
}
}

func handleDalle3SubCmd(s *discordgo.Session, i *discordgo.InteractionCreate, opts []*discordgo.ApplicationCommandInteractionDataOption) {
mdata, err := getInteractionMetaData(i)
if err != nil {
log.Error(err)
interactionFollowUpEphemeralError(s, i, true, err)
return
}

imageCount := uint64(1)
request := &images.CreationRequest{
Model: images.ModelDalle3,
N: &imageCount,
ResponseFormat: images.ResponseFormatB64JSON,
User: mdata.AuthorID,
}
for _, opt := range opts {
switch opt.Name {
case dalle3OptPrompt:
request.Prompt = opt.StringValue()
case dalle3OptSize:
request.Size = opt.StringValue()
case dalle3OptQuality:
request.Quality = opt.StringValue()
case dalle3OptStyle:
request.Style = opt.StringValue()
default:
log.Warn("Unknown option:", opt.Name)
}
}

resp, modr, err := images.MakeModeratedCreationRequest(request, nil)
if err != nil {
targetErr := moderations.NewModerationFlagError()
if errors.As(err, &targetErr) {
contentFlags, err := json.MarshalIndent(modr.Results[0].Categories, "", " ")
if err != nil {
log.Error(err)
contentFlags = []byte("Whoops, couldn't retrieve the details of your violation.")
}
interactionFollowUpEphemeralError(s, i, false, fmt.Errorf("sorry! Your prompt does not appear to conform to [Open AI's Usage Policies](<https://beta.openai.com/docs/usage-policies>)\n```JSON\n%s\n```", contentFlags))
} else if strings.Contains(err.Error(), "safety system") {
interactionFollowUpEphemeralError(s, i, false, err)
} else {
log.Error(err)
interactionFollowUpEphemeralError(s, i, true, err)
}
return
}

unbased, err := base64.StdEncoding.DecodeString(resp.Data[0].B64JSON)
if err != nil {
log.Error(err)
interactionFollowUpEphemeralError(s, i, true, err)
return
}

content := fmt.Sprintf("Prompt:\n> %s\n\nRevised Prompt:\n> %s\n\nImage generated using [DALL·E 3](<https://openai.com/dall-e-3/>).", request.Prompt, resp.Data[0].RevisedPrompt)
_, err = s.InteractionResponseEdit(i.Interaction, &discordgo.WebhookEdit{
Content: &content,
Files: []*discordgo.File{
{
Name: "Dalle-2-Output.png",
ContentType: "image/png",
Reader: bytes.NewReader(unbased),
},
},
AllowedMentions: &discordgo.MessageAllowedMentions{
Users: []string{mdata.AuthorID},
},
})
if err != nil {
log.Error(err)
interactionFollowUpEphemeralError(s, i, true, err)
}
}

0 comments on commit 47bb7de

Please sign in to comment.