Working custom endpoint
This commit is contained in:
parent
1603532150
commit
103d6371c8
11
Chat.go
11
Chat.go
@ -156,7 +156,7 @@ func GetMessageContentHandler(c *fiber.Ctx) error {
|
||||
|
||||
out := "<div class='message-header'>"
|
||||
out += "<p>"
|
||||
out += "<strong>" + selectedMessage.LLM.Name + "</strong> <small>" + selectedMessage.LLM.Model.Name + "</small>"
|
||||
out += "<strong>" + selectedMessage.LLM.Name + "</strong> <small>" + selectedMessage.LLM.Model.ModelID + "</small>"
|
||||
out += " </p>"
|
||||
out += "</div>"
|
||||
out += "<div class='message-body'>"
|
||||
@ -449,19 +449,12 @@ func GenerateModelPopoverHTML(refresh bool) string {
|
||||
}
|
||||
}
|
||||
}
|
||||
FILTER .user = global currentUser AND .name != 'none' AND .to_delete = false
|
||||
FILTER .user = global currentUser AND .name != 'none' AND .to_delete = false
|
||||
`, &llms)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
//for i := 0; i < len(llms); i++ {
|
||||
// // If the modelID len is higher than 15, truncate it
|
||||
// if len(llms[i].Model.ModelID) > 12 {
|
||||
// llms[i].Model.ModelID = llms[i].Model.ModelID[0:12] + "..."
|
||||
// }
|
||||
//}
|
||||
|
||||
modelInfos := GetAvailableModels()
|
||||
|
||||
out, err := pongo2.Must(pongo2.FromFile("views/partials/popover-models.html")).Execute(pongo2.Context{
|
||||
|
43
LLM.go
43
LLM.go
@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/edgedb/edgedb-go"
|
||||
@ -52,12 +53,43 @@ func createLLM(c *fiber.Ctx) error {
|
||||
name := c.FormValue("model-name-input")
|
||||
modelID := c.FormValue("selectedLLMId")
|
||||
temperature := c.FormValue("temperature-slider")
|
||||
systemPrompt := c.FormValue("model-prompt-input")
|
||||
|
||||
f, _ := strconv.ParseFloat(temperature, 32)
|
||||
temperatureFloat := float32(f)
|
||||
|
||||
err := edgeClient.Execute(edgeCtx, `
|
||||
systemPrompt := c.FormValue("model-prompt-input")
|
||||
url := c.FormValue("model-url-input")
|
||||
token := c.FormValue("model-key-input")
|
||||
customID := c.FormValue("model-cid-input")
|
||||
|
||||
fmt.Println(name, modelID, temperatureFloat, systemPrompt, url, token)
|
||||
|
||||
if modelID == "custom" {
|
||||
err := edgeClient.Execute(edgeCtx, `
|
||||
INSERT LLM {
|
||||
name := <str>$0,
|
||||
context := <str>$1,
|
||||
temperature := <float32>$2,
|
||||
modelInfo := (INSERT ModelInfo {
|
||||
name := <str>$0,
|
||||
modelID := <str>$5,
|
||||
inputPrice := 0.0,
|
||||
outputPrice := 0.0,
|
||||
maxToken := 500,
|
||||
company := (SELECT Company FILTER .name = "huggingface" LIMIT 1),
|
||||
}),
|
||||
custom_endpoint := (INSERT CustomEndpoint {
|
||||
endpoint := <str>$3,
|
||||
key := <str>$4,
|
||||
}),
|
||||
user := global currentUser
|
||||
};
|
||||
`, name, systemPrompt, temperatureFloat, url, token, customID) // TODO Add real max token
|
||||
if err != nil {
|
||||
fmt.Println("Error in createLLM: ", err)
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
err := edgeClient.Execute(edgeCtx, `
|
||||
INSERT LLM {
|
||||
name := <str>$0,
|
||||
context := <str>$1,
|
||||
@ -66,8 +98,9 @@ func createLLM(c *fiber.Ctx) error {
|
||||
user := global currentUser
|
||||
}
|
||||
`, name, systemPrompt, temperatureFloat, modelID)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
return c.SendString(GenerateModelPopoverHTML(true))
|
||||
|
@ -14,6 +14,7 @@ type GooseaiCompletionRequest struct {
|
||||
Model string `json:"model"`
|
||||
Prompt []string `json:"prompt"`
|
||||
Temperature float64 `json:"temperature"`
|
||||
MaxToken int32 `json:"max_tokens"`
|
||||
}
|
||||
|
||||
type GooseaiCompletionResponse struct {
|
||||
@ -53,6 +54,7 @@ func TestGooseaiKey(apiKey string) bool {
|
||||
Model: "gpt-j-6b",
|
||||
Prompt: []string{"Hello, how are you?"},
|
||||
Temperature: 0,
|
||||
MaxToken: 10,
|
||||
}
|
||||
|
||||
jsonBody, err := json.Marshal(requestBody)
|
||||
@ -111,10 +113,16 @@ func RequestGooseai(model string, messages []Message, temperature float64) (Goos
|
||||
|
||||
url := "https://api.goose.ai/v1/engines/" + model + "/completions"
|
||||
|
||||
var prompt string
|
||||
for _, message := range messages {
|
||||
prompt += message.Content
|
||||
}
|
||||
|
||||
requestBody := GooseaiCompletionRequest{
|
||||
Model: model,
|
||||
Prompt: []string{messages[len(messages)-1].Content},
|
||||
Prompt: []string{prompt},
|
||||
Temperature: temperature,
|
||||
MaxToken: 300,
|
||||
}
|
||||
|
||||
jsonBody, err := json.Marshal(requestBody)
|
||||
|
@ -77,6 +77,8 @@ func RequestHuggingface(llm LLM, messages []Message, temperature float64) (Huggi
|
||||
req.Header.Set("Authorization", "Bearer "+llm.Endpoint.Key)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
fmt.Println(url, llm.Endpoint.Key)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
|
@ -177,6 +177,9 @@ func RequestMistral(model string, messages []Message, temperature float64) (Mist
|
||||
FILTER .modelID = <str>$0
|
||||
LIMIT 1
|
||||
`, &usedModelInfo, model)
|
||||
if err != nil {
|
||||
return MistralChatCompletionResponse{}, fmt.Errorf("error getting model info: %w", err)
|
||||
}
|
||||
|
||||
if usedModelInfo.InputPrice == 0 || usedModelInfo.OutputPrice == 0 {
|
||||
return MistralChatCompletionResponse{}, fmt.Errorf("model %s not found in Mistral", model)
|
||||
|
2
utils.go
2
utils.go
@ -145,7 +145,7 @@ func GetAvailableModels() []ModelInfo {
|
||||
name,
|
||||
icon
|
||||
}
|
||||
} FILTER .modelID != 'none'
|
||||
} FILTER .modelID != 'none' AND .company.name != 'huggingface'
|
||||
`, &models)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -29,7 +29,7 @@
|
||||
{% if not message.Hidden %}
|
||||
<div class="message-header">
|
||||
<p>
|
||||
<strong>{{ message.Name }}</strong> <small>{{ message.Model }}</small>
|
||||
<strong>{{ message.Name }}</strong> <small>{{ message.ModelID }}</small>
|
||||
</p>
|
||||
</div>
|
||||
<div class="message-body">
|
||||
|
@ -1,14 +1,14 @@
|
||||
<div class="dropdown is-hoverable is-up is-right" id="models-dropdown">
|
||||
<div class="dropdown is-up is-right" id="models-dropdown">
|
||||
<div class="dropdown-trigger">
|
||||
<button class="button is-small" aria-haspopup="true" aria-controls="dropdown-menu4">
|
||||
<button class="button is-small" aria-haspopup="true" aria-controls="dropdown-menu3"
|
||||
onclick="this.parentElement.parentElement.classList.toggle('is-active')">
|
||||
<span class="icon"><i class="fa-solid fa-robot"></i></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="dropdown-menu" id="dropdown-menu4" role="menu">
|
||||
<div class="dropdown-menu" id="dropdown-menu3" role="menu">
|
||||
<div class="dropdown-content is-small">
|
||||
<div class="dropdown-item" id="models-list">
|
||||
{% for LLM in LLMs %}
|
||||
<!-- Added "has-text" as a default class -->
|
||||
<div class="icon-text has-text unselected" onclick="toggleSelection(this)" style="cursor: pointer;"
|
||||
value="{{ LLM.ID.String() }}">
|
||||
<span class="icon">
|
||||
@ -17,7 +17,7 @@
|
||||
<span>{{ LLM.Name }}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="is-flex is-justify-content-space-between mt-3">
|
||||
<div class="is-flex is-justify-content-space-between mt-4">
|
||||
<button class="button is-small is-danger is-outlined" hx-get="/deleteLLM" hx-swap="outerHTML"
|
||||
hx-target="#models-dropdown" hx-confirm="Are you sure?" hx-trigger="click"
|
||||
hx-vals="js:{selectedLLMIds: getSelectedModelsIDs()}">
|
||||
@ -38,7 +38,6 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="dropdown-item is-hidden" id="models-creation">
|
||||
<form id="create-model-form" hx-post="/createLLM" hx-target="#models-dropdown" hx-swap="outerHTML">
|
||||
@ -46,12 +45,18 @@
|
||||
placeholder="Model name">
|
||||
<div class="select is-fullwidth is-small mb-3" id="model-id-input">
|
||||
<select name="selectedLLMId">
|
||||
<option value="custom">Custom endpoint</option>
|
||||
{% for modelInfo in ModelInfos %}
|
||||
<option value="{{ modelInfo.ModelID }}">{{ modelInfo.ModelID }}</option>
|
||||
{% endfor %}
|
||||
<option value="custom">Custom endpoint</option>
|
||||
</select>
|
||||
</div>
|
||||
<input class="input is-small mb-3 is-hidden" type="text" id="model-cid-input" name="model-cid-input"
|
||||
placeholder="Model id">
|
||||
<input class="input is-small mb-3 is-hidden" type="text" id="model-url-input" name="model-url-input"
|
||||
placeholder="URL (with /v1/chat/completions)">
|
||||
<input class="input is-small mb-3 is-hidden" type="text" id="model-key-input" name="model-key-input"
|
||||
placeholder="Token">
|
||||
<p><small>Temperature:</small></p>
|
||||
<input class="slider is-small mb-3" step="0.05" min="0" max="1" value="0" type="range"
|
||||
id="temperature-slider" name="temperature-slider">
|
||||
@ -79,6 +84,27 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function toggleDropdown(event) {
|
||||
event.stopPropagation();
|
||||
document.getElementById('models-dropdown').classList.toggle('is-active');
|
||||
}
|
||||
|
||||
function closeDropdown(event) {
|
||||
if (!document.getElementById('models-dropdown').contains(event.target)) {
|
||||
document.getElementById('models-dropdown').classList.remove('is-active');
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('click', closeDropdown);
|
||||
|
||||
document.getElementById('model-id-input').querySelector('select').addEventListener('change', function () {
|
||||
const customEndpoint = this.value === 'custom';
|
||||
document.getElementById('model-url-input').classList.toggle('is-hidden', !customEndpoint);
|
||||
document.getElementById('model-key-input').classList.toggle('is-hidden', !customEndpoint);
|
||||
document.getElementById('model-cid-input').classList.toggle('is-hidden', !customEndpoint);
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('temperature-slider').addEventListener('input', function () {
|
||||
document.getElementById('temperature-slider-output').innerHTML = this.value;
|
||||
})
|
||||
|
@ -40,6 +40,16 @@
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="field has-addons is-hidden" id="groq-field">
|
||||
<p class="control has-icons-left is-expanded">
|
||||
<input class="input is-small {% if GroqExists %}is-success{% endif %}" type="text"
|
||||
placeholder="Groq API key" {%if not IsLogin %}disabled{% endif %} name="groq_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" title="Gemini is unavailable because of Europe"
|
||||
id="gemini-field">
|
||||
<p class="control has-icons-left is-expanded">
|
||||
@ -50,21 +60,12 @@
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="field has-addons is-hidden" id="goose-field">
|
||||
<div class="field has-addons is-hidden" id="goose-field"
|
||||
title="GooseAI chat API soon to be available">
|
||||
<p class="control has-icons-left is-expanded">
|
||||
<input class="input is-small {% if GooseaiExists %}is-success{% endif %}" type="text"
|
||||
{%if not IsLogin %}disabled{% endif %} placeholder="Gooseai API key"
|
||||
name="goose_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="groq-field">
|
||||
<p class="control has-icons-left is-expanded">
|
||||
<input class="input is-small {% if GroqExists %}is-success{% endif %}" type="text"
|
||||
placeholder="Groq API key" {%if not IsLogin %}disabled{% endif %} name="groq_key"
|
||||
autocomplete="off">
|
||||
name="goose_key" autocomplete="off" disabled>
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fas fa-lock"></i>
|
||||
</span>
|
||||
|
Loading…
x
Reference in New Issue
Block a user