Add WhiteRabbitNeo Provider, Many tiny improvments in the gui

pull/1807/head
Heiner Lohaus 6 months ago
parent bdc61ca273
commit 926ddfd543

@ -1,3 +1,3 @@
ko_fi: xtekky ko_fi: xtekky
github: [xtekky] github: [xtekky, hlohaus]
patreon: xtekky patreon: xtekky

@ -13,6 +13,10 @@ class HuggingFace(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://huggingface.co/chat" url = "https://huggingface.co/chat"
working = True working = True
supports_message_history = True supports_message_history = True
models = [
"mistralai/Mixtral-8x7B-Instruct-v0.1",
"mistralai/Mistral-7B-Instruct-v0.2"
]
default_model = "mistralai/Mixtral-8x7B-Instruct-v0.1" default_model = "mistralai/Mixtral-8x7B-Instruct-v0.1"
@classmethod @classmethod
@ -29,7 +33,7 @@ class HuggingFace(AsyncGeneratorProvider, ProviderModelMixin):
temperature: float = 0.7, temperature: float = 0.7,
**kwargs **kwargs
) -> AsyncResult: ) -> AsyncResult:
model = cls.get_model(model) model = cls.get_model(model) if not model else model
headers = {} headers = {}
if api_key is not None: if api_key is not None:
headers["Authorization"] = f"Bearer {api_key}" headers["Authorization"] = f"Bearer {api_key}"

@ -0,0 +1,57 @@
from __future__ import annotations
from aiohttp import ClientSession, BaseConnector
from ..typing import AsyncResult, Messages, Cookies
from ..requests.raise_for_status import raise_for_status
from .base_provider import AsyncGeneratorProvider
from .helper import get_cookies, get_connector, get_random_string
class WhiteRabbitNeo(AsyncGeneratorProvider):
url = "https://www.whiterabbitneo.com"
working = True
supports_message_history = True
needs_auth = True
@classmethod
async def create_async_generator(
cls,
model: str,
messages: Messages,
cookies: Cookies = None,
connector: BaseConnector = None,
proxy: str = None,
**kwargs
) -> AsyncResult:
if cookies is None:
cookies = get_cookies("www.whiterabbitneo.com")
headers = {
"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0",
"Accept": "*/*",
"Accept-Language": "de,en-US;q=0.7,en;q=0.3",
"Accept-Encoding": "gzip, deflate, br",
"Referer": f"{cls.url}/",
"Content-Type": "text/plain;charset=UTF-8",
"Origin": cls.url,
"Connection": "keep-alive",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"TE": "trailers"
}
async with ClientSession(
headers=headers,
cookies=cookies,
connector=get_connector(connector, proxy)
) as session:
data = {
"messages": messages,
"id": get_random_string(6),
"enhancePrompt": False,
"useFunctions": False
}
async with session.post(f"{cls.url}/api/chat", json=data, proxy=proxy) as response:
await raise_for_status(response)
async for chunk in response.content.iter_any():
if chunk:
yield chunk.decode(errors="ignore")

@ -37,6 +37,7 @@ from .Local import Local
from .PerplexityLabs import PerplexityLabs from .PerplexityLabs import PerplexityLabs
from .Pi import Pi from .Pi import Pi
from .Vercel import Vercel from .Vercel import Vercel
from .WhiteRabbitNeo import WhiteRabbitNeo
from .You import You from .You import You
import sys import sys

