diff --git a/Chat.go b/Chat.go
index ec48210..928eb72 100644
--- a/Chat.go
+++ b/Chat.go
@@ -379,7 +379,7 @@ func LoadKeysHandler(c *fiber.Ctx) error {
if !checkIfLogin() {
return c.SendString("")
}
- openaiExists, anthropicExists, mistralExists, groqExists := getExistingKeys()
+ openaiExists, anthropicExists, mistralExists, groqExists, gooseaiExists, googleExists := getExistingKeys()
out, err := pongo2.Must(pongo2.FromFile("views/partials/popover-keys.html")).Execute(pongo2.Context{
"IsLogin": checkIfLogin(),
@@ -387,7 +387,9 @@ func LoadKeysHandler(c *fiber.Ctx) error {
"AnthropicExists": anthropicExists,
"MistralExists": mistralExists,
"GroqExists": groqExists,
- "AnyExists": openaiExists || anthropicExists || mistralExists || groqExists,
+ "GooseaiExists": gooseaiExists,
+ "GoogleExists": googleExists,
+ "AnyExists": openaiExists || anthropicExists || mistralExists || groqExists || gooseaiExists || googleExists,
})
if err != nil {
c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
diff --git a/Request.go b/Request.go
index 2ee3246..0a4c8f7 100644
--- a/Request.go
+++ b/Request.go
@@ -24,7 +24,7 @@ func GeneratePlaceholderHandler(c *fiber.Ctx) error {
// Step 1 I create a User message and send it as output with a placeholder
// that will make a request to GenerateMultipleMessagesHandler when loading
message := c.FormValue("message", "")
- selectedLLMIds := []string{"1e5a07c4-12fe-11ef-8da6-67d29b408c53", "3cd15ca8-1433-11ef-9f22-93f2b78c78de", "95774e62-1447-11ef-bfea-33f555b75c17", "af3d8686-1447-11ef-bfea-07d880a979ff"} // TODO Hanle in the UI
+ selectedLLMIds := []string{"1e5a07c4-12fe-11ef-8da6-67d29b408c53", "3cd15ca8-1433-11ef-9f22-93f2b78c78de", "95774e62-1447-11ef-bfea-33f555b75c17", "af3d8686-1447-11ef-bfea-07d880a979ff", "be7a922a-1478-11ef-a819-238de8775b87"} // TODO Hanle in the UI
var selectedLLMs []LLM
var selectedLLM LLM
@@ -105,6 +105,8 @@ func GenerateMultipleMessagesHandler(c *fiber.Ctx) error {
addMessageFunc = addMistralMessage
case "groq":
addMessageFunc = addGroqMessage
+ case "gooseai":
+ addMessageFunc = addGooseaiMessage
}
var messageID edgedb.UUID
diff --git a/RequestGoogle.go b/RequestGoogle.go
new file mode 100644
index 0000000..3486dcf
--- /dev/null
+++ b/RequestGoogle.go
@@ -0,0 +1,188 @@
+package main
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+
+ "github.com/edgedb/edgedb-go"
+)
+
+type GoogleRequestMessage struct {
+ Role string `json:"role"`
+ Parts []GooglePart `json:"parts"`
+}
+
+type GooglePart struct {
+ Text string `json:"text"`
+}
+
+type GoogleChatCompletionRequest struct {
+ Messages []GoogleRequestMessage `json:"contents"`
+}
+
+type GoogleChatCompletionResponse struct {
+ ID string `json:"id"`
+ Object string `json:"object"`
+ Created int64 `json:"created"`
+ Model string `json:"model"`
+ Usage GoogleUsage `json:"usage"`
+ Choices []GoogleChoice `json:"choices"`
+}
+
+type GoogleUsage struct {
+ PromptTokens int32 `json:"prompt_tokens"`
+ CompletionTokens int32 `json:"completion_tokens"`
+ TotalTokens int32 `json:"total_tokens"`
+}
+
+type GoogleChoice struct {
+ Message Message `json:"message"`
+ FinishReason string `json:"finish_reason"`
+ Index int `json:"index"`
+}
+
+func addGoogleMessage(llm LLM, selected bool) edgedb.UUID {
+ Messages := getAllSelectedMessages()
+
+ chatCompletion, err := RequestGoogle(llm.Model.ModelID, Messages, float64(llm.Temperature))
+ if err != nil {
+ fmt.Println("Error:", err)
+ } else if len(chatCompletion.Choices) == 0 {
+ fmt.Println("No response from OpenAI")
+ id := insertBotMessage("No response from OpenAI", selected, llm.ID)
+ return id
+ } else {
+ Content := chatCompletion.Choices[0].Message.Content
+ id := insertBotMessage(Content, selected, llm.ID)
+ return id
+ }
+ return edgedb.UUID{}
+}
+
+func TestGoogleKey(apiKey string) bool {
+ url := "https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=" + apiKey
+
+ googlePart := GooglePart{
+ Text: "Hello",
+ }
+ // Convert messages to OpenAI format
+ googleMessages := []GoogleRequestMessage{
+ {
+ Role: "user",
+ Parts: []GooglePart{googlePart},
+ },
+ }
+
+ requestBody := GoogleChatCompletionRequest{
+ Messages: googleMessages,
+ }
+
+ jsonBody, err := json.Marshal(requestBody)
+ if err != nil {
+ return false
+ }
+
+ req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonBody))
+ if err != nil {
+ return false
+ }
+
+ req.Header.Set("Content-Type", "application/json")
+
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ return false
+ }
+ defer resp.Body.Close()
+
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return false
+ }
+
+ fmt.Println(string(body))
+
+ var chatCompletionResponse GoogleChatCompletionResponse
+ err = json.Unmarshal(body, &chatCompletionResponse)
+ if err != nil {
+ return false
+ }
+ if chatCompletionResponse.Usage.CompletionTokens == 0 {
+ return false
+ }
+ return true
+}
+
+func RequestGoogle(model string, messages []Message, temperature float64) (OpenaiChatCompletionResponse, error) {
+ var apiKey string
+ err := edgeClient.QuerySingle(edgeCtx, `
+ with
+ filtered_keys := (
+ select Key {
+ key
+ } filter .company.name = $0 AND .$0
+ `, &usedModelInfo, model)
+
+ var inputCost float32 = float32(chatCompletionResponse.Usage.PromptTokens) * usedModelInfo.InputPrice
+ var outputCost float32 = float32(chatCompletionResponse.Usage.CompletionTokens) * usedModelInfo.OutputPrice
+ addUsage(inputCost, outputCost, chatCompletionResponse.Usage.PromptTokens, chatCompletionResponse.Usage.CompletionTokens, model)
+
+ return chatCompletionResponse, nil
+}
diff --git a/RequestGooseai.go b/RequestGooseai.go
new file mode 100644
index 0000000..f0ccb95
--- /dev/null
+++ b/RequestGooseai.go
@@ -0,0 +1,155 @@
+package main
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+
+ "github.com/edgedb/edgedb-go"
+)
+
+type GooseaiCompletionRequest struct {
+ Model string `json:"model"`
+ Prompt []string `json:"prompt"`
+ Temperature float64 `json:"temperature"`
+}
+
+type GooseaiCompletionResponse struct {
+ ID string `json:"id"`
+ Created int64 `json:"created"`
+ Model string `json:"model"`
+ Choices []GooseaiChoice `json:"choices"`
+}
+
+type GooseaiChoice struct {
+ Text string `json:"text"`
+ FinishReason string `json:"finish_reason"`
+ Index int `json:"index"`
+}
+
+func addGooseaiMessage(llm LLM, selected bool) edgedb.UUID {
+ Messages := getAllSelectedMessages()
+
+ chatCompletion, err := RequestGooseai(llm.Model.ModelID, Messages, float64(llm.Temperature))
+ if err != nil {
+ fmt.Println("Error:", err)
+ } else if len(chatCompletion.Choices) == 0 {
+ fmt.Println("No response from GooseAI")
+ id := insertBotMessage("No response from GooseAI", selected, llm.ID)
+ return id
+ } else {
+ Content := chatCompletion.Choices[0].Text
+ id := insertBotMessage(Content, selected, llm.ID)
+ return id
+ }
+ return edgedb.UUID{}
+}
+
+func TestGooseaiKey(apiKey string) bool {
+ url := "https://api.goose.ai/v1/engines/gpt-j-6b/completions"
+
+ requestBody := GooseaiCompletionRequest{
+ Model: "gpt-j-6b",
+ Prompt: []string{"Hello, how are you?"},
+ Temperature: 0,
+ }
+
+ jsonBody, err := json.Marshal(requestBody)
+ if err != nil {
+ return false
+ }
+
+ req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonBody))
+ if err != nil {
+ return false
+ }
+
+ req.Header.Set("Content-Type", "application/json")
+ req.Header.Set("Authorization", "Bearer "+apiKey)
+
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ return false
+ }
+ defer resp.Body.Close()
+
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return false
+ }
+
+ // Print the response body
+ fmt.Println(string(body))
+
+ var chatCompletionResponse GooseaiCompletionResponse
+ err = json.Unmarshal(body, &chatCompletionResponse)
+ if err != nil {
+ return false
+ }
+ if chatCompletionResponse.Choices[0].Text == "" {
+ return false
+ }
+ return true
+}
+
+func RequestGooseai(model string, messages []Message, temperature float64) (GooseaiCompletionResponse, error) {
+ var apiKey string
+ err := edgeClient.QuerySingle(edgeCtx, `
+ with
+ filtered_keys := (
+ select Key {
+ key
+ } filter .company.name = "gooseai" AND .$0
+ } filter .company.name = $0 AND .$0
+ } filter .company.name = $0 AND .$0
+ } filter .company.name = $0 AND .$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("")
- }
-
if !TestOpenaiKey(openaiKey) {
fmt.Println("Invalid OpenAI API Key")
return c.SendString("Invalid OpenAI API Key\n")
}
// Check if the company key already exists
- err = edgeClient.QuerySingle(edgeCtx, `
+ err := edgeClient.QuerySingle(edgeCtx, `
select exists (
select global currentUser.setting.keys
filter .company.name = "openai"
@@ -188,16 +174,18 @@ func addKeys(c *fiber.Ctx) error {
}
} else {
err = edgeClient.Execute(edgeCtx, `
+ WITH
+ c := (SELECT Company FILTER .name = "openai" LIMIT 1)
UPDATE global currentUser.setting
SET {
keys += (
INSERT Key {
- company := $0,
- key := $1,
- name := $2,
+ company := c,
+ key := $0,
+ name := "OpenAI API Key",
}
)
- }`, "openai", openaiKey, "OpenAI API Key")
+ }`, openaiKey)
if err != nil {
fmt.Println("Error in edgedb.QuerySingle: in addOpenaiKey")
fmt.Println(err)
@@ -207,29 +195,13 @@ func addKeys(c *fiber.Ctx) error {
// 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.name = "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 c.SendString("Invalid Anthropic API Key\n")
}
// Check if the company key already exists
- err = edgeClient.QuerySingle(edgeCtx, `
+ err := edgeClient.QuerySingle(edgeCtx, `
select exists (
select global currentUser.setting.keys
filter .company.name = "anthropic"
@@ -253,11 +225,13 @@ func addKeys(c *fiber.Ctx) error {
}
} else {
err = edgeClient.Execute(edgeCtx, `
+ WITH
+ c := (SELECT Company FILTER .name = "anthropic" LIMIT 1)
UPDATE global currentUser.setting
SET {
keys += (
INSERT Key {
- company := "anthropic",
+ company := c,
key := $0,
name := "Anthropic API Key",
}
@@ -272,29 +246,13 @@ func addKeys(c *fiber.Ctx) error {
// Handle Mistral key
if mistralKey != "" {
- // Check if the OpenAI key already exists
- err := edgeClient.QuerySingle(edgeCtx, `
- select exists (
- select global currentUser.setting.keys
- filter .company.name = "mistral" AND .key = $0
- );
- `, &Exists, openaiKey)
- if err != nil {
- fmt.Println("Error in edgedb.QuerySingle: in addMistralKey: ", err)
- return c.SendString("")
- }
- if Exists {
- fmt.Println("Mistral key already exists")
- return c.SendString("")
- }
-
if !TestMistralKey(mistralKey) {
fmt.Println("Invalid Mistral API Key")
return c.SendString("Invalid Mistral API Key\n")
}
// Check if the company key already exists
- err = edgeClient.QuerySingle(edgeCtx, `
+ err := edgeClient.QuerySingle(edgeCtx, `
select exists (
select global currentUser.setting.keys
filter .company.name = "mistral"
@@ -318,11 +276,13 @@ func addKeys(c *fiber.Ctx) error {
}
} else {
err = edgeClient.Execute(edgeCtx, `
+ WITH
+ c := (SELECT Company FILTER .name = "mistral" LIMIT 1)
UPDATE global currentUser.setting
SET {
keys += (
INSERT Key {
- company := "mistral",
+ company := c,
key := $0,
name := "Mistral API Key",
}
@@ -337,29 +297,13 @@ func addKeys(c *fiber.Ctx) error {
// Handle Groq key
if groqKey != "" {
- // Check if the OpenAI key already exists
- err := edgeClient.QuerySingle(edgeCtx, `
- select exists (
- select global currentUser.setting.keys
- filter .company.name = "groq" AND .key = $0
- );
- `, &Exists, openaiKey)
- if err != nil {
- fmt.Println("Error in edgedb.QuerySingle: in addGroqKey: ", err)
- return c.SendString("")
- }
- if Exists {
- fmt.Println("Groq key already exists")
- return c.SendString("")
- }
-
if !TestGroqKey(groqKey) {
fmt.Println("Invalid Groq API Key")
return c.SendString("Invalid Groq API Key\n")
}
// Check if the company key already exists
- err = edgeClient.QuerySingle(edgeCtx, `
+ err := edgeClient.QuerySingle(edgeCtx, `
select exists (
select global currentUser.setting.keys
filter .company.name = "groq"
@@ -383,11 +327,13 @@ func addKeys(c *fiber.Ctx) error {
}
} else {
err = edgeClient.Execute(edgeCtx, `
+ WITH
+ c := (SELECT Company FILTER .name = "groq" LIMIT 1)
UPDATE global currentUser.setting
SET {
keys += (
INSERT Key {
- company := "groq",
+ company := c,
key := $0,
name := "Groq API Key",
}
@@ -400,5 +346,107 @@ func addKeys(c *fiber.Ctx) error {
}
}
+ // Handle Gooseai key
+ if gooseaiKey != "" {
+ if !TestGooseaiKey(gooseaiKey) {
+ fmt.Println("Invalid Gooseai API Key")
+ return c.SendString("Invalid Gooseai API Key\n")
+ }
+
+ // Check if the company key already exists
+ err := edgeClient.QuerySingle(edgeCtx, `
+ select exists (
+ select global currentUser.setting.keys
+ filter .company.name = "gooseai"
+ );
+ `, &Exists)
+ if err != nil {
+ fmt.Println("Error in edgedb.QuerySingle: in addGooseaiKey")
+ fmt.Println(err)
+ }
+
+ if Exists {
+ err = edgeClient.Execute(edgeCtx, `
+ UPDATE Key filter .company.name = "gooseai" AND .key = $0
+ SET {
+ key := $0,
+ }
+ `, gooseaiKey)
+ if err != nil {
+ fmt.Println("Error in edgedb.QuerySingle: in addGooseaiKey")
+ fmt.Println(err)
+ }
+ } else {
+ err = edgeClient.Execute(edgeCtx, `
+ WITH
+ c := (SELECT Company FILTER .name = "gooseai" LIMIT 1)
+ UPDATE global currentUser.setting
+ SET {
+ keys += (
+ INSERT Key {
+ company := c,
+ key := $0,
+ name := "Gooseai API Key",
+ }
+ )
+ }`, gooseaiKey)
+ if err != nil {
+ fmt.Println("Error in edgedb.QuerySingle: in addGooseaiKey")
+ fmt.Println(err)
+ }
+ }
+ }
+
+ // Handle Google key
+ if googleKey != "" {
+ if !TestGoogleKey(googleKey) {
+ fmt.Println("Invalid Google API Key")
+ return c.SendString("Invalid Google API Key\n")
+ }
+
+ // Check if the company key already exists
+ err := edgeClient.QuerySingle(edgeCtx, `
+ select exists (
+ select global currentUser.setting.keys
+ filter .company.name = "google"
+ );
+ `, &Exists)
+ if err != nil {
+ fmt.Println("Error in edgedb.QuerySingle: in addGoogleKey")
+ fmt.Println(err)
+ }
+
+ if Exists {
+ err = edgeClient.Execute(edgeCtx, `
+ UPDATE Key filter .company.name = "google" AND .key = $0
+ SET {
+ key := $0,
+ }
+ `, googleKey)
+ if err != nil {
+ fmt.Println("Error in edgedb.QuerySingle: in addGoogleKey")
+ fmt.Println(err)
+ }
+ } else {
+ err = edgeClient.Execute(edgeCtx, `
+ WITH
+ c := (SELECT Company FILTER .name = "google" LIMIT 1)
+ UPDATE global currentUser.setting
+ SET {
+ keys += (
+ INSERT Key {
+ company := c,
+ key := $0,
+ name := "Google API Key",
+ }
+ )
+ }`, googleKey)
+ if err != nil {
+ fmt.Println("Error in edgedb.QuerySingle: in addGoogleKey")
+ fmt.Println(err)
+ }
+ }
+ }
+
return c.SendString("")
}
diff --git a/static/icons/azure.png b/static/icons/azure.png
new file mode 100644
index 0000000..06ef419
Binary files /dev/null and b/static/icons/azure.png differ
diff --git a/static/icons/gemini.png b/static/icons/gemini.png
new file mode 100644
index 0000000..63f11cd
Binary files /dev/null and b/static/icons/gemini.png differ
diff --git a/static/icons/gooseai.png b/static/icons/gooseai.png
new file mode 100644
index 0000000..e45c996
Binary files /dev/null and b/static/icons/gooseai.png differ
diff --git a/static/icons/groq.png b/static/icons/groq.png
index c3c5165..64baa83 100644
Binary files a/static/icons/groq.png and b/static/icons/groq.png differ
diff --git a/utils.go b/utils.go
index c8d596c..671d149 100644
--- a/utils.go
+++ b/utils.go
@@ -38,15 +38,19 @@ func addCopyButtonsToCode(htmlContent string) string {
return updatedHTML
}
-func getExistingKeys() (bool, bool, bool, bool) {
+func getExistingKeys() (bool, bool, bool, bool, bool, bool) {
if edgeClient == nil {
- return false, false, false, false
+ return false, false, false, false, false, false
}
- var openaiExists bool
- var anthropicExists bool
- var mistralExists bool
- var groqExists bool
+ var (
+ openaiExists bool
+ anthropicExists bool
+ mistralExists bool
+ groqExists bool
+ gooseaiExists bool
+ googleExists bool
+ )
err := edgeClient.QuerySingle(edgeCtx, `
select exists (
@@ -93,7 +97,29 @@ func getExistingKeys() (bool, bool, bool, bool) {
panic(err)
}
- return openaiExists, anthropicExists, mistralExists, groqExists
+ err = edgeClient.QuerySingle(edgeCtx, `
+ select exists (
+ select global currentUser.setting.keys
+ filter .company.name = "gooseai"
+ );
+ `, &gooseaiExists)
+ if err != nil {
+ fmt.Println("Error in edgedb.QuerySingle checking for gooseai: ", err)
+ panic(err)
+ }
+
+ err = edgeClient.QuerySingle(edgeCtx, `
+ select exists (
+ select global currentUser.setting.keys
+ filter .company.name = "google"
+ );
+ `, &googleExists)
+ if err != nil {
+ fmt.Println("Error in edgedb.QuerySingle checking for google: ", err)
+ panic(err)
+ }
+
+ return openaiExists, anthropicExists, mistralExists, groqExists, gooseaiExists, googleExists
}
func Message2RequestMessage(messages []Message) []RequestMessage {
diff --git a/views/partials/popover-keys.html b/views/partials/popover-keys.html
index e439391..e08f1c7 100644
--- a/views/partials/popover-keys.html
+++ b/views/partials/popover-keys.html
@@ -40,6 +40,25 @@
+
+