diff --git a/Chat.go b/Chat.go index fa29f1f..9775dca 100644 --- a/Chat.go +++ b/Chat.go @@ -24,9 +24,34 @@ func ChatPageHandler(c *fiber.Ctx) error { } func LoadModelSelectionHandler(c *fiber.Ctx) error { + openaiExists, anthropicExists := getExistingKeys() + + var CompanyInfosAvailable []CompanyInfo + + if openaiExists { + var openaiCompanyInfo CompanyInfo + for _, info := range CompanyInfos { + if info.ID == "openai" { + openaiCompanyInfo = info + break + } + } + CompanyInfosAvailable = append(CompanyInfosAvailable, openaiCompanyInfo) + } + if anthropicExists { + var anthropicCompanyInfo CompanyInfo + for _, info := range CompanyInfos { + if info.ID == "anthropic" { + anthropicCompanyInfo = info + break + } + } + CompanyInfosAvailable = append(CompanyInfosAvailable, anthropicCompanyInfo) + } + CheckedModels := []string{"gpt-3.5-turbo"} // Default model out, err := pongo2.Must(pongo2.FromFile("views/partials/popover-models.html")).Execute(pongo2.Context{ - "CompanyInfos": CompanyInfos, + "CompanyInfos": CompanyInfosAvailable, "CheckedModels": CheckedModels, }) if err != nil { @@ -65,7 +90,9 @@ func LoadUsageKPIHandler(c *fiber.Ctx) error { } func LoadSettingsHandler(c *fiber.Ctx) error { - out, err := pongo2.Must(pongo2.FromFile("views/partials/popover-settings.html")).Execute(pongo2.Context{"IsLogin": checkIfLogin()}) + openaiExists, anthropicExists := getExistingKeys() + + out, err := pongo2.Must(pongo2.FromFile("views/partials/popover-settings.html")).Execute(pongo2.Context{"IsLogin": checkIfLogin(), "OpenaiExists": openaiExists, "AnthropicExists": anthropicExists}) if err != nil { c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": "Error rendering template", diff --git a/RequestAnthropic.go b/RequestAnthropic.go index 6b2e6df..1685d88 100644 --- a/RequestAnthropic.go +++ b/RequestAnthropic.go @@ -8,8 +8,6 @@ import ( "net/http" "github.com/edgedb/edgedb-go" - "github.com/flosch/pongo2" - "github.com/gofiber/fiber/v2" ) type AnthropicChatCompletionRequest struct { @@ -171,7 +169,13 @@ func TestAnthropicKey(apiKey string) bool { var chatCompletionResponse AnthropicChatCompletionResponse err = json.Unmarshal(body, &chatCompletionResponse) - return err == nil + if err != nil { + return false + } + if chatCompletionResponse.Content == nil { + return false + } + return true } func RequestAnthropic(model string, messages []Message, maxTokens int, temperature float64) (AnthropicChatCompletionResponse, error) { @@ -244,74 +248,3 @@ func RequestAnthropic(model string, messages []Message, maxTokens int, temperatu return chatCompletionResponse, nil } - -func addAnthropicKey(c *fiber.Ctx) error { - key := c.FormValue("key") - - // Check if the key already exists - err := edgeClient.QuerySingle(edgeCtx, ` - with - filtered_keys := ( - select Key { - key - } filter .key = $0 and .company = "anthropic" - ) - select filtered_keys.key limit 1 - `, &key, key) - if err == nil { - return c.SendString("") - } - - if !TestAnthropicKey(key) { - fmt.Println("Invalid Anthropic API Key") - - NextMessages := []NextMessage{} - nextMsg := NextMessage{ - Icon: "bouvai2", // Assuming Icon is a field you want to include from Message - Content: "
" + markdownToHTML("Invalid Anthropic API Key"), - Hidden: false, // Assuming Hidden is a field you want to include from Message - Id: "0", - Name: "JADE", - } - NextMessages = append(NextMessages, nextMsg) - - botOut, err := botTmpl.Execute(pongo2.Context{"Messages": NextMessages, "ConversationAreaId": 0}) - if err != nil { - panic(err) - } - return c.SendString(botOut) - } - - err = edgeClient.Execute(edgeCtx, ` - UPDATE global currentUser.setting - SET { - keys += ( - INSERT Key { - company := $0, - key := $1, - name := $2, - } - ) - }`, "anthropic", key, "Anthropic API Key") - if err != nil { - fmt.Println("Error in edgedb.QuerySingle: in addOpenaiKey") - fmt.Println(err) - } - - NextMessages := []NextMessage{} - nextMsg := NextMessage{ - Icon: "bouvai2", // Assuming Icon is a field you want to include from Message - Content: "
" + markdownToHTML("Key added successfully!"), - Hidden: false, // Assuming Hidden is a field you want to include from Message - Id: "0", - Name: "JADE", - } - NextMessages = append(NextMessages, nextMsg) - - botOut, err := botTmpl.Execute(pongo2.Context{"Messages": NextMessages, "ConversationAreaId": 0}) - if err != nil { - panic(err) - } - - return c.SendString(botOut) -} diff --git a/RequestOpenai.go b/RequestOpenai.go index eabf6a3..4f242e8 100644 --- a/RequestOpenai.go +++ b/RequestOpenai.go @@ -8,8 +8,6 @@ import ( "net/http" "github.com/edgedb/edgedb-go" - "github.com/flosch/pongo2" - "github.com/gofiber/fiber/v2" ) type OpenaiChatCompletionRequest struct { @@ -161,13 +159,14 @@ func TestOpenaiKey(apiKey string) bool { var chatCompletionResponse OpenaiChatCompletionResponse err = json.Unmarshal(body, &chatCompletionResponse) + fmt.Println(chatCompletionResponse) if err != nil { return false } - if chatCompletionResponse.Choices == nil { + if chatCompletionResponse.Usage.CompletionTokens == 0 { return false } - return false + return true } func RequestOpenai(model string, messages []Message, temperature float64) (OpenaiChatCompletionResponse, error) { @@ -241,103 +240,3 @@ func RequestOpenai(model string, messages []Message, temperature float64) (Opena return chatCompletionResponse, nil } - -func addOpenaiKey(c *fiber.Ctx) error { - key := c.FormValue("key") - - // Check if the key already exists - var keyUUID edgedb.UUID - err := edgeClient.QuerySingle(edgeCtx, ` - with - filtered_keys := ( - select Key { - id - } filter .key = $0 and .company = "openai" - ) - select filtered_keys.key limit 1 - `, &keyUUID, key) - if err == nil { - fmt.Println("Error in edgedb.Query: in addOpenaiKey") - return c.SendString("") - } - - if !TestOpenaiKey(key) { - fmt.Println("Invalid OpenAI API Key") - NextMessages := []NextMessage{} - nextMsg := NextMessage{ - Icon: "bouvai2", // Assuming Icon is a field you want to include from Message - Content: "
" + markdownToHTML("Invalid OpenAI API Key"), - Hidden: false, // Assuming Hidden is a field you want to include from Message - Id: "0", - Name: "JADE", - } - NextMessages = append(NextMessages, nextMsg) - - botOut, err := botTmpl.Execute(pongo2.Context{"Messages": NextMessages, "ConversationAreaId": 0}) - if err != nil { - panic(err) - } - return c.SendString(botOut) - } - - // Check if the company key already exists - err = edgeClient.QuerySingle(edgeCtx, ` - with - filtered_keys := ( - select Key { - id - } filter .company = "openai" - ) - select filtered_keys.key limit 1 - `, &keyUUID, key) - if err != nil { - fmt.Println("Company key already exists") - err = edgeClient.Execute(edgeCtx, ` - UPDATE Key filter .company = $0 AND .key = $1 - SET { - key := $1, - } - `, "openai", key) - if err != nil { - fmt.Println("Error in edgedb.QuerySingle: in addOpenaiKey") - fmt.Println(err) - } - - return c.SendString("") - } - - fmt.Println("OpenAI API key: ", key) - - err = edgeClient.Execute(edgeCtx, ` - UPDATE global currentUser.setting - SET { - keys += ( - INSERT Key { - company := $0, - key := $1, - name := $2, - } - ) - }`, "openai", key, "OpenAI API Key") - if err != nil { - fmt.Println("Error in edgedb.QuerySingle: in addOpenaiKey") - fmt.Println(err) - } - - NextMessages := []NextMessage{} - nextMsg := NextMessage{ - Icon: "bouvai2", // Assuming Icon is a field you want to include from Message - Content: "
Key added successfully!", - Hidden: false, // Assuming Hidden is a field you want to include from Message - Id: "0", - Name: "JADE", - } - NextMessages = append(NextMessages, nextMsg) - - botOut, err := botTmpl.Execute(pongo2.Context{"Messages": NextMessages, "ConversationAreaId": 0}) - if err != nil { - panic(err) - } - - return c.SendString(botOut) -} diff --git a/dbschema/default.esdl b/dbschema/default.esdl index 3445cbe..72d578b 100644 --- a/dbschema/default.esdl +++ b/dbschema/default.esdl @@ -24,7 +24,9 @@ module default { type Setting { default_model: str; - multi keys: Key; + multi keys: Key { + on target delete allow; + }; } type Conversation { diff --git a/dbschema/migrations/00020-m1nsazf.edgeql b/dbschema/migrations/00020-m1nsazf.edgeql new file mode 100644 index 0000000..9519ae1 --- /dev/null +++ b/dbschema/migrations/00020-m1nsazf.edgeql @@ -0,0 +1,9 @@ +CREATE MIGRATION m1nsazfltqdfklverxefbbufjwcq5gorhbovfeeugd7q67txrihd2q + ONTO m1rzoj5rvhxkec6tsew6dc6bd3ksrrmf7t3k532avozbg4722xulhq +{ + ALTER TYPE default::Setting { + ALTER LINK keys { + ON TARGET DELETE ALLOW; + }; + }; +}; diff --git a/main.go b/main.go index d64227e..e39028b 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,8 @@ package main import ( + "fmt" + "github.com/flosch/pongo2" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/logger" @@ -41,8 +43,7 @@ func main() { app.Get("/messageContent", GetMessageContentHandler) // Settings routes - app.Post("/addOpenaiKey", addOpenaiKey) - app.Post("/addAnthropicKey", addAnthropicKey) + app.Post("/addKeys", addKeys) // Popovers app.Get("/loadModelSelection", LoadModelSelectionHandler) @@ -58,3 +59,167 @@ func main() { // Start server app.Listen(":8080") } + +func addKeys(c *fiber.Ctx) error { + openaiKey := c.FormValue("openai_key") + anthropicKey := c.FormValue("anthropic_key") + var Exists bool + + // Handle OpenAI key + if openaiKey != "" { + // Check if the OpenAI key already exists + err := edgeClient.QuerySingle(edgeCtx, ` + select exists ( + select global currentUser.setting.keys + filter .company = "openai" AND .key = $0 + ); + `, &Exists, openaiKey) + if err != nil { + fmt.Println("Error in edgedb.QuerySingle: in addOpenaiKey: ", err) + return c.SendString("") + } + if Exists { + fmt.Println("OpenAI key already exists") + return c.SendString("") + } + + fmt.Println("OpenAI API key: ", openaiKey) + + if !TestOpenaiKey(openaiKey) { + fmt.Println("Invalid OpenAI API Key") + return handleInvalidKey(c, "OpenAI API Key") + } + + // Check if the company key already exists + err = edgeClient.QuerySingle(edgeCtx, ` + select exists ( + select global currentUser.setting.keys + filter .company = "openai" + ); + `, &Exists) + if err != nil { + fmt.Println("Error in edgedb.QuerySingle: in addOpenaiKey") + fmt.Println(err) + } + + if Exists { + fmt.Println("Company key already exists") + err = edgeClient.Execute(edgeCtx, ` + UPDATE Key filter .company = $0 AND .key = $1 + SET { + key := $1, + } + `, "openai", openaiKey) + if err != nil { + fmt.Println("Error in edgedb.QuerySingle: in addOpenaiKey") + fmt.Println(err) + } + } else { + fmt.Println("OpenAI API key: ", openaiKey) + + err = edgeClient.Execute(edgeCtx, ` + UPDATE global currentUser.setting + SET { + keys += ( + INSERT Key { + company := $0, + key := $1, + name := $2, + } + ) + }`, "openai", openaiKey, "OpenAI API Key") + if err != nil { + fmt.Println("Error in edgedb.QuerySingle: in addOpenaiKey") + fmt.Println(err) + } + } + } + + // Handle Anthropic key + if anthropicKey != "" { + // Check if the OpenAI key already exists + err := edgeClient.QuerySingle(edgeCtx, ` + select exists ( + select global currentUser.setting.keys + filter .company = "anthropic" AND .key = $0 + ); + `, &Exists, openaiKey) + if err != nil { + fmt.Println("Error in edgedb.QuerySingle: in addAnthropicKey: ", err) + return c.SendString("") + } + if Exists { + fmt.Println("Anthropic key already exists") + return c.SendString("") + } + + if !TestAnthropicKey(anthropicKey) { + fmt.Println("Invalid Anthropic API Key") + return handleInvalidKey(c, "Anthropic API Key") + } + + // Check if the company key already exists + err = edgeClient.QuerySingle(edgeCtx, ` + select exists ( + select global currentUser.setting.keys + filter .company = "anthropic" + ); + `, &Exists) + if err != nil { + fmt.Println("Error in edgedb.QuerySingle: in addAnthropicKey") + fmt.Println(err) + } + + if Exists { + fmt.Println("Company key already exists") + err = edgeClient.Execute(edgeCtx, ` + UPDATE Key filter .company = "anthropic" AND .key = $0 + SET { + key := $0, + } + `, anthropicKey) + if err != nil { + fmt.Println("Error in edgedb.QuerySingle: in addAnthropicKey") + fmt.Println(err) + } + } else { + fmt.Println("OpenAI API key: ", openaiKey) + + err = edgeClient.Execute(edgeCtx, ` + UPDATE global currentUser.setting + SET { + keys += ( + INSERT Key { + company := "anthropic", + key := $0, + name := "Anthropic API Key", + } + ) + }`, anthropicKey) + if err != nil { + fmt.Println("Error in edgedb.QuerySingle: in addAnthropicKey") + fmt.Println(err) + } + } + } + + return c.SendString("") +} + +func handleInvalidKey(c *fiber.Ctx, keyType string) error { + NextMessages := []NextMessage{} + nextMsg := NextMessage{ + Icon: "bouvai2", + Content: "
" + markdownToHTML(fmt.Sprintf("Invalid %s", keyType)), + Hidden: false, + Id: "0", + Name: "JADE", + } + NextMessages = append(NextMessages, nextMsg) + + botOut, err := botTmpl.Execute(pongo2.Context{"Messages": NextMessages, "ConversationAreaId": 0}) + if err != nil { + panic(err) + } + return c.SendString(botOut) +} diff --git a/utils.go b/utils.go index 1247859..e47815d 100644 --- a/utils.go +++ b/utils.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "fmt" "regexp" "strings" @@ -60,3 +61,34 @@ func model2Name(model string) string { } return "OpenAI" } + +func getExistingKeys() (bool, bool) { + if edgeClient == nil { + return false, false + } + + var openaiExists bool + var anthropicExists bool + + err := edgeClient.QuerySingle(edgeCtx, ` + select exists ( + select global currentUser.setting.keys + filter .company = "openai" + ); + `, &openaiExists) + if err != nil { + fmt.Println("Error in edgedb.QuerySingle: in addOpenaiKey: ", err) + } + + err = edgeClient.QuerySingle(edgeCtx, ` + select exists ( + select global currentUser.setting.keys + filter .company = "anthropic" + ); + `, &anthropicExists) + if err != nil { + fmt.Println("Error in edgedb.QuerySingle: in addOpenaiKey: ", err) + } + + return openaiExists, anthropicExists +} diff --git a/views/partials/popover-settings.html b/views/partials/popover-settings.html index 09a94ed..a14aa53 100644 --- a/views/partials/popover-settings.html +++ b/views/partials/popover-settings.html @@ -8,12 +8,12 @@