@ -57,13 +57,9 @@
</button> </button>
</div> </div>
<div class="bottom_buttons"> <div class="bottom_buttons">
<button onclick="delete_conversations()"> <button onclick="open_settings();">
<i class="fa-regular fa-trash"></i> <i class="fa-solid fa-toolbox"></i>
<span>Clear Conversations</span> <span>Open Settings</span>
</button>
<button onclick="save_storage()">
<i class="fa-solid fa-download"></i>
<a href="" onclick="return false;">Export Conversations</a>
</button> </button>
<div class="info"> <div class="info">
<i class="fa-brands fa-github"></i> <i class="fa-brands fa-github"></i>
@ -76,28 +72,48 @@
</div> </div>
</div> </div>
</div> </div>
<div class="settings"> <div class="settings hidden">
<div class="field box"> <div class="field">
<label for="OpenaiChat-api_key" class="label" title="">OpenaiChat: access_token</label> <span class="label">Web Access</span>
<textarea id="OpenaiChat-api_key" name="OpenaiChat[api_key]" placeholder="..."></textarea> <input type="checkbox" id="switch" />
<label for="switch" class="toogle" title="Add the pages of the first 5 search results to the query."></label>
</div> </div>
<div class="field"> <div class="field">
<span class="label">OpenaiChat: Auto continue</span> <span class="label">Disable History</span>
<input id="OpenaiChat-auto_continue" type="checkbox" name="OpenaiChat[auto_continue]" checked/> <input type="checkbox" id="history" />
<label for="OpenaiChat-auto_continue" class="toogle" title=""></label> <label for="history" class="toogle" title="To improve the reaction time or if you have trouble with large conversations."></label>
</div>
<div class="field">
<span class="label">Hide System prompt</span>
<input type="checkbox" id="hide-systemPrompt" />
<label for="hide-systemPrompt" class="toogle" title="For more space on phones"></label>
</div>
<div class="field">
<span class="label">Auto continue</span>
<input id="auto_continue" type="checkbox" name="auto_continue" checked/>
<label for="auto_continue" class="toogle" title="Continue long responses in OpenaiChat"></label>
</div>
<div class="paper">
<div class="field box">
<label for="OpenaiChat-api_key" class="label" title="">OpenaiChat: api_key</label>
<textarea id="OpenaiChat-api_key" name="OpenaiChat[api_key]" placeholder="..."></textarea>
</div> </div>
<div class="field box"> <div class="field box">
<label for="Bing-api_key" class="label" title="">Bing: "_U" cookie</label> <label for="Bing-api_key" class="label" title="">Bing: "_U" cookie</label>
<textarea id="Bing-api_key" name="Bing[api_key]" placeholder="..."></textarea> <textarea id="Bing-api_key" name="Bing[api_key]" placeholder="..."></textarea>
</div> </div>
<div class="field box"> <div class="field box">
<label for="Gemini-api_key" class="label" title="">Gemini: Auth cookies</label> <label for="Gemini-api_key" class="label" title="">Gemini: Cookies</label>
<textarea id="Gemini-api_key" name="Gemini[api_key]" placeholder="..."></textarea> <textarea id="Gemini-api_key" name="Gemini[api_key]" placeholder="..."></textarea>
</div> </div>
<div class="field box"> <div class="field box">
<label for="Openai-api_key" class="label" title="">Openai: api_key</label> <label for="Openai-api_key" class="label" title="">Openai: api_key</label>
<textarea id="Openai-api_key" name="Openai[api_key]" placeholder="..."></textarea> <textarea id="Openai-api_key" name="Openai[api_key]" placeholder="..."></textarea>
</div> </div>
<div class="field box">
<label for="Openai-api_key" class="label" title="">Groq: api_key</label>
<textarea id="Openai-api_key" name="Groq[api_key]" placeholder="..."></textarea>
</div>
<div class="field box"> <div class="field box">
<label for="GeminiPro-api_key" class="label" title="">GeminiPro: api_key</label> <label for="GeminiPro-api_key" class="label" title="">GeminiPro: api_key</label>
<textarea id="GeminiPro-api_key" name="GeminiPro[api_key]" placeholder="..."></textarea> <textarea id="GeminiPro-api_key" name="GeminiPro[api_key]" placeholder="..."></textarea>
@ -106,6 +122,17 @@
<label for="HuggingFace-api_key" class="label" title="">HuggingFace: api_key</label> <label for="HuggingFace-api_key" class="label" title="">HuggingFace: api_key</label>
<textarea id="HuggingFace-api_key" name="HuggingFace[api_key]" placeholder="..."></textarea> <textarea id="HuggingFace-api_key" name="HuggingFace[api_key]" placeholder="..."></textarea>
</div> </div>
</div>
<div class="bottom_buttons">
<button onclick="delete_conversations()">
<i class="fa-regular fa-trash"></i>
<span>Clear Conversations</span>
</button>
<button onclick="save_storage()">
<i class="fa-solid fa-download"></i>
<a href="" onclick="return false;">Export Conversations</a>
</button>
</div>
</div> </div>
<div class="conversation"> <div class="conversation">
<textarea id="systemPrompt" class="box" placeholder="System prompt"></textarea> <textarea id="systemPrompt" class="box" placeholder="System prompt"></textarea>
@ -161,43 +188,15 @@
<select name="model2" id="model2" class="hidden"></select> <select name="model2" id="model2" class="hidden"></select>
</div> </div>
<div class="field"> <div class="field">
<select name="jailbreak" id="jailbreak" style="display: none;"> <select name="provider" id="provider">
<option value="default" selected>Set Jailbreak</option> <option value="">Provider: Auto</option>
<option value="gpt-math-1.0">math 1.0</option> <option value="Bing">Bing</option>
<option value="gpt-dude-1.0">dude 1.0</option> <option value="OpenaiChat">OpenaiChat</option>
<option value="gpt-dan-1.0">dan 1.0</option> <option value="Gemini">Gemini</option>
<option value="gpt-dan-2.0">dan 2.0</option> <option value="Liaobots">Liaobots</option>
<option value="gpt-dev-2.0">dev 2.0</option> <option value="You">You</option>
<option value="gpt-evil-1.0">evil 1.0</option> <option value="">----</option>
</select> </select>
<div class="field">
<select name="provider" id="provider">
<option value="">Provider: Auto</option>
<option value="Bing">Bing</option>
<option value="OpenaiChat">OpenaiChat</option>
<option value="Gemini">Gemini</option>
<option value="Liaobots">Liaobots</option>
<option value="You">You</option>
<option value="">----</option>
</select>
</div>
</div>
<div class="field">
<input type="checkbox" id="switch" />
<label for="switch" title="Add the pages of the first 5 search results to the query."></label>
<span class="about">Web Access</span>
</div>
<!--
<div class="field">
<input type="checkbox" id="patch" />
<label for="patch" title="Enable create images with Bing."></label>
<span class="about">Image Generator</span>
</div>
-->
<div class="field">
<input type="checkbox" id="history" />
<label for="history" title="To improve the reaction time or if you have trouble with large conversations."></label>
<span class="about">Disable History</span>
</div> </div>
</div> </div>
</div> </div>

