From d4ab83a45bfef2910936dcabf3f875268631e65b Mon Sep 17 00:00:00 2001 From: abc <98614666+xtekky@users.noreply.github.com> Date: Thu, 19 Oct 2023 15:14:48 +0100 Subject: ~ automatic models fetching in GUI. --- g4f/Provider/Vercel.py | 132 ++++++++++++++++++++++------------------- g4f/__init__.py | 41 ++++++------- g4f/gui/client/html/index.html | 9 +-- g4f/gui/client/js/chat.v2.js | 107 +++++++++++++++++---------------- g4f/gui/server/backend.py | 7 ++- g4f/models.py | 18 +++++- 6 files changed, 163 insertions(+), 151 deletions(-) diff --git a/g4f/Provider/Vercel.py b/g4f/Provider/Vercel.py index 2d856664..9b1292a0 100644 --- a/g4f/Provider/Vercel.py +++ b/g4f/Provider/Vercel.py @@ -2,9 +2,10 @@ from __future__ import annotations import json, base64, requests, execjs, random, uuid -from ..typing import Messages, TypedDict, CreateResult +from ..typing import Messages, TypedDict, CreateResult, Any from .base_provider import BaseProvider from abc import abstractmethod +from ..debug import logging class Vercel(BaseProvider): @@ -19,14 +20,16 @@ class Vercel(BaseProvider): model: str, messages: Messages, stream: bool, - proxy: str = None, - **kwargs - ) -> CreateResult: + proxy: str = None, **kwargs) -> CreateResult: + + print(model) + if not model: model = "gpt-3.5-turbo" + elif model not in model_info: - raise ValueError(f"Model are not supported: {model}") - + raise ValueError(f"Vercel does not support {model}") + headers = { 'authority' : 'sdk.vercel.ai', 'accept' : '*/*', @@ -110,40 +113,49 @@ class ModelInfo(TypedDict): default_params: dict[str, Any] model_info: dict[str, ModelInfo] = { - 'claude-instant-v1': { - 'id': 'anthropic:claude-instant-v1', - 'default_params': { - 'temperature': 1, - 'maximumLength': 1024, - 'topP': 1, - 'topK': 1, - 'presencePenalty': 1, - 'frequencyPenalty': 1, - 'stopSequences': ['\n\nHuman:'], - }, - }, - 'claude-v1': { - 'id': 'anthropic:claude-v1', - 'default_params': { - 'temperature': 1, - 'maximumLength': 1024, - 'topP': 1, - 'topK': 1, - 'presencePenalty': 1, - 'frequencyPenalty': 1, - 'stopSequences': ['\n\nHuman:'], - }, - }, - 'claude-v2': { - 'id': 'anthropic:claude-v2', + # 'claude-instant-v1': { + # 'id': 'anthropic:claude-instant-v1', + # 'default_params': { + # 'temperature': 1, + # 'maximumLength': 1024, + # 'topP': 1, + # 'topK': 1, + # 'presencePenalty': 1, + # 'frequencyPenalty': 1, + # 'stopSequences': ['\n\nHuman:'], + # }, + # }, + # 'claude-v1': { + # 'id': 'anthropic:claude-v1', + # 'default_params': { + # 'temperature': 1, + # 'maximumLength': 1024, + # 'topP': 1, + # 'topK': 1, + # 'presencePenalty': 1, + # 'frequencyPenalty': 1, + # 'stopSequences': ['\n\nHuman:'], + # }, + # }, + # 'claude-v2': { + # 'id': 'anthropic:claude-v2', + # 'default_params': { + # 'temperature': 1, + # 'maximumLength': 1024, + # 'topP': 1, + # 'topK': 1, + # 'presencePenalty': 1, + # 'frequencyPenalty': 1, + # 'stopSequences': ['\n\nHuman:'], + # }, + # }, + 'replicate/llama70b-v2-chat': { + 'id': 'replicate:replicate/llama-2-70b-chat', 'default_params': { - 'temperature': 1, - 'maximumLength': 1024, + 'temperature': 0.75, + 'maximumLength': 3000, 'topP': 1, - 'topK': 1, - 'presencePenalty': 1, - 'frequencyPenalty': 1, - 'stopSequences': ['\n\nHuman:'], + 'repetitionPenalty': 1, }, }, 'a16z-infra/llama7b-v2-chat': { @@ -254,28 +266,28 @@ model_info: dict[str, ModelInfo] = { 'stopSequences': [], }, }, - 'gpt-4': { - 'id': 'openai:gpt-4', - 'default_params': { - 'temperature': 0.7, - 'maximumLength': 8192, - 'topP': 1, - 'presencePenalty': 0, - 'frequencyPenalty': 0, - 'stopSequences': [], - }, - }, - 'gpt-4-0613': { - 'id': 'openai:gpt-4-0613', - 'default_params': { - 'temperature': 0.7, - 'maximumLength': 8192, - 'topP': 1, - 'presencePenalty': 0, - 'frequencyPenalty': 0, - 'stopSequences': [], - }, - }, + # 'gpt-4': { + # 'id': 'openai:gpt-4', + # 'default_params': { + # 'temperature': 0.7, + # 'maximumLength': 8192, + # 'topP': 1, + # 'presencePenalty': 0, + # 'frequencyPenalty': 0, + # 'stopSequences': [], + # }, + # }, + # 'gpt-4-0613': { + # 'id': 'openai:gpt-4-0613', + # 'default_params': { + # 'temperature': 0.7, + # 'maximumLength': 8192, + # 'topP': 1, + # 'presencePenalty': 0, + # 'frequencyPenalty': 0, + # 'stopSequences': [], + # }, + # }, 'code-davinci-002': { 'id': 'openai:code-davinci-002', 'default_params': { diff --git a/g4f/__init__.py b/g4f/__init__.py index 492d4e5b..1342452a 100644 --- a/g4f/__init__.py +++ b/g4f/__init__.py @@ -1,14 +1,13 @@ from __future__ import annotations -from requests import get -from g4f.models import Model, ModelUtils -from .Provider import BaseProvider, RetryProvider -from .typing import Messages, CreateResult, Union, List -from .debug import logging +from requests import get +from .models import Model, ModelUtils, _all_models +from .Provider import BaseProvider, RetryProvider +from .typing import Messages, CreateResult, Union, List +from .debug import logging -version = '0.1.6.6' +version = '0.1.6.6' version_check = True - def check_pypi_version() -> None: try: response = get("https://pypi.org/pypi/g4f/json").json() @@ -20,7 +19,6 @@ def check_pypi_version() -> None: except Exception as e: print(f'Failed to check g4f pypi version: {e}') - def get_model_and_provider(model : Union[Model, str], provider : Union[type[BaseProvider], None], stream : bool, @@ -56,7 +54,7 @@ def get_model_and_provider(model : Union[Model, str], class ChatCompletion: @staticmethod - def create(model: Union[Model, str], + def create(model : Union[Model, str], messages : Messages, provider : Union[type[BaseProvider], None] = None, stream : bool = False, @@ -76,12 +74,11 @@ class ChatCompletion: return result if stream else ''.join(result) @staticmethod - async def create_async( - model : Union[Model, str], - messages: Messages, - provider: Union[type[BaseProvider], None] = None, - stream : bool = False, - ignored : List[str] = None, **kwargs) -> str: + async def create_async(model : Union[Model, str], + messages : Messages, + provider : Union[type[BaseProvider], None] = None, + stream : bool = False, + ignored : List[str] = None, **kwargs) -> str: if stream: raise ValueError(f'"create_async" does not support "stream" argument') @@ -90,17 +87,13 @@ class ChatCompletion: return await provider.create_async(model.name, messages, **kwargs) - class Completion: @staticmethod - def create( - model: str, - prompt: str, - provider: Union[type[BaseProvider], None] = None, - stream: bool = False, - ignored : List[str] = None, - **kwargs - ) -> Union[CreateResult, str]: + def create(model : Union[Model, str], + prompt : str, + provider : Union[type[BaseProvider], None] = None, + stream : bool = False, + ignored : List[str] = None, **kwargs) -> Union[CreateResult, str]: allowed_models = [ 'code-davinci-002', diff --git a/g4f/gui/client/html/index.html b/g4f/gui/client/html/index.html index ae5519e6..d6715ede 100644 --- a/g4f/gui/client/html/index.html +++ b/g4f/gui/client/html/index.html @@ -117,14 +117,7 @@
diff --git a/g4f/gui/client/js/chat.v2.js b/g4f/gui/client/js/chat.v2.js index f052b7e6..03c3a87a 100644 --- a/g4f/gui/client/js/chat.v2.js +++ b/g4f/gui/client/js/chat.v2.js @@ -1,13 +1,12 @@ -const query = (obj) => Object.keys(obj).map((k) => encodeURIComponent(k) + "=" + encodeURIComponent(obj[k])).join("&"); -const colorThemes = document.querySelectorAll('[name="theme"]'); -const markdown = window.markdownit(); -const message_box = document.getElementById(`messages`); -const message_input = document.getElementById(`message-input`); +const colorThemes = document.querySelectorAll('[name="theme"]'); +const markdown = window.markdownit(); +const message_box = document.getElementById(`messages`); +const message_input = document.getElementById(`message-input`); const box_conversations = document.querySelector(`.top`); -const spinner = box_conversations.querySelector(".spinner"); -const stop_generating = document.querySelector(`.stop_generating`); -const send_button = document.querySelector(`#send-button`); -let prompt_lock = false; +const spinner = box_conversations.querySelector(".spinner"); +const stop_generating = document.querySelector(`.stop_generating`); +const send_button = document.querySelector(`#send-button`); +let prompt_lock = false; hljs.addPlugin(new CopyButtonPlugin()); @@ -81,8 +80,6 @@ const ask_gpt = async (message) => {
`; - /* .replace(/(?:\r\n|\r|\n)/g, '
') */ - message_box.scrollTop = message_box.scrollHeight; window.scrollTo(0, 0); await new Promise((r) => setTimeout(r, 500)); @@ -108,10 +105,8 @@ const ask_gpt = async (message) => { method: `POST`, signal: window.controller.signal, headers: { - "content-type": `application/json`, + 'content-type': `application/json`, accept: `text/event-stream`, - // v: `1.0.0`, - // ts: Date.now().toString(), }, body: JSON.stringify({ conversation_id: window.conversation_id, @@ -123,12 +118,12 @@ const ask_gpt = async (message) => { id: window.token, content: { conversation: await get_conversation(window.conversation_id), - internet_access: document.getElementById("switch").checked, - content_type: "text", + internet_access: document.getElementById(`switch`).checked, + content_type: `text`, parts: [ { content: message, - role: "user", + role: `user`, }, ], }, @@ -146,8 +141,7 @@ const ask_gpt = async (message) => { text += chunk; - document.getElementById(`gpt_${window.token}`).innerHTML = - markdown.render(text); + document.getElementById(`gpt_${window.token}`).innerHTML = markdown.render(text); document.querySelectorAll(`code`).forEach((el) => { hljs.highlightElement(el); }); @@ -169,6 +163,7 @@ const ask_gpt = async (message) => { await load_conversations(20, 0); window.scrollTo(0, 0); + } catch (e) { add_message(window.conversation_id, "user", message); @@ -227,19 +222,19 @@ const show_option = async (conversation_id) => { const yes = document.getElementById(`yes-${conversation_id}`); const not = document.getElementById(`not-${conversation_id}`); - conv.style.display = "none"; - yes.style.display = "block"; - not.style.display = "block"; + conv.style.display = `none`; + yes.style.display = `block`; + not.style.display = `block`; }; const hide_option = async (conversation_id) => { const conv = document.getElementById(`conv-${conversation_id}`); - const yes = document.getElementById(`yes-${conversation_id}`); - const not = document.getElementById(`not-${conversation_id}`); + const yes = document.getElementById(`yes-${conversation_id}`); + const not = document.getElementById(`not-${conversation_id}`); - conv.style.display = "block"; - yes.style.display = "none"; - not.style.display = "none"; + conv.style.display = `block`; + yes.style.display = `none`; + not.style.display = `none`; }; const delete_conversation = async (conversation_id) => { @@ -272,7 +267,7 @@ const new_conversation = async () => { await clear_conversation(); await load_conversations(20, 0, true); - await make_announcement() + await say_hello() }; const load_conversation = async (conversation_id) => { @@ -287,15 +282,15 @@ const load_conversation = async (conversation_id) => {
${item.role == "assistant" ? gpt_image : user_image} ${item.role == "assistant" - ? `` - : `` - } + ? `` + : `` + }
${item.role == "assistant" - ? markdown.render(item.content) - : item.content - } + ? markdown.render(item.content) + : item.content + }
`; @@ -351,13 +346,10 @@ const add_message = async (conversation_id, role, content) => { localStorage.setItem( `conversation:${conversation_id}`, JSON.stringify(before_adding) - ); // update conversation + ); }; const load_conversations = async (limit, offset, loader) => { - //console.log(loader); - //if (loader === undefined) box_conversations.appendChild(spinner); - let conversations = []; for (let i = 0; i < localStorage.length; i++) { if (localStorage.key(i).startsWith("conversation:")) { @@ -366,7 +358,6 @@ const load_conversations = async (limit, offset, loader) => { } } - //if (loader === undefined) spinner.parentNode.removeChild(spinner) await clear_conversations(); for (conversation of conversations) { @@ -393,17 +384,6 @@ document.getElementById(`cancelButton`).addEventListener(`click`, async () => { console.log(`aborted ${window.conversation_id}`); }); -function h2a(str1) { - var hex = str1.toString(); - var str = ""; - - for (var n = 0; n < hex.length; n += 2) { - str += String.fromCharCode(parseInt(hex.substr(n, 2), 16)); - } - - return str; -} - const uuid = () => { return `xxxxxxxx-xxxx-4xxx-yxxx-${Date.now().toString(16)}`.replace( /[xy]/g, @@ -476,7 +456,7 @@ const load_settings_localstorage = async () => { }); }; -const make_announcement = async () => { +const say_hello = async () => { tokens = [`Hello`, `!`, ` How`,` can`, ` I`,` assist`,` you`,` today`,`?`] message_box.innerHTML += ` @@ -569,8 +549,9 @@ window.onload = async () => { await load_conversation(window.conversation_id); } } - - await make_announcement() + + await load_models(); + await say_hello() message_input.addEventListener(`keydown`, async (evt) => { if (prompt_lock) return; @@ -612,4 +593,22 @@ const observer = new MutationObserver((mutationsList) => { } }); -observer.observe(message_input, { attributes: true }); \ No newline at end of file +observer.observe(message_input, { attributes: true }); + + +const load_models = async () => { + response = await fetch('/backend-api/v2/models') + models = await response.json() + + var MODELS_SELECT = document.getElementById('model'); + + for (model of models) { + + // Create new option elements + var model_info = document.createElement('option'); + model_info.value = model + model_info.text = model + + MODELS_SELECT.appendChild(model_info); + } +} \ No newline at end of file diff --git a/g4f/gui/server/backend.py b/g4f/gui/server/backend.py index cacc57d8..714609f6 100644 --- a/g4f/gui/server/backend.py +++ b/g4f/gui/server/backend.py @@ -24,9 +24,12 @@ class Backend_Api: 'methods': ['POST'] }, } - + def models(self): - return {} + models = g4f._all_models + models.remove('oasst-sft-4-pythia-12b-epoch-3.5') + + return models def _gen_title(self): return { diff --git a/g4f/models.py b/g4f/models.py index d7c29ccb..b34297f5 100644 --- a/g4f/models.py +++ b/g4f/models.py @@ -37,6 +37,10 @@ class Model: name: str base_provider: str best_provider: Union[type[BaseProvider], RetryProvider] = None + + @staticmethod + def __all__() -> list[str]: + return _all_models default = Model( name = "", @@ -231,6 +235,11 @@ llama7b_v2_chat = Model( base_provider = 'replicate', best_provider = Vercel) +llama70b_v2_chat = Model( + name = 'replicate/llama70b-v2-chat', + base_provider = 'replicate', + best_provider = Vercel) + class ModelUtils: convert: dict[str, Model] = { @@ -260,9 +269,9 @@ class ModelUtils: 'llama-13b' : llama_13b, # Vercel - 'claude-instant-v1' : claude_instant_v1, - 'claude-v1' : claude_v1, - 'claude-v2' : claude_v2, + #'claude-instant-v1' : claude_instant_v1, + #'claude-v1' : claude_v1, + #'claude-v2' : claude_v2, 'command-nightly' : command_nightly, 'gpt-neox-20b' : gpt_neox_20b, 'santacoder' : santacoder, @@ -274,6 +283,7 @@ class ModelUtils: 'text-curie-001' : text_curie_001, 'text-davinci-002' : text_davinci_002, 'text-davinci-003' : text_davinci_003, + 'llama70b-v2-chat' : llama70b_v2_chat, 'llama13b-v2-chat' : llama13b_v2_chat, 'llama7b-v2-chat' : llama7b_v2_chat, @@ -281,3 +291,5 @@ class ModelUtils: 'oasst-sft-4-pythia-12b-epoch-3.5' : oasst_sft_4_pythia_12b_epoch_35, 'command-light-nightly' : command_light_nightly, } + +_all_models = list(ModelUtils.convert.keys()) \ No newline at end of file -- cgit v1.2.3