QOL update
This commit is contained in:
parent
d5c9ba6e21
commit
c63813aff4
61
Chat.go
61
Chat.go
@ -258,8 +258,60 @@ func GetEditMessageFormHandler(c *fiber.Ctx) error {
|
||||
return c.SendString(out)
|
||||
}
|
||||
|
||||
func RedoMessageHandler(c *fiber.Ctx) error {
|
||||
messageId := c.FormValue("id")
|
||||
messageUUID, _ := edgedb.ParseUUID(messageId)
|
||||
|
||||
// Delete messages
|
||||
err := edgeClient.Execute(edgeCtx, `
|
||||
WITH
|
||||
messageArea := (SELECT Message FILTER .id = <uuid>$0).area
|
||||
DELETE Area
|
||||
FILTER .position > messageArea.position AND .conversation = messageArea.conversation;
|
||||
`, messageUUID)
|
||||
if err != nil {
|
||||
fmt.Println("Error in edgeClient.Execute: in DeleteMessageHandler")
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
messageOut, err := botTmpl.Execute(pongo2.Context{"IsPlaceholder": true})
|
||||
if err != nil {
|
||||
c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": "Error rendering template",
|
||||
})
|
||||
}
|
||||
|
||||
selectedModelIds := []string{}
|
||||
for ModelInfo := range ModelsInfos {
|
||||
out := c.FormValue("model-check-" + ModelsInfos[ModelInfo].ID)
|
||||
if out != "" {
|
||||
selectedModelIds = append(selectedModelIds, ModelsInfos[ModelInfo].ID)
|
||||
}
|
||||
}
|
||||
lastSelectedModelIds = selectedModelIds
|
||||
|
||||
return c.SendString(messageOut)
|
||||
}
|
||||
|
||||
func ClearChatHandler(c *fiber.Ctx) error {
|
||||
// Delete the default conversation
|
||||
err := edgeClient.Execute(edgeCtx, `
|
||||
DELETE Conversation
|
||||
FILTER .user = global currentUser AND .name = "Default";
|
||||
`)
|
||||
if err != nil {
|
||||
fmt.Println("Error in edgeClient.Execute: in ClearChatHandler")
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
return c.SendString(generateChatHTML())
|
||||
}
|
||||
|
||||
// Popover stuff
|
||||
func LoadUsageKPIHandler(c *fiber.Ctx) error {
|
||||
if !checkIfLogin() {
|
||||
return c.SendString("")
|
||||
}
|
||||
var TotalUsage float32
|
||||
// Using the database. Get the sum of all usage.inputCost and outputCost
|
||||
err := edgeClient.QuerySingle(edgeCtx, `
|
||||
@ -326,6 +378,9 @@ func LoadUsageKPIHandler(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
func LoadKeysHandler(c *fiber.Ctx) error {
|
||||
if !checkIfLogin() {
|
||||
return c.SendString("")
|
||||
}
|
||||
openaiExists, anthropicExists, mistralExists, groqExists := getExistingKeys()
|
||||
|
||||
out, err := pongo2.Must(pongo2.FromFile("views/partials/popover-keys.html")).Execute(pongo2.Context{"IsLogin": checkIfLogin(), "OpenaiExists": openaiExists, "AnthropicExists": anthropicExists, "MistralExists": mistralExists, "GroqExists": groqExists})
|
||||
@ -338,6 +393,9 @@ func LoadKeysHandler(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
func LoadModelSelectionHandler(c *fiber.Ctx) error {
|
||||
if !checkIfLogin() {
|
||||
return c.SendString("")
|
||||
}
|
||||
openaiExists, anthropicExists, mistralExists, groqExists := getExistingKeys()
|
||||
|
||||
var CompanyInfosAvailable []CompanyInfo
|
||||
@ -398,6 +456,9 @@ func LoadModelSelectionHandler(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
func LoadSettingsHandler(c *fiber.Ctx) error {
|
||||
if !checkIfLogin() {
|
||||
return c.SendString("")
|
||||
}
|
||||
out, err := pongo2.Must(pongo2.FromFile("views/partials/popover-settings.html")).Execute(pongo2.Context{"IsLogin": checkIfLogin()})
|
||||
if err != nil {
|
||||
c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
|
44
Request.go
44
Request.go
@ -103,34 +103,34 @@ func GenerateMultipleMessages(c *fiber.Ctx) error {
|
||||
return c.SendString(generateChatHTML())
|
||||
}
|
||||
|
||||
func RequestMultipleMessages(c *fiber.Ctx) error {
|
||||
message := c.FormValue("message")
|
||||
if chatString, commandExecuted := DetectCommand(message, c); commandExecuted {
|
||||
return c.SendString(chatString)
|
||||
}
|
||||
|
||||
// Add an Area with the user message inside
|
||||
insertArea()
|
||||
messageID := insertUserMessage(message)
|
||||
func RequestMultipleMessagesHandler(c *fiber.Ctx) error {
|
||||
message := c.FormValue("message", "")
|
||||
|
||||
selectedModelIds := []string{}
|
||||
for CompanyInfo := range CompanyInfos {
|
||||
for ModelInfo := range CompanyInfos[CompanyInfo].ModelInfos {
|
||||
out := c.FormValue("model-check-" + CompanyInfos[CompanyInfo].ModelInfos[ModelInfo].ID)
|
||||
if out != "" {
|
||||
selectedModelIds = append(selectedModelIds, CompanyInfos[CompanyInfo].ModelInfos[ModelInfo].ID)
|
||||
}
|
||||
for ModelInfo := range ModelsInfos {
|
||||
out := c.FormValue("model-check-" + ModelsInfos[ModelInfo].ID)
|
||||
if out != "" {
|
||||
selectedModelIds = append(selectedModelIds, ModelsInfos[ModelInfo].ID)
|
||||
}
|
||||
}
|
||||
lastSelectedModelIds = selectedModelIds
|
||||
|
||||
out := ""
|
||||
|
||||
messageOut, _ := userTmpl.Execute(pongo2.Context{"Content": markdownToHTML(message), "ID": messageID.String()})
|
||||
out += messageOut
|
||||
|
||||
messageOut, _ = botTmpl.Execute(pongo2.Context{"IsPlaceholder": true, "SelectedModelIds": selectedModelIds, "Message": message})
|
||||
out += messageOut
|
||||
out := RequestMultipleMessages(message, selectedModelIds)
|
||||
|
||||
return c.SendString(out)
|
||||
}
|
||||
|
||||
func RequestMultipleMessages(message string, selectedModelIds []string) string {
|
||||
// Add an Area with the user message inside
|
||||
insertArea()
|
||||
messageID := insertUserMessage(message)
|
||||
|
||||
out := ""
|
||||
messageOut, _ := userTmpl.Execute(pongo2.Context{"Content": markdownToHTML(message), "ID": messageID.String()})
|
||||
out += messageOut
|
||||
|
||||
messageOut, _ = botTmpl.Execute(pongo2.Context{"IsPlaceholder": true})
|
||||
out += messageOut
|
||||
|
||||
return out
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ func init() {
|
||||
}
|
||||
|
||||
func addAnthropicMessage(modelID string, selected bool) edgedb.UUID {
|
||||
Messages := getAllMessages()
|
||||
Messages := getAllSelectedMessages()
|
||||
|
||||
chatCompletion, err := RequestAnthropic(modelID, Messages, 2048, 0.7) // TODO CHange parameters
|
||||
if err != nil {
|
||||
|
@ -47,7 +47,7 @@ func init() {
|
||||
|
||||
modelInfo := ModelInfo{
|
||||
ID: "llama3-8b-8192",
|
||||
Name: "Llama 8B",
|
||||
Name: "Llama 3 8B",
|
||||
Icon: "groq",
|
||||
MaxToken: 8192,
|
||||
InputPrice: 0.00 / 1000000,
|
||||
@ -58,7 +58,7 @@ func init() {
|
||||
|
||||
modelInfo = ModelInfo{
|
||||
ID: "llama3-70b-8192",
|
||||
Name: "Llama 70B",
|
||||
Name: "Llama 3 70B",
|
||||
Icon: "groq",
|
||||
MaxToken: 8192,
|
||||
InputPrice: 0.00 / 1000000,
|
||||
@ -88,7 +88,7 @@ func init() {
|
||||
}
|
||||
|
||||
func addGroqMessage(modelID string, selected bool) edgedb.UUID {
|
||||
Messages := getAllMessages()
|
||||
Messages := getAllSelectedMessages()
|
||||
|
||||
chatCompletion, err := RequestGroq(modelID, Messages, 0.7)
|
||||
if err != nil {
|
||||
|
@ -121,7 +121,7 @@ func init() {
|
||||
}
|
||||
|
||||
func addMistralMessage(modelID string, selected bool) edgedb.UUID {
|
||||
Messages := getAllMessages()
|
||||
Messages := getAllSelectedMessages()
|
||||
|
||||
chatCompletion, err := RequestMistral(modelID, Messages, 0.7)
|
||||
if err != nil {
|
||||
|
@ -77,7 +77,7 @@ func init() {
|
||||
}
|
||||
|
||||
func addOpenaiMessage(modelID string, selected bool) edgedb.UUID {
|
||||
Messages := getAllMessages()
|
||||
Messages := getAllSelectedMessages()
|
||||
|
||||
chatCompletion, err := RequestOpenai(modelID, Messages, 0.7)
|
||||
if err != nil {
|
||||
|
30
database.go
30
database.go
@ -178,7 +178,8 @@ func insertUserMessage(content string) edgedb.UUID {
|
||||
SELECT Conversation
|
||||
FILTER .name = 'Default' AND .user = global currentUser
|
||||
LIMIT 1
|
||||
)
|
||||
),
|
||||
selected := true
|
||||
}
|
||||
`, &inserted, "user", content, lastAreaID)
|
||||
if err != nil {
|
||||
@ -243,6 +244,33 @@ func getAllMessages() []Message {
|
||||
return messages
|
||||
}
|
||||
|
||||
func getAllSelectedMessages() []Message {
|
||||
// If no CurrentUser, return an empty array
|
||||
if !checkIfLogin() {
|
||||
return []Message{}
|
||||
}
|
||||
|
||||
var messages []Message
|
||||
|
||||
err := edgeClient.Query(edgeCtx, `
|
||||
SELECT Message {
|
||||
id,
|
||||
model_id,
|
||||
selected,
|
||||
role,
|
||||
content,
|
||||
date
|
||||
} FILTER .conversation.name = 'Default' AND .conversation.user = global currentUser AND .selected = true
|
||||
ORDER BY .date ASC
|
||||
`, &messages)
|
||||
if err != nil {
|
||||
fmt.Println("Error in edgedb.Query: in getAllMessages")
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
return messages
|
||||
}
|
||||
|
||||
func getCurrentUserKeys() []Key {
|
||||
var result []Key
|
||||
err := edgeClient.Query(edgeCtx, "SELECT global currentUser.setting.keys", &result)
|
||||
|
@ -32,7 +32,7 @@ module default {
|
||||
type Conversation {
|
||||
required name: str;
|
||||
required user: User {
|
||||
on target delete delete source;
|
||||
on target delete allow;
|
||||
};
|
||||
required date: datetime {
|
||||
default := datetime_current();
|
||||
@ -54,7 +54,9 @@ module default {
|
||||
required area: Area {
|
||||
on target delete delete source;
|
||||
};
|
||||
required conversation: Conversation;
|
||||
required conversation: Conversation {
|
||||
on target delete delete source;
|
||||
};
|
||||
required date: datetime {
|
||||
default := datetime_current();
|
||||
}
|
||||
|
14
dbschema/migrations/00021-m1uadgx.edgeql
Normal file
14
dbschema/migrations/00021-m1uadgx.edgeql
Normal file
@ -0,0 +1,14 @@
|
||||
CREATE MIGRATION m1uadgxoeuekkwaessyysetg27ov3wcdfmach7cq5k7vvqn6x6zmrq
|
||||
ONTO m1nsazfltqdfklverxefbbufjwcq5gorhbovfeeugd7q67txrihd2q
|
||||
{
|
||||
ALTER TYPE default::Conversation {
|
||||
ALTER LINK user {
|
||||
ON TARGET DELETE ALLOW;
|
||||
};
|
||||
};
|
||||
ALTER TYPE default::Message {
|
||||
ALTER LINK conversation {
|
||||
ON TARGET DELETE DELETE SOURCE;
|
||||
};
|
||||
};
|
||||
};
|
3
login.go
3
login.go
@ -32,6 +32,8 @@ func generatePKCE() (string, string) {
|
||||
func handleUiSignIn(c *fiber.Ctx) error {
|
||||
verifier, challenge := generatePKCE()
|
||||
|
||||
fmt.Println("Challenge: ", challenge)
|
||||
|
||||
c.Cookie(&fiber.Cookie{
|
||||
Name: "jade-edgedb-pkce-verifier",
|
||||
Value: verifier,
|
||||
@ -121,6 +123,7 @@ func handleCallback(c *fiber.Ctx) error {
|
||||
|
||||
verifier := c.Cookies("jade-edgedb-pkce-verifier")
|
||||
if verifier == "" {
|
||||
fmt.Println("Could not find 'verifier' in the cookie store. Is this the same user agent/browser that started the authorization flow?")
|
||||
return c.Status(fiber.StatusBadRequest).SendString("Could not find 'verifier' in the cookie store. Is this the same user agent/browser that started the authorization flow?")
|
||||
}
|
||||
|
||||
|
4
main.go
4
main.go
@ -37,11 +37,13 @@ func main() {
|
||||
app.Get("/loadChat", LoadChatHandler)
|
||||
|
||||
// Chat routes
|
||||
app.Post("/requestMultipleMessages", RequestMultipleMessages)
|
||||
app.Post("/requestMultipleMessages", RequestMultipleMessagesHandler)
|
||||
app.Post("/deleteMessage", DeleteMessageHandler)
|
||||
app.Get("/generateMultipleMessages", GenerateMultipleMessages)
|
||||
app.Get("/messageContent", GetMessageContentHandler)
|
||||
app.Get("/editMessageForm", GetEditMessageFormHandler)
|
||||
app.Post("/redoMessage", RedoMessageHandler)
|
||||
app.Post("/clearChat", ClearChatHandler)
|
||||
|
||||
// Settings routes
|
||||
app.Post("/addKeys", addKeys)
|
||||
|
@ -4,12 +4,20 @@
|
||||
<div class="chat-input-container mb-5">
|
||||
<div class="textarea-wrapper">
|
||||
<textarea {% if not IsLogin or not HaveKey %}disabled{% endif %} class="textarea"
|
||||
placeholder="Type your message here..." name="message" oninput="toggleSendButton(this)"></textarea>
|
||||
placeholder="Type your message here..." name="message" oninput="toggleSendButton(this)"
|
||||
id="chat-input-textarea"></textarea>
|
||||
<div class="button-group">
|
||||
<hx hx-get="/loadSettings" hx-trigger="load" hx-swap="outerHTML" hx-target="this"></hx>
|
||||
<hx hx-get="/loadKeys" 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="/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"
|
||||
onclick="clearTextArea()" id="clear-button" hx-post="/clearChat" hx-swap="outerHTML"
|
||||
hx-target="#chat-container">
|
||||
<span class="icon">
|
||||
<i class="fa-solid fa-broom"></i>
|
||||
</span>
|
||||
</button>
|
||||
<button disabled type="submit" class="send-button button is-primary is-small"
|
||||
hx-post="/requestMultipleMessages" hx-swap="beforeend settle:200ms" hx-target="#chat-messages"
|
||||
id="chat-input-send-btn" class="chat-input" hx-include="[name='message'], [name^='model-check-']"
|
||||
@ -24,6 +32,9 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const textarea = document.querySelector('.textarea');
|
||||
textarea.addEventListener('keydown', handleTextareaKeydown);
|
||||
|
||||
function toggleSendButton(textarea) {
|
||||
var sendButton = document.getElementById('chat-input-send-btn');
|
||||
sendButton.disabled = textarea.value.trim() === '';
|
||||
@ -31,8 +42,18 @@
|
||||
|
||||
function clearTextArea() {
|
||||
setTimeout(function () {
|
||||
document.querySelector('.textarea').value = '';
|
||||
toggleSendButton(document.querySelector('.textarea'));
|
||||
textarea.value = '';
|
||||
toggleSendButton(textarea);
|
||||
}, 200);
|
||||
}
|
||||
|
||||
function handleTextareaKeydown(event) {
|
||||
if (event.metaKey && event.key === 'Enter') {
|
||||
// Check if the cursor is in the textarea
|
||||
if (event.target === textarea) {
|
||||
// Trigger the same action as the send button
|
||||
document.getElementById('chat-input-send-btn').click();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -8,9 +8,15 @@
|
||||
</figure>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if IsPlaceholder %}
|
||||
<figure class="image is-48x48" style="flex-shrink: 0;">
|
||||
<img src="icons/bouvai2.png" alt="User Image">
|
||||
</figure>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="column" id="content-column">
|
||||
{% if not IsPlaceholder %}
|
||||
<div class="is-flex is-align-items-start">
|
||||
<div class="message-content" id="content-{{ ConversationAreaId }}">
|
||||
{% for message in Messages %}
|
||||
@ -50,7 +56,7 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if IsPlaceholder %}
|
||||
{% elif IsPlaceholder %}
|
||||
<hx hx-get="/generateMultipleMessages" hx-trigger="load" hx-swap="outerHTML" hx-indicator="#spinner"
|
||||
hx-target="#chat-container">
|
||||
</hx>
|
||||
|
@ -22,7 +22,15 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="is-flex is-justify-content mt-2">
|
||||
<button id="redo-button-{{ ID }}" class="button is-small is-primary message-button is-outlined mr-2">
|
||||
<button id="delete-button-{{ ID }}" hx-post="/deleteMessage?id={{ ID }}" hx-swap="outerHTML"
|
||||
hx-target="#chat-container" class="button is-small is-danger message-button is-outlined mr-5">
|
||||
<span class="icon">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</span>
|
||||
</button>
|
||||
<button id="redo-button-{{ ID }}" class="button is-small is-primary message-button is-outlined mr-1"
|
||||
hx-post="/redoMessage?id={{ ID }}" hx-swap="innerHTML settle:200ms" hx-target="next .message-bot"
|
||||
hx-include="[name^='model-check-']">
|
||||
<span class="icon">
|
||||
<i class="fa-solid fa-arrows-rotate"></i>
|
||||
</span>
|
||||
@ -33,12 +41,6 @@
|
||||
<i class="fa-solid fa-pen"></i>
|
||||
</span>
|
||||
</button>
|
||||
<button id="delete-button-{{ ID }}" hx-post="/deleteMessage?id={{ ID }}" hx-swap="outerHTML"
|
||||
hx-target="#chat-container" class="button is-small is-danger message-button is-outlined mr-2">
|
||||
<span class="icon">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -7,13 +7,13 @@
|
||||
<div class="dropdown-menu" id="dropdown-menu4" role="menu">
|
||||
<div class="dropdown-content">
|
||||
<div class="dropdown-item">
|
||||
<a class="button is-small is-info is-outlined mb-1" href="/signout">
|
||||
Log out
|
||||
</a>
|
||||
<a class="button is-small is-info is-outlined" href="https://artificialanalysis.ai/models"
|
||||
<a class="button is-small is-primary is-outlined mb-1" href="https://artificialanalysis.ai/models"
|
||||
target="_blank">
|
||||
Compare models
|
||||
</a>
|
||||
<a class="button is-small is-primary is-outlined mb-1" href="/signout">
|
||||
Log out
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user