Changed HTML to use djlint
This commit is contained in:
parent
5384383908
commit
fa1bd44a99
@ -1,4 +1,7 @@
|
|||||||
<div class="chat-container mt-5" style="padding-bottom: 155px;" hx-indicator="#textarea-control" hx-ext="sse">
|
<div class="chat-container mt-5"
|
||||||
<hx hx-get="/loadChat" hx-trigger="load once" hx-swap="outerHTML"></hx>
|
style="padding-bottom: 155px"
|
||||||
<hx hx-get="/loadChatInput" hx-trigger="load once" hx-swap="outerHTML" id="textarea-control"></hx>
|
hx-indicator="#textarea-control"
|
||||||
|
hx-ext="sse">
|
||||||
|
<hx hx-get="/loadChat" hx-trigger="load once" hx-swap="outerHTML"></hx>
|
||||||
|
<hx hx-get="/loadChatInput" hx-trigger="load once" hx-swap="outerHTML" id="textarea-control"></hx>
|
||||||
</div>
|
</div>
|
@ -1,13 +1,17 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html data-theme="dark" lang="en">
|
<html data-theme="dark" lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
|
<meta name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
|
||||||
<title>JADE</title>
|
<title>JADE</title>
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1.0.0/css/bulma.min.css">
|
<link rel="stylesheet"
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css">
|
href="https://cdn.jsdelivr.net/npm/bulma@1.0.0/css/bulma.min.css">
|
||||||
<link href="https://fonts.googleapis.com/css?family=Russo+One" rel="stylesheet">
|
<link rel="stylesheet"
|
||||||
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Russo+One"
|
||||||
|
rel="stylesheet">
|
||||||
|
|
||||||
<!--link rel="stylesheet" href="/animations.css"-->
|
<!--link rel="stylesheet" href="/animations.css"-->
|
||||||
<link rel="stylesheet" href="/style.css">
|
<link rel="stylesheet" href="/style.css">
|
||||||
@ -19,7 +23,8 @@
|
|||||||
<script async src="https://js.stripe.com/v3/pricing-table.js"></script>
|
<script async src="https://js.stripe.com/v3/pricing-table.js"></script>
|
||||||
|
|
||||||
<!-- highlight.js -->
|
<!-- highlight.js -->
|
||||||
<link rel="stylesheet" href="https://unpkg.com/@highlightjs/cdn-assets@11.9.0/styles/default.min.css">
|
<link rel="stylesheet"
|
||||||
|
href="https://unpkg.com/@highlightjs/cdn-assets@11.9.0/styles/default.min.css">
|
||||||
<script src="https://unpkg.com/@highlightjs/cdn-assets@11.9.0/highlight.min.js"></script>
|
<script src="https://unpkg.com/@highlightjs/cdn-assets@11.9.0/highlight.min.js"></script>
|
||||||
<script>hljs.highlightAll();</script>
|
<script>hljs.highlightAll();</script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||||
@ -31,9 +36,9 @@
|
|||||||
go.run(result.instance);
|
go.run(result.instance);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
{{ embed }}
|
{{ embed }}
|
||||||
|
|
||||||
@ -197,6 +202,6 @@
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
@ -1,123 +1,133 @@
|
|||||||
{% if IsLogin %}
|
{% if IsLogin %}
|
||||||
{% if IsSubscribed or not IsLimiteReached %}
|
{% if IsSubscribed or not IsLimiteReached %}
|
||||||
<div class="chat-input-container mb-5">
|
<div class="chat-input-container mb-5">
|
||||||
<div class="textarea-wrapper">
|
<div class="textarea-wrapper">
|
||||||
<div class="control" id="textarea-control">
|
<div class="control" id="textarea-control">
|
||||||
<textarea {% if not IsLogin or not HaveKey %}disabled{% endif %} class="textarea has-fixed-size"
|
<textarea {% if not IsLogin or not HaveKey %}disabled{% endif %}
|
||||||
placeholder="Type your message here..." name="message" oninput="toggleSendButton()"
|
class="textarea has-fixed-size"
|
||||||
id="chat-input-textarea"></textarea>
|
placeholder="Type your message here..."
|
||||||
|
name="message"
|
||||||
|
oninput="toggleSendButton()"
|
||||||
|
id="chat-input-textarea"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<hx hx-get="/loadSettings" hx-trigger="load" hx-swap="outerHTML" hx-target="this"></hx>
|
<hx hx-get="/loadSettings" 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="/loadUsageKPI" hx-trigger="load" hx-swap="outerHTML" hx-target="this"></hx>
|
||||||
<hx hx-get="/loadConversationSelection" hx-trigger="load" hx-swap="outerHTML" hx-target="this"></hx>
|
<hx hx-get="/loadConversationSelection" hx-trigger="load" hx-swap="outerHTML" hx-target="this"></hx>
|
||||||
<hx hx-get="/loadModelSelection" 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 disabled type="submit" class="send-button button is-primary is-small" hx-post="/generatePlaceholder"
|
<button disabled
|
||||||
hx-swap="beforeend" hx-target="#chat-messages" id="chat-input-send-btn" class="chat-input"
|
type="submit"
|
||||||
hx-include="[name='message']" hx-vals="js:{selectedLLMIds: getSelectedModelsIDs()}"
|
class="send-button button is-primary is-small"
|
||||||
onclick="onClickSendButton()">
|
hx-post="/generatePlaceholder"
|
||||||
<span class="icon">
|
hx-swap="beforeend"
|
||||||
<i class="fa-solid fa-chevron-right"></i>
|
hx-target="#chat-messages"
|
||||||
</span>
|
id="chat-input-send-btn"
|
||||||
</button>
|
class="chat-input"
|
||||||
|
hx-include="[name='message']"
|
||||||
|
hx-vals="js:{selectedLLMIds: getSelectedModelsIDs()}"
|
||||||
|
onclick="onClickSendButton()">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-chevron-right"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% endif %}
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var textareaControl = document.getElementById('textarea-control');
|
var textareaControl = document.getElementById('textarea-control');
|
||||||
|
|
||||||
// Every 0.01s check if the text area have htmx-request class, if yes, add the class is-loading
|
// Every 0.01s check if the text area have htmx-request class, if yes, add the class is-loading
|
||||||
setInterval(function () {
|
setInterval(function () {
|
||||||
if (textareaControl === null) {
|
if (textareaControl === null) {
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
if (textareaControl.classList.contains('htmx-request')) {
|
|
||||||
textareaControl.classList.add('is-loading');
|
|
||||||
} else {
|
|
||||||
textareaControl.classList.remove('is-loading');
|
|
||||||
}
|
|
||||||
}, 10);
|
|
||||||
|
|
||||||
function updateIcons() {
|
|
||||||
if (window.innerWidth < 450) {
|
|
||||||
var elements = document.getElementsByClassName('message-icon');
|
|
||||||
for (var i = 0; i < elements.length; i++) {
|
|
||||||
elements[i].classList.remove('is-48x48');
|
|
||||||
elements[i].classList.add('is-32x32');
|
|
||||||
elements[i].parentElement.style = "padding-right: 0;";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var elements = document.getElementsByClassName('message-icon');
|
|
||||||
for (var i = 0; i < elements.length; i++) {
|
|
||||||
elements[i].classList.remove('is-32x32');
|
|
||||||
elements[i].classList.add('is-48x48');
|
|
||||||
elements[i].parentElement.style = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (textareaControl.classList.contains('htmx-request')) {
|
||||||
// Run when the element is added
|
textareaControl.classList.add('is-loading');
|
||||||
document.addEventListener('htmx:afterSwap', updateIcons);
|
} else {
|
||||||
|
textareaControl.classList.remove('is-loading');
|
||||||
// Run every 0.01s
|
|
||||||
setInterval(updateIcons, 100);
|
|
||||||
|
|
||||||
document.getElementById('chat-input-textarea').addEventListener('focus', function () {
|
|
||||||
var buttons = document.getElementsByClassName('to-reduce-opacity');
|
|
||||||
for (var i = 0; i < buttons.length; i++) {
|
|
||||||
buttons[i].style.opacity = 0.2;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById('chat-input-textarea').addEventListener('blur', function () {
|
|
||||||
var buttons = document.getElementsByClassName('to-reduce-opacity');
|
|
||||||
for (var i = 0; i < buttons.length; i++) {
|
|
||||||
buttons[i].style.opacity = 1;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const textarea = document.querySelector('#chat-input-textarea');
|
|
||||||
textarea.addEventListener('keydown', handleTextareaKeydown);
|
|
||||||
|
|
||||||
document.addEventListener('htmx:afterSwap', toggleSendButton)
|
|
||||||
|
|
||||||
function toggleSendButton() {
|
|
||||||
// check if generate-multiple-messages exists
|
|
||||||
var generateMultipleMessages = document.getElementById('generate-multiple-messages');
|
|
||||||
document.getElementById('chat-input-send-btn').disabled = textarea.value.trim().length === 0 || document.getElementsByClassName('selected icon-llm').length === 0 || generateMultipleMessages !== null;
|
|
||||||
// Do the same for all element with an id that start with redo-button- or edit-button-
|
|
||||||
const buttons = document.querySelectorAll('[id^="redo-button-"], [id^="edit-button-"]');
|
|
||||||
if (document.getElementsByClassName('selected icon-llm').length === 0 || generateMultipleMessages !== null) {
|
|
||||||
buttons.forEach(button => button.classList.add('is-static'));
|
|
||||||
} else {
|
|
||||||
buttons.forEach(button => button.classList.remove('is-static'));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}, 10);
|
||||||
|
|
||||||
function onClickSendButton() {
|
function updateIcons() {
|
||||||
// TODO: Add the message placeholder using WASM
|
if (window.innerWidth < 450) {
|
||||||
messagesPlaceholderHTML = generatePlaceholder(textarea.value);
|
var elements = document.getElementsByClassName('message-icon');
|
||||||
document.getElementById('chat-messages').insertAdjacentHTML('beforeend', messagesPlaceholderHTML);
|
for (var i = 0; i < elements.length; i++) {
|
||||||
|
elements[i].classList.remove('is-48x48');
|
||||||
setTimeout(function () {
|
elements[i].classList.add('is-32x32');
|
||||||
textarea.value = '';
|
elements[i].parentElement.style = "padding-right: 0;";
|
||||||
toggleSendButton();
|
}
|
||||||
}, 20);
|
} else {
|
||||||
|
var elements = document.getElementsByClassName('message-icon');
|
||||||
|
for (var i = 0; i < elements.length; i++) {
|
||||||
|
elements[i].classList.remove('is-32x32');
|
||||||
|
elements[i].classList.add('is-48x48');
|
||||||
|
elements[i].parentElement.style = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function updateIcon(icon, ConversationAreaId) {
|
// Run when the element is added
|
||||||
var selectedIcon = document.getElementById('selectedIcon-' + ConversationAreaId);
|
document.addEventListener('htmx:afterSwap', updateIcons);
|
||||||
selectedIcon.src = icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleTextareaKeydown(event) {
|
// Run every 0.01s
|
||||||
if (event.metaKey && event.key === 'Enter' && event.target === textarea && textarea.value.trim() !== '' && document.getElementsByClassName('selected icon-llm').length !== 0) {
|
setInterval(updateIcons, 100);
|
||||||
// Check if the cursor is in the textarea
|
|
||||||
// Trigger the same action as the send button
|
document.getElementById('chat-input-textarea').addEventListener('focus', function () {
|
||||||
document.getElementById('chat-input-send-btn').click();
|
var buttons = document.getElementsByClassName('to-reduce-opacity');
|
||||||
}
|
for (var i = 0; i < buttons.length; i++) {
|
||||||
|
buttons[i].style.opacity = 0.2;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('chat-input-textarea').addEventListener('blur', function () {
|
||||||
|
var buttons = document.getElementsByClassName('to-reduce-opacity');
|
||||||
|
for (var i = 0; i < buttons.length; i++) {
|
||||||
|
buttons[i].style.opacity = 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const textarea = document.querySelector('#chat-input-textarea');
|
||||||
|
textarea.addEventListener('keydown', handleTextareaKeydown);
|
||||||
|
|
||||||
|
document.addEventListener('htmx:afterSwap', toggleSendButton)
|
||||||
|
|
||||||
|
function toggleSendButton() {
|
||||||
|
// check if generate-multiple-messages exists
|
||||||
|
var generateMultipleMessages = document.getElementById('generate-multiple-messages');
|
||||||
|
document.getElementById('chat-input-send-btn').disabled = textarea.value.trim().length === 0 || document.getElementsByClassName('selected icon-llm').length === 0 || generateMultipleMessages !== null;
|
||||||
|
// Do the same for all element with an id that start with redo-button- or edit-button-
|
||||||
|
const buttons = document.querySelectorAll('[id^="redo-button-"], [id^="edit-button-"]');
|
||||||
|
if (document.getElementsByClassName('selected icon-llm').length === 0 || generateMultipleMessages !== null) {
|
||||||
|
buttons.forEach(button => button.classList.add('is-static'));
|
||||||
|
} else {
|
||||||
|
buttons.forEach(button => button.classList.remove('is-static'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onClickSendButton() {
|
||||||
|
// TODO: Add the message placeholder using WASM
|
||||||
|
messagesPlaceholderHTML = generatePlaceholder(textarea.value);
|
||||||
|
document.getElementById('chat-messages').insertAdjacentHTML('beforeend', messagesPlaceholderHTML);
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
textarea.value = '';
|
||||||
|
toggleSendButton();
|
||||||
|
}, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateIcon(icon, ConversationAreaId) {
|
||||||
|
var selectedIcon = document.getElementById('selectedIcon-' + ConversationAreaId);
|
||||||
|
selectedIcon.src = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleTextareaKeydown(event) {
|
||||||
|
if (event.metaKey && event.key === 'Enter' && event.target === textarea && textarea.value.trim() !== '' && document.getElementsByClassName('selected icon-llm').length !== 0) {
|
||||||
|
// Check if the cursor is in the textarea
|
||||||
|
// Trigger the same action as the send button
|
||||||
|
document.getElementById('chat-input-send-btn').click();
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
@ -3,55 +3,30 @@
|
|||||||
To use JADE, you need to sign up for an API key. You can enter an API key in
|
To use JADE, you need to sign up for an API key. You can enter an API key in
|
||||||
the settings menu. Once enter you get access to all models from this provider.
|
the settings menu. Once enter you get access to all models from this provider.
|
||||||
</p>
|
</p>
|
||||||
<a
|
<a class="button is-small is-primary is-outlined mt-1"
|
||||||
class="button is-small is-primary is-outlined mt-1"
|
href="https://openai.com/index/openai-api/"
|
||||||
href="https://openai.com/index/openai-api/"
|
target="_blank">Get OpenAI API key</a>
|
||||||
target="_blank"
|
<a class="button is-small is-primary is-outlined mt-1"
|
||||||
>
|
href="https://console.anthropic.com/"
|
||||||
Get OpenAI API key
|
target="_blank">Get Anthropic API key</a>
|
||||||
</a>
|
<a class="button is-small is-primary is-outlined mt-1"
|
||||||
<a
|
href="https://console.mistral.ai/"
|
||||||
class="button is-small is-primary is-outlined mt-1"
|
target="_blank">Get Mistral API key</a>
|
||||||
href="https://console.anthropic.com/"
|
<a class="button is-small is-primary is-outlined mt-1"
|
||||||
target="_blank"
|
href="https://console.groq.com/"
|
||||||
>
|
target="_blank">Get Groq API key</a>
|
||||||
Get Anthropic API key
|
<a class="button is-small is-primary is-outlined mt-1"
|
||||||
</a>
|
href="https://aistudio.google.com/app/apikey"
|
||||||
<a
|
target="_blank">Get Google API key</a>
|
||||||
class="button is-small is-primary is-outlined mt-1"
|
<a class="button is-small is-primary is-outlined mt-1"
|
||||||
href="https://console.mistral.ai/"
|
href="https://build.nvidia.com/explore/discover"
|
||||||
target="_blank"
|
target="_blank">Get Nvidia NIM API key</a>
|
||||||
>
|
<a class="button is-small is-primary is-outlined mt-1"
|
||||||
Get Mistral API key
|
href="https://docs.perplexity.ai/docs/getting-started"
|
||||||
</a>
|
target="_blank">Get Perplexity API key</a>
|
||||||
<a
|
<a class="button is-small is-primary is-outlined mt-1"
|
||||||
class="button is-small is-primary is-outlined mt-1"
|
href="https://fireworks.ai/login"
|
||||||
href="https://console.groq.com/"
|
target="_blank">Get Fireworks API key</a>
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
Get Groq API key
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="button is-small is-primary is-outlined mt-1"
|
|
||||||
href="https://aistudio.google.com/app/apikey"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
Get Google API key
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="button is-small is-primary is-outlined mt-1"
|
|
||||||
href="https://docs.perplexity.ai/docs/getting-started"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
Get Perplexity API key
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="button is-small is-primary is-outlined mt-1"
|
|
||||||
href="https://fireworks.ai/login"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
Get Fireworks API key
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<h2>Conversations</h2>
|
<h2>Conversations</h2>
|
||||||
<p>
|
<p>
|
||||||
@ -68,10 +43,10 @@
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
To create a new bot, click the "+" button, enter a name and a model, and
|
To create a new bot, click the "+" button, enter a name and a model, and
|
||||||
optionally set a temperature and a system prompt. Once created, you can select
|
optionally set a temperature, a max tokens and a system prompt. Once created,
|
||||||
a bot by clicking on it and reorder it by dragging. Hold SHIFT and click to
|
you can select a bot by clicking on it and reorder it by dragging. Hold SHIFT
|
||||||
select multiple bots. You can delete selected bots by clicking the trash can
|
and click to select multiple bots. You can delete selected bots by clicking
|
||||||
icon.
|
the trash can icon.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Multi-Models</h2>
|
<h2>Multi-Models</h2>
|
||||||
|
@ -1,114 +1,124 @@
|
|||||||
<div class="message-bot mt-3" id="msg-{{ ConversationAreaId }}">
|
<div class="message-bot mt-3" id="msg-{{ ConversationAreaId }}">
|
||||||
<div class="columns is-mobile">
|
<div class="columns is-mobile">
|
||||||
{% if not DontShowName %}
|
{% if not DontShowName %}
|
||||||
<div class="column is-narrow" id="icon-column">
|
<div class="column is-narrow" id="icon-column">
|
||||||
<!-- Left column with the icon -->
|
<!-- Left column with the icon -->
|
||||||
{% if IsPlaceholder %}
|
{% if IsPlaceholder %}
|
||||||
|
|
||||||
<figure class="image is-48x48 message-icon" style="flex-shrink: 0;"
|
<figure class="image is-48x48 message-icon"
|
||||||
sse-swap="swapIcon-{{ ConversationAreaId }}">
|
style="flex-shrink: 0"
|
||||||
<img src="icons/bouvai2.png" alt="User Image" id="selectedIcon-{{ ConversationAreaId }}">
|
sse-swap="swapIcon-{{ ConversationAreaId }}">
|
||||||
</figure>
|
<img src="icons/bouvai2.png"
|
||||||
|
alt="User Image"
|
||||||
|
id="selectedIcon-{{ ConversationAreaId }}">
|
||||||
|
</figure>
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
|
{% for message in Messages %}
|
||||||
|
{% if not message.Hidden %}
|
||||||
|
<figure class="image is-48x48 message-icon" style="flex-shrink: 0;">
|
||||||
|
<img src="{{ message.Icon }}"
|
||||||
|
alt="User Image"
|
||||||
|
id="selectedIcon-{{ ConversationAreaId }}">
|
||||||
|
</figure>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="column" id="content-column" style="width: 100px;">
|
||||||
|
{% if not IsPlaceholder %}
|
||||||
|
<div class="{% if not notFlex %} is-flex {% endif %} is-align-items-start">
|
||||||
|
<div class="message-content"
|
||||||
|
style="width: 100%;
|
||||||
|
overflow-y: hidden"
|
||||||
|
id="content-{{ ConversationAreaId }}">
|
||||||
|
{% for message in Messages %}
|
||||||
|
{% if not message.Hidden %}
|
||||||
|
{% if not DontShowName %}
|
||||||
|
<div class="message-header">
|
||||||
|
<p>
|
||||||
|
<strong>{{ message.Name }}</strong> <small>{{ message.ModelID }}</small>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="message-body">
|
||||||
|
<div class="content" style="overflow-x: auto; width: 100%;">{{ message.Content | safe }}</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="is-flex is-justify-content mt-2">
|
||||||
|
{% if not NotClickable %}
|
||||||
|
<button class="button is-small is-primary message-button is-outlined mr-5"
|
||||||
|
onclick="copyToClipboard(this)">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-copy"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
{% for message in Messages %}
|
{% for message in Messages %}
|
||||||
{% if not message.Hidden %}
|
<button class="button is-small is-primary message-button is-outlined mr-1"
|
||||||
<figure class="image is-48x48 message-icon" style="flex-shrink: 0;">
|
hx-get="/messageContent?id={{ message.Id }}"
|
||||||
<img src="{{ message.Icon }}" alt="User Image" id="selectedIcon-{{ ConversationAreaId }}">
|
hx-target="#content-{{ ConversationAreaId }}"
|
||||||
</figure>
|
onclick="updateIcon('{{ message.Icon }}', '{{ ConversationAreaId }}')"
|
||||||
{% endif %}
|
title="{{ message.Name }}">
|
||||||
|
<span class="icon is-small">
|
||||||
|
<img src="{{ message.Icon }}"
|
||||||
|
alt="{{ message.Name }}"
|
||||||
|
style="max-height: 100%;
|
||||||
|
max-width: 100%">
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="column" id="content-column" style="width: 100px;">
|
{% elif IsPlaceholder %}
|
||||||
{% if not IsPlaceholder %}
|
<div class="is-flex is-align-items-start">
|
||||||
<div class="{% if not notFlex%} is-flex {% endif %} is-align-items-start">
|
<div class="message-content"
|
||||||
<div class="message-content" style="width: 100%; overflow-y: hidden;"
|
id="content-{{ ConversationAreaId }}"
|
||||||
id="content-{{ ConversationAreaId }}">
|
sse-swap="swapContent-{{ ConversationAreaId }}">
|
||||||
{% for message in Messages %}
|
<hx hx-trigger="load" hx-get="/generateMultipleMessages" id="generate-multiple-messages"></hx>
|
||||||
{% if not message.Hidden %}
|
<div class='message-header'>
|
||||||
{% if not DontShowName %}
|
<p>Waiting...</p>
|
||||||
<div class="message-header">
|
|
||||||
<p>
|
|
||||||
<strong>{{ message.Name }}</strong> <small>{{ message.ModelID }}</small>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<div class="message-body">
|
|
||||||
<div class="content" style="overflow-x: auto; width: 100%;">
|
|
||||||
{{ message.Content | safe }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="is-flex is-justify-content mt-2">
|
<div class="message-body">
|
||||||
{% if not NotClickable %}
|
<div class="content">
|
||||||
<button class="button is-small is-primary message-button is-outlined mr-5"
|
<br>
|
||||||
onclick="copyToClipboard(this)">
|
<img src="/puff.svg" />
|
||||||
<span class="icon">
|
</div>
|
||||||
<i class="fa-solid fa-copy"></i>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{% for message in Messages %}
|
|
||||||
<button class="button is-small is-primary message-button is-outlined mr-1"
|
|
||||||
hx-get="/messageContent?id={{ message.Id }}" hx-target="#content-{{ ConversationAreaId }}"
|
|
||||||
onclick="updateIcon('{{ message.Icon }}', '{{ ConversationAreaId }}')" title="{{ message.Name }}">
|
|
||||||
<span class="icon is-small">
|
|
||||||
<img src="{{ message.Icon }}" alt="{{ message.Name }}"
|
|
||||||
style="max-height: 100%; max-width: 100%;">
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% elif IsPlaceholder %}
|
<div class="is-flex is-justify-content mt-2">
|
||||||
<div class="is-flex is-align-items-start">
|
<button class="button is-small is-primary message-button is-outlined mr-5"
|
||||||
<div class="message-content" id="content-{{ ConversationAreaId }}"
|
onclick="copyToClipboard(this)">
|
||||||
sse-swap="swapContent-{{ ConversationAreaId }}">
|
<span class="icon">
|
||||||
<hx hx-trigger="load" hx-get="/generateMultipleMessages" id="generate-multiple-messages"></hx>
|
<i class="fa-solid fa-copy"></i>
|
||||||
<div class='message-header'>
|
</span>
|
||||||
<p>
|
</button>
|
||||||
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">
|
{% for selectedLLM in SelectedLLMs %}
|
||||||
<button class="button is-small is-primary message-button is-outlined mr-5"
|
<button disable
|
||||||
onclick="copyToClipboard(this)">
|
class="button is-small is-primary message-button is-outlined mr-1"
|
||||||
<span class="icon">
|
sse-swap="swapSelectionBtn-{{ selectedLLM.ID.String() }}"
|
||||||
<i class="fa-solid fa-copy"></i>
|
hx-swap="outerHTML"
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{% for selectedLLM in SelectedLLMs %}
|
|
||||||
<button disable class="button is-small is-primary message-button is-outlined mr-1"
|
|
||||||
sse-swap="swapSelectionBtn-{{ selectedLLM.ID.String() }}" hx-swap="outerHTML"
|
|
||||||
hx-target="this">
|
hx-target="this">
|
||||||
<span class="icon is-small">
|
<span class="icon is-small">
|
||||||
<!--img src="icons/{{ selectedLLM.Company }}.png" alt="{{ selectedLLM.Name }}"
|
<!--img src="icons/{{ selectedLLM.Company }}.png" alt="{{ selectedLLM.Name }}"
|
||||||
style="max-height: 100%; max-width: 100%;"-->
|
style="max-height: 100%; max-width: 100%;"-->
|
||||||
<img src="/puff.svg" />
|
<img src="/puff.svg" />
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
@ -1,56 +1,63 @@
|
|||||||
<div class="message-user mt-3" id="{{ ID }}">
|
<div class="message-user mt-3" id="{{ ID }}">
|
||||||
<div class="columns is-mobile">
|
<div class="columns is-mobile">
|
||||||
<div class="column is-narrow" id="icon-column">
|
<div class="column is-narrow" id="icon-column">
|
||||||
<figure class="image is-48x48" style="flex-shrink: 0;">
|
<figure class="image is-48x48" style="flex-shrink: 0;">
|
||||||
<img src="icons/bouvai2.png" alt="User Image">
|
<img src="icons/bouvai2.png" alt="User Image">
|
||||||
</figure>
|
</figure>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="column" id="content-column">
|
|
||||||
<div class="is-flex is-align-items-start mr-5" style="width: 100%;">
|
|
||||||
<div class="message-content" style="width: 100%;">
|
|
||||||
<div class="message-header">
|
|
||||||
<p>
|
|
||||||
You
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="message-body" style="width: 100%;">
|
|
||||||
<div class="content" id="content-{{ ID }}" style="width: 100%;">
|
|
||||||
<div class="field" style="width: 100%;">
|
|
||||||
<div class="control" style="width: 100%;">
|
|
||||||
<textarea class="textarea is-small has-fixed-size mt-2"
|
|
||||||
placeholder="Enter your message here" rows="{{ Rows }}"
|
|
||||||
style="background-color: transparent; width: 100%;"
|
|
||||||
name="message">{{ Content }}</textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="field is-grouped is-flex is-justify-content-flex-end mb-3">
|
|
||||||
<div class="control">
|
|
||||||
<button hx-get="/userMessage?id={{ ID }}" hx-target="closest .message-user"
|
|
||||||
class="button is-danger is-outlined is-small">
|
|
||||||
<span class="icon">
|
|
||||||
<i class="fa-solid fa-xmark"></i>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<div style="display: none;" hx-trigger="click from:#edit-button-{{ ID }}"
|
|
||||||
hx-target="next .message-bot" hx-swap="outerHTML" hx-get="/empty"></div>
|
|
||||||
<button class="button is-success is-outlined is-small"
|
|
||||||
hx-post="/editMessage?id={{ ID }}" hx-target="closest .message-user"
|
|
||||||
hx-include="[name='message']"
|
|
||||||
hx-vals="js:{selectedLLMIds: getSelectedModelsIDs()}" hx-swap="outerHTML"
|
|
||||||
id="edit-button-{{ ID }}" hx-trigger="click">
|
|
||||||
<span class="icon">
|
|
||||||
<i class="fa-solid fa-check"></i>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="column" id="content-column">
|
||||||
|
<div class="is-flex is-align-items-start mr-5" style="width: 100%;">
|
||||||
|
<div class="message-content" style="width: 100%;">
|
||||||
|
<div class="message-header">
|
||||||
|
<p>You</p>
|
||||||
|
</div>
|
||||||
|
<div class="message-body" style="width: 100%;">
|
||||||
|
<div class="content" id="content-{{ ID }}" style="width: 100%;">
|
||||||
|
<div class="field" style="width: 100%;">
|
||||||
|
<div class="control" style="width: 100%;">
|
||||||
|
<textarea class="textarea is-small has-fixed-size mt-2"
|
||||||
|
placeholder="Enter your message here"
|
||||||
|
rows="{{ Rows }}"
|
||||||
|
style="background-color: transparent;
|
||||||
|
width: 100%"
|
||||||
|
name="message">{{ Content }}</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field is-grouped is-flex is-justify-content-flex-end mb-3">
|
||||||
|
<div class="control">
|
||||||
|
<button hx-get="/userMessage?id={{ ID }}"
|
||||||
|
hx-target="closest .message-user"
|
||||||
|
class="button is-danger is-outlined is-small">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-xmark"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<div style="display: none"
|
||||||
|
hx-trigger="click from:#edit-button-{{ ID }}"
|
||||||
|
hx-target="next .message-bot"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-get="/empty"></div>
|
||||||
|
<button class="button is-success is-outlined is-small"
|
||||||
|
hx-post="/editMessage?id={{ ID }}"
|
||||||
|
hx-target="closest .message-user"
|
||||||
|
hx-include="[name='message']"
|
||||||
|
hx-vals="js:{selectedLLMIds: getSelectedModelsIDs()}"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
id="edit-button-{{ ID }}"
|
||||||
|
hx-trigger="click">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-check"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
@ -1,47 +1,54 @@
|
|||||||
<div class="message-user mt-3" id="msg-{{ ID }}">
|
<div class="message-user mt-3" id="msg-{{ ID }}">
|
||||||
<div class="columns is-mobile">
|
<div class="columns is-mobile">
|
||||||
<div class="column is-narrow" id="icon-column">
|
<div class="column is-narrow" id="icon-column">
|
||||||
<figure class="image is-48x48 message-icon" style="flex-shrink: 0;">
|
<figure class="image is-48x48 message-icon" style="flex-shrink: 0;">
|
||||||
<img src="icons/bouvai2.png" alt="User Image">
|
<img src="icons/bouvai2.png" alt="User Image">
|
||||||
</figure>
|
</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%;" id="content-{{ ID }}">
|
|
||||||
{{ Content | safe }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="is-flex is-justify-content mt-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-primary is-small message-button is-outlined mr-1 is-static"
|
|
||||||
hx-post="/redoMessage?id={{ ID }}" hx-swap="innerHTML settle:200ms" hx-target="next .message-bot"
|
|
||||||
hx-vals="js:{selectedLLMIds: getSelectedModelsIDs()}">
|
|
||||||
<span class="icon">
|
|
||||||
<i class="fa-solid fa-arrows-rotate"></i>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<button hx-get="/editMessageForm?id={{ ID }}" hx-target="closest .message-user"
|
|
||||||
id="edit-button-{{ ID }}" class="button is-primary is-small message-button is-outlined is-static mr-5">
|
|
||||||
<span class="icon">
|
|
||||||
<i class="fa-solid fa-pen"></i>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</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%"
|
||||||
|
id="content-{{ ID }}">{{ Content | safe }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="is-flex is-justify-content mt-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-primary is-small message-button is-outlined mr-1 is-static"
|
||||||
|
hx-post="/redoMessage?id={{ ID }}"
|
||||||
|
hx-swap="innerHTML settle:200ms"
|
||||||
|
hx-target="next .message-bot"
|
||||||
|
hx-vals="js:{selectedLLMIds: getSelectedModelsIDs()}">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-arrows-rotate"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button hx-get="/editMessageForm?id={{ ID }}"
|
||||||
|
hx-target="closest .message-user"
|
||||||
|
id="edit-button-{{ ID }}"
|
||||||
|
class="button is-primary is-small message-button is-outlined is-static mr-5">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-pen"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
@ -1,7 +1,12 @@
|
|||||||
<button class="button is-small is-primary message-button is-outlined mr-1" hx-get="/messageContent?id={{ message.Id }}"
|
<button class="button is-small is-primary message-button is-outlined mr-1"
|
||||||
hx-target="#content-{{ ConversationAreaId }}" onclick="updateIcon('{{ message.Icon }}', '{{ ConversationAreaId }}')"
|
hx-get="/messageContent?id={{ message.Id }}"
|
||||||
title="{{ message.Name }}">
|
hx-target="#content-{{ ConversationAreaId }}"
|
||||||
<span class="icon is-small">
|
onclick="updateIcon('{{ message.Icon }}', '{{ ConversationAreaId }}')"
|
||||||
<img src="{{ message.Icon }}" alt="{{ message.Name }}" style="max-height: 100%; max-width: 100%;">
|
title="{{ message.Name }}">
|
||||||
</span>
|
<span class="icon is-small">
|
||||||
|
<img src="{{ message.Icon }}"
|
||||||
|
alt="{{ message.Name }}"
|
||||||
|
style="max-height: 100%;
|
||||||
|
max-width: 100%">
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
@ -1,78 +1,96 @@
|
|||||||
<div class="dropdown is-up is-right {% if IsActive %} is-active {% endif %}" id="conversation-dropdown">
|
<div class="dropdown is-up is-right {% if IsActive %}is-active{% endif %}"
|
||||||
<div class="dropdown-trigger">
|
id="conversation-dropdown">
|
||||||
<button class="button is-small to-reduce-opacity" aria-haspopup="true" aria-controls="dropdown-menu3"
|
<div class="dropdown-trigger">
|
||||||
|
<button class="button is-small to-reduce-opacity"
|
||||||
|
aria-haspopup="true"
|
||||||
|
aria-controls="dropdown-menu3"
|
||||||
onclick="this.parentElement.parentElement.classList.toggle('is-active')">
|
onclick="this.parentElement.parentElement.classList.toggle('is-active')">
|
||||||
<span class="icon">
|
<span class="icon">
|
||||||
<i class="fa-solid fa-comments"></i>
|
<i class="fa-solid fa-comments"></i>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-menu" id="dropdown-menu3" role="menu">
|
<div class="dropdown-menu" id="dropdown-menu3" role="menu">
|
||||||
<div class="dropdown-content">
|
<div class="dropdown-content">
|
||||||
<div class="dropdown-item">
|
<div class="dropdown-item">
|
||||||
<div id="conversation-list">
|
<div id="conversation-list">
|
||||||
{% for Conversation in Conversations %}
|
{% for Conversation in Conversations %}
|
||||||
<div class="icon-text has-text unselected icon-conv {% if Conversation.Selected %} selected {% endif %}"
|
<div class="icon-text has-text unselected icon-conv {% if Conversation.Selected %}selected{% endif %}"
|
||||||
data-id="{{ Conversation.ID.String() }}" style="cursor: pointer;"
|
data-id="{{ Conversation.ID.String() }}"
|
||||||
onclick="toggleConversationSelection(this, '{{ Conversation.Name }}')"
|
style="cursor: pointer"
|
||||||
hx-get="/selectConversation?conversation-id={{ Conversation.ID.String() }}" hx-swap="outerHTML"
|
onclick="toggleConversationSelection(this, '{{ Conversation.Name }}')"
|
||||||
hx-target="#chat-container" name="{{ Conversation.Name }}">
|
hx-get="/selectConversation?conversation-id={{ Conversation.ID.String() }}"
|
||||||
<span>{{ Conversation.Name }}</span>
|
hx-swap="outerHTML"
|
||||||
</div>
|
hx-target="#chat-container"
|
||||||
{% endfor %}
|
name="{{ Conversation.Name }}">
|
||||||
</div>
|
<span>{{ Conversation.Name }}</span>
|
||||||
<input class="input is-small mt-2 is-hidden" type="text" id="conversation-name-input"
|
|
||||||
name="conversation-name-input" placeholder="Conversation name" autocomplete="off">
|
|
||||||
<div class="is-flex is-justify-content-space-between mt-4 ">
|
|
||||||
<button class="button is-small is-danger {% if SelectedIsDefault %} is-hidden {% endif %}"
|
|
||||||
id="delete-conversation-button" hx-get="/deleteConversation" hx-swap="outerHTML"
|
|
||||||
hx-target="#conversation-dropdown" hx-vals="js:{conversationId: findSelectedConversationID()}">
|
|
||||||
<span class="icon">
|
|
||||||
<i class="fa-solid fa-trash"></i>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="button is-small is-primary is-outlined {% if not SelectedIsDefault %} is-hidden {% endif %}"
|
|
||||||
id="archive-default-conversation-button">
|
|
||||||
<span class="icon">
|
|
||||||
<i class="fa-solid fa-box-archive"></i>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<button class="button is-small is-danger is-outlined is-hidden" id="cancel-conversation-button">
|
|
||||||
<span class="icon">
|
|
||||||
<i class="fa-solid fa-xmark"></i>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<div class="is-flex is-justify-content-flex-end">
|
|
||||||
|
|
||||||
<button class="button is-small is-success is-outlined" id="create-conversation-button">
|
|
||||||
<span class="icon">
|
|
||||||
<i class="fa-solid fa-plus"></i>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<button class="button is-small is-success is-outlined is-hidden"
|
|
||||||
id="confirm-conversation-button" hx-get="/createConversation"
|
|
||||||
hx-include="[name='conversation-name-input']" hx-swap="outerHTML"
|
|
||||||
hx-target="#conversation-dropdown">
|
|
||||||
<span class="icon">
|
|
||||||
<i class="fa-solid fa-check"></i>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<button class="button is-small is-success is-outlined is-hidden"
|
|
||||||
id="confirm-archive-default-conversation-button" hx-post="/archiveDefaultConversation"
|
|
||||||
hx-include="[name='conversation-name-input']" hx-swap="outerHTML"
|
|
||||||
hx-target="#conversation-dropdown">
|
|
||||||
<span class="icon">
|
|
||||||
<i class="fa-solid fa-check"></i>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<input class="input is-small mt-2 is-hidden"
|
||||||
|
type="text"
|
||||||
|
id="conversation-name-input"
|
||||||
|
name="conversation-name-input"
|
||||||
|
placeholder="Conversation name"
|
||||||
|
autocomplete="off">
|
||||||
|
<div class="is-flex is-justify-content-space-between mt-4 ">
|
||||||
|
<button class="button is-small is-danger {% if SelectedIsDefault %}is-hidden{% endif %}"
|
||||||
|
id="delete-conversation-button"
|
||||||
|
hx-get="/deleteConversation"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-target="#conversation-dropdown"
|
||||||
|
hx-vals="js:{conversationId: findSelectedConversationID()}">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-trash"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button class="button is-small is-primary is-outlined {% if not SelectedIsDefault %}is-hidden{% endif %}"
|
||||||
|
id="archive-default-conversation-button">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-box-archive"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button class="button is-small is-danger is-outlined is-hidden"
|
||||||
|
id="cancel-conversation-button">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-xmark"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<div class="is-flex is-justify-content-flex-end">
|
||||||
|
|
||||||
<script>
|
<button class="button is-small is-success is-outlined"
|
||||||
|
id="create-conversation-button">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-plus"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button class="button is-small is-success is-outlined is-hidden"
|
||||||
|
id="confirm-conversation-button"
|
||||||
|
hx-get="/createConversation"
|
||||||
|
hx-include="[name='conversation-name-input']"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-target="#conversation-dropdown">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-check"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button class="button is-small is-success is-outlined is-hidden"
|
||||||
|
id="confirm-archive-default-conversation-button"
|
||||||
|
hx-post="/archiveDefaultConversation"
|
||||||
|
hx-include="[name='conversation-name-input']"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-target="#conversation-dropdown">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-check"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
function findSelectedConversationID() {
|
function findSelectedConversationID() {
|
||||||
return document.getElementsByClassName('icon-conv selected')[0].getAttribute('data-id');
|
return document.getElementsByClassName('icon-conv selected')[0].getAttribute('data-id');
|
||||||
}
|
}
|
||||||
@ -172,5 +190,5 @@
|
|||||||
document.getElementById('confirm-archive-default-conversation-button').classList.add('is-hidden');
|
document.getElementById('confirm-archive-default-conversation-button').classList.add('is-hidden');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
@ -1,96 +1,148 @@
|
|||||||
<div class="dropdown 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 to-reduce-opacity" aria-haspopup="true" aria-controls="dropdown-menu3"
|
<button class="button is-small to-reduce-opacity"
|
||||||
|
aria-haspopup="true"
|
||||||
|
aria-controls="dropdown-menu3"
|
||||||
onclick="this.parentElement.parentElement.classList.toggle('is-active')">
|
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-menu3" role="menu">
|
<div class="dropdown-menu" id="dropdown-menu3" role="menu">
|
||||||
<div class="dropdown-content">
|
<div class="dropdown-content">
|
||||||
<div class="dropdown-item" id="models-list">
|
<div class="dropdown-item" id="models-list">
|
||||||
<div id="llm-list">
|
<div id="llm-list">
|
||||||
{% for LLM in LLMs %}
|
{% for LLM in LLMs %}
|
||||||
<div class="icon-text has-text unselected icon-llm" data-id="{{ LLM.ID.String() }}"
|
<div class="icon-text has-text unselected icon-llm"
|
||||||
style="cursor: pointer;" onclick="toggleSelection(this)">
|
data-id="{{ LLM.ID.String() }}"
|
||||||
<span class="icon">
|
style="cursor: pointer"
|
||||||
<img src="{{ LLM.Model.Company.Icon }}" />
|
onclick="toggleSelection(this)">
|
||||||
</span>
|
<span class="icon">
|
||||||
<span>{{ LLM.Name }}</span>
|
<img src="{{ LLM.Model.Company.Icon }}" />
|
||||||
</div>
|
</span>
|
||||||
{% endfor %}
|
<span>{{ LLM.Name }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="is-flex is-justify-content-space-between mt-4">
|
{% endfor %}
|
||||||
<button disabled class="button is-small is-danger" hx-get="/deleteLLM" hx-swap="outerHTML"
|
</div>
|
||||||
hx-target="#models-dropdown" hx-confirm="Are you sure?" hx-trigger="click"
|
<div class="is-flex is-justify-content-space-between mt-4">
|
||||||
hx-vals="js:{selectedLLMIds: getSelectedModelsIDs()}" id="delete-model-button">
|
<button disabled
|
||||||
<span class="icon">
|
class="button is-small is-danger"
|
||||||
<i class="fa-solid fa-trash"></i>
|
hx-get="/deleteLLM"
|
||||||
</span>
|
hx-swap="outerHTML"
|
||||||
</button>
|
hx-target="#models-dropdown"
|
||||||
<div>
|
hx-confirm="Are you sure?"
|
||||||
<!--button disabled class="button is-small is-primary mr-2 ml-5">
|
hx-trigger="click"
|
||||||
|
hx-vals="js:{selectedLLMIds: getSelectedModelsIDs()}"
|
||||||
|
id="delete-model-button">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-trash"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<div>
|
||||||
|
<!--button disabled class="button is-small is-primary mr-2 ml-5">
|
||||||
<span class="icon">
|
<span class="icon">
|
||||||
<i class="fa-solid fa-pen"></i>
|
<i class="fa-solid fa-pen"></i>
|
||||||
</span>
|
</span>
|
||||||
</button-->
|
</button -->
|
||||||
<button class="button is-small is-success is-outlined" id="create-model-button">
|
<button class="button is-small is-success is-outlined"
|
||||||
<span class="icon">
|
id="create-model-button">
|
||||||
<i class="fa-solid fa-plus"></i>
|
<span class="icon">
|
||||||
</span>
|
<i class="fa-solid fa-plus"></i>
|
||||||
</button>
|
</span>
|
||||||
</div>
|
</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">
|
|
||||||
<input class="input is-small mb-3" type="text" id="model-name-input" name="model-name-input"
|
|
||||||
placeholder="Model name" autocomplete="off">
|
|
||||||
<div class="select is-fullwidth is-small mb-3" id="model-id-input">
|
|
||||||
<select name="selectedLLMId">
|
|
||||||
{% for modelInfo in ModelInfos %}
|
|
||||||
<option value="{{ modelInfo.ModelID }}">{{ modelInfo.Company.Name }} - {{ modelInfo.Name }}</option>
|
|
||||||
{% endfor %}
|
|
||||||
<option value="{% if IsPremium %}custom{% else %}none{% endif %}">Custom Endpoints</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<p class="is-hidden" style="color: red;" id="endpoint-error">
|
|
||||||
<small>Need premium subscription</small>
|
|
||||||
</p>
|
|
||||||
<input class="input is-small mb-3 is-hidden" type="text" id="model-cid-input" name="model-cid-input"
|
|
||||||
placeholder="Model id" autocomplete="off">
|
|
||||||
<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)" autocomplete="off">
|
|
||||||
<input class="input is-small mb-3 is-hidden" type="text" id="model-key-input" name="model-key-input"
|
|
||||||
placeholder="Token" autocomplete="off">
|
|
||||||
<p><small>Temperature:</small></p>
|
|
||||||
<input class="slider is-small mb-3" step="0.05" min="0" max="2" value="0" type="range"
|
|
||||||
id="temperature-slider" name="temperature-slider">
|
|
||||||
<output id="temperature-slider-output">0</output>
|
|
||||||
<p><small>Max token (optional):</small></p>
|
|
||||||
<input class="input is-small mb-3" type="number" id="max-token-input" name="max-token-input"
|
|
||||||
placeholder="" autocomplete="off">
|
|
||||||
<p><small>System prompt (optional):</small></p>
|
|
||||||
<textarea class="textarea is-small mb-5 has-fixed-size" id="model-prompt-input"
|
|
||||||
name="model-prompt-input"></textarea>
|
|
||||||
<div class="is-flex is-justify-content-flex-end">
|
|
||||||
<button class="button is-small is-danger is-outlined mr-3" id="cancel-create-model-button"
|
|
||||||
type="button">
|
|
||||||
<span class="icon">
|
|
||||||
<i class="fa-solid fa-xmark"></i>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<button disabled class="button is-small is-success" id="confirm-create-model-button"
|
|
||||||
type="submit">
|
|
||||||
<span class="icon">
|
|
||||||
<i class="fa-solid fa-check"></i>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</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">
|
||||||
|
<input class="input is-small mb-3"
|
||||||
|
type="text"
|
||||||
|
id="model-name-input"
|
||||||
|
name="model-name-input"
|
||||||
|
placeholder="Model name"
|
||||||
|
autocomplete="off">
|
||||||
|
<div class="select is-fullwidth is-small mb-3" id="model-id-input">
|
||||||
|
<select name="selectedLLMId">
|
||||||
|
{% for modelInfo in ModelInfos %}
|
||||||
|
<option value="{{ modelInfo.ModelID }}">
|
||||||
|
{{ modelInfo.Company.Name }} - {{ modelInfo.Name }}
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
<option value="{% if IsPremium %}custom{% else %}none{% endif %}">Custom Endpoints</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<p class="is-hidden" style="color: red;" id="endpoint-error">
|
||||||
|
<small>Need premium subscription</small>
|
||||||
|
</p>
|
||||||
|
<input class="input is-small mb-3 is-hidden"
|
||||||
|
type="text"
|
||||||
|
id="model-cid-input"
|
||||||
|
name="model-cid-input"
|
||||||
|
placeholder="Model id"
|
||||||
|
autocomplete="off">
|
||||||
|
<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)"
|
||||||
|
autocomplete="off">
|
||||||
|
<input class="input is-small mb-3 is-hidden"
|
||||||
|
type="text"
|
||||||
|
id="model-key-input"
|
||||||
|
name="model-key-input"
|
||||||
|
placeholder="Token"
|
||||||
|
autocomplete="off">
|
||||||
|
<p>
|
||||||
|
<small>Temperature:</small>
|
||||||
|
</p>
|
||||||
|
<input class="slider is-small mb-3"
|
||||||
|
step="0.05"
|
||||||
|
min="0"
|
||||||
|
max="2"
|
||||||
|
value="0"
|
||||||
|
type="range"
|
||||||
|
id="temperature-slider"
|
||||||
|
name="temperature-slider">
|
||||||
|
<output id="temperature-slider-output">0</output>
|
||||||
|
<p>
|
||||||
|
<small>Max token (optional):</small>
|
||||||
|
</p>
|
||||||
|
<input class="input is-small mb-3"
|
||||||
|
type="number"
|
||||||
|
id="max-token-input"
|
||||||
|
name="max-token-input"
|
||||||
|
placeholder=""
|
||||||
|
autocomplete="off">
|
||||||
|
<p>
|
||||||
|
<small>System prompt (optional):</small>
|
||||||
|
</p>
|
||||||
|
<textarea class="textarea is-small mb-5 has-fixed-size"
|
||||||
|
id="model-prompt-input"
|
||||||
|
name="model-prompt-input"></textarea>
|
||||||
|
<div class="is-flex is-justify-content-flex-end">
|
||||||
|
<button class="button is-small is-danger is-outlined mr-3"
|
||||||
|
id="cancel-create-model-button"
|
||||||
|
type="button">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-xmark"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button disabled
|
||||||
|
class="button is-small is-success"
|
||||||
|
id="confirm-create-model-button"
|
||||||
|
type="submit">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-check"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
</div>
|
||||||
|
<script>
|
||||||
var sortable = new Sortable(document.getElementById('llm-list'), {
|
var sortable = new Sortable(document.getElementById('llm-list'), {
|
||||||
animation: 150,
|
animation: 150,
|
||||||
onEnd: function (evt) {
|
onEnd: function (evt) {
|
||||||
@ -173,5 +225,5 @@
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,170 +1,215 @@
|
|||||||
<div class="dropdown is-up is-right" id="settings-dropdown">
|
<div class="dropdown is-up is-right" id="settings-dropdown">
|
||||||
<div class="dropdown-trigger">
|
<div class="dropdown-trigger">
|
||||||
<button class="button is-small {% if not AnyExists %} is-danger{% endif %} to-reduce-opacity"
|
<button class="button is-small {% if not AnyExists %}is-danger{% endif %} to-reduce-opacity"
|
||||||
aria-haspopup="true" aria-controls="dropdown-menu3"
|
aria-haspopup="true"
|
||||||
|
aria-controls="dropdown-menu3"
|
||||||
onclick="this.parentElement.parentElement.classList.toggle('is-active')">
|
onclick="this.parentElement.parentElement.classList.toggle('is-active')">
|
||||||
<span class="icon"><i class="fa-solid fa-bars"></i></i></span>
|
<span class="icon"><i class="fa-solid fa-bars"></i></i></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-menu" id="dropdown-menu3" role="menu">
|
<div class="dropdown-menu" id="dropdown-menu3" role="menu">
|
||||||
<div class="dropdown-content">
|
<div class="dropdown-content">
|
||||||
<div class="dropdown-item">
|
<div class="dropdown-item">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<form id="api-keys-form" hx-post="/addKeys" hx-trigger="submit" hx-target="#api-keys-status">
|
<form id="api-keys-form"
|
||||||
<div class="field has-addons is-hidden" id="openai-field">
|
hx-post="/addKeys"
|
||||||
<p class="control has-icons-left is-expanded">
|
hx-trigger="submit"
|
||||||
<input class="input is-small {% if OpenaiExists %}is-success{% endif %}" type="text"
|
hx-target="#api-keys-status">
|
||||||
{%if not IsLogin %}disabled{% endif %} placeholder="OpenAI API key"
|
<div class="field has-addons is-hidden" id="openai-field">
|
||||||
name="openai_key" autocomplete="off">
|
<p class="control has-icons-left is-expanded">
|
||||||
<span class="icon is-small is-left">
|
<input class="input is-small {% if OpenaiExists %}is-success{% endif %}"
|
||||||
<i class="fas fa-lock"></i>
|
type="text"
|
||||||
</span>
|
{% if not IsLogin %}disabled{% endif %}
|
||||||
</p>
|
placeholder="OpenAI API key"
|
||||||
</div>
|
name="openai_key"
|
||||||
<div class="field has-addons is-hidden" id="anthropic-field">
|
autocomplete="off">
|
||||||
<p class="control has-icons-left is-expanded">
|
<span class="icon is-small is-left">
|
||||||
<input class="input is-small {% if AnthropicExists %}is-success{% endif %}" type="text"
|
<i class="fas fa-lock"></i>
|
||||||
{% if not IsLogin %}disabled{% endif %} placeholder="Anthropic API key"
|
</span>
|
||||||
name="anthropic_key" autocomplete="off">
|
</p>
|
||||||
<span class="icon is-small is-left">
|
|
||||||
<i class="fas fa-lock"></i>
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="field has-addons is-hidden" id="mistral-field">
|
|
||||||
<p class="control has-icons-left is-expanded">
|
|
||||||
<input class="input is-small {% if MistralExists %}is-success{% endif %}" type="text"
|
|
||||||
{%if not IsLogin %}disabled{% endif %} placeholder="Mistral API key"
|
|
||||||
name="mistral_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">
|
|
||||||
<span class="icon is-small is-left">
|
|
||||||
<i class="fas fa-lock"></i>
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="field has-addons is-hidden" id="gemini-field">
|
|
||||||
<p class="control has-icons-left is-expanded">
|
|
||||||
<input class="input is-small {% if GoogleExists %}is-success{% endif %}" type="text"
|
|
||||||
placeholder="Google API key" name="google_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="nim-field">
|
|
||||||
<p class="control has-icons-left is-expanded">
|
|
||||||
<input class="input is-small {% if NimExists %}is-success{% endif %}" type="text"
|
|
||||||
placeholder="NIM API key" name="nim_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="perplexity-field">
|
|
||||||
<p class="control has-icons-left is-expanded">
|
|
||||||
<input class="input is-small {% if PerplexityExists %}is-success{% endif %}" type="text"
|
|
||||||
placeholder="Perplexity API key" name="perplexity_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="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">
|
|
||||||
<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" disabled>
|
|
||||||
<span class="icon is-small is-left">
|
|
||||||
<i class="fas fa-lock"></i>
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="field has-addons" id="save-field">
|
|
||||||
<p class="control">
|
|
||||||
<button disabled id="save-keys-button" type="submit" class="button is-small">
|
|
||||||
<span class="icon is-small">
|
|
||||||
<i class="fas fa-check"></i>
|
|
||||||
</span>
|
|
||||||
<span>Save keys</span>
|
|
||||||
</button>
|
|
||||||
</p>
|
|
||||||
<p class="control">
|
|
||||||
<button id="toggle-keys-button" type="button"
|
|
||||||
class="button is-small {% if not AnyExists %}is-danger{% endif %}">
|
|
||||||
<span class="icon is-small">
|
|
||||||
<i class="fa-solid fa-chevron-down"></i>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<p id="api-keys-status"></p>
|
|
||||||
</div>
|
|
||||||
{% if isBasic or isPremium %}
|
|
||||||
<a class="button is-small mt-1" href="{{ StripeSubLink }}" target="_blank">
|
|
||||||
<span class="icon is-small" {% if isPremium %}style="color: #b00202" {%else%}style="color: #126d0f"
|
|
||||||
{% endif %}>
|
|
||||||
<i class="fa-solid fa-heart"></i>
|
|
||||||
</span>
|
|
||||||
<span>Manage subscription</span>
|
|
||||||
</a>
|
|
||||||
{% else %}
|
|
||||||
<a class="button is-small mt-1" hx-get="/pricingTable" hx-target="#chat-container" hx-swap="outerHTML"
|
|
||||||
hx-trigger="click">
|
|
||||||
<span class="icon is-small">
|
|
||||||
<i class="fa-solid fa-heart"></i>
|
|
||||||
</span>
|
|
||||||
<span>Subscribe to JADE</span>
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
<a class="button is-small mt-1" hx-get="/generateTermAndService" hx-target="#chat-container"
|
|
||||||
hx-swap="outerHTML" hx-trigger="click">
|
|
||||||
<span class="icon is-small">
|
|
||||||
<i class="fa-regular fa-file-lines"></i>
|
|
||||||
</span>
|
|
||||||
<span>Terms and conditions</span>
|
|
||||||
</a>
|
|
||||||
<a class="button is-small mt-1" hx-get="/help" hx-target="#chat-container" hx-swap="outerHTML"
|
|
||||||
hx-trigger="click">
|
|
||||||
<span class="icon is-small">
|
|
||||||
<i class="fa-solid fa-info"></i>
|
|
||||||
</span>
|
|
||||||
<span>Help</span>
|
|
||||||
</a>
|
|
||||||
<a class="button is-small mt-1" href="https://www.bouvai.com/contact">
|
|
||||||
<span class="icon is-small">
|
|
||||||
<i class="fa-solid fa-address-card"></i>
|
|
||||||
</span>
|
|
||||||
<span>Contact</span>
|
|
||||||
</a>
|
|
||||||
<a class="button is-small mt-1" href="/signout">
|
|
||||||
<span class="icon is-small">
|
|
||||||
<i class="fa-solid fa-right-from-bracket"></i>
|
|
||||||
</span>
|
|
||||||
<span>Sign out</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="field has-addons is-hidden" id="anthropic-field">
|
||||||
|
<p class="control has-icons-left is-expanded">
|
||||||
|
<input class="input is-small {% if AnthropicExists %}is-success{% endif %}"
|
||||||
|
type="text"
|
||||||
|
{% if not IsLogin %}disabled{% endif %}
|
||||||
|
placeholder="Anthropic API key"
|
||||||
|
name="anthropic_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="mistral-field">
|
||||||
|
<p class="control has-icons-left is-expanded">
|
||||||
|
<input class="input is-small {% if MistralExists %}is-success{% endif %}"
|
||||||
|
type="text"
|
||||||
|
{% if not IsLogin %}disabled{% endif %}
|
||||||
|
placeholder="Mistral API key"
|
||||||
|
name="mistral_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">
|
||||||
|
<span class="icon is-small is-left">
|
||||||
|
<i class="fas fa-lock"></i>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="field has-addons is-hidden" id="gemini-field">
|
||||||
|
<p class="control has-icons-left is-expanded">
|
||||||
|
<input class="input is-small {% if GoogleExists %}is-success{% endif %}"
|
||||||
|
type="text"
|
||||||
|
placeholder="Google API key"
|
||||||
|
name="google_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="nim-field">
|
||||||
|
<p class="control has-icons-left is-expanded">
|
||||||
|
<input class="input is-small {% if NimExists %}is-success{% endif %}"
|
||||||
|
type="text"
|
||||||
|
placeholder="NIM API key"
|
||||||
|
name="nim_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="perplexity-field">
|
||||||
|
<p class="control has-icons-left is-expanded">
|
||||||
|
<input class="input is-small {% if PerplexityExists %}is-success{% endif %}"
|
||||||
|
type="text"
|
||||||
|
placeholder="Perplexity API key"
|
||||||
|
name="perplexity_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="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">
|
||||||
|
<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"
|
||||||
|
disabled>
|
||||||
|
<span class="icon is-small is-left">
|
||||||
|
<i class="fas fa-lock"></i>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="field has-addons" id="save-field">
|
||||||
|
<p class="control">
|
||||||
|
<button disabled id="save-keys-button" type="submit" class="button is-small">
|
||||||
|
<span class="icon is-small">
|
||||||
|
<i class="fas fa-check"></i>
|
||||||
|
</span>
|
||||||
|
<span>Save keys</span>
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
<p class="control">
|
||||||
|
<button id="toggle-keys-button"
|
||||||
|
type="button"
|
||||||
|
class="button is-small {% if not AnyExists %}is-danger{% endif %}">
|
||||||
|
<span class="icon is-small">
|
||||||
|
<i class="fa-solid fa-chevron-down"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<p id="api-keys-status"></p>
|
||||||
</div>
|
</div>
|
||||||
|
{% if isBasic or isPremium %}
|
||||||
|
<a class="button is-small mt-1"
|
||||||
|
href="{{ StripeSubLink }}"
|
||||||
|
target="_blank">
|
||||||
|
<span class="icon is-small"
|
||||||
|
{% if isPremium %}style="color: #b00202" {% else %}style="color: #126d0f" {% endif %}>
|
||||||
|
<i class="fa-solid fa-heart"></i>
|
||||||
|
</span>
|
||||||
|
<span>Manage subscription</span>
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
<a class="button is-small mt-1"
|
||||||
|
hx-get="/pricingTable"
|
||||||
|
hx-target="#chat-container"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-trigger="click">
|
||||||
|
<span class="icon is-small">
|
||||||
|
<i class="fa-solid fa-heart"></i>
|
||||||
|
</span>
|
||||||
|
<span>Subscribe to JADE</span>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
<a class="button is-small mt-1"
|
||||||
|
hx-get="/generateTermAndService"
|
||||||
|
hx-target="#chat-container"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-trigger="click">
|
||||||
|
<span class="icon is-small">
|
||||||
|
<i class="fa-regular fa-file-lines"></i>
|
||||||
|
</span>
|
||||||
|
<span>Terms and conditions</span>
|
||||||
|
</a>
|
||||||
|
<a class="button is-small mt-1"
|
||||||
|
hx-get="/help"
|
||||||
|
hx-target="#chat-container"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-trigger="click">
|
||||||
|
<span class="icon is-small">
|
||||||
|
<i class="fa-solid fa-info"></i>
|
||||||
|
</span>
|
||||||
|
<span>Help</span>
|
||||||
|
</a>
|
||||||
|
<a class="button is-small mt-1" href="https://www.bouvai.com/contact">
|
||||||
|
<span class="icon is-small">
|
||||||
|
<i class="fa-solid fa-address-card"></i>
|
||||||
|
</span>
|
||||||
|
<span>Contact</span>
|
||||||
|
</a>
|
||||||
|
<a class="button is-small mt-1" href="/signout">
|
||||||
|
<span class="icon is-small">
|
||||||
|
<i class="fa-solid fa-right-from-bracket"></i>
|
||||||
|
</span>
|
||||||
|
<span>Sign out</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -1,81 +1,92 @@
|
|||||||
<div class="dropdown is-up is-right {% if IsActive %} is-active{% endif %}" id="usage-dropdown">
|
<div class="dropdown is-up is-right {% if IsActive %}is-active{% endif %}"
|
||||||
<div class="dropdown-trigger">
|
id="usage-dropdown">
|
||||||
<button class="button is-small to-reduce-opacity" aria-haspopup="true" aria-controls="dropdown-menu3"
|
<div class="dropdown-trigger">
|
||||||
|
<button class="button is-small to-reduce-opacity"
|
||||||
|
aria-haspopup="true"
|
||||||
|
aria-controls="dropdown-menu3"
|
||||||
onclick="this.parentElement.parentElement.classList.toggle('is-active')">
|
onclick="this.parentElement.parentElement.classList.toggle('is-active')">
|
||||||
<span class="icon"><i class="fa-regular fa-money-bill-1"></i></span>
|
<span class="icon"><i class="fa-regular fa-money-bill-1"></i></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-menu" id="dropdown-menu3" role="menu">
|
<div class="dropdown-menu" id="dropdown-menu3" role="menu">
|
||||||
<div class="dropdown-content">
|
<div class="dropdown-content">
|
||||||
<div class="dropdown-item">
|
<div class="dropdown-item">
|
||||||
<!-- Placeholder for additional text -->
|
<!-- Placeholder for additional text -->
|
||||||
<div class="content" id="usage-content" style="max-height: 30vh; overflow-y: auto;">
|
<div class="content"
|
||||||
<table class="table is-narrow is-fullwidth is-striped" style="max-width: 200px;">
|
id="usage-content"
|
||||||
<tbody>
|
style="max-height: 30vh;
|
||||||
{% for usage in usages %}
|
overflow-y: auto">
|
||||||
<tr>
|
<table class="table is-narrow is-fullwidth is-striped"
|
||||||
<td>
|
style="max-width: 200px">
|
||||||
<small>{{ usage.Key.ModelID }}</small>
|
<tbody>
|
||||||
</td>
|
{% for usage in usages %}
|
||||||
<td class="has-text-right totalCostCell">
|
<tr>
|
||||||
<small>{{ usage.TotalCost|floatformat:2 }}$</small>
|
<td>
|
||||||
</td>
|
<small>{{ usage.Key.ModelID }}</small>
|
||||||
<td class="has-text-right is-hidden totalCountCell">
|
</td>
|
||||||
<small>{{ usage.TotalCount }}</small>
|
<td class="has-text-right totalCostCell">
|
||||||
</td>
|
<small>{{ usage.TotalCost|floatformat:2 }}$</small>
|
||||||
</tr>
|
</td>
|
||||||
{% endfor %}
|
<td class="has-text-right is-hidden totalCountCell">
|
||||||
</tbody>
|
<small>{{ usage.TotalCount }}</small>
|
||||||
</table>
|
</td>
|
||||||
</div>
|
</tr>
|
||||||
<!-- Total cost -->
|
{% endfor %}
|
||||||
<div class="content totalCostCell">
|
</tbody>
|
||||||
<p>
|
</table>
|
||||||
<strong>Total: </strong>
|
|
||||||
<span class="totalCost">
|
|
||||||
{{ TotalCost|floatformat:2 }}$
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<!-- Total count -->
|
|
||||||
<div class="content is-hidden totalCountCell">
|
|
||||||
<p>
|
|
||||||
<strong>Total: </strong>
|
|
||||||
<span class="totalCount">
|
|
||||||
{{ TotalCount }} messages
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<!-- Top buttons -->
|
|
||||||
<div class="buttons has-addons is-centered">
|
|
||||||
<button class="button is-small is-primary" title="Money Spent" id="money-spent-button">
|
|
||||||
<span class="icon ml-4 mr-4"><i class="fa-regular fa-money-bill-1"></i></span>
|
|
||||||
</button>
|
|
||||||
<button class="button is-small" title="Messages Sent" id="messages-sent-button">
|
|
||||||
<span class="icon ml-4 mr-4"><i class="fa-regular fa-envelope"></i></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<!-- Row with text and buttons -->
|
|
||||||
<div class="level is-mobile">
|
|
||||||
<div class="level-left">
|
|
||||||
<button class="button is-small" hx-get="/loadUsageKPI?month={{ DateID }}&offset=-1"
|
|
||||||
hx-swap="outerHTML" hx-target="#usage-dropdown">
|
|
||||||
<span class="icon"><i class="fa-solid fa-chevron-left"></i></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="level-item">
|
|
||||||
<p>{{ Date }}</p>
|
|
||||||
</div>
|
|
||||||
<div class="level-right">
|
|
||||||
<button class="button is-small" hx-get="/loadUsageKPI?month={{ DateID }}&offset=1"
|
|
||||||
hx-swap="outerHTML" hx-target="#usage-dropdown">
|
|
||||||
<span class="icon"><i class="fa-solid fa-chevron-right"></i></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Total cost -->
|
||||||
|
<div class="content totalCostCell">
|
||||||
|
<p>
|
||||||
|
<strong>Total:</strong>
|
||||||
|
<span class="totalCost">{{ TotalCost|floatformat:2 }}$</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<!-- Total count -->
|
||||||
|
<div class="content is-hidden totalCountCell">
|
||||||
|
<p>
|
||||||
|
<strong>Total:</strong>
|
||||||
|
<span class="totalCount">{{ TotalCount }} messages</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<!-- Top buttons -->
|
||||||
|
<div class="buttons has-addons is-centered">
|
||||||
|
<button class="button is-small is-primary"
|
||||||
|
title="Money Spent"
|
||||||
|
id="money-spent-button">
|
||||||
|
<span class="icon ml-4 mr-4"><i class="fa-regular fa-money-bill-1"></i></span>
|
||||||
|
</button>
|
||||||
|
<button class="button is-small"
|
||||||
|
title="Messages Sent"
|
||||||
|
id="messages-sent-button">
|
||||||
|
<span class="icon ml-4 mr-4"><i class="fa-regular fa-envelope"></i></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<!-- Row with text and buttons -->
|
||||||
|
<div class="level is-mobile">
|
||||||
|
<div class="level-left">
|
||||||
|
<button class="button is-small"
|
||||||
|
hx-get="/loadUsageKPI?month={{ DateID }}&offset=-1"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-target="#usage-dropdown">
|
||||||
|
<span class="icon"><i class="fa-solid fa-chevron-left"></i></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="level-item">
|
||||||
|
<p>{{ Date }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="level-right">
|
||||||
|
<button class="button is-small"
|
||||||
|
hx-get="/loadUsageKPI?month={{ DateID }}&offset=1"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-target="#usage-dropdown">
|
||||||
|
<span class="icon"><i class="fa-solid fa-chevron-right"></i></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<h1 class="title is-1">JADE: Simple Multi-Model Chatbot</h1>
|
<h1 class="title is-1">JADE: Simple Multi-Model Chatbot</h1>
|
||||||
<br /><br />
|
<br />
|
||||||
|
<br />
|
||||||
<p>
|
<p>
|
||||||
I often use LLMs and quickly found myself asking GPT4, Gemini and Claude the
|
I often use LLMs and quickly found myself asking GPT4, Gemini and Claude the
|
||||||
same question. I wanted to be able to ask the same question to multiple
|
same question. I wanted to be able to ask the same question to multiple
|
||||||
@ -15,18 +16,15 @@
|
|||||||
When asking a question, you can use multiple models and compare their
|
When asking a question, you can use multiple models and compare their
|
||||||
responses to choose the best one.
|
responses to choose the best one.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>The selected response can be used for the next message across all models.</li>
|
||||||
The selected response can be used for the next message across all models.
|
|
||||||
</li>
|
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<p>For example, a response from GPT-4 Omni can be used by Claude Haiku.</p>
|
<p>For example, a response from GPT-4 Omni can be used by Claude Haiku.</p>
|
||||||
|
|
||||||
<a class="button is-primary mt-2 mb-2" href="/signin">
|
<a class="button is-primary mt-2 mb-2" href="/signin">Try JADE now for free!</a>
|
||||||
Try JADE now for free!
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<br /><br />
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
<h2>More information</h2>
|
<h2>More information</h2>
|
||||||
<p>
|
<p>
|
||||||
@ -39,32 +37,33 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<h3>
|
<h3>
|
||||||
Get access to all models.<button
|
Get access to all models.
|
||||||
class="button ml-2 is-small is-primary is-outlined"
|
<button class="button ml-2 is-small is-primary is-outlined"
|
||||||
onclick="toggleDetails('all-models-details')"
|
onclick="toggleDetails('all-models-details')">
|
||||||
>
|
|
||||||
<span class="icon is-small">
|
<span class="icon is-small">
|
||||||
<i class="fa-solid fa-info"></i>
|
<i class="fa-solid fa-info"></i>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</h3>
|
</h3>
|
||||||
<p id="all-models-details" style="display: none">
|
<p id="all-models-details" style="display: none">
|
||||||
With JADE, you can easily switch between models like GPT 3.5 or 4o,
|
With JADE, you can easily switch between models like GPT 3.5 or 4o, Gemini, Llama, Mistral, Claude, and more. Even custom endpoint.
|
||||||
Gemini, Llama, Mistral, Claude, and more. Even custom endpoint.
|
<br />
|
||||||
<br /><br />This means you can choose the best model for your specific
|
<br />
|
||||||
|
This means you can choose the best model for your specific
|
||||||
needs, whether it's for general knowledge, creative writing, or technical
|
needs, whether it's for general knowledge, creative writing, or technical
|
||||||
expertise. Having access to multiple models allows you to take advantage
|
expertise. Having access to multiple models allows you to take advantage
|
||||||
of their unique strengths and weaknesses, ensuring you get the most
|
of their unique strengths and weaknesses, ensuring you get the most
|
||||||
accurate and relevant responses. (See all models available in the last
|
accurate and relevant responses. (See all models available in the last
|
||||||
section)<br /><br />
|
section)
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<h3>
|
<h3>
|
||||||
Get the best answer from multiple models.<button
|
Get the best answer from multiple models.
|
||||||
class="button ml-2 is-small is-primary is-outlined"
|
<button class="button ml-2 is-small is-primary is-outlined"
|
||||||
onclick="toggleDetails('multi-models-details')"
|
onclick="toggleDetails('multi-models-details')">
|
||||||
>
|
|
||||||
<span class="icon is-small">
|
<span class="icon is-small">
|
||||||
<i class="fa-solid fa-info"></i>
|
<i class="fa-solid fa-info"></i>
|
||||||
</span>
|
</span>
|
||||||
@ -73,16 +72,19 @@
|
|||||||
<p id="multi-models-details" style="display: none">
|
<p id="multi-models-details" style="display: none">
|
||||||
You can ask a question and receive responses from several models at once,
|
You can ask a question and receive responses from several models at once,
|
||||||
enabling you to compare their answers and choose the most suitable one.
|
enabling you to compare their answers and choose the most suitable one.
|
||||||
<br /><br />This feature is particularly useful for complex queries where
|
<br />
|
||||||
different models might offer unique insights or solutions.<br /><br />
|
<br />
|
||||||
|
This feature is particularly useful for complex queries where
|
||||||
|
different models might offer unique insights or solutions.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<h3>
|
<h3>
|
||||||
Even from the same model.<button
|
Even from the same model.
|
||||||
class="button ml-2 is-small is-primary is-outlined"
|
<button class="button ml-2 is-small is-primary is-outlined"
|
||||||
onclick="toggleDetails('same-models-details')"
|
onclick="toggleDetails('same-models-details')">
|
||||||
>
|
|
||||||
<span class="icon is-small">
|
<span class="icon is-small">
|
||||||
<i class="fa-solid fa-info"></i>
|
<i class="fa-solid fa-info"></i>
|
||||||
</span>
|
</span>
|
||||||
@ -90,17 +92,21 @@
|
|||||||
</h3>
|
</h3>
|
||||||
<p id="same-models-details" style="display: none">
|
<p id="same-models-details" style="display: none">
|
||||||
The core feature of JADE are the bots. Each bot have a name, model,
|
The core feature of JADE are the bots. Each bot have a name, model,
|
||||||
temperature and system prompt. <br /><br />You can create as many bot as
|
temperature and system prompt.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
You can create as many bot as
|
||||||
you want and select as many to answer each question. An example is
|
you want and select as many to answer each question. An example is
|
||||||
creating the same model that reponse in different language.<br /><br />
|
creating the same model that reponse in different language.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<h3>
|
<h3>
|
||||||
Reduce Hallucination.<button
|
Reduce Hallucination.
|
||||||
class="button is-small ml-2 is-primary is-outlined"
|
<button class="button is-small ml-2 is-primary is-outlined"
|
||||||
onclick="toggleDetails('reduce-hallucination-details')"
|
onclick="toggleDetails('reduce-hallucination-details')">
|
||||||
>
|
|
||||||
<span class="icon is-small">
|
<span class="icon is-small">
|
||||||
<i class="fa-solid fa-info"></i>
|
<i class="fa-solid fa-info"></i>
|
||||||
</span>
|
</span>
|
||||||
@ -108,17 +114,21 @@
|
|||||||
</h3>
|
</h3>
|
||||||
<p id="reduce-hallucination-details" style="display: none">
|
<p id="reduce-hallucination-details" style="display: none">
|
||||||
AI models sometimes generate information that is inaccurate or misleading,
|
AI models sometimes generate information that is inaccurate or misleading,
|
||||||
a phenomenon known as "hallucination." <br /><br />By using multiple
|
a phenomenon known as "hallucination."
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
By using multiple
|
||||||
models, JADE reduces each model's bias. This ensures that the responses
|
models, JADE reduces each model's bias. This ensures that the responses
|
||||||
you receive are more reliable and trustworthy.<br /><br />
|
you receive are more reliable and trustworthy.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<h3>
|
<h3>
|
||||||
Pay only for what you use or not at all.<button
|
Pay only for what you use or not at all.
|
||||||
class="button ml-2 is-small is-primary is-outlined"
|
<button class="button ml-2 is-small is-primary is-outlined"
|
||||||
onclick="toggleDetails('flexible-pricing-details')"
|
onclick="toggleDetails('flexible-pricing-details')">
|
||||||
>
|
|
||||||
<span class="icon is-small">
|
<span class="icon is-small">
|
||||||
<i class="fa-solid fa-info"></i>
|
<i class="fa-solid fa-info"></i>
|
||||||
</span>
|
</span>
|
||||||
@ -126,57 +136,64 @@
|
|||||||
</h3>
|
</h3>
|
||||||
<p id="flexible-pricing-details" style="display: none">
|
<p id="flexible-pricing-details" style="display: none">
|
||||||
JADE use API, so you get access to free credits or tiers depending of the
|
JADE use API, so you get access to free credits or tiers depending of the
|
||||||
provider (see next section). <br /><br />This is particularly beneficial
|
provider (see next section).
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
This is particularly beneficial
|
||||||
for users who may not need to use the chatbot extensively. Once the free
|
for users who may not need to use the chatbot extensively. Once the free
|
||||||
credit use, you pay based on the length of you message and the response
|
credit use, you pay based on the length of you message and the response
|
||||||
generated in tokens (a token is around 3 characters). Groq and Google also
|
generated in tokens (a token is around 3 characters). Groq and Google also
|
||||||
offer free tiers that are enough for conversation.<<br /><br />The app itself is free until 200 messages per month then 0.95$ per month.<br /><br />
|
offer free tiers that are enough for conversation.<
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
The app itself is free until 200 messages per month then 0.95$ per month.
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<h3>
|
<h3>
|
||||||
All providers and models.<button
|
All providers and models.
|
||||||
class="button ml-2 is-small is-primary is-outlined"
|
<button class="button ml-2 is-small is-primary is-outlined"
|
||||||
onclick="toggleDetails('provider-details')"
|
onclick="toggleDetails('provider-details')">
|
||||||
>
|
|
||||||
<span class="icon is-small">
|
<span class="icon is-small">
|
||||||
<i class="fa-solid fa-info"></i>
|
<i class="fa-solid fa-info"></i>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</h3>
|
</h3>
|
||||||
<div id="provider-details" style="display: none; overflow-x: hidden">
|
<div id="provider-details" style="display: none; overflow-x: hidden">
|
||||||
<strong>OpenAI</strong> - OpenAI offer 5$ credits when creating an API
|
<strong>OpenAI</strong> - OpenAI offer 5$ credits when creating an API
|
||||||
account. Around 10 000 small question to GPT-4 Omni or 100 000 to
|
account. Around 10 000 small question to GPT-4 Omni or 100 000 to
|
||||||
GPT-3.5 Turbo.
|
GPT-3.5 Turbo.
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<strong>Anthropic</strong> - Anthropic offer 5$ credits when creating an
|
<strong>Anthropic</strong> - Anthropic offer 5$ credits when creating an
|
||||||
API account. Around 2 000 small question to Claude 3 Opus or 120 000 to
|
API account. Around 2 000 small question to Claude 3 Opus or 120 000 to
|
||||||
Claude Haiku.
|
Claude Haiku.
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<strong>Mistral</strong> - Mistral do not offer free credits.
|
<strong>Mistral</strong> - Mistral do not offer free credits.
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<strong>Groq</strong> - Groq offer a free tier with limit of tokens and
|
<strong>Groq</strong> - Groq offer a free tier with limit of tokens and
|
||||||
request per minutes. The rate is plenty for a chatbot. 30 messages and
|
request per minutes. The rate is plenty for a chatbot. 30 messages and
|
||||||
between 6 000 and 30 000 tokens per minute. Per tokens coming soon.
|
between 6 000 and 30 000 tokens per minute. Per tokens coming soon.
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<strong>Google</strong> - Like Groq, Google offer a free tier with limit
|
<strong>Google</strong> - Like Groq, Google offer a free tier with limit
|
||||||
of tokens and request per minutes. The rate is plenty for a chatbot. 15
|
of tokens and request per minutes. The rate is plenty for a chatbot. 15
|
||||||
messages and 1 000 000 tokens per minute. Per tokens also available.
|
messages and 1 000 000 tokens per minute. Per tokens also available.
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<strong>Perplexity</strong> - Perplexity do not offer a free tier or
|
<strong>Perplexity</strong> - Perplexity do not offer a free tier or
|
||||||
credits. Perplexity offer what they call 'online' models that can search
|
credits. Perplexity offer what they call 'online' models that can search
|
||||||
online. So you can ask for the current weather for example. Those models
|
online. So you can ask for the current weather for example. Those models
|
||||||
have additional cost of 5$ per 1 000 requests.
|
have additional cost of 5$ per 1 000 requests.
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<strong>Fireworks</strong> - Fireworks AI offer 1$ of free credits when
|
<strong>Fireworks</strong> - Fireworks AI offer 1$ of free credits when
|
||||||
creating an account. Firework AI have a lot of open source models. I may
|
creating an account. Firework AI have a lot of open source models. I may
|
||||||
add fine tuned models in the future.
|
add fine tuned models in the future.
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<strong>Custom endpoint</strong> - You can also use custom endpoints as long as the key is valid and it use
|
<strong>Custom endpoint</strong> - You can also use custom endpoints as long as the key is valid and it use
|
||||||
|
Loading…
x
Reference in New Issue
Block a user