mirror of
https://github.com/xtekky/gpt4free.git
synced 2024-11-23 17:23:57 +03:00
Merge branch 'main' of https://github.com/xtekky/gpt4free
This commit is contained in:
commit
9d17588fcb
@ -26,6 +26,7 @@ docker pull hlohaus789/g4f
|
|||||||
- [/docs/guides/help_me](/docs/guides/help_me.md)
|
- [/docs/guides/help_me](/docs/guides/help_me.md)
|
||||||
- Join our Telegram Channel: [t.me/g4f_channel](https://telegram.me/g4f_channel)
|
- Join our Telegram Channel: [t.me/g4f_channel](https://telegram.me/g4f_channel)
|
||||||
- Join our Discord Group: [discord.gg/XfybzPXPH5](https://discord.gg/XfybzPXPH5)
|
- Join our Discord Group: [discord.gg/XfybzPXPH5](https://discord.gg/XfybzPXPH5)
|
||||||
|
- Check out [G4F, but 100% local](https://github.com/gpt4free/g4f-local)
|
||||||
|
|
||||||
## 🔻 Site Takedown
|
## 🔻 Site Takedown
|
||||||
Is your site on this repository and you want to take it down? Send an email to takedown@g4f.ai with proof it is yours and it will be removed as fast as possible. To prevent reproduction please secure your API ;)
|
Is your site on this repository and you want to take it down? Send an email to takedown@g4f.ai with proof it is yours and it will be removed as fast as possible. To prevent reproduction please secure your API ;)
|
||||||
|
@ -85,7 +85,9 @@ class Api:
|
|||||||
if config.api_key is None and request is not None:
|
if config.api_key is None and request is not None:
|
||||||
auth_header = request.headers.get("Authorization")
|
auth_header = request.headers.get("Authorization")
|
||||||
if auth_header is not None:
|
if auth_header is not None:
|
||||||
config.api_key = auth_header.split(None, 1)[-1]
|
auth_header = auth_header.split(None, 1)[-1]
|
||||||
|
if auth_header and auth_header != "Bearer":
|
||||||
|
config.api_key = auth_header
|
||||||
response = self.client.chat.completions.create(
|
response = self.client.chat.completions.create(
|
||||||
**config.dict(exclude_none=True),
|
**config.dict(exclude_none=True),
|
||||||
ignored=self.list_ignored_providers
|
ignored=self.list_ignored_providers
|
||||||
|
@ -119,7 +119,7 @@ body {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 15px;
|
gap: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conversation #messages {
|
.conversation #messages {
|
||||||
@ -129,11 +129,12 @@ body {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
padding-bottom: 20px;
|
padding-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conversation .user-input {
|
.conversation .user-input {
|
||||||
max-height: 200px;
|
max-height: 200px;
|
||||||
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conversation .user-input input {
|
.conversation .user-input input {
|
||||||
@ -385,12 +386,29 @@ body {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.toolbar {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#input-count {
|
||||||
|
width: fit-content;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 6px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
.stop_generating, .regenerate {
|
.stop_generating, .regenerate {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 122px;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
z-index: 1000000;
|
z-index: 1000000;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 40em) {
|
||||||
|
.stop_generating, .regenerate {
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
right: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.stop_generating button, .regenerate button{
|
.stop_generating button, .regenerate button{
|
||||||
@ -399,7 +417,7 @@ body {
|
|||||||
background-color: var(--blur-bg);
|
background-color: var(--blur-bg);
|
||||||
border-radius: var(--border-radius-1);
|
border-radius: var(--border-radius-1);
|
||||||
border: 1px solid var(--blur-border);
|
border: 1px solid var(--blur-border);
|
||||||
padding: 10px 15px;
|
padding: 5px 15px;
|
||||||
color: var(--colour-3);
|
color: var(--colour-3);
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -112,19 +112,23 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="conversation">
|
<div class="conversation">
|
||||||
<div class="stop_generating stop_generating-hidden">
|
<div id="messages" class="box"></div>
|
||||||
<button id="cancelButton">
|
<div class="toolbar">
|
||||||
<span>Stop Generating</span>
|
<div id="input-count" class="">
|
||||||
<i class="fa-regular fa-stop"></i>
|
|
||||||
</button>
|
</div>
|
||||||
</div>
|
<div class="stop_generating stop_generating-hidden">
|
||||||
<div class="regenerate regenerate-hidden">
|
<button id="cancelButton">
|
||||||
<button id="regenerateButton">
|
<span>Stop Generating</span>
|
||||||
<span>Regenerate</span>
|
<i class="fa-regular fa-stop"></i>
|
||||||
<i class="fa-solid fa-rotate"></i>
|
</button>
|
||||||
</button>
|
</div>
|
||||||
</div>
|
<div class="regenerate regenerate-hidden">
|
||||||
<div class="box" id="messages">
|
<button id="regenerateButton">
|
||||||
|
<span>Regenerate</span>
|
||||||
|
<i class="fa-solid fa-rotate"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="user-input">
|
<div class="user-input">
|
||||||
<div class="box input-box">
|
<div class="box input-box">
|
||||||
|
@ -5,10 +5,14 @@ const message_input = document.getElementById(`message-input`);
|
|||||||
const box_conversations = document.querySelector(`.top`);
|
const box_conversations = document.querySelector(`.top`);
|
||||||
const stop_generating = document.querySelector(`.stop_generating`);
|
const stop_generating = document.querySelector(`.stop_generating`);
|
||||||
const regenerate = document.querySelector(`.regenerate`);
|
const regenerate = document.querySelector(`.regenerate`);
|
||||||
const send_button = document.querySelector(`#send-button`);
|
const sidebar = document.querySelector(".conversations");
|
||||||
const imageInput = document.querySelector('#image');
|
const sidebar_button = document.querySelector(".mobile-sidebar");
|
||||||
const cameraInput = document.querySelector('#camera');
|
const send_button = document.getElementById("send-button");
|
||||||
const fileInput = document.querySelector('#file');
|
const imageInput = document.getElementById("image");
|
||||||
|
const cameraInput = document.getElementById("camera");
|
||||||
|
const fileInput = document.getElementById("file");
|
||||||
|
const inputCount = document.getElementById("input-count")
|
||||||
|
const modelSelect = document.getElementById("model");
|
||||||
|
|
||||||
let prompt_lock = false;
|
let prompt_lock = false;
|
||||||
|
|
||||||
@ -63,6 +67,13 @@ const register_remove_message = async () => {
|
|||||||
|
|
||||||
const delete_conversations = async () => {
|
const delete_conversations = async () => {
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
|
for (let i = 0; i < localStorage.length; i++){
|
||||||
|
let key = localStorage.key(i);
|
||||||
|
if (key.startsWith("conversation:")) {
|
||||||
|
localStorage.removeItem(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hide_sidebar();
|
||||||
await new_conversation();
|
await new_conversation();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -75,6 +86,7 @@ const handle_ask = async () => {
|
|||||||
if (message.length > 0) {
|
if (message.length > 0) {
|
||||||
message_input.value = '';
|
message_input.value = '';
|
||||||
prompt_lock = true;
|
prompt_lock = true;
|
||||||
|
count_input()
|
||||||
await add_conversation(window.conversation_id, message);
|
await add_conversation(window.conversation_id, message);
|
||||||
if ("text" in fileInput.dataset) {
|
if ("text" in fileInput.dataset) {
|
||||||
message += '\n```' + fileInput.dataset.type + '\n';
|
message += '\n```' + fileInput.dataset.type + '\n';
|
||||||
@ -89,6 +101,7 @@ const handle_ask = async () => {
|
|||||||
if (input.files.length > 0) imageInput.dataset.src = URL.createObjectURL(input.files[0]);
|
if (input.files.length > 0) imageInput.dataset.src = URL.createObjectURL(input.files[0]);
|
||||||
else delete imageInput.dataset.src
|
else delete imageInput.dataset.src
|
||||||
|
|
||||||
|
model = modelSelect.options[modelSelect.selectedIndex].value
|
||||||
message_box.innerHTML += `
|
message_box.innerHTML += `
|
||||||
<div class="message" data-index="${message_index}">
|
<div class="message" data-index="${message_index}">
|
||||||
<div class="user">
|
<div class="user">
|
||||||
@ -97,11 +110,14 @@ const handle_ask = async () => {
|
|||||||
<i class="fa-regular fa-phone-arrow-up-right"></i>
|
<i class="fa-regular fa-phone-arrow-up-right"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="content" id="user_${token}">
|
<div class="content" id="user_${token}">
|
||||||
|
<div class="content_inner">
|
||||||
${markdown_render(message)}
|
${markdown_render(message)}
|
||||||
${imageInput.dataset.src
|
${imageInput.dataset.src
|
||||||
? '<img src="' + imageInput.dataset.src + '" alt="Image upload">'
|
? '<img src="' + imageInput.dataset.src + '" alt="Image upload">'
|
||||||
: ''
|
: ''
|
||||||
}
|
}
|
||||||
|
</div>
|
||||||
|
<div class="count">${count_words_and_tokens(message, model)}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@ -120,19 +136,25 @@ const remove_cancel_button = async () => {
|
|||||||
}, 300);
|
}, 300);
|
||||||
};
|
};
|
||||||
|
|
||||||
const filter_messages = (messages) => {
|
const filter_messages = (messages, filter_last_message = true) => {
|
||||||
// Removes none user messages at end
|
// Removes none user messages at end
|
||||||
let last_message;
|
if (filter_last_message) {
|
||||||
while (last_message = messages.pop()) {
|
let last_message;
|
||||||
if (last_message["role"] == "user") {
|
while (last_message = messages.pop()) {
|
||||||
messages.push(last_message);
|
if (last_message["role"] == "user") {
|
||||||
break;
|
messages.push(last_message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove history, if it is selected
|
// Remove history, if it is selected
|
||||||
if (document.getElementById('history')?.checked) {
|
if (document.getElementById('history')?.checked) {
|
||||||
messages = [messages[messages.length-1]];
|
if (filter_last_message) {
|
||||||
|
messages = [messages.pop()];
|
||||||
|
} else {
|
||||||
|
messages = [messages.pop(), messages.pop()];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let new_messages = [];
|
let new_messages = [];
|
||||||
@ -165,7 +187,6 @@ const ask_gpt = async () => {
|
|||||||
|
|
||||||
jailbreak = document.getElementById("jailbreak");
|
jailbreak = document.getElementById("jailbreak");
|
||||||
provider = document.getElementById("provider");
|
provider = document.getElementById("provider");
|
||||||
model = document.getElementById("model");
|
|
||||||
window.text = '';
|
window.text = '';
|
||||||
|
|
||||||
stop_generating.classList.remove(`stop_generating-hidden`);
|
stop_generating.classList.remove(`stop_generating-hidden`);
|
||||||
@ -188,11 +209,13 @@ const ask_gpt = async () => {
|
|||||||
<div class="content" id="gpt_${window.token}">
|
<div class="content" id="gpt_${window.token}">
|
||||||
<div class="provider"></div>
|
<div class="provider"></div>
|
||||||
<div class="content_inner"><span id="cursor"></span></div>
|
<div class="content_inner"><span id="cursor"></span></div>
|
||||||
|
<div class="count"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
content = document.getElementById(`gpt_${window.token}`);
|
content = document.getElementById(`gpt_${window.token}`);
|
||||||
content_inner = content.querySelector('.content_inner');
|
content_inner = content.querySelector('.content_inner');
|
||||||
|
content_count = content.querySelector('.count');
|
||||||
|
|
||||||
message_box.scrollTop = message_box.scrollHeight;
|
message_box.scrollTop = message_box.scrollHeight;
|
||||||
window.scrollTo(0, 0);
|
window.scrollTo(0, 0);
|
||||||
@ -200,7 +223,7 @@ const ask_gpt = async () => {
|
|||||||
let body = JSON.stringify({
|
let body = JSON.stringify({
|
||||||
id: window.token,
|
id: window.token,
|
||||||
conversation_id: window.conversation_id,
|
conversation_id: window.conversation_id,
|
||||||
model: model.options[model.selectedIndex].value,
|
model: modelSelect.options[modelSelect.selectedIndex].value,
|
||||||
jailbreak: jailbreak.options[jailbreak.selectedIndex].value,
|
jailbreak: jailbreak.options[jailbreak.selectedIndex].value,
|
||||||
web_search: document.getElementById(`switch`).checked,
|
web_search: document.getElementById(`switch`).checked,
|
||||||
provider: provider.options[provider.selectedIndex].value,
|
provider: provider.options[provider.selectedIndex].value,
|
||||||
@ -270,6 +293,7 @@ const ask_gpt = async () => {
|
|||||||
html = html.substring(0, lastIndex) + '<span id="cursor"></span>' + lastElement;
|
html = html.substring(0, lastIndex) + '<span id="cursor"></span>' + lastElement;
|
||||||
}
|
}
|
||||||
content_inner.innerHTML = html;
|
content_inner.innerHTML = html;
|
||||||
|
content_count.innerText = count_words_and_tokens(text, provider?.model);
|
||||||
highlight(content_inner);
|
highlight(content_inner);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -380,7 +404,8 @@ const set_conversation = async (conversation_id) => {
|
|||||||
|
|
||||||
await clear_conversation();
|
await clear_conversation();
|
||||||
await load_conversation(conversation_id);
|
await load_conversation(conversation_id);
|
||||||
await load_conversations();
|
load_conversations();
|
||||||
|
hide_sidebar();
|
||||||
};
|
};
|
||||||
|
|
||||||
const new_conversation = async () => {
|
const new_conversation = async () => {
|
||||||
@ -388,23 +413,23 @@ const new_conversation = async () => {
|
|||||||
window.conversation_id = uuid();
|
window.conversation_id = uuid();
|
||||||
|
|
||||||
await clear_conversation();
|
await clear_conversation();
|
||||||
await load_conversations();
|
load_conversations();
|
||||||
|
hide_sidebar();
|
||||||
await say_hello()
|
say_hello();
|
||||||
};
|
};
|
||||||
|
|
||||||
const load_conversation = async (conversation_id) => {
|
const load_conversation = async (conversation_id) => {
|
||||||
let messages = await get_messages(conversation_id);
|
let messages = await get_messages(conversation_id);
|
||||||
|
|
||||||
let elements = "";
|
let elements = "";
|
||||||
|
let last_model = null;
|
||||||
for (i in messages) {
|
for (i in messages) {
|
||||||
let item = messages[i];
|
let item = messages[i];
|
||||||
|
last_model = item?.provider?.model;
|
||||||
let next_i = parseInt(i) + 1;
|
let next_i = parseInt(i) + 1;
|
||||||
let next_provider = item.provider ? item.provider : (messages.length > next_i ? messages[next_i].provider : null);
|
let next_provider = item.provider ? item.provider : (messages.length > next_i ? messages[next_i].provider : null);
|
||||||
let tokens_count = next_provider?.model ? count_tokens(next_provider.model, item.content) : "";
|
|
||||||
let append_count = tokens_count ? `, ${tokens_count} tokens` : "";
|
let provider_link = item.provider?.name ? `<a href="${item.provider?.url}" target="_blank">${item.provider.name}</a>` : "";
|
||||||
let words_count = `(${count_words(item.content)} words${append_count})`
|
|
||||||
let provider_link = item?.provider?.name ? `<a href="${item?.provider?.url}" target="_blank">${item.provider.name}</a>` : "";
|
|
||||||
let provider = provider_link ? `
|
let provider = provider_link ? `
|
||||||
<div class="provider">
|
<div class="provider">
|
||||||
${provider_link}
|
${provider_link}
|
||||||
@ -413,7 +438,7 @@ const load_conversation = async (conversation_id) => {
|
|||||||
` : "";
|
` : "";
|
||||||
elements += `
|
elements += `
|
||||||
<div class="message" data-index="${i}">
|
<div class="message" data-index="${i}">
|
||||||
<div class=${item.role == "assistant" ? "assistant" : "user"}>
|
<div class="${item.role}">
|
||||||
${item.role == "assistant" ? gpt_image : user_image}
|
${item.role == "assistant" ? gpt_image : user_image}
|
||||||
<i class="fa-solid fa-xmark"></i>
|
<i class="fa-solid fa-xmark"></i>
|
||||||
${item.role == "assistant"
|
${item.role == "assistant"
|
||||||
@ -424,15 +449,16 @@ const load_conversation = async (conversation_id) => {
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
${provider}
|
${provider}
|
||||||
<div class="content_inner">${markdown_render(item.content)}</div>
|
<div class="content_inner">${markdown_render(item.content)}</div>
|
||||||
<div class="count">${words_count}</div>
|
<div class="count">${count_words_and_tokens(item.content, next_provider?.model)}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const filtered = filter_messages(messages);
|
const filtered = filter_messages(messages, false);
|
||||||
if (filtered.length > 0) {
|
if (filtered.length > 0) {
|
||||||
let count_total = GPTTokenizer_cl100k_base?.encodeChat(filtered, "gpt-3.5-turbo").length
|
last_model = last_model?.startsWith("gpt-4") ? "gpt-4" : "gpt-3.5-turbo"
|
||||||
|
let count_total = GPTTokenizer_cl100k_base?.encodeChat(filtered, last_model).length
|
||||||
if (count_total > 0) {
|
if (count_total > 0) {
|
||||||
elements += `<div class="count_total">(${count_total} tokens used)</div>`;
|
elements += `<div class="count_total">(${count_total} tokens used)</div>`;
|
||||||
}
|
}
|
||||||
@ -440,7 +466,7 @@ const load_conversation = async (conversation_id) => {
|
|||||||
|
|
||||||
message_box.innerHTML = elements;
|
message_box.innerHTML = elements;
|
||||||
|
|
||||||
await register_remove_message();
|
register_remove_message();
|
||||||
highlight(message_box);
|
highlight(message_box);
|
||||||
|
|
||||||
message_box.scrollTo({ top: message_box.scrollHeight, behavior: "smooth" });
|
message_box.scrollTo({ top: message_box.scrollHeight, behavior: "smooth" });
|
||||||
@ -450,13 +476,14 @@ const load_conversation = async (conversation_id) => {
|
|||||||
}, 500);
|
}, 500);
|
||||||
};
|
};
|
||||||
|
|
||||||
function count_words(text) {
|
// https://stackoverflow.com/questions/20396456/how-to-do-word-counts-for-a-mixture-of-english-and-chinese-in-javascript
|
||||||
var matches = text.match(/[\w\d\’\'-]+/gi);
|
function count_words(str) {
|
||||||
|
var matches = str.match(/[\u00ff-\uffff]|\S+/g);
|
||||||
return matches ? matches.length : 0;
|
return matches ? matches.length : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function count_tokens(model, text) {
|
function count_tokens(model, text) {
|
||||||
if (model.startsWith("gpt-3") || model.startsWith("gpt-4") || model.startsWith("text-davinci")) {
|
if (model.startsWith("gpt-3") || model.startsWith("gpt-4")) {
|
||||||
return GPTTokenizer_cl100k_base?.encode(text).length;
|
return GPTTokenizer_cl100k_base?.encode(text).length;
|
||||||
}
|
}
|
||||||
if (model.startsWith("llama2") || model.startsWith("codellama")) {
|
if (model.startsWith("llama2") || model.startsWith("codellama")) {
|
||||||
@ -467,6 +494,12 @@ function count_tokens(model, text) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function count_words_and_tokens(text, model) {
|
||||||
|
const tokens_count = model ? count_tokens(model, text) : null;
|
||||||
|
const tokens_append = tokens_count ? `, ${tokens_count} tokens` : "";
|
||||||
|
return `(${count_words(text)} words${tokens_append})`
|
||||||
|
}
|
||||||
|
|
||||||
const get_conversation = async (conversation_id) => {
|
const get_conversation = async (conversation_id) => {
|
||||||
let conversation = await JSON.parse(
|
let conversation = await JSON.parse(
|
||||||
localStorage.getItem(`conversation:${conversation_id}`)
|
localStorage.getItem(`conversation:${conversation_id}`)
|
||||||
@ -503,7 +536,9 @@ const add_conversation = async (conversation_id, content) => {
|
|||||||
const hide_last_message = async (conversation_id) => {
|
const hide_last_message = async (conversation_id) => {
|
||||||
const conversation = await get_conversation(conversation_id)
|
const conversation = await get_conversation(conversation_id)
|
||||||
const last_message = conversation.items.pop();
|
const last_message = conversation.items.pop();
|
||||||
last_message["regenerate"] = true;
|
if (last_message["role"] == "assistant") {
|
||||||
|
last_message["regenerate"] = true;
|
||||||
|
}
|
||||||
conversation.items.push(last_message);
|
conversation.items.push(last_message);
|
||||||
|
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
@ -605,15 +640,17 @@ const message_id = () => {
|
|||||||
return BigInt(`0b${unix}${random_bytes}`).toString();
|
return BigInt(`0b${unix}${random_bytes}`).toString();
|
||||||
};
|
};
|
||||||
|
|
||||||
document.querySelector(".mobile-sidebar").addEventListener("click", (event) => {
|
async function hide_sidebar() {
|
||||||
const sidebar = document.querySelector(".conversations");
|
sidebar.classList.remove("shown");
|
||||||
|
sidebar_button.classList.remove("rotated");
|
||||||
|
}
|
||||||
|
|
||||||
|
sidebar_button.addEventListener("click", (event) => {
|
||||||
if (sidebar.classList.contains("shown")) {
|
if (sidebar.classList.contains("shown")) {
|
||||||
sidebar.classList.remove("shown");
|
hide_sidebar();
|
||||||
event.target.classList.remove("rotated");
|
|
||||||
} else {
|
} else {
|
||||||
sidebar.classList.add("shown");
|
sidebar.classList.add("shown");
|
||||||
event.target.classList.add("rotated");
|
sidebar_button.classList.add("rotated");
|
||||||
}
|
}
|
||||||
|
|
||||||
window.scrollTo(0, 0);
|
window.scrollTo(0, 0);
|
||||||
@ -703,28 +740,34 @@ colorThemes.forEach((themeOption) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const count_input = async () => {
|
||||||
|
if (message_input.value) {
|
||||||
|
model = modelSelect.options[modelSelect.selectedIndex].value;
|
||||||
|
inputCount.innerText = count_words_and_tokens(message_input.value, model);
|
||||||
|
} else {
|
||||||
|
inputCount.innerHTML = " "
|
||||||
|
}
|
||||||
|
};
|
||||||
|
message_input.addEventListener("keyup", count_input);
|
||||||
|
|
||||||
window.onload = async () => {
|
window.onload = async () => {
|
||||||
setTheme();
|
setTheme();
|
||||||
|
|
||||||
let conversations = 0;
|
count_input();
|
||||||
for (let i = 0; i < localStorage.length; i++) {
|
|
||||||
if (localStorage.key(i).startsWith("conversation:")) {
|
if (/\/chat\/.+/.test(window.location.href)) {
|
||||||
conversations += 1;
|
load_conversation(window.conversation_id);
|
||||||
}
|
} else {
|
||||||
|
say_hello()
|
||||||
}
|
}
|
||||||
|
|
||||||
await setTimeout(() => {
|
setTimeout(() => {
|
||||||
load_conversations();
|
load_conversations();
|
||||||
}, 1);
|
}, 1);
|
||||||
|
|
||||||
if (/\/chat\/.+/.test(window.location.href)) {
|
message_input.addEventListener("keydown", async (evt) => {
|
||||||
await load_conversation(window.conversation_id);
|
|
||||||
} else {
|
|
||||||
await say_hello()
|
|
||||||
}
|
|
||||||
|
|
||||||
message_input.addEventListener(`keydown`, async (evt) => {
|
|
||||||
if (prompt_lock) return;
|
if (prompt_lock) return;
|
||||||
|
|
||||||
if (evt.keyCode === 13 && !evt.shiftKey) {
|
if (evt.keyCode === 13 && !evt.shiftKey) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
console.log("pressed enter");
|
console.log("pressed enter");
|
||||||
@ -768,12 +811,11 @@ observer.observe(message_input, { attributes: true });
|
|||||||
(async () => {
|
(async () => {
|
||||||
response = await fetch('/backend-api/v2/models')
|
response = await fetch('/backend-api/v2/models')
|
||||||
models = await response.json()
|
models = await response.json()
|
||||||
let select = document.getElementById('model');
|
|
||||||
|
|
||||||
for (model of models) {
|
for (model of models) {
|
||||||
let option = document.createElement('option');
|
let option = document.createElement('option');
|
||||||
option.value = option.text = model;
|
option.value = option.text = model;
|
||||||
select.appendChild(option);
|
modelSelect.appendChild(option);
|
||||||
}
|
}
|
||||||
|
|
||||||
response = await fetch('/backend-api/v2/providers')
|
response = await fetch('/backend-api/v2/providers')
|
||||||
|
Loading…
Reference in New Issue
Block a user