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 := "<div class='message-header'>"
|
||||||
out += "<p>"
|
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 += " </p>"
|
||||||
out += "</div>"
|
out += "</div>"
|
||||||
out += "<div class='message-body'>"
|
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)
|
`, &llms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
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()
|
modelInfos := GetAvailableModels()
|
||||||
|
|
||||||
out, err := pongo2.Must(pongo2.FromFile("views/partials/popover-models.html")).Execute(pongo2.Context{
|
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 (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/edgedb/edgedb-go"
|
"github.com/edgedb/edgedb-go"
|
||||||
@ -52,12 +53,43 @@ func createLLM(c *fiber.Ctx) error {
|
|||||||
name := c.FormValue("model-name-input")
|
name := c.FormValue("model-name-input")
|
||||||
modelID := c.FormValue("selectedLLMId")
|
modelID := c.FormValue("selectedLLMId")
|
||||||
temperature := c.FormValue("temperature-slider")
|
temperature := c.FormValue("temperature-slider")
|
||||||
systemPrompt := c.FormValue("model-prompt-input")
|
|
||||||
|
|
||||||
f, _ := strconv.ParseFloat(temperature, 32)
|
f, _ := strconv.ParseFloat(temperature, 32)
|
||||||
temperatureFloat := float32(f)
|
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 {
|
INSERT LLM {
|
||||||
name := <str>$0,
|
name := <str>$0,
|
||||||
context := <str>$1,
|
context := <str>$1,
|
||||||
@ -66,8 +98,9 @@ func createLLM(c *fiber.Ctx) error {
|
|||||||
user := global currentUser
|
user := global currentUser
|
||||||
}
|
}
|
||||||
`, name, systemPrompt, temperatureFloat, modelID)
|
`, name, systemPrompt, temperatureFloat, modelID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.SendString(GenerateModelPopoverHTML(true))
|
return c.SendString(GenerateModelPopoverHTML(true))
|
||||||
|
@ -14,6 +14,7 @@ type GooseaiCompletionRequest struct {
|
|||||||
Model string `json:"model"`
|
Model string `json:"model"`
|
||||||
Prompt []string `json:"prompt"`
|
Prompt []string `json:"prompt"`
|
||||||
Temperature float64 `json:"temperature"`
|
Temperature float64 `json:"temperature"`
|
||||||
|
MaxToken int32 `json:"max_tokens"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GooseaiCompletionResponse struct {
|
type GooseaiCompletionResponse struct {
|
||||||
@ -53,6 +54,7 @@ func TestGooseaiKey(apiKey string) bool {
|
|||||||
Model: "gpt-j-6b",
|
Model: "gpt-j-6b",
|
||||||
Prompt: []string{"Hello, how are you?"},
|
Prompt: []string{"Hello, how are you?"},
|
||||||
Temperature: 0,
|
Temperature: 0,
|
||||||
|
MaxToken: 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonBody, err := json.Marshal(requestBody)
|
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"
|
url := "https://api.goose.ai/v1/engines/" + model + "/completions"
|
||||||
|
|
||||||
|
var prompt string
|
||||||
|
for _, message := range messages {
|
||||||
|
prompt += message.Content
|
||||||
|
}
|
||||||
|
|
||||||
requestBody := GooseaiCompletionRequest{
|
requestBody := GooseaiCompletionRequest{
|
||||||
Model: model,
|
Model: model,
|
||||||
Prompt: []string{messages[len(messages)-1].Content},
|
Prompt: []string{prompt},
|
||||||
Temperature: temperature,
|
Temperature: temperature,
|
||||||
|
MaxToken: 300,
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonBody, err := json.Marshal(requestBody)
|
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("Authorization", "Bearer "+llm.Endpoint.Key)
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
fmt.Println(url, llm.Endpoint.Key)
|
||||||
|
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -177,6 +177,9 @@ func RequestMistral(model string, messages []Message, temperature float64) (Mist
|
|||||||
FILTER .modelID = <str>$0
|
FILTER .modelID = <str>$0
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
`, &usedModelInfo, model)
|
`, &usedModelInfo, model)
|
||||||
|
if err != nil {
|
||||||
|
return MistralChatCompletionResponse{}, fmt.Errorf("error getting model info: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
if usedModelInfo.InputPrice == 0 || usedModelInfo.OutputPrice == 0 {
|
if usedModelInfo.InputPrice == 0 || usedModelInfo.OutputPrice == 0 {
|
||||||
return MistralChatCompletionResponse{}, fmt.Errorf("model %s not found in Mistral", model)
|
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,
|
name,
|
||||||
icon
|
icon
|
||||||
}
|
}
|
||||||
} FILTER .modelID != 'none'
|
} FILTER .modelID != 'none' AND .company.name != 'huggingface'
|
||||||
`, &models)
|
`, &models)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
{% if not message.Hidden %}
|
{% if not message.Hidden %}
|
||||||
<div class="message-header">
|
<div class="message-header">
|
||||||
<p>
|
<p>
|
||||||
<strong>{{ message.Name }}</strong> <small>{{ message.Model }}</small>
|
<strong>{{ message.Name }}</strong> <small>{{ message.ModelID }}</small>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="message-body">
|
<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">
|
<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>
|
<span class="icon"><i class="fa-solid fa-robot"></i></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</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-content is-small">
|
||||||
<div class="dropdown-item" id="models-list">
|
<div class="dropdown-item" id="models-list">
|
||||||
{% for LLM in LLMs %}
|
{% for LLM in LLMs %}
|
||||||
<!-- Added "has-text" as a default class -->
|
|
||||||
<div class="icon-text has-text unselected" onclick="toggleSelection(this)" style="cursor: pointer;"
|
<div class="icon-text has-text unselected" onclick="toggleSelection(this)" style="cursor: pointer;"
|
||||||
value="{{ LLM.ID.String() }}">
|
value="{{ LLM.ID.String() }}">
|
||||||
<span class="icon">
|
<span class="icon">
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<span>{{ LLM.Name }}</span>
|
<span>{{ LLM.Name }}</span>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% 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"
|
<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-target="#models-dropdown" hx-confirm="Are you sure?" hx-trigger="click"
|
||||||
hx-vals="js:{selectedLLMIds: getSelectedModelsIDs()}">
|
hx-vals="js:{selectedLLMIds: getSelectedModelsIDs()}">
|
||||||
@ -38,7 +38,6 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-item is-hidden" id="models-creation">
|
<div class="dropdown-item is-hidden" id="models-creation">
|
||||||
<form id="create-model-form" hx-post="/createLLM" hx-target="#models-dropdown" hx-swap="outerHTML">
|
<form id="create-model-form" hx-post="/createLLM" hx-target="#models-dropdown" hx-swap="outerHTML">
|
||||||
@ -46,12 +45,18 @@
|
|||||||
placeholder="Model name">
|
placeholder="Model name">
|
||||||
<div class="select is-fullwidth is-small mb-3" id="model-id-input">
|
<div class="select is-fullwidth is-small mb-3" id="model-id-input">
|
||||||
<select name="selectedLLMId">
|
<select name="selectedLLMId">
|
||||||
<option value="custom">Custom endpoint</option>
|
|
||||||
{% for modelInfo in ModelInfos %}
|
{% for modelInfo in ModelInfos %}
|
||||||
<option value="{{ modelInfo.ModelID }}">{{ modelInfo.ModelID }}</option>
|
<option value="{{ modelInfo.ModelID }}">{{ modelInfo.ModelID }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
<option value="custom">Custom endpoint</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</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>
|
<p><small>Temperature:</small></p>
|
||||||
<input class="slider is-small mb-3" step="0.05" min="0" max="1" value="0" type="range"
|
<input class="slider is-small mb-3" step="0.05" min="0" max="1" value="0" type="range"
|
||||||
id="temperature-slider" name="temperature-slider">
|
id="temperature-slider" name="temperature-slider">
|
||||||
@ -79,6 +84,27 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<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').addEventListener('input', function () {
|
||||||
document.getElementById('temperature-slider-output').innerHTML = this.value;
|
document.getElementById('temperature-slider-output').innerHTML = this.value;
|
||||||
})
|
})
|
||||||
|
@ -40,6 +40,16 @@
|
|||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</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"
|
<div class="field has-addons is-hidden" title="Gemini is unavailable because of Europe"
|
||||||
id="gemini-field">
|
id="gemini-field">
|
||||||
<p class="control has-icons-left is-expanded">
|
<p class="control has-icons-left is-expanded">
|
||||||
@ -50,21 +60,12 @@
|
|||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</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">
|
<p class="control has-icons-left is-expanded">
|
||||||
<input class="input is-small {% if GooseaiExists %}is-success{% endif %}" type="text"
|
<input class="input is-small {% if GooseaiExists %}is-success{% endif %}" type="text"
|
||||||
{%if not IsLogin %}disabled{% endif %} placeholder="Gooseai API key"
|
{%if not IsLogin %}disabled{% endif %} placeholder="Gooseai API key"
|
||||||
name="goose_key" autocomplete="off">
|
name="goose_key" autocomplete="off" disabled>
|
||||||
<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">
|
|
||||||
<span class="icon is-small is-left">
|
<span class="icon is-small is-left">
|
||||||
<i class="fas fa-lock"></i>
|
<i class="fas fa-lock"></i>
|
||||||
</span>
|
</span>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user