Added firework ai and improved some logo

This commit is contained in:
Adrien Bouvais 2024-06-16 11:40:35 +02:00
parent 1125f86331
commit c7ca2bc4a0
15 changed files with 234 additions and 10 deletions

12
Chat.go
View File

@ -531,7 +531,7 @@ func generateLimitReachedChatHTML(c *fiber.Ctx) string {
return htmlString
}
// Buton actions
// Button actions
func GetEditMessageFormHandler(c *fiber.Ctx) error {
id := c.FormValue("id")
idUUID, _ := edgedb.ParseUUID(id)
@ -727,7 +727,7 @@ func LoadUsageKPIHandler(c *fiber.Ctx) error {
}
func GenerateModelPopoverHTML(refresh bool, c *fiber.Ctx) string {
openaiExists, anthropicExists, mistralExists, groqExists, gooseaiExists, googleExists, perplexityExists := getExistingKeys(c)
openaiExists, anthropicExists, mistralExists, groqExists, gooseaiExists, googleExists, perplexityExists, fireworksExists := getExistingKeys(c)
var llms []LLM
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).Query(edgeCtx, `
@ -765,7 +765,8 @@ func GenerateModelPopoverHTML(refresh bool, c *fiber.Ctx) string {
"GooseaiExists": gooseaiExists,
"GoogleExists": googleExists,
"PerplexityExists": perplexityExists,
"AnyExists": openaiExists || anthropicExists || mistralExists || groqExists || gooseaiExists || googleExists || perplexityExists,
"FireworksExists": fireworksExists,
"AnyExists": fireworksExists || openaiExists || anthropicExists || mistralExists || groqExists || gooseaiExists || googleExists || perplexityExists,
"LLMs": llms,
"ModelInfos": modelInfos,
"DeleteUpdate": refresh,
@ -856,7 +857,7 @@ func LoadSettingsHandler(c *fiber.Ctx) error {
stripeSubLink := "https://billing.stripe.com/p/login/6oE6sc0PTfvq1Hi288?prefilled_email=" + user.Email
openaiExists, anthropicExists, mistralExists, groqExists, gooseaiExists, googleExists, perplexityExists := getExistingKeys(c)
openaiExists, anthropicExists, mistralExists, groqExists, gooseaiExists, googleExists, perplexityExists, fireworksExists := getExistingKeys(c)
isPremium, isBasic := IsCurrentUserSubscribed(c)
out, err := settingPopoverTmpl.Execute(pongo2.Context{
@ -868,7 +869,8 @@ func LoadSettingsHandler(c *fiber.Ctx) error {
"GooseaiExists": gooseaiExists,
"GoogleExists": googleExists,
"PerplexityExists": perplexityExists,
"AnyExists": openaiExists || anthropicExists || mistralExists || groqExists || gooseaiExists || googleExists || perplexityExists,
"FireworksExists": fireworksExists,
"AnyExists": fireworksExists || openaiExists || anthropicExists || mistralExists || groqExists || gooseaiExists || googleExists || perplexityExists,
"isPremium": isPremium,
"isBasic": isBasic,
"StripeSubLink": stripeSubLink,

View File

@ -78,9 +78,9 @@ func addCodeHeader(htmlContent string, languages []string) string {
return updatedHTML
}
func getExistingKeys(c *fiber.Ctx) (bool, bool, bool, bool, bool, bool, bool) {
func getExistingKeys(c *fiber.Ctx) (bool, bool, bool, bool, bool, bool, bool, bool) {
if edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}) == nil {
return false, false, false, false, false, false, false
return false, false, false, false, false, false, false, false
}
var (
@ -91,6 +91,7 @@ func getExistingKeys(c *fiber.Ctx) (bool, bool, bool, bool, bool, bool, bool) {
gooseaiExists bool
googleExists bool
perplexityExists bool
fireworksExists bool
)
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
@ -170,7 +171,18 @@ func getExistingKeys(c *fiber.Ctx) (bool, bool, bool, bool, bool, bool, bool) {
panic(err)
}
return openaiExists, anthropicExists, mistralExists, groqExists, gooseaiExists, googleExists, perplexityExists
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 = "fireworks"
);
`, &fireworksExists)
if err != nil {
fmt.Println("Error checking if Fireworks key exists")
panic(err)
}
return openaiExists, anthropicExists, mistralExists, groqExists, gooseaiExists, googleExists, perplexityExists, fireworksExists
}
func Message2RequestMessage(messages []Message, context string) []RequestMessage {

View File

@ -164,6 +164,8 @@ func GenerateMultipleMessagesHandler(c *fiber.Ctx) error {
addMessageFunc = addGoogleMessage
case "perplexity":
addMessageFunc = addPerplexityMessage
case "fireworks":
addMessageFunc = addFireworkMessage
}
var messageID edgedb.UUID

184
RequestFirework.go Normal file
View File

@ -0,0 +1,184 @@
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"github.com/edgedb/edgedb-go"
"github.com/gofiber/fiber/v2"
)
type FireworkChatCompletionRequest struct {
Model string `json:"model"`
Messages []RequestMessage `json:"messages"`
Temperature float64 `json:"temperature"`
}
type FireworkChatCompletionResponse struct {
ID string `json:"id"`
Object string `json:"object"`
Created int64 `json:"created"`
Model string `json:"model"`
Usage FireworkUsage `json:"usage"`
Choices []FireworkChoice `json:"choices"`
}
type FireworkUsage struct {
PromptTokens int32 `json:"prompt_tokens"`
CompletionTokens int32 `json:"completion_tokens"`
TotalTokens int32 `json:"total_tokens"`
}
type FireworkChoice struct {
Message Message `json:"message"`
FinishReason string `json:"finish_reason"`
Index int `json:"index"`
}
func addFireworkMessage(c *fiber.Ctx, llm LLM, selected bool) edgedb.UUID {
Messages := getAllSelectedMessages(c)
chatCompletion, err := RequestFirework(c, llm.Model.ModelID, Messages, float64(llm.Temperature), llm.Context)
if err != nil {
fmt.Println("Error fetching user profile")
panic(err)
} else if len(chatCompletion.Choices) == 0 {
fmt.Println("No response from OpenAI")
id := insertBotMessage(c, "No response from Firework", selected, llm.ID)
return id
} else {
Content := chatCompletion.Choices[0].Message.Content
id := insertBotMessage(c, Content, selected, llm.ID)
return id
}
}
func TestFireworkKey(apiKey string) bool {
url := "https://api.fireworks.ai/inference/v1/chat/completions"
// Convert messages to OpenAI format
fireworkMessages := []RequestMessage{
{
Role: "user",
Content: "Hello",
},
}
requestBody := OpenaiChatCompletionRequest{
Model: "accounts/fireworks/models/llama-v2-7b-chat",
Messages: fireworkMessages,
Temperature: 0,
}
jsonBody, err := json.Marshal(requestBody)
if err != nil {
return false
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonBody))
if err != nil {
return false
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+apiKey)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return false
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return false
}
var chatCompletionResponse FireworkChatCompletionResponse
err = json.Unmarshal(body, &chatCompletionResponse)
if err != nil {
return false
}
if chatCompletionResponse.Usage.CompletionTokens == 0 {
return false
}
return true
}
func RequestFirework(c *fiber.Ctx, model string, messages []Message, temperature float64, context string) (FireworkChatCompletionResponse, error) {
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, "openai")
if err != nil {
return FireworkChatCompletionResponse{}, fmt.Errorf("error getting OpenAI API key: %w", err)
}
url := "https://api.fireworks.ai/inference/v1/chat/completions"
requestBody := FireworkChatCompletionRequest{
Model: model,
Messages: Message2RequestMessage(messages, context),
Temperature: temperature,
}
jsonBody, err := json.Marshal(requestBody)
if err != nil {
return FireworkChatCompletionResponse{}, fmt.Errorf("error marshaling JSON: %w", err)
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonBody))
if err != nil {
return FireworkChatCompletionResponse{}, fmt.Errorf("error creating request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+apiKey)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return FireworkChatCompletionResponse{}, fmt.Errorf("error sending request: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return FireworkChatCompletionResponse{}, fmt.Errorf("error reading response body: %w", err)
}
var chatCompletionResponse FireworkChatCompletionResponse
err = json.Unmarshal(body, &chatCompletionResponse)
if err != nil {
return FireworkChatCompletionResponse{}, fmt.Errorf("error unmarshaling JSON: %w", err)
}
var usedModelInfo ModelInfo
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 {
return FireworkChatCompletionResponse{}, fmt.Errorf("error getting model info: %w", err)
}
var inputCost float32 = float32(chatCompletionResponse.Usage.PromptTokens) * usedModelInfo.InputPrice
var outputCost float32 = float32(chatCompletionResponse.Usage.CompletionTokens) * usedModelInfo.OutputPrice
addUsage(c, inputCost, outputCost, chatCompletionResponse.Usage.PromptTokens, chatCompletionResponse.Usage.CompletionTokens, model)
return chatCompletionResponse, nil
}

