package main import ( "fmt" "log" "os" "strings" "sync" "github.com/flosch/pongo2" "github.com/gofiber/contrib/websocket" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/logger" "github.com/gofiber/fiber/v2/middleware/monitor" "github.com/gofiber/fiber/v2/middleware/recover" "github.com/gofiber/template/django/v3" "github.com/stripe/stripe-go" ) var ( userTmpl *pongo2.Template botTmpl *pongo2.Template selectBtnTmpl *pongo2.Template modelPopoverTmpl *pongo2.Template usagePopoverTmpl *pongo2.Template settingPopoverTmpl *pongo2.Template messageEditTmpl *pongo2.Template conversationPopoverTmpl *pongo2.Template welcomeChatTmpl *pongo2.Template chatInputTmpl *pongo2.Template explainLLMconvChatTmpl *pongo2.Template mu sync.Mutex app *fiber.App ) func main() { // Use STRIPE_KEY environment variable stripe.Key = os.Getenv("STRIPE_KEY") botTmpl = pongo2.Must(pongo2.FromFile("views/partials/message-bot.html")) userTmpl = pongo2.Must(pongo2.FromFile("views/partials/message-user.html")) selectBtnTmpl = pongo2.Must(pongo2.FromFile("views/partials/model-selection-btn.html")) modelPopoverTmpl = pongo2.Must(pongo2.FromFile("views/partials/popover-models.html")) conversationPopoverTmpl = pongo2.Must(pongo2.FromFile("views/partials/popover-conversation.html")) 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")) explainLLMconvChatTmpl = pongo2.Must(pongo2.FromFile("views/partials/explain-llm-conv-chat.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", }) defer app.Shutdown() // Add default logger app.Use(logger.New()) app.Use(recover.New()) // Main routes app.Get("/", ChatPageHandler) app.Get("/loadChat", LoadChatHandler) app.Get("/loadChatInput", LoadChatInputHandler) app.Get("/pricingTable", PricingTableHandler) app.Get("/generateTermAndService", generateTermAndServiceHandler) // Chat routes app.Post("/deleteMessage", DeleteMessageHandler) app.Post("/generatePlaceholder", GeneratePlaceholderHandler) app.Get("/generateMultipleMessages", GenerateMultipleMessagesHandler) app.Get("/messageContent", GetMessageContentHandler) app.Get("/editMessageForm", GetEditMessageFormHandler) app.Post("/redoMessage", RedoMessageHandler) app.Post("/clearChat", ClearChatHandler) app.Get("/userMessage", GetUserMessageHandler) app.Post("/editMessage", EditMessageHandler) app.Get("/help", generateHelpChatHandler) // Settings routes app.Post("/addKeys", addKeys) // Popovers app.Get("/loadModelSelection", LoadModelSelectionHandler) app.Get("/loadConversationSelection", LoadConversationSelectionHandler) app.Get("/loadUsageKPI", LoadUsageKPIHandler) app.Get("/loadSettings", LoadSettingsHandler) app.Get("/refreshConversationSelection", RefreshConversationSelectionHandler) // Conversation routes app.Get("/createConversation", CreateConversationHandler) app.Get("/deleteConversation", DeleteConversationHandler) app.Get("/selectConversation", SelectConversationHandler) app.Post("/updateConversationPositionBatch", updateConversationPositionBatch) app.Post("/archiveDefaultConversation", ArchiveDefaultConversationHandler) // Authentication app.Get("/signin", handleUiSignIn) app.Get("/signout", handleSignOut) app.Get("/callback", handleCallback) app.Get("/callbackSignup", handleCallbackSignup) // LLM app.Get("/deleteLLM", deleteLLM) app.Post("/createLLM", createLLM) app.Post("/updateLLMPositionBatch", updateLLMPositionBatch) //Admin monitoring app.Get("/metrics", monitor.New()) // Add static files app.Static("/", "./static") app.Get("/empty", func(c *fiber.Ctx) error { return c.SendString("") }) app.Get("/ws", websocket.New(handleWebSocket)) app.Get("/errorLogs", ErrorCodeLogsHandler) // Update models routes app.Get("/models/together", UpdateTogetherModelsHandler) // Start server if err := app.Listen(":8080"); err != nil { log.Fatal(err) } } func addKeys(c *fiber.Ctx) error { keys := map[string]string{ "openai": c.FormValue("openai_key"), "anthropic": c.FormValue("anthropic_key"), "mistral": c.FormValue("mistral_key"), "groq": c.FormValue("groq_key"), "gooseai": c.FormValue("goose_key"), "google": c.FormValue("google_key"), "nim": c.FormValue("nim_key"), "perplexity": c.FormValue("perplexity_key"), "fireworks": c.FormValue("fireworks_key"), "together": c.FormValue("together_key"), "deepseek": c.FormValue("deepseek_key"), } requestFunctions := map[string]func(*fiber.Ctx, LLM, []Message) string{ "openai": RequestOpenai, "anthropic": RequestAnthropic, "mistral": RequestMistral, "groq": RequestGroq, "google": RequestGoogle, "nim": RequestNim, "perplexity": RequestPerplexity, "fireworks": RequestFirework, "together": RequestTogether, "deepseek": RequestDeepseek, } testModels := map[string]string{ "openai": "gpt-3.5-turbo", "anthropic": "claude-3-haiku-20240307", "mistral": "open-mistral-7b", "groq": "llama3-8b-8192", "google": "gemini-pro", "nim": "meta/llama3-8b-instruct", "perplexity": "llama-3-8b-instruct", "fireworks": "accounts/fireworks/models/llama-v2-7b-chat", "together": "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo", "deepseek": "deepseek-chat", } openaiExists, anthropicExists, mistralExists, groqExists, googleExists, perplexityExists, fireworksExists, nimExists, togetherExists, deepseekExists := getExistingKeysNew(c) keyExists := map[string]bool{ "openai": openaiExists, "anthropic": anthropicExists, "mistral": mistralExists, "groq": groqExists, "google": googleExists, "nim": nimExists, "perplexity": perplexityExists, "fireworks": fireworksExists, "together": togetherExists, "deepseek": deepseekExists, } var messages = []Message{ { Content: "You are useful", Role: "context", }, { Content: "hello", Role: "user", }, } for company, key := range keys { if key != "" { var llm LLM = LLM{ Model: ModelInfo{ModelID: testModels[company]}, Temperature: 0, MaxToken: 10, Context: "", } var responseText string = requestFunctions[company](c, llm, messages) if responseText == "" || strings.Contains(responseText, "JADE internal error") || strings.Contains(responseText, "Provider error") { return c.SendString(fmt.Sprintf("Invalid %s API Key\n", company)) } if keyExists[company] { err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, ` UPDATE Key FILTER .company.name = $0 AND .$1, } `, company, key) if err != nil { fmt.Println("Error updating key") panic(err) } } else { err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Execute(edgeCtx, ` WITH c := (SELECT Company FILTER .name = $0 LIMIT 1) UPDATE global currentUser.setting SET { keys += ( INSERT Key { company := c, key := $1, name := $2 ++ " API Key", } ) }`, company, key, company) if err != nil { fmt.Println("Error adding key") panic(err) } } } } return c.SendString("") }