diff --git a/Chat.go b/Chat.go index d4c67b6..afa234f 100644 --- a/Chat.go +++ b/Chat.go @@ -269,11 +269,14 @@ func GenerateMessageContentHTML(authCookie string, messageId string, onlyContent panic(err) } - _ = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": authCookie}).Execute(edgeCtx, ` + err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": authCookie}).Execute(edgeCtx, ` UPDATE Message FILTER .id = $0 SET {selected := true}; `, messageUUID) + if err != nil { + panic(err) + } return out } diff --git a/RequestTogetherai.go b/RequestTogetherai.go index 5f5b259..3be794e 100644 --- a/RequestTogetherai.go +++ b/RequestTogetherai.go @@ -4,9 +4,12 @@ import ( "bytes" "encoding/json" "io" + "math" "net/http" "strings" + "fmt" + "github.com/gofiber/fiber/v2" ) @@ -139,3 +142,162 @@ func RequestTogether(c *fiber.Ctx, llm LLM, messages []Message) string { return chatCompletionResponse.Choices[0].Text } + +type TogetherModel struct { + ID string `json:"id"` + Object string `json:"object"` + Created int64 `json:"created"` + Type string `json:"type"` + DisplayName string `json:"display_name"` + Organization string `json:"organization"` + Link string `json:"link"` + License string `json:"license"` + ContextLength int `json:"context_length"` + Pricing TogetherPricing `json:"pricing"` +} + +type TogetherPricing struct { + Hourly float64 `json:"hourly"` + Input float64 `json:"input"` + Output float64 `json:"output"` + Base float64 `json:"base"` + Finetune float64 `json:"finetune"` +} + +// TODO: Use my key everytime, no auth needed +func UpdateTogetherModels(c *fiber.Ctx, currentModelInfos []ModelInfo) { + url := "https://api.together.xyz/v1/models" + + var apiKey string + err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, ` + with + filtered_keys := ( + select Key { + key + } filter .company.name = $0 AND . epsilon || + math.Abs(model.Pricing.Output/1000000-float64(savedModel.OutputPrice)) > epsilon { + fmt.Println("Found one existing model with changed price:", model.ID, ". Updating price from ", float64(savedModel.InputPrice), " to ", model.Pricing.Input/1000000) + err = edgeGlobalClient.Execute(edgeCtx, ` + UPDATE ModelInfo FILTER .modelID = $0 SET { inputPrice := $1, outputPrice := $2} + `, model.ID, float32(model.Pricing.Input)/1000000, float32(model.Pricing.Output)/1000000) + if err != nil { + fmt.Println("Error updating price:", err.Error()) + } + } + } else { + fmt.Println("Found new model:", model.ID) + newModelFound = true + err = edgeGlobalClient.Execute(edgeCtx, ` + INSERT ModelInfo { name := "New model, name coming soon...", modelID := $0, inputPrice := $1, outputPrice := $2, company := assert_single(( SELECT Company FILTER .name = $3))} + `, model.ID, float32(model.Pricing.Input)/1000000, float32(model.Pricing.Output)/1000000, "together") + if err != nil { + fmt.Println("Error creating new modelInfo:", err.Error()) + } + } + } + } + + if newModelFound { + SendNoreplyEmail("adrien.bouvais.pro@gmail.com", "New Together models found", "Look like new model have been found, you should name it.") + } + + // Delete all unfound models + for _, currentModel := range currentModelInfos { + if currentModel.Company.Name != "together" { + continue + } + + exist = false + for _, model := range togetherModels { + if model.ID == currentModel.ModelID { + exist = true + } + } + + if !exist { + fmt.Println("A ModelInfo using this modelID:", currentModel.ModelID, ", was found using a modelID that doesn't exist anymore. Deleting it.") + err = edgeGlobalClient.Execute(edgeCtx, ` + DELETE ModelInfo FILTER .modelID = $0 AND .company.name = $1 + `, currentModel.ModelID, "together") + if err != nil { + fmt.Println("Error deleting a ModelInfo with an unfound modelID.") + } + } + } +} + +func UpdateTogetherModelsHandler(c *fiber.Ctx) error { + if !IsUserAdmin(c) { + return c.SendString("That's for admin, how did you manage to come here ?") + } + + var currentModelInfos []ModelInfo + err := edgeGlobalClient.Query(edgeCtx, `SELECT ModelInfo { id, name, modelID, inputPrice, outputPrice, company}`, ¤tModelInfos) + if err != nil { + fmt.Println("Error getting all ModelInfo for updating them") + } + UpdateTogetherModels(c, currentModelInfos) + return c.SendString("Models from together ai updated") +} diff --git a/TODO.md b/TODO.md index 5a2921e..00bbc65 100644 --- a/TODO.md +++ b/TODO.md @@ -1,12 +1,12 @@ # Bugs -[ ] Sometime I can redo or edit but the button is not available +[X] Sometime I can redo or edit but the button is not available [X] The SSE event that sometime fails after some times. Reconnect when sending a new message. [X] 2 selected messages [X] On first response, code block width are too long [X] Change Terms of service to say that I use one cookie [X] Change the lastSelectedLLMs, 2 users can't use the same time... [X] CTRL + Enter not working -[ ] Add all Together AI models +[X] Add all Together AI models # Features [X] SSE to WebSocket @@ -19,7 +19,7 @@ [ ] Add login with email and password [ ] Add login with AppleID [ ] Better temperature settings. (Anthropic from 0-1, OpenAI from 0-2, DeepSeek from -2-2, ect) -[ ] Auto update the modelsInfos db (At least remove unavailable models and send me an email when new one arrive) +[X] Auto update the modelsInfos db (At least remove unavailable models and send me an email when new one arrive) [ ] Encrypt the API keys # Opti @@ -28,7 +28,6 @@ [ ] Look to reduce memory # Other -[ ] Remove all panic [ ] Change the terms of service and enter keys page to an HTML [X] Use the normal RequestProvider function instead of TestProvider to remove TestProvider [ ] Implement the JADE_IN_DEV env variable to dev locally on my laptop diff --git a/main.go b/main.go index 72115de..d45b725 100644 --- a/main.go +++ b/main.go @@ -123,6 +123,9 @@ func main() { 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)