View File

@ -191,6 +191,7 @@ func addKeys(c *fiber.Ctx) error {
"gooseai": c.FormValue("goose_key"),
"google": c.FormValue("google_key"),
"perplexity": c.FormValue("perplexity_key"),
"fireworks": c.FormValue("fireworks_key"),
}
testFunctions := map[string]func(string) bool{
@ -201,6 +202,7 @@ func addKeys(c *fiber.Ctx) error {
"gooseai": TestGooseaiKey,
"google": TestGoogleKey,
"perplexity": TestPerplexityKey,
"fireworks": TestFireworkKey,
}
for company, key := range keys {

BIN
static/icons/fireworks.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
static/icons/old/groq.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

View File

@ -23,13 +23,26 @@
<script src="https://unpkg.com/@highlightjs/cdn-assets@11.9.0/highlight.min.js"></script>
<script>hljs.highlightAll();</script>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script src="wasm_exec.js"></script>
<script>
const go = new Go();
WebAssembly.instantiateStreaming(fetch("main-v1.wasm"), go.importObject).then((result) => {
go.run(result.instance);
});
</script>
</head>
<body hx-ext="sse" sse-connect="/sse">
<body>
{{ embed }}
<script>
// run printHello(); every 5 seconds
setInterval(function () {
printHello();
}, 5000);
function generateMessagePlaceholder(content) {
marked.setOptions({
highlight: function (code, lang) {

View File

@ -69,6 +69,15 @@
</span>
</p>
</div>
<div class="field has-addons is-hidden" id="fireworks-field">
<p class="control has-icons-left is-expanded">
<input class="input is-small {% if FireworksExists %}is-success{% endif %}" type="text"
placeholder="Fireworks API key" name="fireworks_key" autocomplete="off">
<span class="icon is-small is-left">
<i class="fas fa-lock"></i>
</span>
</p>
</div>
<div class="field has-addons is-hidden" id="goose-field"
title="GooseAI chat API will be available soon">
<p class="control has-icons-left is-expanded">