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 {
var (
isSub bool
limitReach bool
)
if c.Cookies("jade-edgedb-auth-token", "") == "" {
fmt.Println("Not logged in")
isSub = false
limitReach = false
fmt.Println("Cookies: ", c.Cookies("jade-edgedb-auth-token"))
if c.Cookies("jade-edgedb-auth-token") == "" {
return c.Render("chat", fiber.Map{"IsLogin": false, "HaveKey": false, "IsSubscribed": false, "IsLimiteReached": false}, "layouts/main")
} else {
isSub = IsCurrentUserSubscribed(c)
limitReach = IsCurrentUserLimiteReached(c)
return c.Render("chat", fiber.Map{"IsLogin": checkIfLogin(c), "HaveKey": checkIfHaveKey(c), "IsSubscribed": isSub, "IsLimiteReached": limitReach}, "layouts/main")
fmt.Println("Here")
return c.Render("chat", fiber.Map{"IsLogin": checkIfLogin(c), "HaveKey": checkIfHaveKey(c), "IsSubscribed": IsCurrentUserSubscribed(c), "IsLimiteReached": IsCurrentUserLimiteReached(c)}, "layouts/main")
}
}
@ -42,7 +34,7 @@ func DeleteMessageHandler(c *fiber.Ctx) error {
}
// 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
messageArea := (SELECT Message FILTER .id = <uuid>$0).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 {
Icon string
Content string
@ -84,7 +94,7 @@ type TemplateMessage struct {
func generateChatHTML(c *fiber.Ctx) string {
// Println the name of the current 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)
if err != nil {
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...
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 {
id,
selected,
@ -184,7 +194,7 @@ func GetUserMessageHandler(c *fiber.Ctx) error {
messageUUID, _ := edgedb.ParseUUID(id)
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 {
content
}
@ -212,7 +222,7 @@ func GetMessageContentHandler(c *fiber.Ctx) error {
messageUUID, _ := edgedb.ParseUUID(messageId)
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 {
content,
llm : {
@ -246,7 +256,7 @@ func GetMessageContentHandler(c *fiber.Ctx) error {
out += "</div>"
// 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)
UPDATE Message
FILTER .area = m.area
@ -256,7 +266,7 @@ func GetMessageContentHandler(c *fiber.Ctx) error {
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
FILTER .id = <uuid>$0
SET {selected := true};
@ -266,22 +276,18 @@ func GetMessageContentHandler(c *fiber.Ctx) error {
}
func generateWelcomeChatHTML() string {
welcomeMessage := `
No fancy stuff, easy to use, pay as you use, multi-models, work on low 3g...
To start using JADE, please login.`
loginButton := `
<a class="button is-primary is-small" href="/signin">
Log in
</a>`
welcomeMessage, err := welcomeChatTmpl.Execute(pongo2.Context{})
if err != nil {
fmt.Println("Error executing welcome chat template")
panic(err)
}
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{}
nextMsg := TemplateMessage{
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
Id: "0",
Name: "JADE",
@ -304,14 +310,14 @@ func generateWelcomeChatHTML() string {
func generateEnterKeyChatHTML() string {
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>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>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>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>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 or per month, which means you have a balance in your account that you can use to generate messages.</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>
<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>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 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, you can ask 2,000 questions to GPT-4o, or 20,000 to GPT-3.5 turbo (around 100 tokens per message).</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 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>
<p>Remember, prices and token limits may vary depending on the provider and the specific LLM you're using.</p>
<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>
<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>
<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 := `
@ -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.`
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 {
fmt.Println("Error getting current user")
panic(err)
@ -481,7 +487,7 @@ func GetEditMessageFormHandler(c *fiber.Ctx) error {
idUUID, _ := edgedb.ParseUUID(id)
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 }
FILTER .id = <uuid>$0;
`, &message, idUUID)
@ -516,7 +522,7 @@ func RedoMessageHandler(c *fiber.Ctx) error {
}
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 }
FILTER .id = <uuid>$0;
`, &message, messageUUID)
@ -526,7 +532,7 @@ func RedoMessageHandler(c *fiber.Ctx) error {
}
// 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
messageArea := (SELECT Message FILTER .id = <uuid>$0).area
DELETE Area
@ -557,7 +563,7 @@ func EditMessageHandler(c *fiber.Ctx) error {
}
// 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
messageArea := (SELECT Message FILTER .id = <uuid>$0).area
DELETE Area
@ -573,7 +579,7 @@ func EditMessageHandler(c *fiber.Ctx) error {
func ClearChatHandler(c *fiber.Ctx) error {
// 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
FILTER .conversation = global currentConversation;
`)
@ -619,7 +625,7 @@ func LoadUsageKPIHandler(c *fiber.Ctx) error {
}
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
U := (
SELECT Usage
@ -674,7 +680,7 @@ func GenerateModelPopoverHTML(refresh bool, c *fiber.Ctx) string {
openaiExists, anthropicExists, mistralExists, groqExists, gooseaiExists, googleExists := getExistingKeys(c)
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 {
id,
name,
@ -729,7 +735,7 @@ func LoadModelSelectionHandler(c *fiber.Ctx) error {
func GenerateConversationPopoverHTML(isActive bool, c *fiber.Ctx) string {
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 {
name,
position,
@ -782,7 +788,7 @@ func LoadSettingsHandler(c *fiber.Ctx) error {
}
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 {
email
}
@ -825,7 +831,7 @@ func CreateConversationHandler(c *fiber.Ctx) error {
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
C := (
SELECT Conversation
@ -854,7 +860,7 @@ func DeleteConversationHandler(c *fiber.Ctx) error {
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
FILTER .user = global currentUser AND .id = <uuid>$0;
`, conversationUUID)
@ -864,7 +870,7 @@ func DeleteConversationHandler(c *fiber.Ctx) error {
}
// 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
FILTER .user = global currentUser AND .name = 'Default'
SET {
@ -891,7 +897,7 @@ func SelectConversationHandler(c *fiber.Ctx) error {
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
FILTER .user = global currentUser
SET {
@ -903,7 +909,7 @@ func SelectConversationHandler(c *fiber.Ctx) error {
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
FILTER .user = global currentUser AND .id = <uuid>$0
SET {
@ -921,7 +927,7 @@ func SelectConversationHandler(c *fiber.Ctx) error {
func ArchiveDefaultConversationHandler(c *fiber.Ctx) error {
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
FILTER .user = global currentUser AND .name = 'Default'
SET {
@ -933,7 +939,7 @@ func ArchiveDefaultConversationHandler(c *fiber.Ctx) error {
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
C := (
SELECT Conversation

12
LLM.go
View File

@ -20,7 +20,7 @@ func deleteLLM(c *fiber.Ctx) error {
for _, id := range selectedLLMIds {
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
FILTER .id = <uuid>$0 AND .user = global currentUser
SET {
@ -39,7 +39,7 @@ func deleteLLM(c *fiber.Ctx) error {
}
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
filter .to_delete = true and not exists(
select Message filter .llm = LLM
@ -63,7 +63,7 @@ func createLLM(c *fiber.Ctx) error {
customID := c.FormValue("model-cid-input")
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
countLLM := count((SELECT LLM FILTER .user = global currentUser))
INSERT LLM {
@ -91,7 +91,7 @@ func createLLM(c *fiber.Ctx) error {
panic(err)
}
} 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
countLLM := count((SELECT LLM FILTER .user = global currentUser))
INSERT LLM {
@ -130,7 +130,7 @@ func updateLLMPositionBatch(c *fiber.Ctx) error {
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
FILTER .id = <uuid>$0 AND .user = global currentUser
SET {
@ -161,7 +161,7 @@ func updateConversationPositionBatch(c *fiber.Ctx) error {
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
FILTER .id = <uuid>$0 AND .user = global currentUser
SET {

View File

@ -50,7 +50,7 @@ func GeneratePlaceholderHTML(c *fiber.Ctx, message string, selectedLLMIds []stri
for _, id := range selectedLLMIds {
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 {
id,
name,
@ -145,7 +145,7 @@ func GenerateMultipleMessagesHandler(c *fiber.Ctx) error {
}
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 {
id,
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) {
// 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 {
input_cost := <float32>$0,
output_cost := <float32>$1,

View File

@ -113,7 +113,7 @@ func RequestAnthropic(c *fiber.Ctx, model string, messages []Message, maxTokens
var apiKey struct {
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 {
key
}
@ -167,7 +167,7 @@ func RequestAnthropic(c *fiber.Ctx, model string, messages []Message, maxTokens
}
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 {
inputPrice,
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) {
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
filtered_keys := (
select Key {
@ -199,7 +199,7 @@ func RequestGoogle(c *fiber.Ctx, model string, messages []Message, temperature f
}
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 {
inputPrice,
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) {
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
filtered_keys := (
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) {
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
filtered_keys := (
select Key {
@ -164,7 +164,7 @@ func RequestGroq(c *fiber.Ctx, model string, messages []Message, temperature flo
}
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 {
inputPrice,
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) {
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
filtered_keys := (
select Key {
@ -170,7 +170,7 @@ func RequestMistral(c *fiber.Ctx, model string, messages []Message, temperature
}
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 {
inputPrice,
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) {
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
filtered_keys := (
select Key {
@ -164,7 +164,7 @@ func RequestOpenai(c *fiber.Ctx, model string, messages []Message, temperature f
}
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 {
inputPrice,
outputPrice

View File

@ -20,7 +20,7 @@ func PricingTableHandler(c *fiber.Ctx) error {
func generatePricingTableChatHTML(c *fiber.Ctx) string {
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 {
fmt.Println("Error getting user")
panic(err)
@ -85,7 +85,7 @@ func CreateNewStripeCustomer(name string, email string) string {
func IsCurrentUserSubscribed(c *fiber.Ctx) bool {
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 {
fmt.Println("Error getting user")
panic(err)
@ -105,7 +105,7 @@ func IsCurrentUserSubscribed(c *fiber.Ctx) bool {
func IsCurrentUserLimiteReached(c *fiber.Ctx) bool {
// Count the number of Usage for the current user
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
U := (
SELECT Usage
@ -122,7 +122,7 @@ func IsCurrentUserLimiteReached(c *fiber.Ctx) bool {
func CreateClientSecretSession(c *fiber.Ctx) string {
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 {
fmt.Println("Error getting user")
panic(err)

View File

@ -133,13 +133,13 @@ func init() {
}
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) {
// Insert a new area.
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
positionVar := count((SELECT Area FILTER .conversation = global currentConversation)) + 1
INSERT Area {
@ -153,7 +153,7 @@ func insertArea(c *fiber.Ctx) (edgedb.UUID, 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 {
position,
}
@ -171,7 +171,7 @@ func insertArea(c *fiber.Ctx) (edgedb.UUID, int64) {
func insertUserMessage(c *fiber.Ctx, content string) edgedb.UUID {
// Insert a new user.
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 {
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
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 {
role := <str>$0,
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 {
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 {
id
}
@ -223,7 +223,7 @@ func insertBotMessage(c *fiber.Ctx, content string, selected bool, llmUUID edged
}
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 {
role := <str>$0,
content := <str>$2,
@ -260,7 +260,7 @@ func getAllSelectedMessages(c *fiber.Ctx) []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 {
id,
selected,
@ -288,7 +288,7 @@ func getAllSelectedMessages(c *fiber.Ctx) []Message {
func checkIfHaveKey(c *fiber.Ctx) bool {
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 {
panic(err)
}

View File

@ -210,7 +210,7 @@ func handleCallbackSignup(c *fiber.Ctx) error {
fmt.Println("Error parsing UUID")
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 {
issuer
} FILTER .id = <uuid>$0
@ -235,7 +235,7 @@ func handleCallbackSignup(c *fiber.Ctx) error {
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 {
stripe_id := <str>$0,
email := <str>$1,

52
main.go
View File

@ -24,6 +24,8 @@ var (
settingPopoverTmpl *pongo2.Template
messageEditTmpl *pongo2.Template
conversationPopoverTmpl *pongo2.Template
welcomeChatTmpl *pongo2.Template
chatInputTmpl *pongo2.Template
clients = make(map[chan SSE]bool)
mu sync.Mutex
)
@ -56,15 +58,16 @@ func main() {
usagePopoverTmpl = pongo2.Must(pongo2.FromFile("views/partials/popover-usage.html"))
settingPopoverTmpl = pongo2.Must(pongo2.FromFile("views/partials/popover-settings.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
engine := django.New("./views", ".html")
// Create new Fiber instance
app := fiber.New(fiber.Config{
Views: engine,
AppName: "JADE",
EnablePrintRoutes: true,
Views: engine,
AppName: "JADE",
})
defer app.Shutdown()
@ -72,12 +75,10 @@ func main() {
app.Use(logger.New())
app.Use(recover.New())
// Add static files
app.Static("/", "./static")
// Main routes
app.Get("/", ChatPageHandler)
app.Get("/loadChat", LoadChatHandler)
app.Get("/loadChatInput", LoadChatInputHandler)
app.Get("/pricingTable", PricingTableHandler)
app.Get("/generateTermAndService", generateTermAndServiceHandler)
@ -118,6 +119,9 @@ func main() {
app.Get("deleteLLM", deleteLLM)
app.Post("/createLLM", createLLM)
// Add static files
app.Static("/", "./static")
app.Get("/empty", func(c *fiber.Ctx) error {
return c.SendString("")
})
@ -183,7 +187,7 @@ func addKeys(c *fiber.Ctx) error {
}
// 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 global currentUser.setting.keys
filter .company.name = "openai"
@ -195,7 +199,7 @@ func addKeys(c *fiber.Ctx) error {
}
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
SET {
key := <str>$1,
@ -206,7 +210,7 @@ func addKeys(c *fiber.Ctx) error {
panic(err)
}
} 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
c := (SELECT Company FILTER .name = "openai" LIMIT 1)
UPDATE global currentUser.setting
@ -233,7 +237,7 @@ func addKeys(c *fiber.Ctx) error {
}
// 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 global currentUser.setting.keys
filter .company.name = "anthropic"
@ -245,7 +249,7 @@ func addKeys(c *fiber.Ctx) error {
}
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
SET {
key := <str>$0,
@ -256,7 +260,7 @@ func addKeys(c *fiber.Ctx) error {
panic(err)
}
} 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
c := (SELECT Company FILTER .name = "anthropic" LIMIT 1)
UPDATE global currentUser.setting
@ -283,7 +287,7 @@ func addKeys(c *fiber.Ctx) error {
}
// 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 global currentUser.setting.keys
filter .company.name = "mistral"
@ -295,7 +299,7 @@ func addKeys(c *fiber.Ctx) error {
}
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
SET {
key := <str>$0,
@ -306,7 +310,7 @@ func addKeys(c *fiber.Ctx) error {
panic(err)
}
} 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
c := (SELECT Company FILTER .name = "mistral" LIMIT 1)
UPDATE global currentUser.setting
@ -333,7 +337,7 @@ func addKeys(c *fiber.Ctx) error {
}
// 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 global currentUser.setting.keys
filter .company.name = "groq"
@ -345,7 +349,7 @@ func addKeys(c *fiber.Ctx) error {
}
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
SET {
key := <str>$0,
@ -356,7 +360,7 @@ func addKeys(c *fiber.Ctx) error {
panic(err)
}
} 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
c := (SELECT Company FILTER .name = "groq" LIMIT 1)
UPDATE global currentUser.setting
@ -383,7 +387,7 @@ func addKeys(c *fiber.Ctx) error {
}
// 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 global currentUser.setting.keys
filter .company.name = "gooseai"
@ -395,7 +399,7 @@ func addKeys(c *fiber.Ctx) error {
}
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
SET {
key := <str>$0,
@ -406,7 +410,7 @@ func addKeys(c *fiber.Ctx) error {
panic(err)
}
} 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
c := (SELECT Company FILTER .name = "gooseai" LIMIT 1)
UPDATE global currentUser.setting
@ -433,7 +437,7 @@ func addKeys(c *fiber.Ctx) error {
}
// 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 global currentUser.setting.keys
filter .company.name = "google"
@ -445,7 +449,7 @@ func addKeys(c *fiber.Ctx) error {
}
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
SET {
key := <str>$0,
@ -456,7 +460,7 @@ func addKeys(c *fiber.Ctx) error {
panic(err)
}
} 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
c := (SELECT Company FILTER .name = "google" LIMIT 1)
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) {
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
}
@ -92,7 +92,7 @@ func getExistingKeys(c *fiber.Ctx) (bool, bool, bool, bool, bool, 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 global currentUser.setting.keys
filter .company.name = "openai"
@ -103,7 +103,7 @@ func getExistingKeys(c *fiber.Ctx) (bool, bool, bool, bool, bool, bool) {
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 global currentUser.setting.keys
filter .company.name = "anthropic"
@ -114,7 +114,7 @@ func getExistingKeys(c *fiber.Ctx) (bool, bool, bool, bool, bool, bool) {
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 global currentUser.setting.keys
filter .company.name = "mistral"
@ -125,7 +125,7 @@ func getExistingKeys(c *fiber.Ctx) (bool, bool, bool, bool, bool, bool) {
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 global currentUser.setting.keys
filter .company.name = "groq"
@ -136,7 +136,7 @@ func getExistingKeys(c *fiber.Ctx) (bool, bool, bool, bool, bool, bool) {
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 global currentUser.setting.keys
filter .company.name = "gooseai"
@ -147,7 +147,7 @@ func getExistingKeys(c *fiber.Ctx) (bool, bool, bool, bool, bool, bool) {
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 global currentUser.setting.keys
filter .company.name = "google"
@ -211,7 +211,7 @@ func Message2RequestMessage(messages []Message, context string) []RequestMessage
func GetAvailableModels(c *fiber.Ctx) []ModelInfo {
// TODO Filter if key is not available
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 {
modelID,
name,

View File

@ -1,111 +1,5 @@
<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>
{% 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 %}
</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>
<hx hx-get="/loadChatInput" hx-trigger="load once" hx-swap="outerHTML"></hx>
</div>

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>
</div>
<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">
<input class="input is-small {% if GooseaiExists %}is-success{% endif %}" type="text"
{%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>