This commit is contained in:
Adrien Bouvais 2024-06-01 13:49:50 +02:00
parent 3a325efcbf
commit fceaaef732
18 changed files with 253 additions and 230 deletions

114
Chat.go
View File

@ -15,20 +15,12 @@ import (
) )
func ChatPageHandler(c *fiber.Ctx) error { func ChatPageHandler(c *fiber.Ctx) error {
var ( fmt.Println("Cookies: ", c.Cookies("jade-edgedb-auth-token"))
isSub bool if c.Cookies("jade-edgedb-auth-token") == "" {
limitReach bool
)
if c.Cookies("jade-edgedb-auth-token", "") == "" {
fmt.Println("Not logged in")
isSub = false
limitReach = false
return c.Render("chat", fiber.Map{"IsLogin": false, "HaveKey": false, "IsSubscribed": false, "IsLimiteReached": false}, "layouts/main") return c.Render("chat", fiber.Map{"IsLogin": false, "HaveKey": false, "IsSubscribed": false, "IsLimiteReached": false}, "layouts/main")
} else { } else {
isSub = IsCurrentUserSubscribed(c) fmt.Println("Here")
limitReach = IsCurrentUserLimiteReached(c) return c.Render("chat", fiber.Map{"IsLogin": checkIfLogin(c), "HaveKey": checkIfHaveKey(c), "IsSubscribed": IsCurrentUserSubscribed(c), "IsLimiteReached": IsCurrentUserLimiteReached(c)}, "layouts/main")
return c.Render("chat", fiber.Map{"IsLogin": checkIfLogin(c), "HaveKey": checkIfHaveKey(c), "IsSubscribed": isSub, "IsLimiteReached": limitReach}, "layouts/main")
} }
} }
@ -42,7 +34,7 @@ func DeleteMessageHandler(c *fiber.Ctx) error {
} }
// Delete all messages // Delete all messages
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
WITH WITH
messageArea := (SELECT Message FILTER .id = <uuid>$0).area messageArea := (SELECT Message FILTER .id = <uuid>$0).area
DELETE Area DELETE Area
@ -71,6 +63,24 @@ func LoadChatHandler(c *fiber.Ctx) error {
} }
} }
func LoadChatInputHandler(c *fiber.Ctx) error {
if c.Cookies("jade-edgedb-auth-token") == "" {
out, err := chatInputTmpl.Execute(pongo2.Context{"IsLogin": false, "HaveKey": false, "IsSubscribed": false, "IsLimiteReached": false})
if err != nil {
fmt.Println("Error executing chat input template")
panic(err)
}
return c.SendString(out)
} else {
out, err := chatInputTmpl.Execute(pongo2.Context{"IsLogin": checkIfLogin(c), "HaveKey": checkIfHaveKey(c), "IsSubscribed": IsCurrentUserSubscribed(c), "IsLimiteReached": IsCurrentUserLimiteReached(c)})
if err != nil {
fmt.Println("Error executing chat input template")
panic(err)
}
return c.SendString(out)
}
}
type TemplateMessage struct { type TemplateMessage struct {
Icon string Icon string
Content string Content string
@ -84,7 +94,7 @@ type TemplateMessage struct {
func generateChatHTML(c *fiber.Ctx) string { func generateChatHTML(c *fiber.Ctx) string {
// Println the name of the current conversation // Println the name of the current conversation
var currentConv Conversation var currentConv Conversation
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
SELECT global currentConversation { name }`, &currentConv) SELECT global currentConversation { name }`, &currentConv)
if err != nil { if err != nil {
fmt.Println("Error getting current conversation") fmt.Println("Error getting current conversation")
@ -95,7 +105,7 @@ func generateChatHTML(c *fiber.Ctx) string {
// Maybe redo that to be area by area because look like shit rn. It come from early stage of dev. It work tho soooo... // Maybe redo that to be area by area because look like shit rn. It come from early stage of dev. It work tho soooo...
var Messages []Message var Messages []Message
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Query(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Query(edgeCtx, `
SELECT Message { SELECT Message {
id, id,
selected, selected,
@ -184,7 +194,7 @@ func GetUserMessageHandler(c *fiber.Ctx) error {
messageUUID, _ := edgedb.ParseUUID(id) messageUUID, _ := edgedb.ParseUUID(id)
var selectedMessage Message var selectedMessage Message
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(context.Background(), ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(context.Background(), `
SELECT Message { SELECT Message {
content content
} }
@ -212,7 +222,7 @@ func GetMessageContentHandler(c *fiber.Ctx) error {
messageUUID, _ := edgedb.ParseUUID(messageId) messageUUID, _ := edgedb.ParseUUID(messageId)
var selectedMessage Message var selectedMessage Message
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(context.Background(), ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(context.Background(), `
SELECT Message { SELECT Message {
content, content,
llm : { llm : {
@ -246,7 +256,7 @@ func GetMessageContentHandler(c *fiber.Ctx) error {
out += "</div>" out += "</div>"
// Update the selected value of messages in the database // Update the selected value of messages in the database
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
WITH m := (SELECT Message FILTER .id = <uuid>$0) WITH m := (SELECT Message FILTER .id = <uuid>$0)
UPDATE Message UPDATE Message
FILTER .area = m.area FILTER .area = m.area
@ -256,7 +266,7 @@ func GetMessageContentHandler(c *fiber.Ctx) error {
panic(err) panic(err)
} }
_ = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` _ = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
UPDATE Message UPDATE Message
FILTER .id = <uuid>$0 FILTER .id = <uuid>$0
SET {selected := true}; SET {selected := true};
@ -266,22 +276,18 @@ func GetMessageContentHandler(c *fiber.Ctx) error {
} }
func generateWelcomeChatHTML() string { func generateWelcomeChatHTML() string {
welcomeMessage := ` welcomeMessage, err := welcomeChatTmpl.Execute(pongo2.Context{})
No fancy stuff, easy to use, pay as you use, multi-models, work on low 3g... if err != nil {
fmt.Println("Error executing welcome chat template")
To start using JADE, please login.` panic(err)
}
loginButton := `
<a class="button is-primary is-small" href="/signin">
Log in
</a>`
htmlString := "<div class='columns is-centered' id='chat-container'><div class='column is-12-mobile is-8-tablet is-6-desktop' id='chat-messages'>" htmlString := "<div class='columns is-centered' id='chat-container'><div class='column is-12-mobile is-8-tablet is-6-desktop' id='chat-messages'>"
NextMessages := []TemplateMessage{} NextMessages := []TemplateMessage{}
nextMsg := TemplateMessage{ nextMsg := TemplateMessage{
Icon: "icons/bouvai2.png", // Assuming Icon is a field you want to include from Message Icon: "icons/bouvai2.png", // Assuming Icon is a field you want to include from Message
Content: "<br>" + welcomeMessage + loginButton, Content: "<br>" + welcomeMessage,
Hidden: false, // Assuming Hidden is a field you want to include from Message Hidden: false, // Assuming Hidden is a field you want to include from Message
Id: "0", Id: "0",
Name: "JADE", Name: "JADE",
@ -304,14 +310,14 @@ func generateWelcomeChatHTML() string {
func generateEnterKeyChatHTML() string { func generateEnterKeyChatHTML() string {
welcomeMessage := ` welcomeMessage := `
<p class="mt-2">JADE require at least one API key to work. Add one in the settings at the bottom right of the page.</p> <p class="mt-2">JADE require at least one API key to work. Add one in the settings at the bottom right of the page.</p>
<p>API keys are unique codes that allow you to access and use the services provided by different Large Language Model (LLM) providers. When you sign up for an account with a provider like OpenAI, Anthropic, Groq, or MistralAI, you'll receive an API key that you can use to make requests to their LLMs.</p> <p>API keys are unique codes that allow you to access and use different Large Language Model (LLM) providers.</p>
<p>Most providers offer free credits when you first sign up, which means you have a balance in your account that you can use to generate messages. You pay for the service based on the number of tokens generated. A token is a small unit of text, roughly equivalent to 3 characters. So, a small input and output text will cost very little.</p> <p>Most providers offer free credits when you first sign up or per month, which means you have a balance in your account that you can use to generate messages.</p>
<p>To get an idea of how many tokens your text contains, you can use a tokenizer like the one provided by OpenAI: <a href="https://platform.openai.com/tokenizer" target="_blank">https://platform.openai.com/tokenizer</a>. Keep in mind that different models may have slightly different tokenizers.</p> <p><strong>You pay for the service based on the number of tokens input and generated.</strong> A token is a small unit of text, roughly equivalent to 3 characters. So, a small input and output text will cost very little.</p>
<h2>Pricing Examples</h2> <h2>Pricing Examples</h2>
<ul> <ul>
<li>Tou can ask 2,000 small questions for just $1 to GPT-4o, or 20,000 to GPT-3.5 turbo.</li> <li>For $1, you can ask 2,000 questions to GPT-4o, or 20,000 to GPT-3.5 turbo (around 100 tokens per message).</li>
<li>If you ask a small question that is around 100 tokens (approximately 300 characters), and the price is $5 per 1 million tokens (GPT-4o), it would cost you $0.0005.</li> <li>For 1 message it would cost you $0.0005 for GPT-4o or $0.00005 for GPT-3.5 turbo (around 100 tokens per message).</li>
<li>For a larger text, like a PDF file with 30,000 characters (roughly 10,000 tokens), you would pay around $0.05 per message.</li> <li>For 1 large text, like a PDF with 30,000 characters (60-120 pages), you would pay around $0.05 per message for GPT-4o or $0.005 for GPT-3.5 turbo.</li>
</ul> </ul>
<p>Remember, prices and token limits may vary depending on the provider and the specific LLM you're using.</p> <p>Remember, prices and token limits may vary depending on the provider and the specific LLM you're using.</p>
<h2>Learn More</h2> <h2>Learn More</h2>
@ -387,12 +393,12 @@ func generateTermAndServiceChatHTML() string {
<p>We reserve the right to modify these Terms at any time. Any changes will be effective immediately upon posting the updated Terms on our website or within the App. Your continued use of the App after any such changes constitutes your acceptance of the new Terms.</p> <p>We reserve the right to modify these Terms at any time. Any changes will be effective immediately upon posting the updated Terms on our website or within the App. Your continued use of the App after any such changes constitutes your acceptance of the new Terms.</p>
<h2>9. Governing Law</h2> <h2>9. Governing Law</h2>
<p>These Terms shall be governed and construed in accordance with the laws of [Your Country/State], without regard to its conflict of law principles.</p> <p>These Terms shall be governed and construed in accordance with the laws of Luxembourg, without regard to its conflict of law principles.</p>
<h2>10. Contact Information</h2> <h2>10. Contact Information</h2>
<p>If you have any questions about these Terms, please contact us at adrien.bouvais.pro@gmail.com.</p> <p>If you have any questions about these Terms, please contact us at adrien.bouvais.pro@gmail.com.</p>
<p>**BouvAI**</p> <strong>BouvAI</strong>
` `
closeBtn := ` closeBtn := `
@ -434,7 +440,7 @@ func generateLimitReachedChatHTML(c *fiber.Ctx) string {
welcomeMessage := `You have reached the maximum number of messages for a free account. Please upgrade your account to continue using JADE.` welcomeMessage := `You have reached the maximum number of messages for a free account. Please upgrade your account to continue using JADE.`
var result User var result User
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, "SELECT global currentUser { stripe_id, email } LIMIT 1;", &result) err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, "SELECT global currentUser { stripe_id, email } LIMIT 1;", &result)
if err != nil { if err != nil {
fmt.Println("Error getting current user") fmt.Println("Error getting current user")
panic(err) panic(err)
@ -481,7 +487,7 @@ func GetEditMessageFormHandler(c *fiber.Ctx) error {
idUUID, _ := edgedb.ParseUUID(id) idUUID, _ := edgedb.ParseUUID(id)
var message Message var message Message
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(context.Background(), ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(context.Background(), `
SELECT Message { content } SELECT Message { content }
FILTER .id = <uuid>$0; FILTER .id = <uuid>$0;
`, &message, idUUID) `, &message, idUUID)
@ -516,7 +522,7 @@ func RedoMessageHandler(c *fiber.Ctx) error {
} }
var message Message var message Message
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(context.Background(), ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(context.Background(), `
SELECT Message { content } SELECT Message { content }
FILTER .id = <uuid>$0; FILTER .id = <uuid>$0;
`, &message, messageUUID) `, &message, messageUUID)
@ -526,7 +532,7 @@ func RedoMessageHandler(c *fiber.Ctx) error {
} }
// Delete messages // Delete messages
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
WITH WITH
messageArea := (SELECT Message FILTER .id = <uuid>$0).area messageArea := (SELECT Message FILTER .id = <uuid>$0).area
DELETE Area DELETE Area
@ -557,7 +563,7 @@ func EditMessageHandler(c *fiber.Ctx) error {
} }
// Delete messages // Delete messages
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
WITH WITH
messageArea := (SELECT Message FILTER .id = <uuid>$0).area messageArea := (SELECT Message FILTER .id = <uuid>$0).area
DELETE Area DELETE Area
@ -573,7 +579,7 @@ func EditMessageHandler(c *fiber.Ctx) error {
func ClearChatHandler(c *fiber.Ctx) error { func ClearChatHandler(c *fiber.Ctx) error {
// Delete the default conversation // Delete the default conversation
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
DELETE Area DELETE Area
FILTER .conversation = global currentConversation; FILTER .conversation = global currentConversation;
`) `)
@ -619,7 +625,7 @@ func LoadUsageKPIHandler(c *fiber.Ctx) error {
} }
var usages []UsageKPI var usages []UsageKPI
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Query(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Query(edgeCtx, `
WITH WITH
U := ( U := (
SELECT Usage SELECT Usage
@ -674,7 +680,7 @@ func GenerateModelPopoverHTML(refresh bool, c *fiber.Ctx) string {
openaiExists, anthropicExists, mistralExists, groqExists, gooseaiExists, googleExists := getExistingKeys(c) openaiExists, anthropicExists, mistralExists, groqExists, gooseaiExists, googleExists := getExistingKeys(c)
var llms []LLM var llms []LLM
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Query(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Query(edgeCtx, `
SELECT LLM { SELECT LLM {
id, id,
name, name,
@ -729,7 +735,7 @@ func LoadModelSelectionHandler(c *fiber.Ctx) error {
func GenerateConversationPopoverHTML(isActive bool, c *fiber.Ctx) string { func GenerateConversationPopoverHTML(isActive bool, c *fiber.Ctx) string {
var conversations []Conversation var conversations []Conversation
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Query(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Query(edgeCtx, `
SELECT Conversation { SELECT Conversation {
name, name,
position, position,
@ -782,7 +788,7 @@ func LoadSettingsHandler(c *fiber.Ctx) error {
} }
var user User var user User
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
SELECT User { SELECT User {
email email
} }
@ -825,7 +831,7 @@ func CreateConversationHandler(c *fiber.Ctx) error {
name = "New Conversation" name = "New Conversation"
} }
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
WITH WITH
C := ( C := (
SELECT Conversation SELECT Conversation
@ -854,7 +860,7 @@ func DeleteConversationHandler(c *fiber.Ctx) error {
panic(err) panic(err)
} }
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
DELETE Conversation DELETE Conversation
FILTER .user = global currentUser AND .id = <uuid>$0; FILTER .user = global currentUser AND .id = <uuid>$0;
`, conversationUUID) `, conversationUUID)
@ -864,7 +870,7 @@ func DeleteConversationHandler(c *fiber.Ctx) error {
} }
// Select the default conversation // Select the default conversation
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
UPDATE Conversation UPDATE Conversation
FILTER .user = global currentUser AND .name = 'Default' FILTER .user = global currentUser AND .name = 'Default'
SET { SET {
@ -891,7 +897,7 @@ func SelectConversationHandler(c *fiber.Ctx) error {
panic(err) panic(err)
} }
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
UPDATE Conversation UPDATE Conversation
FILTER .user = global currentUser FILTER .user = global currentUser
SET { SET {
@ -903,7 +909,7 @@ func SelectConversationHandler(c *fiber.Ctx) error {
panic(err) panic(err)
} }
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
UPDATE Conversation UPDATE Conversation
FILTER .user = global currentUser AND .id = <uuid>$0 FILTER .user = global currentUser AND .id = <uuid>$0
SET { SET {
@ -921,7 +927,7 @@ func SelectConversationHandler(c *fiber.Ctx) error {
func ArchiveDefaultConversationHandler(c *fiber.Ctx) error { func ArchiveDefaultConversationHandler(c *fiber.Ctx) error {
name := c.FormValue("conversation-name-input") name := c.FormValue("conversation-name-input")
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
UPDATE Conversation UPDATE Conversation
FILTER .user = global currentUser AND .name = 'Default' FILTER .user = global currentUser AND .name = 'Default'
SET { SET {
@ -933,7 +939,7 @@ func ArchiveDefaultConversationHandler(c *fiber.Ctx) error {
panic(err) panic(err)
} }
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
WITH WITH
C := ( C := (
SELECT Conversation SELECT Conversation

12
LLM.go
View File

@ -20,7 +20,7 @@ func deleteLLM(c *fiber.Ctx) error {
for _, id := range selectedLLMIds { for _, id := range selectedLLMIds {
idUUID, _ := edgedb.ParseUUID(id) idUUID, _ := edgedb.ParseUUID(id)
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
UPDATE LLM UPDATE LLM
FILTER .id = <uuid>$0 AND .user = global currentUser FILTER .id = <uuid>$0 AND .user = global currentUser
SET { SET {
@ -39,7 +39,7 @@ func deleteLLM(c *fiber.Ctx) error {
} }
func deleteLLMtoDelete(c *fiber.Ctx) { func deleteLLMtoDelete(c *fiber.Ctx) {
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
delete LLM delete LLM
filter .to_delete = true and not exists( filter .to_delete = true and not exists(
select Message filter .llm = LLM select Message filter .llm = LLM
@ -63,7 +63,7 @@ func createLLM(c *fiber.Ctx) error {
customID := c.FormValue("model-cid-input") customID := c.FormValue("model-cid-input")
if modelID == "custom" { if modelID == "custom" {
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
WITH WITH
countLLM := count((SELECT LLM FILTER .user = global currentUser)) countLLM := count((SELECT LLM FILTER .user = global currentUser))
INSERT LLM { INSERT LLM {
@ -91,7 +91,7 @@ func createLLM(c *fiber.Ctx) error {
panic(err) panic(err)
} }
} else { } else {
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
WITH WITH
countLLM := count((SELECT LLM FILTER .user = global currentUser)) countLLM := count((SELECT LLM FILTER .user = global currentUser))
INSERT LLM { INSERT LLM {
@ -130,7 +130,7 @@ func updateLLMPositionBatch(c *fiber.Ctx) error {
panic(err) panic(err)
} }
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
UPDATE LLM UPDATE LLM
FILTER .id = <uuid>$0 AND .user = global currentUser FILTER .id = <uuid>$0 AND .user = global currentUser
SET { SET {
@ -161,7 +161,7 @@ func updateConversationPositionBatch(c *fiber.Ctx) error {
panic(err) panic(err)
} }
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
UPDATE Conversation UPDATE Conversation
FILTER .id = <uuid>$0 AND .user = global currentUser FILTER .id = <uuid>$0 AND .user = global currentUser
SET { SET {

View File

@ -50,7 +50,7 @@ func GeneratePlaceholderHTML(c *fiber.Ctx, message string, selectedLLMIds []stri
for _, id := range selectedLLMIds { for _, id := range selectedLLMIds {
idUUID, _ := edgedb.ParseUUID(id) idUUID, _ := edgedb.ParseUUID(id)
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(context.Background(), ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(context.Background(), `
SELECT LLM { SELECT LLM {
id, id,
name, name,
@ -145,7 +145,7 @@ func GenerateMultipleMessagesHandler(c *fiber.Ctx) error {
} }
var message Message var message Message
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
SELECT Message { SELECT Message {
id, id,
content, content,
@ -249,7 +249,7 @@ func GenerateMultipleMessagesHandler(c *fiber.Ctx) error {
func addUsage(c *fiber.Ctx, inputCost float32, outputCost float32, inputToken int32, outputToken int32, modelID string) { func addUsage(c *fiber.Ctx, inputCost float32, outputCost float32, inputToken int32, outputToken int32, modelID string) {
// Create a new usage // Create a new usage
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
INSERT Usage { INSERT Usage {
input_cost := <float32>$0, input_cost := <float32>$0,
output_cost := <float32>$1, output_cost := <float32>$1,

View File

@ -113,7 +113,7 @@ func RequestAnthropic(c *fiber.Ctx, model string, messages []Message, maxTokens
var apiKey struct { var apiKey struct {
Key string `edgedb:"key"` Key string `edgedb:"key"`
} }
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
SELECT Key { SELECT Key {
key key
} }
@ -167,7 +167,7 @@ func RequestAnthropic(c *fiber.Ctx, model string, messages []Message, maxTokens
} }
var usedModelInfo ModelInfo var usedModelInfo ModelInfo
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
SELECT ModelInfo { SELECT ModelInfo {
inputPrice, inputPrice,
outputPrice outputPrice

View File

@ -133,7 +133,7 @@ func TestGoogleKey(apiKey string) bool {
func RequestGoogle(c *fiber.Ctx, model string, messages []Message, temperature float64, context string) (GoogleChatCompletionResponse, error) { func RequestGoogle(c *fiber.Ctx, model string, messages []Message, temperature float64, context string) (GoogleChatCompletionResponse, error) {
var apiKey string var apiKey string
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
with with
filtered_keys := ( filtered_keys := (
select Key { select Key {
@ -199,7 +199,7 @@ func RequestGoogle(c *fiber.Ctx, model string, messages []Message, temperature f
} }
var usedModelInfo ModelInfo var usedModelInfo ModelInfo
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
SELECT ModelInfo { SELECT ModelInfo {
inputPrice, inputPrice,
outputPrice outputPrice

View File

@ -100,7 +100,7 @@ func TestGooseaiKey(apiKey string) bool {
func RequestGooseai(c *fiber.Ctx, model string, messages []Message, temperature float64) (GooseaiCompletionResponse, error) { func RequestGooseai(c *fiber.Ctx, model string, messages []Message, temperature float64) (GooseaiCompletionResponse, error) {
var apiKey string var apiKey string
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
with with
filtered_keys := ( filtered_keys := (
select Key { select Key {

View File

@ -111,7 +111,7 @@ func TestGroqKey(apiKey string) bool {
func RequestGroq(c *fiber.Ctx, model string, messages []Message, temperature float64, context string) (GroqChatCompletionResponse, error) { func RequestGroq(c *fiber.Ctx, model string, messages []Message, temperature float64, context string) (GroqChatCompletionResponse, error) {
var apiKey string var apiKey string
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
with with
filtered_keys := ( filtered_keys := (
select Key { select Key {
@ -164,7 +164,7 @@ func RequestGroq(c *fiber.Ctx, model string, messages []Message, temperature flo
} }
var usedModelInfo ModelInfo var usedModelInfo ModelInfo
edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
SELECT ModelInfo { SELECT ModelInfo {
inputPrice, inputPrice,
outputPrice outputPrice

View File

@ -116,7 +116,7 @@ func TestMistralKey(apiKey string) bool {
func RequestMistral(c *fiber.Ctx, model string, messages []Message, temperature float64, context string) (MistralChatCompletionResponse, error) { func RequestMistral(c *fiber.Ctx, model string, messages []Message, temperature float64, context string) (MistralChatCompletionResponse, error) {
var apiKey string var apiKey string
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
with with
filtered_keys := ( filtered_keys := (
select Key { select Key {
@ -170,7 +170,7 @@ func RequestMistral(c *fiber.Ctx, model string, messages []Message, temperature
} }
var usedModelInfo ModelInfo var usedModelInfo ModelInfo
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
SELECT ModelInfo { SELECT ModelInfo {
inputPrice, inputPrice,
outputPrice outputPrice

View File

@ -111,7 +111,7 @@ func TestOpenaiKey(apiKey string) bool {
func RequestOpenai(c *fiber.Ctx, model string, messages []Message, temperature float64, context string) (OpenaiChatCompletionResponse, error) { func RequestOpenai(c *fiber.Ctx, model string, messages []Message, temperature float64, context string) (OpenaiChatCompletionResponse, error) {
var apiKey string var apiKey string
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
with with
filtered_keys := ( filtered_keys := (
select Key { select Key {
@ -164,7 +164,7 @@ func RequestOpenai(c *fiber.Ctx, model string, messages []Message, temperature f
} }
var usedModelInfo ModelInfo var usedModelInfo ModelInfo
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
SELECT ModelInfo { SELECT ModelInfo {
inputPrice, inputPrice,
outputPrice outputPrice

View File

@ -20,7 +20,7 @@ func PricingTableHandler(c *fiber.Ctx) error {
func generatePricingTableChatHTML(c *fiber.Ctx) string { func generatePricingTableChatHTML(c *fiber.Ctx) string {
var result User var result User
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, "SELECT global currentUser { stripe_id, email } LIMIT 1;", &result) err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, "SELECT global currentUser { stripe_id, email } LIMIT 1;", &result)
if err != nil { if err != nil {
fmt.Println("Error getting user") fmt.Println("Error getting user")
panic(err) panic(err)
@ -85,7 +85,7 @@ func CreateNewStripeCustomer(name string, email string) string {
func IsCurrentUserSubscribed(c *fiber.Ctx) bool { func IsCurrentUserSubscribed(c *fiber.Ctx) bool {
var user User var user User
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, "SELECT global currentUser { stripe_id } LIMIT 1;", &user) err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, "SELECT global currentUser { stripe_id } LIMIT 1;", &user)
if err != nil { if err != nil {
fmt.Println("Error getting user") fmt.Println("Error getting user")
panic(err) panic(err)
@ -105,7 +105,7 @@ func IsCurrentUserSubscribed(c *fiber.Ctx) bool {
func IsCurrentUserLimiteReached(c *fiber.Ctx) bool { func IsCurrentUserLimiteReached(c *fiber.Ctx) bool {
// Count the number of Usage for the current user // Count the number of Usage for the current user
var count int64 var count int64
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
WITH WITH
U := ( U := (
SELECT Usage SELECT Usage
@ -122,7 +122,7 @@ func IsCurrentUserLimiteReached(c *fiber.Ctx) bool {
func CreateClientSecretSession(c *fiber.Ctx) string { func CreateClientSecretSession(c *fiber.Ctx) string {
var user User var user User
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, "SELECT global currentUser { stripe_id } LIMIT 1;", &user) err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, "SELECT global currentUser { stripe_id } LIMIT 1;", &user)
if err != nil { if err != nil {
fmt.Println("Error getting user") fmt.Println("Error getting user")
panic(err) panic(err)

View File

@ -133,13 +133,13 @@ func init() {
} }
func checkIfLogin(c *fiber.Ctx) bool { func checkIfLogin(c *fiber.Ctx) bool {
return c.Cookies("jade-edgedb-auth-token", "") != "" return c.Cookies("jade-edgedb-auth-token") != "" && c.Cookies("jade-edgedb-auth-token") != "null"
} }
func insertArea(c *fiber.Ctx) (edgedb.UUID, int64) { func insertArea(c *fiber.Ctx) (edgedb.UUID, int64) {
// Insert a new area. // Insert a new area.
var inserted struct{ id edgedb.UUID } var inserted struct{ id edgedb.UUID }
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
WITH WITH
positionVar := count((SELECT Area FILTER .conversation = global currentConversation)) + 1 positionVar := count((SELECT Area FILTER .conversation = global currentConversation)) + 1
INSERT Area { INSERT Area {
@ -153,7 +153,7 @@ func insertArea(c *fiber.Ctx) (edgedb.UUID, int64) {
} }
var positionSet struct{ position int64 } var positionSet struct{ position int64 }
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
SELECT Area { SELECT Area {
position, position,
} }
@ -171,7 +171,7 @@ func insertArea(c *fiber.Ctx) (edgedb.UUID, int64) {
func insertUserMessage(c *fiber.Ctx, content string) edgedb.UUID { func insertUserMessage(c *fiber.Ctx, content string) edgedb.UUID {
// Insert a new user. // Insert a new user.
var lastArea Area var lastArea Area
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
SELECT Area { SELECT Area {
id id
} }
@ -185,7 +185,7 @@ func insertUserMessage(c *fiber.Ctx, content string) edgedb.UUID {
} }
var inserted struct{ id edgedb.UUID } // TODO: Maybe remove that hard code LLM var inserted struct{ id edgedb.UUID } // TODO: Maybe remove that hard code LLM
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
INSERT Message { INSERT Message {
role := <str>$0, role := <str>$0,
content := <str>$1, content := <str>$1,
@ -209,7 +209,7 @@ func insertUserMessage(c *fiber.Ctx, content string) edgedb.UUID {
func insertBotMessage(c *fiber.Ctx, content string, selected bool, llmUUID edgedb.UUID) edgedb.UUID { func insertBotMessage(c *fiber.Ctx, content string, selected bool, llmUUID edgedb.UUID) edgedb.UUID {
var lastArea Area var lastArea Area
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
SELECT Area { SELECT Area {
id id
} }
@ -223,7 +223,7 @@ func insertBotMessage(c *fiber.Ctx, content string, selected bool, llmUUID edged
} }
var inserted struct{ id edgedb.UUID } var inserted struct{ id edgedb.UUID }
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
INSERT Message { INSERT Message {
role := <str>$0, role := <str>$0,
content := <str>$2, content := <str>$2,
@ -260,7 +260,7 @@ func getAllSelectedMessages(c *fiber.Ctx) []Message {
var messages []Message var messages []Message
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Query(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Query(edgeCtx, `
SELECT Message { SELECT Message {
id, id,
selected, selected,
@ -288,7 +288,7 @@ func getAllSelectedMessages(c *fiber.Ctx) []Message {
func checkIfHaveKey(c *fiber.Ctx) bool { func checkIfHaveKey(c *fiber.Ctx) bool {
var keys []Key var keys []Key
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Query(edgeCtx, "SELECT global currentUser.setting.keys", &keys) err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Query(edgeCtx, "SELECT global currentUser.setting.keys", &keys)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@ -210,7 +210,7 @@ func handleCallbackSignup(c *fiber.Ctx) error {
fmt.Println("Error parsing UUID") fmt.Println("Error parsing UUID")
panic(err) panic(err)
} }
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
SELECT ext::auth::Identity { SELECT ext::auth::Identity {
issuer issuer
} FILTER .id = <uuid>$0 } FILTER .id = <uuid>$0
@ -235,7 +235,7 @@ func handleCallbackSignup(c *fiber.Ctx) error {
stripCustID := CreateNewStripeCustomer(providerName, providerEmail) stripCustID := CreateNewStripeCustomer(providerName, providerEmail)
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
INSERT User { INSERT User {
stripe_id := <str>$0, stripe_id := <str>$0,
email := <str>$1, email := <str>$1,

52
main.go
View File

@ -24,6 +24,8 @@ var (
settingPopoverTmpl *pongo2.Template settingPopoverTmpl *pongo2.Template
messageEditTmpl *pongo2.Template messageEditTmpl *pongo2.Template
conversationPopoverTmpl *pongo2.Template conversationPopoverTmpl *pongo2.Template
welcomeChatTmpl *pongo2.Template
chatInputTmpl *pongo2.Template
clients = make(map[chan SSE]bool) clients = make(map[chan SSE]bool)
mu sync.Mutex mu sync.Mutex
) )
@ -56,15 +58,16 @@ func main() {
usagePopoverTmpl = pongo2.Must(pongo2.FromFile("views/partials/popover-usage.html")) usagePopoverTmpl = pongo2.Must(pongo2.FromFile("views/partials/popover-usage.html"))
settingPopoverTmpl = pongo2.Must(pongo2.FromFile("views/partials/popover-settings.html")) settingPopoverTmpl = pongo2.Must(pongo2.FromFile("views/partials/popover-settings.html"))
messageEditTmpl = pongo2.Must(pongo2.FromFile("views/partials/message-edit-form.html")) messageEditTmpl = pongo2.Must(pongo2.FromFile("views/partials/message-edit-form.html"))
welcomeChatTmpl = pongo2.Must(pongo2.FromFile("views/partials/welcome-chat.html"))
chatInputTmpl = pongo2.Must(pongo2.FromFile("views/partials/chat-input.html"))
// Import HTML using django engine/template // Import HTML using django engine/template
engine := django.New("./views", ".html") engine := django.New("./views", ".html")
// Create new Fiber instance // Create new Fiber instance
app := fiber.New(fiber.Config{ app := fiber.New(fiber.Config{
Views: engine, Views: engine,
AppName: "JADE", AppName: "JADE",
EnablePrintRoutes: true,
}) })
defer app.Shutdown() defer app.Shutdown()
@ -72,12 +75,10 @@ func main() {
app.Use(logger.New()) app.Use(logger.New())
app.Use(recover.New()) app.Use(recover.New())
// Add static files
app.Static("/", "./static")
// Main routes // Main routes
app.Get("/", ChatPageHandler) app.Get("/", ChatPageHandler)
app.Get("/loadChat", LoadChatHandler) app.Get("/loadChat", LoadChatHandler)
app.Get("/loadChatInput", LoadChatInputHandler)
app.Get("/pricingTable", PricingTableHandler) app.Get("/pricingTable", PricingTableHandler)
app.Get("/generateTermAndService", generateTermAndServiceHandler) app.Get("/generateTermAndService", generateTermAndServiceHandler)
@ -118,6 +119,9 @@ func main() {
app.Get("deleteLLM", deleteLLM) app.Get("deleteLLM", deleteLLM)
app.Post("/createLLM", createLLM) app.Post("/createLLM", createLLM)
// Add static files
app.Static("/", "./static")
app.Get("/empty", func(c *fiber.Ctx) error { app.Get("/empty", func(c *fiber.Ctx) error {
return c.SendString("") return c.SendString("")
}) })
@ -183,7 +187,7 @@ func addKeys(c *fiber.Ctx) error {
} }
// Check if the company key already exists // Check if the company key already exists
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
select exists ( select exists (
select global currentUser.setting.keys select global currentUser.setting.keys
filter .company.name = "openai" filter .company.name = "openai"
@ -195,7 +199,7 @@ func addKeys(c *fiber.Ctx) error {
} }
if Exists { if Exists {
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
UPDATE Key filter .company.name = <str>$0 AND .key = <str>$1 UPDATE Key filter .company.name = <str>$0 AND .key = <str>$1
SET { SET {
key := <str>$1, key := <str>$1,
@ -206,7 +210,7 @@ func addKeys(c *fiber.Ctx) error {
panic(err) panic(err)
} }
} else { } else {
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
WITH WITH
c := (SELECT Company FILTER .name = "openai" LIMIT 1) c := (SELECT Company FILTER .name = "openai" LIMIT 1)
UPDATE global currentUser.setting UPDATE global currentUser.setting
@ -233,7 +237,7 @@ func addKeys(c *fiber.Ctx) error {
} }
// Check if the company key already exists // Check if the company key already exists
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
select exists ( select exists (
select global currentUser.setting.keys select global currentUser.setting.keys
filter .company.name = "anthropic" filter .company.name = "anthropic"
@ -245,7 +249,7 @@ func addKeys(c *fiber.Ctx) error {
} }
if Exists { if Exists {
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
UPDATE Key filter .company.name = "anthropic" AND .key = <str>$0 UPDATE Key filter .company.name = "anthropic" AND .key = <str>$0
SET { SET {
key := <str>$0, key := <str>$0,
@ -256,7 +260,7 @@ func addKeys(c *fiber.Ctx) error {
panic(err) panic(err)
} }
} else { } else {
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
WITH WITH
c := (SELECT Company FILTER .name = "anthropic" LIMIT 1) c := (SELECT Company FILTER .name = "anthropic" LIMIT 1)
UPDATE global currentUser.setting UPDATE global currentUser.setting
@ -283,7 +287,7 @@ func addKeys(c *fiber.Ctx) error {
} }
// Check if the company key already exists // Check if the company key already exists
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
select exists ( select exists (
select global currentUser.setting.keys select global currentUser.setting.keys
filter .company.name = "mistral" filter .company.name = "mistral"
@ -295,7 +299,7 @@ func addKeys(c *fiber.Ctx) error {
} }
if Exists { if Exists {
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
UPDATE Key filter .company.name = "mistral" AND .key = <str>$0 UPDATE Key filter .company.name = "mistral" AND .key = <str>$0
SET { SET {
key := <str>$0, key := <str>$0,
@ -306,7 +310,7 @@ func addKeys(c *fiber.Ctx) error {
panic(err) panic(err)
} }
} else { } else {
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
WITH WITH
c := (SELECT Company FILTER .name = "mistral" LIMIT 1) c := (SELECT Company FILTER .name = "mistral" LIMIT 1)
UPDATE global currentUser.setting UPDATE global currentUser.setting
@ -333,7 +337,7 @@ func addKeys(c *fiber.Ctx) error {
} }
// Check if the company key already exists // Check if the company key already exists
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
select exists ( select exists (
select global currentUser.setting.keys select global currentUser.setting.keys
filter .company.name = "groq" filter .company.name = "groq"
@ -345,7 +349,7 @@ func addKeys(c *fiber.Ctx) error {
} }
if Exists { if Exists {
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
UPDATE Key filter .company.name = "groq" AND .key = <str>$0 UPDATE Key filter .company.name = "groq" AND .key = <str>$0
SET { SET {
key := <str>$0, key := <str>$0,
@ -356,7 +360,7 @@ func addKeys(c *fiber.Ctx) error {
panic(err) panic(err)
} }
} else { } else {
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
WITH WITH
c := (SELECT Company FILTER .name = "groq" LIMIT 1) c := (SELECT Company FILTER .name = "groq" LIMIT 1)
UPDATE global currentUser.setting UPDATE global currentUser.setting
@ -383,7 +387,7 @@ func addKeys(c *fiber.Ctx) error {
} }
// Check if the company key already exists // Check if the company key already exists
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
select exists ( select exists (
select global currentUser.setting.keys select global currentUser.setting.keys
filter .company.name = "gooseai" filter .company.name = "gooseai"
@ -395,7 +399,7 @@ func addKeys(c *fiber.Ctx) error {
} }
if Exists { if Exists {
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
UPDATE Key filter .company.name = "gooseai" AND .key = <str>$0 UPDATE Key filter .company.name = "gooseai" AND .key = <str>$0
SET { SET {
key := <str>$0, key := <str>$0,
@ -406,7 +410,7 @@ func addKeys(c *fiber.Ctx) error {
panic(err) panic(err)
} }
} else { } else {
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
WITH WITH
c := (SELECT Company FILTER .name = "gooseai" LIMIT 1) c := (SELECT Company FILTER .name = "gooseai" LIMIT 1)
UPDATE global currentUser.setting UPDATE global currentUser.setting
@ -433,7 +437,7 @@ func addKeys(c *fiber.Ctx) error {
} }
// Check if the company key already exists // Check if the company key already exists
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
select exists ( select exists (
select global currentUser.setting.keys select global currentUser.setting.keys
filter .company.name = "google" filter .company.name = "google"
@ -445,7 +449,7 @@ func addKeys(c *fiber.Ctx) error {
} }
if Exists { if Exists {
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
UPDATE Key filter .company.name = "google" AND .key = <str>$0 UPDATE Key filter .company.name = "google" AND .key = <str>$0
SET { SET {
key := <str>$0, key := <str>$0,
@ -456,7 +460,7 @@ func addKeys(c *fiber.Ctx) error {
panic(err) panic(err)
} }
} else { } else {
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Execute(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, `
WITH WITH
c := (SELECT Company FILTER .name = "google" LIMIT 1) c := (SELECT Company FILTER .name = "google" LIMIT 1)
UPDATE global currentUser.setting UPDATE global currentUser.setting

View File

@ -79,7 +79,7 @@ func addCodeHeader(htmlContent string, languages []string) string {
} }
func getExistingKeys(c *fiber.Ctx) (bool, bool, bool, bool, bool, bool) { func getExistingKeys(c *fiber.Ctx) (bool, bool, bool, bool, bool, bool) {
if edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}) == nil { if edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}) == nil {
return false, false, false, false, false, false return false, false, false, false, false, false
} }
@ -92,7 +92,7 @@ func getExistingKeys(c *fiber.Ctx) (bool, bool, bool, bool, bool, bool) {
googleExists bool googleExists bool
) )
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
select exists ( select exists (
select global currentUser.setting.keys select global currentUser.setting.keys
filter .company.name = "openai" filter .company.name = "openai"
@ -103,7 +103,7 @@ func getExistingKeys(c *fiber.Ctx) (bool, bool, bool, bool, bool, bool) {
panic(err) panic(err)
} }
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
select exists ( select exists (
select global currentUser.setting.keys select global currentUser.setting.keys
filter .company.name = "anthropic" filter .company.name = "anthropic"
@ -114,7 +114,7 @@ func getExistingKeys(c *fiber.Ctx) (bool, bool, bool, bool, bool, bool) {
panic(err) panic(err)
} }
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
select exists ( select exists (
select global currentUser.setting.keys select global currentUser.setting.keys
filter .company.name = "mistral" filter .company.name = "mistral"
@ -125,7 +125,7 @@ func getExistingKeys(c *fiber.Ctx) (bool, bool, bool, bool, bool, bool) {
panic(err) panic(err)
} }
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
select exists ( select exists (
select global currentUser.setting.keys select global currentUser.setting.keys
filter .company.name = "groq" filter .company.name = "groq"
@ -136,7 +136,7 @@ func getExistingKeys(c *fiber.Ctx) (bool, bool, bool, bool, bool, bool) {
panic(err) panic(err)
} }
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
select exists ( select exists (
select global currentUser.setting.keys select global currentUser.setting.keys
filter .company.name = "gooseai" filter .company.name = "gooseai"
@ -147,7 +147,7 @@ func getExistingKeys(c *fiber.Ctx) (bool, bool, bool, bool, bool, bool) {
panic(err) panic(err)
} }
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).QuerySingle(edgeCtx, ` err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
select exists ( select exists (
select global currentUser.setting.keys select global currentUser.setting.keys
filter .company.name = "google" filter .company.name = "google"
@ -211,7 +211,7 @@ func Message2RequestMessage(messages []Message, context string) []RequestMessage
func GetAvailableModels(c *fiber.Ctx) []ModelInfo { func GetAvailableModels(c *fiber.Ctx) []ModelInfo {
// TODO Filter if key is not available // TODO Filter if key is not available
var models []ModelInfo var models []ModelInfo
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token", "")}).Query(edgeCtx, ` err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Query(edgeCtx, `
SELECT ModelInfo { SELECT ModelInfo {
modelID, modelID,
name, name,

View File

@ -1,111 +1,5 @@
<div class="chat-container mt-5" style="padding-bottom: 155px;" hx-indicator="#textarea-control"> <div class="chat-container mt-5" style="padding-bottom: 155px;" hx-indicator="#textarea-control">
<hx hx-get="/loadChat" hx-trigger="load once" hx-swap="outerHTML"></hx> <hx hx-get="/loadChat" hx-trigger="load once" hx-swap="outerHTML"></hx>
{% if IsSubscribed or not IsLimiteReached %} <hx hx-get="/loadChatInput" hx-trigger="load once" hx-swap="outerHTML"></hx>
<div class="chat-input-container mb-5">
<div class="textarea-wrapper">
<div class="control" id="textarea-control">
<textarea {% if not IsLogin or not HaveKey %}disabled{% endif %} class="textarea has-fixed-size"
placeholder="Type your message here..." name="message" oninput="toggleSendButton()"
id="chat-input-textarea"></textarea>
</div>
<div class="button-group">
<hx hx-get="/loadSettings" hx-trigger="load" hx-swap="outerHTML" hx-target="this"></hx>
<hx hx-get="/loadUsageKPI" hx-trigger="load" hx-swap="outerHTML" hx-target="this"></hx>
<hx hx-get="/loadConversationSelection" hx-trigger="load" hx-swap="outerHTML" hx-target="this"></hx>
<hx hx-get="/loadModelSelection" hx-trigger="load" hx-swap="outerHTML" hx-target="this"></hx>
<!--button {% if not IsLogin or not HaveKey %}style="display: none;" {%endif%}
class="button is-small to-reduce-opacity" onclick="clearTextArea()" id="clear-button"
hx-post="/clearChat" hx-swap="outerHTML" hx-target="#chat-container" title="Clear chat">
<span class="icon">
<i class="fa-solid fa-broom"></i>
</span>
</button-->
<!--button type="submit" class="button is-small" hx-get="/test" hx-swap="beforeend">
<span class="icon">
<i class="fa-solid fa-vials"></i>
</span>
</button-->
<button disabled type="submit" class="send-button button is-primary is-small"
hx-post="/generatePlaceholder" hx-swap="beforeend" hx-target="#chat-messages"
id="chat-input-send-btn" class="chat-input" hx-include="[name='message']"
hx-vals="js:{selectedLLMIds: getSelectedModelsIDs()}" onclick="clearTextArea()">
<span class="icon">
<i class="fa-solid fa-chevron-right"></i>
</span>
</button>
</div>
</div>
</div>
{% endif %}
</div> </div>
<script>
var textareaControl = document.getElementById('textarea-control');
// Every 0.01s check if the text area have htmx-request class, if yes, add the class is-loading
setInterval(function () {
if (textareaControl.classList.contains('htmx-request')) {
textareaControl.classList.add('is-loading');
} else {
textareaControl.classList.remove('is-loading');
}
}, 10);
setInterval(function () {
if (window.innerWidth < 450) {
var elements = document.getElementsByClassName('message-icon');
for (var i = 0; i < elements.length; i++) {
elements[i].classList.remove('is-48x48');
elements[i].classList.add('is-32x32');
}
} else {
var elements = document.getElementsByClassName('message-icon');
for (var i = 0; i < elements.length; i++) {
elements[i].classList.remove('is-32x32');
elements[i].classList.add('is-48x48');
}
}
}, 300);
document.getElementById('chat-input-textarea').addEventListener('focus', function () {
var buttons = document.getElementsByClassName('to-reduce-opacity');
for (var i = 0; i < buttons.length; i++) {
buttons[i].style.opacity = 0.2;
}
});
document.getElementById('chat-input-textarea').addEventListener('blur', function () {
var buttons = document.getElementsByClassName('to-reduce-opacity');
for (var i = 0; i < buttons.length; i++) {
buttons[i].style.opacity = 1;
}
});
const textarea = document.querySelector('#chat-input-textarea');
textarea.addEventListener('keydown', handleTextareaKeydown);
function toggleSendButton() {
document.getElementById('chat-input-send-btn').disabled = textarea.value.trim().length === 0 || document.getElementsByClassName('selected icon-llm').length === 0;
}
function clearTextArea() {
setTimeout(function () {
textarea.value = '';
toggleSendButton();
}, 200);
}
function updateIcon(icon, ConversationAreaId) {
var selectedIcon = document.getElementById('selectedIcon-' + ConversationAreaId);
selectedIcon.src = icon;
}
function handleTextareaKeydown(event) {
if (event.metaKey && event.key === 'Enter' && event.target === textarea && textarea.value.trim() !== '' && document.getElementsByClassName('selected icon-llm').length !== 0) {
// Check if the cursor is in the textarea
// Trigger the same action as the send button
document.getElementById('chat-input-send-btn').click();
}
}
</script>

View File

@ -0,0 +1,109 @@
{% if IsSubscribed or not IsLimiteReached %}
<div class="chat-input-container mb-5">
<div class="textarea-wrapper">
<div class="control" id="textarea-control">
<textarea {% if not IsLogin or not HaveKey %}disabled{% endif %} class="textarea has-fixed-size"
placeholder="Type your message here..." name="message" oninput="toggleSendButton()"
id="chat-input-textarea"></textarea>
</div>
<div class="button-group">
<hx hx-get="/loadSettings" hx-trigger="load" hx-swap="outerHTML" hx-target="this"></hx>
<hx hx-get="/loadUsageKPI" hx-trigger="load" hx-swap="outerHTML" hx-target="this"></hx>
<hx hx-get="/loadConversationSelection" hx-trigger="load" hx-swap="outerHTML" hx-target="this"></hx>
<hx hx-get="/loadModelSelection" hx-trigger="load" hx-swap="outerHTML" hx-target="this"></hx>
<!--button {% if not IsLogin or not HaveKey %}style="display: none;" {%endif%}
class="button is-small to-reduce-opacity" onclick="clearTextArea()" id="clear-button"
hx-post="/clearChat" hx-swap="outerHTML" hx-target="#chat-container" title="Clear chat">
<span class="icon">
<i class="fa-solid fa-broom"></i>
</span>
</button-->
<!--button type="submit" class="button is-small" hx-get="/test" hx-swap="beforeend">
<span class="icon">
<i class="fa-solid fa-vials"></i>
</span>
</button-->
<button disabled type="submit" class="send-button button is-primary is-small" hx-post="/generatePlaceholder"
hx-swap="beforeend" hx-target="#chat-messages" id="chat-input-send-btn" class="chat-input"
hx-include="[name='message']" hx-vals="js:{selectedLLMIds: getSelectedModelsIDs()}"
onclick="clearTextArea()">
<span class="icon">
<i class="fa-solid fa-chevron-right"></i>
</span>
</button>
</div>
</div>
</div>
{% endif %}
<script>
var textareaControl = document.getElementById('textarea-control');
// Every 0.01s check if the text area have htmx-request class, if yes, add the class is-loading
setInterval(function () {
if (textareaControl.classList.contains('htmx-request')) {
textareaControl.classList.add('is-loading');
} else {
textareaControl.classList.remove('is-loading');
}
}, 10);
setInterval(function () {
if (window.innerWidth < 450) {
var elements = document.getElementsByClassName('message-icon');
for (var i = 0; i < elements.length; i++) {
elements[i].classList.remove('is-48x48');
elements[i].classList.add('is-32x32');
elements[i].parentElement.style = "padding-right: 0;"
}
} else {
var elements = document.getElementsByClassName('message-icon');
for (var i = 0; i < elements.length; i++) {
elements[i].classList.remove('is-32x32');
elements[i].classList.add('is-48x48');
elements[i].parentElement.style = ""
}
}
}, 300);
document.getElementById('chat-input-textarea').addEventListener('focus', function () {
var buttons = document.getElementsByClassName('to-reduce-opacity');
for (var i = 0; i < buttons.length; i++) {
buttons[i].style.opacity = 0.2;
}
});
document.getElementById('chat-input-textarea').addEventListener('blur', function () {
var buttons = document.getElementsByClassName('to-reduce-opacity');
for (var i = 0; i < buttons.length; i++) {
buttons[i].style.opacity = 1;
}
});
const textarea = document.querySelector('#chat-input-textarea');
textarea.addEventListener('keydown', handleTextareaKeydown);
function toggleSendButton() {
document.getElementById('chat-input-send-btn').disabled = textarea.value.trim().length === 0 || document.getElementsByClassName('selected icon-llm').length === 0;
}
function clearTextArea() {
setTimeout(function () {
textarea.value = '';
toggleSendButton();
}, 200);
}
function updateIcon(icon, ConversationAreaId) {
var selectedIcon = document.getElementById('selectedIcon-' + ConversationAreaId);
selectedIcon.src = icon;
}
function handleTextareaKeydown(event) {
if (event.metaKey && event.key === 'Enter' && event.target === textarea && textarea.value.trim() !== '' && document.getElementsByClassName('selected icon-llm').length !== 0) {
// Check if the cursor is in the textarea
// Trigger the same action as the send button
document.getElementById('chat-input-send-btn').click();
}
}
</script>

View File

@ -62,7 +62,7 @@
</p> </p>
</div> </div>
<div class="field has-addons is-hidden" id="goose-field" <div class="field has-addons is-hidden" id="goose-field"
title="GooseAI chat API soon to be available"> title="GooseAI chat API will be available soon">
<p class="control has-icons-left is-expanded"> <p class="control has-icons-left is-expanded">
<input class="input is-small {% if GooseaiExists %}is-success{% endif %}" type="text" <input class="input is-small {% if GooseaiExists %}is-success{% endif %}" type="text"
{%if not IsLogin %}disabled{% endif %} placeholder="Gooseai API key" {%if not IsLogin %}disabled{% endif %} placeholder="Gooseai API key"

View File

@ -0,0 +1,10 @@
<strong>Welcome to JADE, a chatbot that makes requests to various third-party APIs to provide information and
services.</strong>
<p>No fancy stuff, easy to use, pay as you use, multi-models, work on low 3g...</p>
<p>To start using JADE, please login.</p>
<a class="button is-primary is-small" href="/signin">
Log in
</a>