@ -84,7 +84,7 @@ body {
} }
body { body {
padding: var(--section-gap); padding: 10px;
background: var(--colour-1); background: var(--colour-1);
color: var(--colour-3); color: var(--colour-3);
height: 100vh; height: 100vh;
@ -92,7 +92,7 @@ body {
.row { .row {
display: flex; display: flex;
gap: var(--section-gap); gap: 10px;
height: 100%; height: 100%;
} }
@ -111,7 +111,7 @@ body {
} }
.conversations { .conversations {
max-width: 260px; max-width: 280px;
padding: var(--section-gap); padding: var(--section-gap);
overflow: auto; overflow: auto;
flex-shrink: 0; flex-shrink: 0;
@ -183,8 +183,8 @@ body {
.conversations { .conversations {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: var(--inner-gap); gap: 10px;
padding: var(--inner-gap); padding: 10px;
} }
.conversations .title { .conversations .title {
@ -207,7 +207,12 @@ body {
cursor: pointer; cursor: pointer;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10px; gap: 4px;
}
.conversations .convo .fa-trash {
position: absolute;
right: 8px;
} }
.conversations .convo .choise { .conversations .convo .choise {
@ -216,7 +221,7 @@ body {
background-color: var(--blur-bg); background-color: var(--blur-bg);
} }
.conversations i { .conversations i, .bottom_buttons i {
color: var(--conversations); color: var(--conversations);
cursor: pointer; cursor: pointer;
} }
@ -229,6 +234,10 @@ body {
white-space: nowrap; white-space: nowrap;
} }
.convo-title .datetime {
font-size: 10px;
}
.message { .message {
width: 100%; width: 100%;
overflow-wrap: break-word; overflow-wrap: break-word;
@ -351,10 +360,23 @@ body {
cursor: pointer; cursor: pointer;
} }
.message .count .fa-clipboard {
z-index: 1000;
cursor: pointer;
}
.message .user .fa-xmark { .message .user .fa-xmark {
color: var(--colour-1); color: var(--colour-1);
} }
.message .count .fa-clipboard {
color: var(--colour-3);
}
.message .count .fa-clipboard.clicked {
color: var(--accent);
}
.message .assistant:hover .fa-xmark, .message .assistant:hover .fa-xmark,
.message .user:hover .fa-xmark { .message .user:hover .fa-xmark {
display: block; display: block;
@ -556,6 +578,16 @@ label[for="camera"] {
background: var(--accent); background: var(--accent);
} }
.settings .bottom_buttons {
flex-direction: row;
}
.settings .bottom_buttons button {
display: inline-block;
max-width: 210px;
width: 100%;
}
.buttons input:checked+label:after { .buttons input:checked+label:after {
left: calc(100% - 5px - 20px); left: calc(100% - 5px - 20px);
} }
@ -565,6 +597,7 @@ label[for="camera"] {
align-items: center; align-items: center;
justify-content: left; justify-content: left;
width: 100%; width: 100%;
margin-bottom: 2px;
} }
.field { .field {
@ -635,6 +668,7 @@ select {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
margin: 4px;
} }
.bottom_buttons button { .bottom_buttons button {
@ -1026,7 +1060,14 @@ a:-webkit-any-link {
.settings { .settings {
width: 100%; width: 100%;
display: none; min-width: 700px;
display: flex;
flex-direction: column;
}
.settings .paper {
overflow: auto;
flex-direction: column;
} }
.settings .field { .settings .field {

@ -15,13 +15,13 @@ const providerSelect = document.getElementById("provider");
const modelSelect = document.getElementById("model"); const modelSelect = document.getElementById("model");
const modelProvider = document.getElementById("model2"); const modelProvider = document.getElementById("model2");
const systemPrompt = document.getElementById("systemPrompt") const systemPrompt = document.getElementById("systemPrompt")
const jailbreak = document.getElementById("jailbreak"); const settings = document.querySelector(".settings")
let prompt_lock = false; let prompt_lock = false;
let content, content_inner, content_count = null; let content, content_inner, content_count = null;
const options = ["switch", "model", "model2", "jailbreak", "patch", "provider", "history"]; const optionElements = document.querySelectorAll(".settings input, .settings textarea, #model, #model2, #provider")
messageInput.addEventListener("blur", () => { messageInput.addEventListener("blur", () => {
window.scrollTo(0, 0); window.scrollTo(0, 0);
@ -63,7 +63,7 @@ const highlight = (container) => {
); );
} }
const register_remove_message = async () => { const register_message_buttons = async () => {
document.querySelectorAll(".message .fa-xmark").forEach(async (el) => { document.querySelectorAll(".message .fa-xmark").forEach(async (el) => {
if (!("click" in el.dataset)) { if (!("click" in el.dataset)) {
el.dataset.click = "true"; el.dataset.click = "true";
@ -77,6 +77,18 @@ const register_remove_message = async () => {
}) })
} }
}); });
document.querySelectorAll(".message .fa-clipboard").forEach(async (el) => {
if (!("click" in el.dataset)) {
el.dataset.click = "true";
el.addEventListener("click", async () => {
const message_el = el.parentElement.parentElement;
const copyText = await get_message(window.conversation_id, message_el.dataset.index);
navigator.clipboard.writeText(copyText);
el.classList.add("clicked");
setTimeout(() => el.classList.remove("clicked"), 1000);
})
}
});
} }
const delete_conversations = async () => { const delete_conversations = async () => {
@ -132,7 +144,7 @@ const handle_ask = async () => {
: '' : ''
} }
</div> </div>
<div class="count">${count_words_and_tokens(message, get_selected_model())}</div> <div class="count">${count_words_and_tokens(message, get_selected_model())} <i class="fa-regular fa-clipboard"></i></div>
</div> </div>
</div> </div>
`; `;
@ -305,15 +317,22 @@ const ask_gpt = async () => {
try { try {
const input = imageInput && imageInput.files.length > 0 ? imageInput : cameraInput; const input = imageInput && imageInput.files.length > 0 ? imageInput : cameraInput;
const file = input && input.files.length > 0 ? input.files[0] : null; const file = input && input.files.length > 0 ? input.files[0] : null;
const provider = providerSelect.options[providerSelect.selectedIndex].value;
const auto_continue = document.getElementById("auto_continue")?.checked;
if (file && !provider)
provider = "Bing";
let api_key = null;
if (provider)
api_key = document.getElementById(`${provider}-api_key`)?.value;
await api("conversation", { await api("conversation", {
id: window.token, id: window.token,
conversation_id: window.conversation_id, conversation_id: window.conversation_id,
model: get_selected_model(), model: get_selected_model(),
jailbreak: jailbreak?.options[jailbreak.selectedIndex].value,
web_search: document.getElementById("switch").checked, web_search: document.getElementById("switch").checked,
provider: providerSelect.options[providerSelect.selectedIndex].value, provider: provider,
patch_provider: document.getElementById("patch")?.checked, messages: messages,
messages: messages auto_continue: auto_continue,
api_key: api_key
}, file); }, file);
if (!error) { if (!error) {
html = markdown_render(text); html = markdown_render(text);
@ -341,7 +360,7 @@ const ask_gpt = async () => {
window.scrollTo(0, 0); window.scrollTo(0, 0);
message_box.scrollTop = message_box.scrollHeight; message_box.scrollTop = message_box.scrollHeight;
await remove_cancel_button(); await remove_cancel_button();
await register_remove_message(); await register_message_buttons();
prompt_lock = false; prompt_lock = false;
await load_conversations(); await load_conversations();
regenerate.classList.remove("regenerate-hidden"); regenerate.classList.remove("regenerate-hidden");
@ -459,7 +478,7 @@ const load_conversation = async (conversation_id, scroll=true) => {
<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">${count_words_and_tokens(item.content, next_provider?.model)}</div> <div class="count">${count_words_and_tokens(item.content, next_provider?.model)} <i class="fa-regular fa-clipboard"></i></div>
</div> </div>
</div> </div>
`; `;
@ -475,8 +494,9 @@ const load_conversation = async (conversation_id, scroll=true) => {
} }
message_box.innerHTML = elements; message_box.innerHTML = elements;
register_remove_message(); register_message_buttons();
highlight(message_box); highlight(message_box);
regenerate.classList.remove("regenerate-hidden");
if (scroll) { if (scroll) {
message_box.scrollTo({ top: message_box.scrollHeight, behavior: "smooth" }); message_box.scrollTo({ top: message_box.scrollHeight, behavior: "smooth" });
@ -495,6 +515,7 @@ async function get_conversation(conversation_id) {
} }
async function save_conversation(conversation_id, conversation) { async function save_conversation(conversation_id, conversation) {
conversation.updated = Date.now();
appStorage.setItem( appStorage.setItem(
`conversation:${conversation_id}`, `conversation:${conversation_id}`,
JSON.stringify(conversation) JSON.stringify(conversation)
@ -517,6 +538,7 @@ async function add_conversation(conversation_id, content) {
await save_conversation(conversation_id, { await save_conversation(conversation_id, {
id: conversation_id, id: conversation_id,
title: title, title: title,
added: Date.now(),
system: systemPrompt?.value, system: systemPrompt?.value,
items: [], items: [],
}); });
@ -563,6 +585,11 @@ const remove_message = async (conversation_id, index) => {
await save_conversation(conversation_id, conversation); await save_conversation(conversation_id, conversation);
}; };
const get_message = async (conversation_id, index) => {
const conversation = await get_conversation(conversation_id);
return conversation.items[index]["content"];
};
const add_message = async (conversation_id, role, content, provider) => { const add_message = async (conversation_id, role, content, provider) => {
const conversation = await get_conversation(conversation_id); const conversation = await get_conversation(conversation_id);
conversation.items.push({ conversation.items.push({
@ -586,11 +613,17 @@ const load_conversations = async () => {
await clear_conversations(); await clear_conversations();
for (conversation of conversations) { for (conversation of conversations) {
let updated = "";
if (conversation.updated) {
const date = new Date(conversation.updated);
updated = date.toLocaleString('en-GB', {dateStyle: 'short', timeStyle: 'short', monthStyle: 'short'});
updated = updated.replace("/" + date.getFullYear(), "")
}
box_conversations.innerHTML += ` box_conversations.innerHTML += `
<div class="convo" id="convo-${conversation.id}"> <div class="convo" id="convo-${conversation.id}">
<div class="left" onclick="set_conversation('${conversation.id}')"> <div class="left" onclick="set_conversation('${conversation.id}')">
<i class="fa-regular fa-comments"></i> <i class="fa-regular fa-comments"></i>
<span class="convo-title">${conversation.title}</span> <span class="convo-title"><span class="datetime">${updated}</span> ${conversation.title}</span>
</div> </div>
<i onclick="show_option('${conversation.id}')" class="fa-regular fa-trash" id="conv-${conversation.id}"></i> <i onclick="show_option('${conversation.id}')" class="fa-regular fa-trash" id="conv-${conversation.id}"></i>
<div id="cho-${conversation.id}" class="choise" style="display:none;"> <div id="cho-${conversation.id}" class="choise" style="display:none;">
@ -642,7 +675,8 @@ const message_id = () => {
async function hide_sidebar() { async function hide_sidebar() {
sidebar.classList.remove("shown"); sidebar.classList.remove("shown");
sidebar_button.classList.remove("rotated"); sidebar_button.classList.remove("rotated");
if (window.location.pathname == "/menu/") { settings.classList.add("hidden");
if (window.location.pathname == "/menu/" || window.location.pathname == "/settings/") {
history.back(); history.back();
} }
} }
@ -650,6 +684,7 @@ async function hide_sidebar() {
window.addEventListener('popstate', hide_sidebar, false); window.addEventListener('popstate', hide_sidebar, false);
sidebar_button.addEventListener("click", (event) => { sidebar_button.addEventListener("click", (event) => {
settings.classList.add("hidden");
if (sidebar.classList.contains("shown")) { if (sidebar.classList.contains("shown")) {
hide_sidebar(); hide_sidebar();
} else { } else {
@ -660,19 +695,25 @@ sidebar_button.addEventListener("click", (event) => {
window.scrollTo(0, 0); window.scrollTo(0, 0);
}); });
function open_settings() {
if (settings.classList.contains("hidden")) {
sidebar.classList.remove("shown");
settings.classList.remove("hidden");
history.pushState({}, null, "/settings/");
} else {
settings.classList.add("hidden");
}
}
const register_settings_storage = async () => { const register_settings_storage = async () => {
options.forEach((id) => { optionElements.forEach((element) => {
element = document.getElementById(id);
if (!element) {
return;
}
element.addEventListener('change', async (event) => { element.addEventListener('change', async (event) => {
switch (event.target.type) { switch (event.target.type) {
case "checkbox": case "checkbox":
appStorage.setItem(id, event.target.checked); appStorage.setItem(element.id, event.target.checked);
break; break;
case "select-one": case "select-one":
appStorage.setItem(id, event.target.selectedIndex); appStorage.setItem(element.id, event.target.selectedIndex);
break; break;
default: default:
console.warn("Unresolved element type"); console.warn("Unresolved element type");
@ -682,9 +723,8 @@ const register_settings_storage = async () => {
} }
const load_settings_storage = async () => { const load_settings_storage = async () => {
options.forEach((id) => { optionElements.forEach((element) => {
element = document.getElementById(id); if (!(value = appStorage.getItem(element.id))) {
if (!element || !(value = appStorage.getItem(id))) {
return; return;
} }
if (value) { if (value) {
@ -859,6 +899,18 @@ async function on_api() {
await load_provider_models(appStorage.getItem("provider")); await load_provider_models(appStorage.getItem("provider"));
await load_settings_storage() await load_settings_storage()
const hide_systemPrompt = document.getElementById("hide-systemPrompt")
if (hide_systemPrompt.checked) {
systemPrompt.classList.add("hidden");
}
hide_systemPrompt.addEventListener('change', async (event) => {
if (event.target.checked) {
systemPrompt.classList.add("hidden");
} else {
systemPrompt.classList.remove("hidden");
}
});
} }
async function load_version() { async function load_version() {
@ -875,7 +927,7 @@ async function load_version() {
} }
document.getElementById("version_text").innerHTML = text document.getElementById("version_text").innerHTML = text
} }
setTimeout(load_version, 5000); setTimeout(load_version, 2000);
for (const el of [imageInput, cameraInput]) { for (const el of [imageInput, cameraInput]) {
el.addEventListener('click', async () => { el.addEventListener('click', async () => {
@ -1035,7 +1087,7 @@ function save_storage() {
let item = appStorage.getItem(key); let item = appStorage.getItem(key);
if (key.startsWith("conversation:")) { if (key.startsWith("conversation:")) {
data[key] = JSON.parse(item); data[key] = JSON.parse(item);
} else { } else if (!key.includes("api_key")) {
data["options"][key] = item; data["options"][key] = item;
} }
} }

@ -80,13 +80,12 @@ class Api():
Returns: Returns:
dict: Arguments prepared for chat completion. dict: Arguments prepared for chat completion.
""" """
provider = json_data.get('provider', None) model = json_data.get('model') or models.default
if "image" in kwargs and provider is None: provider = json_data.get('provider')
provider = "Bing"
if provider == 'OpenaiChat':
kwargs['auto_continue'] = True
messages = json_data['messages'] messages = json_data['messages']
api_key = json_data.get("api_key")
if api_key is not None:
kwargs["api_key"] = api_key
if json_data.get('web_search'): if json_data.get('web_search'):
if provider == "Bing": if provider == "Bing":
kwargs['web_search'] = True kwargs['web_search'] = True
@ -98,8 +97,6 @@ class Api():
if conversation_id and provider in conversations and conversation_id in conversations[provider]: if conversation_id and provider in conversations and conversation_id in conversations[provider]:
kwargs["conversation"] = conversations[provider][conversation_id] kwargs["conversation"] = conversations[provider][conversation_id]
model = json_data.get('model') or models.default
return { return {
"model": model, "model": model,
"provider": provider, "provider": provider,

@ -1,6 +1,5 @@
from __future__ import annotations from __future__ import annotations
import logging
import json import json
import os.path import os.path
from typing import Iterator from typing import Iterator

@ -4,9 +4,11 @@ from flask import render_template, redirect
class Website: class Website:
def __init__(self, app) -> None: def __init__(self, app) -> None:
self.app = app self.app = app
def redirect_home():
return redirect('/chat')
self.routes = { self.routes = {
'/': { '/': {
'function': lambda: redirect('/chat'), 'function': redirect_home,
'methods': ['GET', 'POST'] 'methods': ['GET', 'POST']
}, },
'/chat/': { '/chat/': {
@ -17,6 +19,14 @@ class Website:
'function': self._chat, 'function': self._chat,
'methods': ['GET', 'POST'] 'methods': ['GET', 'POST']
}, },
'/menu/': {
'function': redirect_home,
'methods': ['GET', 'POST']
},
'/settings/': {
'function': redirect_home,
'methods': ['GET', 'POST']
},
} }
def _chat(self, conversation_id): def _chat(self, conversation_id):

Loading…
Cancel
Save