Compare commits
No commits in common. "edd5c58a7b802feed439de68ef443c552db456df" and "2f17a129ae3dd62d8a4871564bd25d1cd295f19d" have entirely different histories.
edd5c58a7b
...
2f17a129ae
@ -261,8 +261,7 @@ func handleCallbackSignup(c *fiber.Ctx) error {
|
||||
INSERT Conversation {
|
||||
name := 'Default',
|
||||
user := global currentUser,
|
||||
position := 1,
|
||||
selected := true,
|
||||
position := 1
|
||||
}`)
|
||||
if err != nil {
|
||||
fmt.Println("Error creating default conversation")
|
||||
@ -292,13 +291,13 @@ func handleCallback(c *fiber.Ctx) error {
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != fiber.StatusOK {
|
||||
return c.Render("error", fiber.Map{"Text": "Response Status is not OK"}, "layouts/main")
|
||||
return c.Render("error", fiber.Map{"Text": "Hello"}, "layouts/main")
|
||||
}
|
||||
|
||||
var tokenResponse TokenResponse
|
||||
err = json.NewDecoder(resp.Body).Decode(&tokenResponse)
|
||||
if err != nil {
|
||||
return c.Render("error", fiber.Map{"Text": "Can't decode response"}, "layouts/main")
|
||||
return c.Render("error", fiber.Map{"Text": "Hello"}, "layouts/main")
|
||||
}
|
||||
|
||||
c.Cookie(&fiber.Cookie{
|
||||
@ -319,7 +318,7 @@ func handleSignOut(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
func handleEmailVerification(c *fiber.Ctx) error {
|
||||
return c.Render("error", fiber.Map{"Text": "Email auth not yet implemented"}, "layouts/main")
|
||||
return c.Render("error", fiber.Map{"Text": "Hello"}, "layouts/main")
|
||||
}
|
||||
|
||||
func SendNoreplyEmail(to string, subject string, content string) {
|
||||
|
5
Chat.go
5
Chat.go
@ -269,14 +269,11 @@ func GenerateMessageContentHTML(authCookie string, messageId string, onlyContent
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": authCookie}).Execute(edgeCtx, `
|
||||
_ = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": authCookie}).Execute(edgeCtx, `
|
||||
UPDATE Message
|
||||
FILTER .id = <uuid>$0
|
||||
SET {selected := true};
|
||||
`, messageUUID)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
@ -105,30 +105,8 @@ type CompanyInfo struct {
|
||||
Icon string `edgedb:"icon"`
|
||||
}
|
||||
|
||||
var (
|
||||
edgeCtx context.Context
|
||||
edgeGlobalClient *edgedb.Client
|
||||
allModelInfo []ModelInfo
|
||||
allCompany []CompanyInfo
|
||||
)
|
||||
|
||||
func getModelInfoByID(id edgedb.UUID) (ModelInfo, bool) {
|
||||
for _, model := range allModelInfo {
|
||||
if model.ID == id {
|
||||
return model, true
|
||||
}
|
||||
}
|
||||
return ModelInfo{}, false
|
||||
}
|
||||
|
||||
func getCompanyInfoByID(id edgedb.UUID) (CompanyInfo, bool) {
|
||||
for _, company := range allCompany {
|
||||
if company.ID == id {
|
||||
return company, true
|
||||
}
|
||||
}
|
||||
return CompanyInfo{}, false
|
||||
}
|
||||
var edgeCtx context.Context
|
||||
var edgeGlobalClient *edgedb.Client
|
||||
|
||||
func init() {
|
||||
var ctx = context.Background()
|
||||
@ -140,16 +118,6 @@ func init() {
|
||||
|
||||
edgeCtx = ctx
|
||||
edgeGlobalClient = client
|
||||
|
||||
err = edgeGlobalClient.Query(edgeCtx, `SELECT ModelInfo { id, inputPrice, outputPrice, modelID, name, company}`, &allModelInfo)
|
||||
if err != nil {
|
||||
panic("Can't get all ModelInfo")
|
||||
}
|
||||
|
||||
err = edgeGlobalClient.Query(edgeCtx, `SELECT Company { id, icon, name}`, &allCompany)
|
||||
if err != nil {
|
||||
panic("Can't get all Company")
|
||||
}
|
||||
}
|
||||
|
||||
func checkIfLogin(c *fiber.Ctx) bool {
|
||||
|
@ -53,7 +53,6 @@ func GeneratePlaceholderHTML(c *fiber.Ctx, message string, selectedLLMIds []stri
|
||||
key
|
||||
},
|
||||
modelInfo : {
|
||||
id,
|
||||
modelID,
|
||||
company : {
|
||||
icon,
|
||||
@ -139,7 +138,7 @@ func GenerateMultipleMessagesHandler(c *fiber.Ctx) error {
|
||||
defer cancel() // Ensure the context is cancelled to free resources
|
||||
|
||||
// Determine which message function to call based on the model
|
||||
var addMessageFunc func(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string) string
|
||||
var addMessageFunc func(c *fiber.Ctx, llm LLM, messages []Message) string
|
||||
switch selectedLLMs[idx].Model.Company.Name {
|
||||
case "openai":
|
||||
addMessageFunc = RequestOpenai
|
||||
@ -150,7 +149,7 @@ func GenerateMultipleMessagesHandler(c *fiber.Ctx) error {
|
||||
case "groq":
|
||||
addMessageFunc = RequestGroq
|
||||
case "huggingface":
|
||||
addMessageFunc = RequestCustomEndpoint
|
||||
addMessageFunc = RequestHuggingface
|
||||
case "google":
|
||||
addMessageFunc = RequestGoogle
|
||||
case "perplexity":
|
||||
@ -165,7 +164,7 @@ func GenerateMultipleMessagesHandler(c *fiber.Ctx) error {
|
||||
addMessageFunc = RequestDeepseek
|
||||
}
|
||||
|
||||
var content string = addMessageFunc(c, selectedLLMs[idx], messages, "")
|
||||
var content string = addMessageFunc(c, selectedLLMs[idx], messages)
|
||||
var messageUUID edgedb.UUID = insertBotMessage(c, content, selectedLLMs[idx].ID)
|
||||
|
||||
var message Message
|
||||
|
@ -50,7 +50,7 @@ func init() {
|
||||
AnthropicErrorCodes["529"] = "Provider error: Anthropic’s server is temporarily overloaded."
|
||||
}
|
||||
|
||||
func RequestAnthropic(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string) string {
|
||||
func RequestAnthropic(c *fiber.Ctx, llm LLM, messages []Message) string {
|
||||
model := llm.Model.ModelID
|
||||
temperature := float64(llm.Temperature)
|
||||
context := llm.Context
|
||||
@ -63,20 +63,15 @@ func RequestAnthropic(c *fiber.Ctx, llm LLM, messages []Message, testApiKey stri
|
||||
var apiKey struct {
|
||||
Key string `edgedb:"key"`
|
||||
}
|
||||
|
||||
if testApiKey == "" {
|
||||
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
|
||||
}
|
||||
FILTER .<keys[is Setting].<setting[is User] = global currentUser and .company.name = "anthropic"
|
||||
LIMIT 1
|
||||
`, &apiKey, "anthropic")
|
||||
if err != nil {
|
||||
return "JADE internal error: 01-00-0000. Please contact the support."
|
||||
}
|
||||
} else {
|
||||
apiKey.Key = testApiKey
|
||||
if err != nil {
|
||||
return "JADE internal error: 01-00-0000. Please contact the support."
|
||||
}
|
||||
|
||||
url := "https://api.anthropic.com/v1/messages"
|
||||
@ -132,13 +127,16 @@ func RequestAnthropic(c *fiber.Ctx, llm LLM, messages []Message, testApiKey stri
|
||||
return "JADE internal error: 01-01-0005. Please contact the support."
|
||||
}
|
||||
|
||||
if testApiKey != "" {
|
||||
return chatCompletionResponse.Content[0].Text
|
||||
}
|
||||
|
||||
var usedModelInfo ModelInfo
|
||||
usedModelInfo, found := getModelInfoByID(llm.Model.ID)
|
||||
if !found {
|
||||
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
|
||||
SELECT ModelInfo {
|
||||
inputPrice,
|
||||
outputPrice
|
||||
}
|
||||
FILTER .modelID = <str>$0
|
||||
LIMIT 1
|
||||
`, &usedModelInfo, model)
|
||||
if err != nil {
|
||||
logErrorCode.Println("01-00-0006")
|
||||
return "JADE internal error: 01-00-0006. Please contact the support."
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func RequestCustomEndpoint(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string) string {
|
||||
func RequestHuggingface(c *fiber.Ctx, llm LLM, messages []Message) string {
|
||||
url := llm.Endpoint.Endpoint
|
||||
temperature := float64(llm.Temperature)
|
||||
context := llm.Context
|
||||
|
@ -23,7 +23,7 @@ func init() {
|
||||
DeepseekErrorCodes["503"] = "Provider error: Deepseek’s server is temporarily overloaded."
|
||||
}
|
||||
|
||||
func RequestDeepseek(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string) string {
|
||||
func RequestDeepseek(c *fiber.Ctx, llm LLM, messages []Message) string {
|
||||
model := llm.Model.ModelID
|
||||
temperature := float64(llm.Temperature)
|
||||
context := llm.Context
|
||||
@ -32,8 +32,7 @@ func RequestDeepseek(c *fiber.Ctx, llm LLM, messages []Message, testApiKey strin
|
||||
url := "https://api.deepseek.com/chat/completions"
|
||||
|
||||
var apiKey string
|
||||
if testApiKey == "" {
|
||||
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 {
|
||||
@ -42,12 +41,8 @@ func RequestDeepseek(c *fiber.Ctx, llm LLM, messages []Message, testApiKey strin
|
||||
)
|
||||
select filtered_keys.key limit 1
|
||||
`, &apiKey, "deepseek")
|
||||
if err != nil {
|
||||
logErrorCode.Println("08-00-0000")
|
||||
return "JADE internal error: 08-00-0000. Please contact the support."
|
||||
}
|
||||
} else {
|
||||
apiKey = testApiKey
|
||||
if err != nil {
|
||||
return "JADE internal error: 08-00-0000. Please contact the support."
|
||||
}
|
||||
|
||||
requestBody := OpenaiChatCompletionRequest{
|
||||
@ -99,13 +94,16 @@ func RequestDeepseek(c *fiber.Ctx, llm LLM, messages []Message, testApiKey strin
|
||||
return "JADE internal error: 08-01-0005. Please contact the support."
|
||||
}
|
||||
|
||||
if testApiKey != "" {
|
||||
return chatCompletionResponse.Choices[0].Message.Content
|
||||
}
|
||||
|
||||
var usedModelInfo ModelInfo
|
||||
usedModelInfo, found := getModelInfoByID(llm.Model.ID)
|
||||
if !found {
|
||||
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
|
||||
SELECT ModelInfo {
|
||||
inputPrice,
|
||||
outputPrice
|
||||
}
|
||||
FILTER .modelID = <str>$0
|
||||
LIMIT 1
|
||||
`, &usedModelInfo, model)
|
||||
if err != nil {
|
||||
logErrorCode.Println("08-00-0006")
|
||||
return "JADE internal error: 08-00-0006. Please contact the support."
|
||||
}
|
||||
|
@ -10,15 +10,14 @@ import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func RequestFirework(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string) string {
|
||||
func RequestFirework(c *fiber.Ctx, llm LLM, messages []Message) string {
|
||||
model := llm.Model.ModelID
|
||||
temperature := float64(llm.Temperature)
|
||||
context := llm.Context
|
||||
maxTokens := int(llm.MaxToken)
|
||||
|
||||
var apiKey string
|
||||
if testApiKey == "" {
|
||||
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 {
|
||||
@ -27,12 +26,9 @@ func RequestFirework(c *fiber.Ctx, llm LLM, messages []Message, testApiKey strin
|
||||
)
|
||||
select filtered_keys.key limit 1
|
||||
`, &apiKey, "fireworks")
|
||||
if err != nil {
|
||||
logErrorCode.Println("09-00-0000")
|
||||
return "JADE internal error: 09-00-0000. Please contact the support."
|
||||
}
|
||||
} else {
|
||||
apiKey = testApiKey
|
||||
if err != nil {
|
||||
logErrorCode.Println("09-00-0000")
|
||||
return "JADE internal error: 09-00-0000. Please contact the support."
|
||||
}
|
||||
|
||||
url := "https://api.fireworks.ai/inference/v1/chat/completions"
|
||||
@ -86,13 +82,16 @@ func RequestFirework(c *fiber.Ctx, llm LLM, messages []Message, testApiKey strin
|
||||
return "JADE internal error: 09-01-0005. Please contact the support."
|
||||
}
|
||||
|
||||
if testApiKey != "" {
|
||||
return chatCompletionResponse.Choices[0].Message.Content
|
||||
}
|
||||
|
||||
var usedModelInfo ModelInfo
|
||||
usedModelInfo, found := getModelInfoByID(llm.Model.ID)
|
||||
if !found {
|
||||
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
|
||||
SELECT ModelInfo {
|
||||
inputPrice,
|
||||
outputPrice
|
||||
}
|
||||
FILTER .modelID = <str>$0
|
||||
LIMIT 1
|
||||
`, &usedModelInfo, model)
|
||||
if err != nil {
|
||||
logErrorCode.Println("09-00-0006")
|
||||
return "JADE internal error: 09-00-0006. Please contact the support."
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ func init() {
|
||||
GoogleErrorCodes["503"] = "Provider error: Servers are experiencing high traffic - Please retry your requests after a brief wait."
|
||||
}
|
||||
|
||||
func RequestGoogle(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string) string {
|
||||
func RequestGoogle(c *fiber.Ctx, llm LLM, messages []Message) string {
|
||||
model := llm.Model.ModelID
|
||||
|
||||
// TODO: Use those parameters
|
||||
@ -71,8 +71,7 @@ func RequestGoogle(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string)
|
||||
//maxTokens := int(llm.MaxToken)
|
||||
|
||||
var apiKey string
|
||||
if testApiKey == "" {
|
||||
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 {
|
||||
@ -81,12 +80,8 @@ func RequestGoogle(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string)
|
||||
)
|
||||
select filtered_keys.key limit 1
|
||||
`, &apiKey, "google")
|
||||
if err != nil {
|
||||
logErrorCode.Println("03-00-0000")
|
||||
return "JADE internal error: 03-00-0000. Please contact the support."
|
||||
}
|
||||
} else {
|
||||
apiKey = testApiKey
|
||||
if err != nil {
|
||||
return "JADE internal error: 03-00-0000. Please contact the support."
|
||||
}
|
||||
|
||||
url := "https://generativelanguage.googleapis.com/v1beta/models/" + model + ":generateContent?key=" + apiKey
|
||||
@ -152,13 +147,16 @@ func RequestGoogle(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string)
|
||||
return "JADE internal error: 03-01-0005. Please contact the support."
|
||||
}
|
||||
|
||||
if testApiKey != "" {
|
||||
return chatCompletionResponse.Candidates[0].Content.Parts[0].Text
|
||||
}
|
||||
|
||||
var usedModelInfo ModelInfo
|
||||
usedModelInfo, found := getModelInfoByID(llm.Model.ID)
|
||||
if !found {
|
||||
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
|
||||
SELECT ModelInfo {
|
||||
inputPrice,
|
||||
outputPrice
|
||||
}
|
||||
FILTER .modelID = <str>$0
|
||||
LIMIT 1
|
||||
`, &usedModelInfo, model)
|
||||
if err != nil {
|
||||
logErrorCode.Println("03-00-0006")
|
||||
return "JADE internal error: 03-00-0006. Please contact the support."
|
||||
}
|
||||
|
@ -23,15 +23,14 @@ func init() {
|
||||
GroqErrorCodes["503"] = "Provider error: The server is not ready to handle the request, often due to maintenance or overload. Wait before retrying the request."
|
||||
}
|
||||
|
||||
func RequestGroq(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string) string {
|
||||
func RequestGroq(c *fiber.Ctx, llm LLM, messages []Message) string {
|
||||
model := llm.Model.ModelID
|
||||
temperature := float64(llm.Temperature)
|
||||
context := llm.Context
|
||||
maxTokens := int(llm.MaxToken)
|
||||
|
||||
var apiKey string
|
||||
if testApiKey == "" {
|
||||
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 {
|
||||
@ -40,12 +39,9 @@ func RequestGroq(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string) s
|
||||
)
|
||||
select filtered_keys.key limit 1
|
||||
`, &apiKey, "groq")
|
||||
if err != nil {
|
||||
logErrorCode.Println("04-00-0000")
|
||||
return "JADE internal error: 04-00-0000. Please contact the support."
|
||||
}
|
||||
} else {
|
||||
apiKey = testApiKey
|
||||
if err != nil {
|
||||
logErrorCode.Println("04-00-0000")
|
||||
return "JADE internal error: 04-00-0000. Please contact the support."
|
||||
}
|
||||
|
||||
url := "https://api.groq.com/openai/v1/chat/completions"
|
||||
@ -99,13 +95,16 @@ func RequestGroq(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string) s
|
||||
return "JADE internal error: 04-01-0005. Please contact the support."
|
||||
}
|
||||
|
||||
if testApiKey != "" {
|
||||
return chatCompletionResponse.Choices[0].Message.Content
|
||||
}
|
||||
|
||||
var usedModelInfo ModelInfo
|
||||
usedModelInfo, found := getModelInfoByID(llm.Model.ID)
|
||||
if !found {
|
||||
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
|
||||
SELECT ModelInfo {
|
||||
inputPrice,
|
||||
outputPrice
|
||||
}
|
||||
FILTER .modelID = <str>$0
|
||||
LIMIT 1
|
||||
`, &usedModelInfo, model)
|
||||
if err != nil {
|
||||
logErrorCode.Println("04-00-0006")
|
||||
return "JADE internal error: 04-00-0006. Please contact the support."
|
||||
}
|
||||
|
@ -10,15 +10,14 @@ import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func RequestMistral(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string) string {
|
||||
func RequestMistral(c *fiber.Ctx, llm LLM, messages []Message) string {
|
||||
model := llm.Model.ModelID
|
||||
temperature := float64(llm.Temperature)
|
||||
context := llm.Context
|
||||
maxTokens := int(llm.MaxToken)
|
||||
|
||||
var apiKey string
|
||||
if testApiKey == "" {
|
||||
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 {
|
||||
@ -27,12 +26,9 @@ func RequestMistral(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string
|
||||
)
|
||||
select filtered_keys.key limit 1
|
||||
`, &apiKey, "mistral")
|
||||
if err != nil {
|
||||
logErrorCode.Println("02-00-0000")
|
||||
return "JADE internal error: 02-00-0000. Please contact the support."
|
||||
}
|
||||
} else {
|
||||
apiKey = testApiKey
|
||||
if err != nil {
|
||||
logErrorCode.Println("02-00-0000")
|
||||
return "JADE internal error: 02-00-0000. Please contact the support."
|
||||
}
|
||||
|
||||
url := "https://api.mistral.ai/v1/chat/completions"
|
||||
@ -86,13 +82,16 @@ func RequestMistral(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string
|
||||
return "JADE internal error: 02-01-0005. Please contact the support."
|
||||
}
|
||||
|
||||
if testApiKey != "" {
|
||||
return chatCompletionResponse.Choices[0].Message.Content
|
||||
}
|
||||
|
||||
var usedModelInfo ModelInfo
|
||||
usedModelInfo, found := getModelInfoByID(llm.Model.ID)
|
||||
if !found {
|
||||
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
|
||||
SELECT ModelInfo {
|
||||
inputPrice,
|
||||
outputPrice
|
||||
}
|
||||
FILTER .modelID = <str>$0
|
||||
LIMIT 1
|
||||
`, &usedModelInfo, model)
|
||||
if err != nil {
|
||||
logErrorCode.Println("02-00-0006")
|
||||
return "JADE internal error: 02-00-0006. Please contact the support."
|
||||
}
|
||||
|
@ -10,15 +10,14 @@ import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func RequestNim(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string) string {
|
||||
func RequestNim(c *fiber.Ctx, llm LLM, messages []Message) string {
|
||||
model := llm.Model.ModelID
|
||||
temperature := float64(llm.Temperature)
|
||||
context := llm.Context
|
||||
maxTokens := int(llm.MaxToken)
|
||||
|
||||
var apiKey string
|
||||
if testApiKey == "" {
|
||||
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 {
|
||||
@ -27,12 +26,9 @@ func RequestNim(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string) st
|
||||
)
|
||||
select filtered_keys.key limit 1
|
||||
`, &apiKey, "nim")
|
||||
if err != nil {
|
||||
logErrorCode.Println("05-00-0000")
|
||||
return "JADE internal error: 05-00-0000. Please contact the support."
|
||||
}
|
||||
} else {
|
||||
apiKey = testApiKey
|
||||
if err != nil {
|
||||
logErrorCode.Println("05-0")
|
||||
return "JADE internal error: 05-00-0000. Please contact the support."
|
||||
}
|
||||
|
||||
url := "https://integrate.api.nvidia.com/v1/chat/completions"
|
||||
@ -86,13 +82,16 @@ func RequestNim(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string) st
|
||||
return "JADE internal error: 05-01-0005. Please contact the support."
|
||||
}
|
||||
|
||||
if testApiKey != "" {
|
||||
return chatCompletionResponse.Choices[0].Message.Content
|
||||
}
|
||||
|
||||
var usedModelInfo ModelInfo
|
||||
usedModelInfo, found := getModelInfoByID(llm.Model.ID)
|
||||
if !found {
|
||||
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
|
||||
SELECT ModelInfo {
|
||||
inputPrice,
|
||||
outputPrice
|
||||
}
|
||||
FILTER .modelID = <str>$0
|
||||
LIMIT 1
|
||||
`, &usedModelInfo, model)
|
||||
if err != nil {
|
||||
logErrorCode.Println("05-00-0006")
|
||||
return "JADE internal error: 05-00-0006. Please contact the support."
|
||||
}
|
||||
|
@ -51,15 +51,14 @@ func init() {
|
||||
OpenaiErrorCodes["503"] = "Provider error: Servers are experiencing high traffic - Please retry your requests after a brief wait."
|
||||
}
|
||||
|
||||
func RequestOpenai(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string) string {
|
||||
func RequestOpenai(c *fiber.Ctx, llm LLM, messages []Message) string {
|
||||
model := llm.Model.ModelID
|
||||
temperature := float64(llm.Temperature)
|
||||
context := llm.Context
|
||||
maxTokens := int(llm.MaxToken)
|
||||
|
||||
var apiKey string
|
||||
if testApiKey == "" {
|
||||
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 {
|
||||
@ -68,12 +67,9 @@ func RequestOpenai(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string)
|
||||
)
|
||||
select filtered_keys.key limit 1
|
||||
`, &apiKey, "openai")
|
||||
if err != nil {
|
||||
logErrorCode.Println("00-00-0000")
|
||||
return "JADE internal error: 00-00-0000. Please contact the support."
|
||||
}
|
||||
} else {
|
||||
apiKey = testApiKey
|
||||
if err != nil {
|
||||
logErrorCode.Println("00-00-0000")
|
||||
return "JADE internal error: 00-00-0000. Please contact the support."
|
||||
}
|
||||
|
||||
url := "https://api.openai.com/v1/chat/completions"
|
||||
@ -127,13 +123,16 @@ func RequestOpenai(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string)
|
||||
return "JADE internal error: 00-01-0005. Please contact the support."
|
||||
}
|
||||
|
||||
if testApiKey != "" {
|
||||
return chatCompletionResponse.Choices[0].Message.Content
|
||||
}
|
||||
|
||||
var usedModelInfo ModelInfo
|
||||
usedModelInfo, found := getModelInfoByID(llm.Model.ID)
|
||||
if !found {
|
||||
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
|
||||
SELECT ModelInfo {
|
||||
inputPrice,
|
||||
outputPrice
|
||||
}
|
||||
FILTER .modelID = <str>$0
|
||||
LIMIT 1
|
||||
`, &usedModelInfo, model)
|
||||
if err != nil {
|
||||
logErrorCode.Println("00-00-0006")
|
||||
return "JADE internal error: 00-00-0006. Please contact the support."
|
||||
}
|
||||
|
@ -10,15 +10,14 @@ import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func RequestPerplexity(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string) string {
|
||||
func RequestPerplexity(c *fiber.Ctx, llm LLM, messages []Message) string {
|
||||
model := llm.Model.ModelID
|
||||
temperature := float64(llm.Temperature)
|
||||
context := llm.Context
|
||||
maxTokens := int(llm.MaxToken)
|
||||
|
||||
var apiKey string
|
||||
if testApiKey == "" {
|
||||
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 {
|
||||
@ -27,12 +26,9 @@ func RequestPerplexity(c *fiber.Ctx, llm LLM, messages []Message, testApiKey str
|
||||
)
|
||||
select filtered_keys.key limit 1
|
||||
`, &apiKey, "perplexity")
|
||||
if err != nil {
|
||||
logErrorCode.Println("06-00-0000")
|
||||
return "JADE internal error: 06-00-0000. Please contact the support."
|
||||
}
|
||||
} else {
|
||||
apiKey = testApiKey
|
||||
if err != nil {
|
||||
logErrorCode.Println("06-00-0000")
|
||||
return "JADE internal error: 06-00-0000. Please contact the support."
|
||||
}
|
||||
|
||||
url := "https://api.perplexity.ai/chat/completions"
|
||||
@ -86,13 +82,16 @@ func RequestPerplexity(c *fiber.Ctx, llm LLM, messages []Message, testApiKey str
|
||||
return "JADE internal error: 06-01-0005. Please contact the support."
|
||||
}
|
||||
|
||||
if testApiKey != "" {
|
||||
return chatCompletionResponse.Choices[0].Message.Content
|
||||
}
|
||||
|
||||
var usedModelInfo ModelInfo
|
||||
usedModelInfo, found := getModelInfoByID(llm.Model.ID)
|
||||
if !found {
|
||||
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
|
||||
SELECT ModelInfo {
|
||||
inputPrice,
|
||||
outputPrice
|
||||
}
|
||||
FILTER .modelID = <str>$0
|
||||
LIMIT 1
|
||||
`, &usedModelInfo, model)
|
||||
if err != nil {
|
||||
logErrorCode.Println("06-00-0006")
|
||||
return "JADE internal error: 06-00-0006. Please contact the support."
|
||||
}
|
||||
|
@ -4,12 +4,9 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"math"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
@ -45,15 +42,14 @@ func init() {
|
||||
TogetherErrorCodes["529"] = "Provider error: n unexpected error has occurred internal to Together’s systems."
|
||||
}
|
||||
|
||||
func RequestTogether(c *fiber.Ctx, llm LLM, messages []Message, testApiKey string) string {
|
||||
func RequestTogether(c *fiber.Ctx, llm LLM, messages []Message) string {
|
||||
model := llm.Model.ModelID
|
||||
temperature := float64(llm.Temperature)
|
||||
context := llm.Context
|
||||
maxTokens := int(llm.MaxToken)
|
||||
|
||||
var apiKey string
|
||||
if testApiKey == "" {
|
||||
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 {
|
||||
@ -62,12 +58,9 @@ func RequestTogether(c *fiber.Ctx, llm LLM, messages []Message, testApiKey strin
|
||||
)
|
||||
select filtered_keys.key limit 1
|
||||
`, &apiKey, "together")
|
||||
if err != nil {
|
||||
logErrorCode.Println("07-00-0000")
|
||||
return "JADE internal error: 07-00-0000. Please contact the support."
|
||||
}
|
||||
} else {
|
||||
apiKey = testApiKey
|
||||
if err != nil {
|
||||
logErrorCode.Println("07-00-0000")
|
||||
return "JADE internal error: 07-00-0000. Please contact the support."
|
||||
}
|
||||
|
||||
url := "https://api.together.xyz/v1/completions"
|
||||
@ -121,13 +114,16 @@ func RequestTogether(c *fiber.Ctx, llm LLM, messages []Message, testApiKey strin
|
||||
return "JADE internal error: 07-01-0005. Please contact the support."
|
||||
}
|
||||
|
||||
if testApiKey != "" {
|
||||
return chatCompletionResponse.Choices[0].Text
|
||||
}
|
||||
|
||||
var usedModelInfo ModelInfo
|
||||
usedModelInfo, found := getModelInfoByID(llm.Model.ID)
|
||||
if !found {
|
||||
err = edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
|
||||
SELECT ModelInfo {
|
||||
inputPrice,
|
||||
outputPrice
|
||||
}
|
||||
FILTER .modelID = <str>$0
|
||||
LIMIT 1
|
||||
`, &usedModelInfo, model)
|
||||
if err != nil {
|
||||
logErrorCode.Println("07-00-0006")
|
||||
return "JADE internal error: 07-00-0006. Please contact the support."
|
||||
}
|
||||
@ -143,162 +139,3 @@ func RequestTogether(c *fiber.Ctx, llm LLM, messages []Message, testApiKey strin
|
||||
|
||||
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 = <str>$0 AND .<keys[is Setting].<setting[is User] = global currentUser
|
||||
)
|
||||
select filtered_keys.key limit 1
|
||||
`, &apiKey, "together")
|
||||
if err != nil {
|
||||
logErrorCode.Println("08-00-0000")
|
||||
return
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
logErrorCode.Println("08-01-0001")
|
||||
return
|
||||
}
|
||||
|
||||
req.Header.Set("Accept", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer "+apiKey)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
logErrorCode.Println("08-02-0002")
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
logErrorCode.Println("08-01-0003")
|
||||
return
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
logErrorCode.Println("08-03-0004 -", resp.Status, "-", string(body))
|
||||
return
|
||||
}
|
||||
|
||||
var togetherModels []TogetherModel
|
||||
err = json.Unmarshal(body, &togetherModels)
|
||||
if err != nil {
|
||||
logErrorCode.Println("08-01-0005")
|
||||
return
|
||||
}
|
||||
|
||||
var exist bool
|
||||
var savedModel ModelInfo
|
||||
var newModelFound bool = false
|
||||
const epsilon = 1e-9
|
||||
|
||||
fmt.Println("Updating Together ModelInfo:")
|
||||
for _, model := range togetherModels {
|
||||
if model.Type == "chat" {
|
||||
exist = false
|
||||
for _, currentModel := range currentModelInfos {
|
||||
if currentModel.ModelID == model.ID {
|
||||
exist = true
|
||||
savedModel = currentModel
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if exist {
|
||||
if math.Abs(model.Pricing.Input/1000000-float64(savedModel.InputPrice)) > 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 = <str>$0 SET { inputPrice := <float32>$1, outputPrice := <float32>$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 := <str>$0, inputPrice := <float32>$1, outputPrice := <float32>$2, company := assert_single(( SELECT Company FILTER .name = <str>$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 = <str>$0 AND .company.name = <str>$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")
|
||||
}
|
||||
|
21
TODO.md
21
TODO.md
@ -1,12 +1,12 @@
|
||||
# Bugs
|
||||
[X] Sometime I can redo or edit but the button is not available
|
||||
[ ] 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
|
||||
[X] Add all Together AI models
|
||||
[ ] Add all Together AI models
|
||||
|
||||
# Features
|
||||
[X] SSE to WebSocket
|
||||
@ -16,18 +16,21 @@
|
||||
[X] Add Deepseek API
|
||||
[X] Add TogetherAI API
|
||||
[X] Add Nvidia NIM
|
||||
[ ] Host the database on Fly.io
|
||||
[ ] Add login with email and password
|
||||
[ ] Add login with AppleID
|
||||
[X] Better temperature settings. (Anthropic from 0-1, OpenAI from 0-2, DeepSeek from -2-2, ect)
|
||||
[X] Auto update the modelsInfos db (At least remove unavailable models and send me an email when new one arrive)
|
||||
[ ] Add login with other provider
|
||||
[ ] Better temperature settings. (Anthropic from 0-1, OpenAI from 0-2, DeepSeek from -2-2, ect)
|
||||
[ ] Auto update the modelsInfos list
|
||||
[ ] Encrypt the API keys
|
||||
[ ] Send me an email every xh with the new code error logs
|
||||
|
||||
# Opti
|
||||
[ ] Import all company and modelInfos at the start to not request the db
|
||||
[ ] Reduce db query
|
||||
[ ] 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
|
||||
[ ] Split Chat.go into smaller files
|
||||
[ ] Create a Request package
|
||||
[ ] Use the normal RequestProvider function instead of TestProvider to remove TestProvider
|
||||
[ ] Add a dashboard to see the use of the app (Like how many this route or this model, ect) accross all users
|
||||
|
Binary file not shown.
Binary file not shown.
1
edgedb.key
Normal file
1
edgedb.key
Normal file
@ -0,0 +1 @@
|
||||
nbwt1_eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJlZGIuZC5hbGwiOnRydWUsImVkYi5pIjpbIk1yQm91bnR5L0pBREUiXSwiZWRiLnIuYWxsIjp0cnVlLCJpYXQiOjE3MTQ2NzcwMjQsImlzcyI6ImF3cy5lZGdlZGIuY2xvdWQiLCJqdGkiOiJvVUJNaWdpM0VlLXZ5MXZMejdLQUNBIiwic3ViIjoic3BWSkxBTV9FZS0yY1dfZzRSY1V0ZyJ9.awIKoPzGKsBzAfTgI2HwmmFf8fbHKTsVV57M3lFSn2jbPEMEZhtwJdvsRoPGRiD922qSFFVmcPQ_IKkVNVZT6g
|
@ -1,2 +1,2 @@
|
||||
[edgedb]
|
||||
server-version = "5.6"
|
||||
server-version = "5.2"
|
||||
|
7
main.go
7
main.go
@ -123,9 +123,6 @@ 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)
|
||||
@ -147,7 +144,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
"deepseek": c.FormValue("deepseek_key"),
|
||||
}
|
||||
|
||||
requestFunctions := map[string]func(*fiber.Ctx, LLM, []Message, string) string{
|
||||
requestFunctions := map[string]func(*fiber.Ctx, LLM, []Message) string{
|
||||
"openai": RequestOpenai,
|
||||
"anthropic": RequestAnthropic,
|
||||
"mistral": RequestMistral,
|
||||
@ -208,7 +205,7 @@ func addKeys(c *fiber.Ctx) error {
|
||||
Context: "",
|
||||
}
|
||||
|
||||
var responseText string = requestFunctions[company](c, llm, messages, key)
|
||||
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))
|
||||
|
BIN
static/main-v0.4.wasm
Normal file
BIN
static/main-v0.4.wasm
Normal file
Binary file not shown.
561
static/wasm_exec.js
Normal file
561
static/wasm_exec.js
Normal file
@ -0,0 +1,561 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
"use strict";
|
||||
|
||||
(() => {
|
||||
const enosys = () => {
|
||||
const err = new Error("not implemented");
|
||||
err.code = "ENOSYS";
|
||||
return err;
|
||||
};
|
||||
|
||||
if (!globalThis.fs) {
|
||||
let outputBuf = "";
|
||||
globalThis.fs = {
|
||||
constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1 }, // unused
|
||||
writeSync(fd, buf) {
|
||||
outputBuf += decoder.decode(buf);
|
||||
const nl = outputBuf.lastIndexOf("\n");
|
||||
if (nl != -1) {
|
||||
console.log(outputBuf.substring(0, nl));
|
||||
outputBuf = outputBuf.substring(nl + 1);
|
||||
}
|
||||
return buf.length;
|
||||
},
|
||||
write(fd, buf, offset, length, position, callback) {
|
||||
if (offset !== 0 || length !== buf.length || position !== null) {
|
||||
callback(enosys());
|
||||
return;
|
||||
}
|
||||
const n = this.writeSync(fd, buf);
|
||||
callback(null, n);
|
||||
},
|
||||
chmod(path, mode, callback) { callback(enosys()); },
|
||||
chown(path, uid, gid, callback) { callback(enosys()); },
|
||||
close(fd, callback) { callback(enosys()); },
|
||||
fchmod(fd, mode, callback) { callback(enosys()); },
|
||||
fchown(fd, uid, gid, callback) { callback(enosys()); },
|
||||
fstat(fd, callback) { callback(enosys()); },
|
||||
fsync(fd, callback) { callback(null); },
|
||||
ftruncate(fd, length, callback) { callback(enosys()); },
|
||||
lchown(path, uid, gid, callback) { callback(enosys()); },
|
||||
link(path, link, callback) { callback(enosys()); },
|
||||
lstat(path, callback) { callback(enosys()); },
|
||||
mkdir(path, perm, callback) { callback(enosys()); },
|
||||
open(path, flags, mode, callback) { callback(enosys()); },
|
||||
read(fd, buffer, offset, length, position, callback) { callback(enosys()); },
|
||||
readdir(path, callback) { callback(enosys()); },
|
||||
readlink(path, callback) { callback(enosys()); },
|
||||
rename(from, to, callback) { callback(enosys()); },
|
||||
rmdir(path, callback) { callback(enosys()); },
|
||||
stat(path, callback) { callback(enosys()); },
|
||||
symlink(path, link, callback) { callback(enosys()); },
|
||||
truncate(path, length, callback) { callback(enosys()); },
|
||||
unlink(path, callback) { callback(enosys()); },
|
||||
utimes(path, atime, mtime, callback) { callback(enosys()); },
|
||||
};
|
||||
}
|
||||
|
||||
if (!globalThis.process) {
|
||||
globalThis.process = {
|
||||
getuid() { return -1; },
|
||||
getgid() { return -1; },
|
||||
geteuid() { return -1; },
|
||||
getegid() { return -1; },
|
||||
getgroups() { throw enosys(); },
|
||||
pid: -1,
|
||||
ppid: -1,
|
||||
umask() { throw enosys(); },
|
||||
cwd() { throw enosys(); },
|
||||
chdir() { throw enosys(); },
|
||||
}
|
||||
}
|
||||
|
||||
if (!globalThis.crypto) {
|
||||
throw new Error("globalThis.crypto is not available, polyfill required (crypto.getRandomValues only)");
|
||||
}
|
||||
|
||||
if (!globalThis.performance) {
|
||||
throw new Error("globalThis.performance is not available, polyfill required (performance.now only)");
|
||||
}
|
||||
|
||||
if (!globalThis.TextEncoder) {
|
||||
throw new Error("globalThis.TextEncoder is not available, polyfill required");
|
||||
}
|
||||
|
||||
if (!globalThis.TextDecoder) {
|
||||
throw new Error("globalThis.TextDecoder is not available, polyfill required");
|
||||
}
|
||||
|
||||
const encoder = new TextEncoder("utf-8");
|
||||
const decoder = new TextDecoder("utf-8");
|
||||
|
||||
globalThis.Go = class {
|
||||
constructor() {
|
||||
this.argv = ["js"];
|
||||
this.env = {};
|
||||
this.exit = (code) => {
|
||||
if (code !== 0) {
|
||||
console.warn("exit code:", code);
|
||||
}
|
||||
};
|
||||
this._exitPromise = new Promise((resolve) => {
|
||||
this._resolveExitPromise = resolve;
|
||||
});
|
||||
this._pendingEvent = null;
|
||||
this._scheduledTimeouts = new Map();
|
||||
this._nextCallbackTimeoutID = 1;
|
||||
|
||||
const setInt64 = (addr, v) => {
|
||||
this.mem.setUint32(addr + 0, v, true);
|
||||
this.mem.setUint32(addr + 4, Math.floor(v / 4294967296), true);
|
||||
}
|
||||
|
||||
const setInt32 = (addr, v) => {
|
||||
this.mem.setUint32(addr + 0, v, true);
|
||||
}
|
||||
|
||||
const getInt64 = (addr) => {
|
||||
const low = this.mem.getUint32(addr + 0, true);
|
||||
const high = this.mem.getInt32(addr + 4, true);
|
||||
return low + high * 4294967296;
|
||||
}
|
||||
|
||||
const loadValue = (addr) => {
|
||||
const f = this.mem.getFloat64(addr, true);
|
||||
if (f === 0) {
|
||||
return undefined;
|
||||
}
|
||||
if (!isNaN(f)) {
|
||||
return f;
|
||||
}
|
||||
|
||||
const id = this.mem.getUint32(addr, true);
|
||||
return this._values[id];
|
||||
}
|
||||
|
||||
const storeValue = (addr, v) => {
|
||||
const nanHead = 0x7FF80000;
|
||||
|
||||
if (typeof v === "number" && v !== 0) {
|
||||
if (isNaN(v)) {
|
||||
this.mem.setUint32(addr + 4, nanHead, true);
|
||||
this.mem.setUint32(addr, 0, true);
|
||||
return;
|
||||
}
|
||||
this.mem.setFloat64(addr, v, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (v === undefined) {
|
||||
this.mem.setFloat64(addr, 0, true);
|
||||
return;
|
||||
}
|
||||
|
||||
let id = this._ids.get(v);
|
||||
if (id === undefined) {
|
||||
id = this._idPool.pop();
|
||||
if (id === undefined) {
|
||||
id = this._values.length;
|
||||
}
|
||||
this._values[id] = v;
|
||||
this._goRefCounts[id] = 0;
|
||||
this._ids.set(v, id);
|
||||
}
|
||||
this._goRefCounts[id]++;
|
||||
let typeFlag = 0;
|
||||
switch (typeof v) {
|
||||
case "object":
|
||||
if (v !== null) {
|
||||
typeFlag = 1;
|
||||
}
|
||||
break;
|
||||
case "string":
|
||||
typeFlag = 2;
|
||||
break;
|
||||
case "symbol":
|
||||
typeFlag = 3;
|
||||
break;
|
||||
case "function":
|
||||
typeFlag = 4;
|
||||
break;
|
||||
}
|
||||
this.mem.setUint32(addr + 4, nanHead | typeFlag, true);
|
||||
this.mem.setUint32(addr, id, true);
|
||||
}
|
||||
|
||||
const loadSlice = (addr) => {
|
||||
const array = getInt64(addr + 0);
|
||||
const len = getInt64(addr + 8);
|
||||
return new Uint8Array(this._inst.exports.mem.buffer, array, len);
|
||||
}
|
||||
|
||||
const loadSliceOfValues = (addr) => {
|
||||
const array = getInt64(addr + 0);
|
||||
const len = getInt64(addr + 8);
|
||||
const a = new Array(len);
|
||||
for (let i = 0; i < len; i++) {
|
||||
a[i] = loadValue(array + i * 8);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
const loadString = (addr) => {
|
||||
const saddr = getInt64(addr + 0);
|
||||
const len = getInt64(addr + 8);
|
||||
return decoder.decode(new DataView(this._inst.exports.mem.buffer, saddr, len));
|
||||
}
|
||||
|
||||
const timeOrigin = Date.now() - performance.now();
|
||||
this.importObject = {
|
||||
_gotest: {
|
||||
add: (a, b) => a + b,
|
||||
},
|
||||
gojs: {
|
||||
// Go's SP does not change as long as no Go code is running. Some operations (e.g. calls, getters and setters)
|
||||
// may synchronously trigger a Go event handler. This makes Go code get executed in the middle of the imported
|
||||
// function. A goroutine can switch to a new stack if the current stack is too small (see morestack function).
|
||||
// This changes the SP, thus we have to update the SP used by the imported function.
|
||||
|
||||
// func wasmExit(code int32)
|
||||
"runtime.wasmExit": (sp) => {
|
||||
sp >>>= 0;
|
||||
const code = this.mem.getInt32(sp + 8, true);
|
||||
this.exited = true;
|
||||
delete this._inst;
|
||||
delete this._values;
|
||||
delete this._goRefCounts;
|
||||
delete this._ids;
|
||||
delete this._idPool;
|
||||
this.exit(code);
|
||||
},
|
||||
|
||||
// func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)
|
||||
"runtime.wasmWrite": (sp) => {
|
||||
sp >>>= 0;
|
||||
const fd = getInt64(sp + 8);
|
||||
const p = getInt64(sp + 16);
|
||||
const n = this.mem.getInt32(sp + 24, true);
|
||||
fs.writeSync(fd, new Uint8Array(this._inst.exports.mem.buffer, p, n));
|
||||
},
|
||||
|
||||
// func resetMemoryDataView()
|
||||
"runtime.resetMemoryDataView": (sp) => {
|
||||
sp >>>= 0;
|
||||
this.mem = new DataView(this._inst.exports.mem.buffer);
|
||||
},
|
||||
|
||||
// func nanotime1() int64
|
||||
"runtime.nanotime1": (sp) => {
|
||||
sp >>>= 0;
|
||||
setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000);
|
||||
},
|
||||
|
||||
// func walltime() (sec int64, nsec int32)
|
||||
"runtime.walltime": (sp) => {
|
||||
sp >>>= 0;
|
||||
const msec = (new Date).getTime();
|
||||
setInt64(sp + 8, msec / 1000);
|
||||
this.mem.setInt32(sp + 16, (msec % 1000) * 1000000, true);
|
||||
},
|
||||
|
||||
// func scheduleTimeoutEvent(delay int64) int32
|
||||
"runtime.scheduleTimeoutEvent": (sp) => {
|
||||
sp >>>= 0;
|
||||
const id = this._nextCallbackTimeoutID;
|
||||
this._nextCallbackTimeoutID++;
|
||||
this._scheduledTimeouts.set(id, setTimeout(
|
||||
() => {
|
||||
this._resume();
|
||||
while (this._scheduledTimeouts.has(id)) {
|
||||
// for some reason Go failed to register the timeout event, log and try again
|
||||
// (temporary workaround for https://github.com/golang/go/issues/28975)
|
||||
console.warn("scheduleTimeoutEvent: missed timeout event");
|
||||
this._resume();
|
||||
}
|
||||
},
|
||||
getInt64(sp + 8),
|
||||
));
|
||||
this.mem.setInt32(sp + 16, id, true);
|
||||
},
|
||||
|
||||
// func clearTimeoutEvent(id int32)
|
||||
"runtime.clearTimeoutEvent": (sp) => {
|
||||
sp >>>= 0;
|
||||
const id = this.mem.getInt32(sp + 8, true);
|
||||
clearTimeout(this._scheduledTimeouts.get(id));
|
||||
this._scheduledTimeouts.delete(id);
|
||||
},
|
||||
|
||||
// func getRandomData(r []byte)
|
||||
"runtime.getRandomData": (sp) => {
|
||||
sp >>>= 0;
|
||||
crypto.getRandomValues(loadSlice(sp + 8));
|
||||
},
|
||||
|
||||
// func finalizeRef(v ref)
|
||||
"syscall/js.finalizeRef": (sp) => {
|
||||
sp >>>= 0;
|
||||
const id = this.mem.getUint32(sp + 8, true);
|
||||
this._goRefCounts[id]--;
|
||||
if (this._goRefCounts[id] === 0) {
|
||||
const v = this._values[id];
|
||||
this._values[id] = null;
|
||||
this._ids.delete(v);
|
||||
this._idPool.push(id);
|
||||
}
|
||||
},
|
||||
|
||||
// func stringVal(value string) ref
|
||||
"syscall/js.stringVal": (sp) => {
|
||||
sp >>>= 0;
|
||||
storeValue(sp + 24, loadString(sp + 8));
|
||||
},
|
||||
|
||||
// func valueGet(v ref, p string) ref
|
||||
"syscall/js.valueGet": (sp) => {
|
||||
sp >>>= 0;
|
||||
const result = Reflect.get(loadValue(sp + 8), loadString(sp + 16));
|
||||
sp = this._inst.exports.getsp() >>> 0; // see comment above
|
||||
storeValue(sp + 32, result);
|
||||
},
|
||||
|
||||
// func valueSet(v ref, p string, x ref)
|
||||
"syscall/js.valueSet": (sp) => {
|
||||
sp >>>= 0;
|
||||
Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32));
|
||||
},
|
||||
|
||||
// func valueDelete(v ref, p string)
|
||||
"syscall/js.valueDelete": (sp) => {
|
||||
sp >>>= 0;
|
||||
Reflect.deleteProperty(loadValue(sp + 8), loadString(sp + 16));
|
||||
},
|
||||
|
||||
// func valueIndex(v ref, i int) ref
|
||||
"syscall/js.valueIndex": (sp) => {
|
||||
sp >>>= 0;
|
||||
storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16)));
|
||||
},
|
||||
|
||||
// valueSetIndex(v ref, i int, x ref)
|
||||
"syscall/js.valueSetIndex": (sp) => {
|
||||
sp >>>= 0;
|
||||
Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24));
|
||||
},
|
||||
|
||||
// func valueCall(v ref, m string, args []ref) (ref, bool)
|
||||
"syscall/js.valueCall": (sp) => {
|
||||
sp >>>= 0;
|
||||
try {
|
||||
const v = loadValue(sp + 8);
|
||||
const m = Reflect.get(v, loadString(sp + 16));
|
||||
const args = loadSliceOfValues(sp + 32);
|
||||
const result = Reflect.apply(m, v, args);
|
||||
sp = this._inst.exports.getsp() >>> 0; // see comment above
|
||||
storeValue(sp + 56, result);
|
||||
this.mem.setUint8(sp + 64, 1);
|
||||
} catch (err) {
|
||||
sp = this._inst.exports.getsp() >>> 0; // see comment above
|
||||
storeValue(sp + 56, err);
|
||||
this.mem.setUint8(sp + 64, 0);
|
||||
}
|
||||
},
|
||||
|
||||
// func valueInvoke(v ref, args []ref) (ref, bool)
|
||||
"syscall/js.valueInvoke": (sp) => {
|
||||
sp >>>= 0;
|
||||
try {
|
||||
const v = loadValue(sp + 8);
|
||||
const args = loadSliceOfValues(sp + 16);
|
||||
const result = Reflect.apply(v, undefined, args);
|
||||
sp = this._inst.exports.getsp() >>> 0; // see comment above
|
||||
storeValue(sp + 40, result);
|
||||
this.mem.setUint8(sp + 48, 1);
|
||||
} catch (err) {
|
||||
sp = this._inst.exports.getsp() >>> 0; // see comment above
|
||||
storeValue(sp + 40, err);
|
||||
this.mem.setUint8(sp + 48, 0);
|
||||
}
|
||||
},
|
||||
|
||||
// func valueNew(v ref, args []ref) (ref, bool)
|
||||
"syscall/js.valueNew": (sp) => {
|
||||
sp >>>= 0;
|
||||
try {
|
||||
const v = loadValue(sp + 8);
|
||||
const args = loadSliceOfValues(sp + 16);
|
||||
const result = Reflect.construct(v, args);
|
||||
sp = this._inst.exports.getsp() >>> 0; // see comment above
|
||||
storeValue(sp + 40, result);
|
||||
this.mem.setUint8(sp + 48, 1);
|
||||
} catch (err) {
|
||||
sp = this._inst.exports.getsp() >>> 0; // see comment above
|
||||
storeValue(sp + 40, err);
|
||||
this.mem.setUint8(sp + 48, 0);
|
||||
}
|
||||
},
|
||||
|
||||
// func valueLength(v ref) int
|
||||
"syscall/js.valueLength": (sp) => {
|
||||
sp >>>= 0;
|
||||
setInt64(sp + 16, parseInt(loadValue(sp + 8).length));
|
||||
},
|
||||
|
||||
// valuePrepareString(v ref) (ref, int)
|
||||
"syscall/js.valuePrepareString": (sp) => {
|
||||
sp >>>= 0;
|
||||
const str = encoder.encode(String(loadValue(sp + 8)));
|
||||
storeValue(sp + 16, str);
|
||||
setInt64(sp + 24, str.length);
|
||||
},
|
||||
|
||||
// valueLoadString(v ref, b []byte)
|
||||
"syscall/js.valueLoadString": (sp) => {
|
||||
sp >>>= 0;
|
||||
const str = loadValue(sp + 8);
|
||||
loadSlice(sp + 16).set(str);
|
||||
},
|
||||
|
||||
// func valueInstanceOf(v ref, t ref) bool
|
||||
"syscall/js.valueInstanceOf": (sp) => {
|
||||
sp >>>= 0;
|
||||
this.mem.setUint8(sp + 24, (loadValue(sp + 8) instanceof loadValue(sp + 16)) ? 1 : 0);
|
||||
},
|
||||
|
||||
// func copyBytesToGo(dst []byte, src ref) (int, bool)
|
||||
"syscall/js.copyBytesToGo": (sp) => {
|
||||
sp >>>= 0;
|
||||
const dst = loadSlice(sp + 8);
|
||||
const src = loadValue(sp + 32);
|
||||
if (!(src instanceof Uint8Array || src instanceof Uint8ClampedArray)) {
|
||||
this.mem.setUint8(sp + 48, 0);
|
||||
return;
|
||||
}
|
||||
const toCopy = src.subarray(0, dst.length);
|
||||
dst.set(toCopy);
|
||||
setInt64(sp + 40, toCopy.length);
|
||||
this.mem.setUint8(sp + 48, 1);
|
||||
},
|
||||
|
||||
// func copyBytesToJS(dst ref, src []byte) (int, bool)
|
||||
"syscall/js.copyBytesToJS": (sp) => {
|
||||
sp >>>= 0;
|
||||
const dst = loadValue(sp + 8);
|
||||
const src = loadSlice(sp + 16);
|
||||
if (!(dst instanceof Uint8Array || dst instanceof Uint8ClampedArray)) {
|
||||
this.mem.setUint8(sp + 48, 0);
|
||||
return;
|
||||
}
|
||||
const toCopy = src.subarray(0, dst.length);
|
||||
dst.set(toCopy);
|
||||
setInt64(sp + 40, toCopy.length);
|
||||
this.mem.setUint8(sp + 48, 1);
|
||||
},
|
||||
|
||||
"debug": (value) => {
|
||||
console.log(value);
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async run(instance) {
|
||||
if (!(instance instanceof WebAssembly.Instance)) {
|
||||
throw new Error("Go.run: WebAssembly.Instance expected");
|
||||
}
|
||||
this._inst = instance;
|
||||
this.mem = new DataView(this._inst.exports.mem.buffer);
|
||||
this._values = [ // JS values that Go currently has references to, indexed by reference id
|
||||
NaN,
|
||||
0,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
globalThis,
|
||||
this,
|
||||
];
|
||||
this._goRefCounts = new Array(this._values.length).fill(Infinity); // number of references that Go has to a JS value, indexed by reference id
|
||||
this._ids = new Map([ // mapping from JS values to reference ids
|
||||
[0, 1],
|
||||
[null, 2],
|
||||
[true, 3],
|
||||
[false, 4],
|
||||
[globalThis, 5],
|
||||
[this, 6],
|
||||
]);
|
||||
this._idPool = []; // unused ids that have been garbage collected
|
||||
this.exited = false; // whether the Go program has exited
|
||||
|
||||
// Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.
|
||||
let offset = 4096;
|
||||
|
||||
const strPtr = (str) => {
|
||||
const ptr = offset;
|
||||
const bytes = encoder.encode(str + "\0");
|
||||
new Uint8Array(this.mem.buffer, offset, bytes.length).set(bytes);
|
||||
offset += bytes.length;
|
||||
if (offset % 8 !== 0) {
|
||||
offset += 8 - (offset % 8);
|
||||
}
|
||||
return ptr;
|
||||
};
|
||||
|
||||
const argc = this.argv.length;
|
||||
|
||||
const argvPtrs = [];
|
||||
this.argv.forEach((arg) => {
|
||||
argvPtrs.push(strPtr(arg));
|
||||
});
|
||||
argvPtrs.push(0);
|
||||
|
||||
const keys = Object.keys(this.env).sort();
|
||||
keys.forEach((key) => {
|
||||
argvPtrs.push(strPtr(`${key}=${this.env[key]}`));
|
||||
});
|
||||
argvPtrs.push(0);
|
||||
|
||||
const argv = offset;
|
||||
argvPtrs.forEach((ptr) => {
|
||||
this.mem.setUint32(offset, ptr, true);
|
||||
this.mem.setUint32(offset + 4, 0, true);
|
||||
offset += 8;
|
||||
});
|
||||
|
||||
// The linker guarantees global data starts from at least wasmMinDataAddr.
|
||||
// Keep in sync with cmd/link/internal/ld/data.go:wasmMinDataAddr.
|
||||
const wasmMinDataAddr = 4096 + 8192;
|
||||
if (offset >= wasmMinDataAddr) {
|
||||
throw new Error("total length of command line and environment variables exceeds limit");
|
||||
}
|
||||
|
||||
this._inst.exports.run(argc, argv);
|
||||
if (this.exited) {
|
||||
this._resolveExitPromise();
|
||||
}
|
||||
await this._exitPromise;
|
||||
}
|
||||
|
||||
_resume() {
|
||||
if (this.exited) {
|
||||
throw new Error("Go program has already exited");
|
||||
}
|
||||
this._inst.exports.resume();
|
||||
if (this.exited) {
|
||||
this._resolveExitPromise();
|
||||
}
|
||||
}
|
||||
|
||||
_makeFuncWrapper(id) {
|
||||
const go = this;
|
||||
return function () {
|
||||
const event = { id: id, this: this, args: arguments };
|
||||
go._pendingEvent = event;
|
||||
go._resume();
|
||||
return event.result;
|
||||
};
|
||||
}
|
||||
}
|
||||
})();
|
@ -22,8 +22,8 @@
|
||||
<script defer src="dependencies/highlight.js"></script>
|
||||
<script defer src="dependencies/marked.js"></script>
|
||||
|
||||
<!--script defer src="wasm_exec.js"></script>
|
||||
<script>
|
||||
<script defer src="wasm_exec.js"></script>
|
||||
<script>
|
||||
window.addEventListener('load', function() {
|
||||
hljs.highlightAll();
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
go.run(result.instance);
|
||||
});
|
||||
});
|
||||
</script -->
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -40,19 +40,6 @@
|
||||
{{ embed }}
|
||||
|
||||
<script>
|
||||
const companyTempMinMaxValues = {
|
||||
'openai': { min: 0, max: 2 },
|
||||
'anthropic': { min: 0, max: 1 },
|
||||
'deepseek': { min: 0, max: 2 },
|
||||
'fireworks': { min: 0, max: 2 },
|
||||
'google': { min: 0, max: 2 },
|
||||
'groq': { min: 0, max: 2 },
|
||||
'mistral': { min: 0, max: 2 },
|
||||
'nim': { min: 0, max: 2 },
|
||||
'perplexity': { min: 0, max: 2 },
|
||||
'together': { min: 0, max: 2 },
|
||||
};
|
||||
|
||||
function copyToClipboardCode(button) {
|
||||
// Get the code element next to the button
|
||||
var codeElement = button.parentElement.nextElementSibling;
|
||||
|
@ -38,7 +38,6 @@
|
||||
|
||||
<script>
|
||||
var textareaControl = document.getElementById('textarea-control');
|
||||
const textarea = document.getElementById('chat-input-textarea');
|
||||
|
||||
// Every 0.01s check if the text area have htmx-request class, if yes, add the class is-loading
|
||||
setInterval(function () {
|
||||
@ -50,10 +49,7 @@
|
||||
} else {
|
||||
textareaControl.classList.remove('is-loading');
|
||||
}
|
||||
if (document.getElementById('chat-input-textarea') != null ) {
|
||||
toggleSendButton();
|
||||
}
|
||||
}, 100);
|
||||
}, 10);
|
||||
|
||||
function updateIcons() {
|
||||
if (window.innerWidth < 450) {
|
||||
@ -93,6 +89,7 @@
|
||||
}
|
||||
});
|
||||
|
||||
const textarea = document.querySelector('#chat-input-textarea');
|
||||
textarea.addEventListener('keydown', handleTextareaKeydown);
|
||||
|
||||
document.addEventListener('htmx:afterSwap', toggleSendButton)
|
||||
@ -110,64 +107,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
function generatePlaceholder() {
|
||||
return `
|
||||
<div class="message-user mt-3 message-placeholder wasm-placeholder">
|
||||
<div class="columns is-mobile">
|
||||
<div class="column is-narrow" id="icon-column">
|
||||
<figure class="image is-48x48 message-icon" style="flex-shrink: 0;">
|
||||
<img src="icons/bouvai2.png" alt="User Image">
|
||||
</figure>
|
||||
</div>
|
||||
<div class="column" id="content-column" style="width: 100px;">
|
||||
<div class="is-flex is-align-items-start">
|
||||
<div class="message-content" style="width: 100%%; overflow-y: hidden;">
|
||||
<div class="message-header">
|
||||
<p>You</p>
|
||||
</div>
|
||||
<div class="message-body">
|
||||
<div class="content" style="overflow-x: auto; width: 100%%;">
|
||||
<p>Rendering...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="is-flex is-justify-content mt-2">
|
||||
<div style="height: 30px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="message-bot mt-3 message-placeholder">
|
||||
<div class="columns is-mobile">
|
||||
<div class="column is-narrow" id="icon-column">
|
||||
<figure class="image is-48x48 message-icon" style="flex-shrink: 0;">
|
||||
<img src="icons/bouvai2.png" alt="User Image">
|
||||
</figure>
|
||||
</div>
|
||||
<div class="column" id="content-column" style="width: 100px;">
|
||||
<div class="is-flex is-align-items-start">
|
||||
<div class="message-content">
|
||||
<div class='message-header'>
|
||||
<p>Waiting...</p>
|
||||
</div>
|
||||
<div class="message-body">
|
||||
<div class="content">
|
||||
<br>
|
||||
<img src="/puff.svg" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="is-flex is-justify-content mt-2">
|
||||
<div style="height: 30px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
function onClickSendButton() {
|
||||
// TODO: Add the message placeholder using WASM
|
||||
messagesPlaceholderHTML = generatePlaceholder(textarea.value);
|
||||
|
@ -44,7 +44,7 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="message-body">
|
||||
<div class="content" style="overflow: hidden; width: 100%;">{{ message.Content | safe }}</div>
|
||||
<div class="content" style="overflow-x: auto; width: 100%;">{{ message.Content | safe }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
@ -14,7 +14,7 @@
|
||||
</div>
|
||||
<div class="message-body">
|
||||
<div class="content"
|
||||
style="overflow: hidden;
|
||||
style="overflow-x: auto;
|
||||
width: 100%"
|
||||
id="content-{{ ID }}">{{ Content | safe }}</div>
|
||||
</div>
|
||||
|
@ -64,7 +64,7 @@
|
||||
placeholder="Model name"
|
||||
autocomplete="off">
|
||||
<div class="select is-fullwidth is-small mb-3" id="model-id-input">
|
||||
<select name="selectedLLMId" id="modelID-select">
|
||||
<select name="selectedLLMId">
|
||||
{% for modelInfo in ModelInfos %}
|
||||
<option value="{{ modelInfo.ModelID }}">
|
||||
{{ modelInfo.Company.Name }} - {{ modelInfo.Name }}
|
||||
@ -100,7 +100,7 @@
|
||||
<input class="slider is-small mb-3"
|
||||
step="0.05"
|
||||
min="0"
|
||||
max="1"
|
||||
max="2"
|
||||
value="0"
|
||||
type="range"
|
||||
id="temperature-slider"
|
||||
@ -161,25 +161,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('modelID-select').addEventListener('change', handleSelectChange)
|
||||
|
||||
function handleSelectChange() {
|
||||
const selectElement = document.getElementById('modelID-select');
|
||||
const selectedOption = selectElement.options[selectElement.selectedIndex];
|
||||
const selectedText = selectedOption.innerHTML;
|
||||
|
||||
if (selectedText != "Custom Endpoints") {
|
||||
const companyName = selectedText.split(' - ')[0].trim();
|
||||
var companyMinMax = companyTempMinMaxValues[companyName];
|
||||
} else {
|
||||
var companyMinMax = companyTempMinMaxValues['openai'];
|
||||
}
|
||||
|
||||
var tempSlider = document.getElementById('temperature-slider');
|
||||
tempSlider.setAttribute("min", companyMinMax.min.toString());
|
||||
tempSlider.setAttribute("max", companyMinMax.max.toString());
|
||||
}
|
||||
|
||||
document.getElementById('model-name-input').addEventListener('input', function () {
|
||||
document.getElementById('confirm-create-model-button').disabled = this.value === '' || !document.getElementById('endpoint-error').classList.contains('is-hidden');
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user