XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/gpt4free

Add CohereForAI provider, Updates for You.com provider Add default system prompt in UI Expose novnc port in docker

2064bb73
Heiner Lohaus <hlohaus@users.noreply.github.com>
提交于

代码差异

11 个文件 +212 -76
Modified docker/Dockerfile +1 -1
@@ -84,4 +84,4 @@ RUN pip install --break-system-packages --upgrade pip \
84 84 ADD --chown=$G4F_USER:$G4F_USER g4f $G4F_DIR/g4f
85 85
86 86 # Expose ports
87 EXPOSE 8080 1337
87 EXPOSE 8080 1337 7900
Modified g4f/Provider/You.py +12 -12
@@ -10,7 +10,7 @@ from .helper import format_prompt
10 10 from ..image import ImageResponse, ImagePreview, EXTENSIONS_MAP, to_bytes, is_accepted_format
11 11 from ..requests import StreamSession, FormData, raise_for_status, get_nodriver
12 12 from ..cookies import get_cookies
13 from ..errors import MissingRequirementsError
13 from ..errors import MissingRequirementsError, ResponseError
14 14 from .. import debug
15 15
16 16 class You(AsyncGeneratorProvider, ProviderModelMixin):
@@ -23,18 +23,19 @@ class You(AsyncGeneratorProvider, ProviderModelMixin):
23 23 models = [
24 24 default_model,
25 25 "gpt-4o",
26 "gpt-4o-mini",
26 27 "gpt-4-turbo",
27 "gpt-4",
28 "grok-2",
28 29 "claude-3.5-sonnet",
30 "claude-3.5-haiku",
29 31 "claude-3-opus",
30 32 "claude-3-sonnet",
31 33 "claude-3-haiku",
32 "claude-2",
34 "llama-3.3-70b",
33 35 "llama-3.1-70b",
34 36 "llama-3",
35 37 "gemini-1-5-flash",
36 38 "gemini-1-5-pro",
37 "gemini-1-0-pro",
38 39 "databricks-dbrx-instruct",
39 40 "command-r",
40 41 "command-r-plus",
@@ -105,19 +106,14 @@ class You(AsyncGeneratorProvider, ProviderModelMixin):
105 106 "conversationTurnId": str(uuid.uuid4()),
106 107 "chatId": str(uuid.uuid4()),
107 108 }
108 params = {
109 "userFiles": upload,
110 "selectedChatMode": chat_mode,
111 }
112 109 if chat_mode == "custom":
113 110 if debug.logging:
114 111 print(f"You model: {model}")
115 params["selectedAiModel"] = model.replace("-", "_")
112 data["selectedAiModel"] = model.replace("-", "_")
116 113
117 async with (session.post if chat_mode == "default" else session.get)(
114 async with session.get(
118 115 f"{cls.url}/api/streamingSearch",
119 data=data if chat_mode == "default" else None,
120 params=params if chat_mode == "default" else data,
116 params=data,
121 117 headers=headers,
122 118 cookies=cookies
123 119 ) as response:
@@ -126,9 +122,13 @@ class You(AsyncGeneratorProvider, ProviderModelMixin):
126 122 if line.startswith(b'event: '):
127 123 event = line[7:].decode()
128 124 elif line.startswith(b'data: '):
125 if event == "error":
126 raise ResponseError(line[6:])
129 127 if event in ["youChatUpdate", "youChatToken"]:
130 128 data = json.loads(line[6:])
131 129 if event == "youChatToken" and event in data and data[event]:
130 if data[event].startswith("#### You\'ve hit your free quota for the Model Agent. For more usage of the Model Agent, learn more at:"):
131 continue
132 132 yield data[event]
133 133 elif event == "youChatUpdate" and "t" in data and data["t"]:
134 134 if chat_mode == "create":
Added g4f/Provider/hf_space/CohereForAI.py +95 -0
@@ -0,0 +1,95 @@
1 from __future__ import annotations
2
3 import json
4 import uuid
5 from aiohttp import ClientSession, FormData
6
7 from ...typing import AsyncResult, Messages
8 from ...requests import raise_for_status
9 from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin
10 from ..helper import format_prompt
11 from ...providers.response import JsonConversation, TitleGeneration
12
13 class CohereForAI(AsyncGeneratorProvider, ProviderModelMixin):
14 url = "https://cohereforai-c4ai-command.hf.space"
15 conversation_url = f"{url}/conversation"
16
17 working = True
18
19 default_model = "command-r-plus-08-2024"
20 models = [
21 default_model,
22 "command-r-08-2024",
23 "command-r-plus",
24 "command-r",
25 "command-r7b-12-2024",
26 ]
27
28 @classmethod
29 async def create_async_generator(
30 cls, model: str, messages: Messages,
31 api_key: str = None,
32 proxy: str = None,
33 conversation: JsonConversation = None,
34 return_conversation: bool = False,
35 **kwargs
36 ) -> AsyncResult:
37 model = cls.get_model(model)
38 headers = {
39 "Origin": cls.url,
40 "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0",
41 "Accept": "*/*",
42 "Accept-Language": "en-US,en;q=0.5",
43 "Referer": "https://cohereforai-c4ai-command.hf.space/",
44 "Sec-Fetch-Dest": "empty",
45 "Sec-Fetch-Mode": "cors",
46 "Sec-Fetch-Site": "same-origin",
47 "Priority": "u=4",
48 }
49 if api_key is not None:
50 headers["Authorization"] = f"Bearer {api_key}"
51 async with ClientSession(
52 headers=headers,
53 cookies=None if conversation is None else conversation.cookies
54 ) as session:
55 system_prompt = "\n".join([message["content"] for message in messages if message["role"] == "system"])
56 messages = [message for message in messages if message["role"] != "system"]
57 inputs = format_prompt(messages) if conversation is None else messages[-1]["content"]
58 if conversation is None or conversation.model != model or conversation.preprompt != system_prompt:
59 data = {"model": model, "preprompt": system_prompt}
60 async with session.post(cls.conversation_url, json=data, proxy=proxy) as response:
61 await raise_for_status(response)
62 conversation = JsonConversation(
63 **await response.json(),
64 **data,
65 cookies={n: c.value for n, c in response.cookies.items()}
66 )
67 if return_conversation:
68 yield conversation
69 async with session.get(f"{cls.conversation_url}/{conversation.conversationId}/__data.json?x-sveltekit-invalidated=11", proxy=proxy) as response:
70 await raise_for_status(response)
71 node = json.loads((await response.text()).splitlines()[0])["nodes"][1]
72 if node["type"] == "error":
73 raise RuntimeError(node["error"])
74 data = node["data"]
75 message_id = data[data[data[data[0]["messages"]][-1]]["id"]]
76 data = FormData()
77 inputs = messages[-1]["content"]
78 data.add_field(
79 "data",
80 json.dumps({"inputs": inputs, "id": message_id, "is_retry": False, "is_continue": False, "web_search": False, "tools": []}),
81 content_type="application/json"
82 )
83 async with session.post(f"{cls.conversation_url}/{conversation.conversationId}", data=data, proxy=proxy) as response:
84 await raise_for_status(response)
85 async for chunk in response.content:
86 try:
87 data = json.loads(chunk)
88 except (json.JSONDecodeError) as e:
89 raise RuntimeError(f"Failed to read response: {chunk.decode(errors='replace')}", e)
90 if data["type"] == "stream":
91 yield data["token"].replace("\u0000", "")
92 elif data["type"] == "title":
93 yield TitleGeneration(data["title"])
94 elif data["type"] == "finalAnswer":
95 break
Modified g4f/Provider/hf_space/__init__.py +8 -5
@@ -8,6 +8,7 @@ from .BlackForestLabsFlux1Dev import BlackForestLabsFlux1Dev
8 8 from .BlackForestLabsFlux1Schnell import BlackForestLabsFlux1Schnell
9 9 from .VoodoohopFlux1Schnell import VoodoohopFlux1Schnell
10 10 from .StableDiffusion35Large import StableDiffusion35Large
11 from .CohereForAI import CohereForAI
11 12 from .Qwen_QVQ_72B import Qwen_QVQ_72B
12 13
13 14 class HuggingSpace(AsyncGeneratorProvider, ProviderModelMixin):
@@ -16,7 +17,7 @@ class HuggingSpace(AsyncGeneratorProvider, ProviderModelMixin):
16 17 working = True
17 18 default_model = BlackForestLabsFlux1Dev.default_model
18 19 default_vision_model = Qwen_QVQ_72B.default_model
19 providers = [BlackForestLabsFlux1Dev, BlackForestLabsFlux1Schnell, VoodoohopFlux1Schnell, StableDiffusion35Large, Qwen_QVQ_72B]
20 providers = [BlackForestLabsFlux1Dev, BlackForestLabsFlux1Schnell, VoodoohopFlux1Schnell, StableDiffusion35Large, CohereForAI, Qwen_QVQ_72B]
20 21
21 22 @classmethod
22 23 def get_parameters(cls, **kwargs) -> dict:
@@ -28,11 +29,13 @@ class HuggingSpace(AsyncGeneratorProvider, ProviderModelMixin):
28 29 @classmethod
29 30 def get_models(cls, **kwargs) -> list[str]:
30 31 if not cls.models:
32 models = []
31 33 for provider in cls.providers:
32 cls.models.extend(provider.get_models(**kwargs))
33 cls.models.extend(provider.model_aliases.keys())
34 cls.models = list(set(cls.models))
35 cls.models.sort()
34 models.extend(provider.get_models(**kwargs))
35 models.extend(provider.model_aliases.keys())
36 models = list(set(models))
37 models.sort()
38 cls.models = models
36 39 return cls.models
37 40
38 41 @classmethod
Modified g4f/Provider/needs_auth/HuggingFace.py +10 -9
@@ -28,15 +28,16 @@ class HuggingFace(AsyncGeneratorProvider, ProviderModelMixin):
28 28 def get_models(cls) -> list[str]:
29 29 if not cls.models:
30 30 url = "https://huggingface.co/api/models?inference=warm&pipeline_tag=text-generation"
31 cls.models = [model["id"] for model in requests.get(url).json()]
32 cls.models.append("meta-llama/Llama-3.2-11B-Vision-Instruct")
33 cls.models.append("nvidia/Llama-3.1-Nemotron-70B-Instruct-HF")
34 cls.models.sort()
35 if not cls.image_models:
36 url = "https://huggingface.co/api/models?pipeline_tag=text-to-image"
37 cls.image_models = [model["id"] for model in requests.get(url).json() if model["trendingScore"] >= 20]
38 cls.image_models.sort()
39 cls.models.extend(cls.image_models)
31 models = [model["id"] for model in requests.get(url).json()]
32 models.append("meta-llama/Llama-3.2-11B-Vision-Instruct")
33 models.append("nvidia/Llama-3.1-Nemotron-70B-Instruct-HF")
34 models.sort()
35 if not cls.image_models:
36 url = "https://huggingface.co/api/models?pipeline_tag=text-to-image"
37 cls.image_models = [model["id"] for model in requests.get(url).json() if model["trendingScore"] >= 20]
38 cls.image_models.sort()
39 models.extend(cls.image_models)
40 cls.models = models
40 41 return cls.models
41 42
42 43 @classmethod
Modified g4f/Provider/needs_auth/__init__.py +0 -1
@@ -25,7 +25,6 @@ from .Poe import Poe
25 25 from .Raycast import Raycast
26 26 from .Reka import Reka
27 27 from .Replicate import Replicate
28 from .Theb import Theb
29 28 from .ThebApi import ThebApi
30 29 from .WhiteRabbitNeo import WhiteRabbitNeo
31 30 from .xAI import xAI
Renamed g4f/Provider/not_working/Theb.py +0 -0
此文件没有可显示的逐行差异。
Modified g4f/Provider/not_working/__init__.py +1 -0
@@ -14,4 +14,5 @@ from .Koala import Koala
14 14 from .MagickPen import MagickPen
15 15 from .MyShell import MyShell
16 16 from .RobocodersAPI import RobocodersAPI
17 from .Theb import Theb
17 18 from .Upstage import Upstage
Modified g4f/gui/client/index.html +8 -1
@@ -142,6 +142,10 @@
142 142 <input type="checkbox" id="refine"/>
143 143 <label for="refine" class="toogle" title=""></label>
144 144 </div>
145 <div class="field box">
146 <label for="systemPrompt" class="label" title="">Default for System prompt</label>
147 <textarea id="systemPrompt" placeholder="You are a helpful assistant."></textarea>
148 </div>
145 149 <div class="field box">
146 150 <label for="message-input-height" class="label" title="">Input max. height</label>
147 151 <input type="number" id="message-input-height" value="200"/>
@@ -149,6 +153,9 @@
149 153 <div class="field box">
150 154 <label for="recognition-language" class="label" title="">Speech recognition language</label>
151 155 <input type="text" id="recognition-language" value="" placeholder="navigator.language"/>
156 <script>
157 document.getElementById('recognition-language').placeholder = navigator.language;
158 </script>
152 159 </div>
153 160 <div class="field box hidden">
154 161 <label for="BingCreateImages-api_key" class="label" title="">Microsoft Designer in Bing:</label>
@@ -179,7 +186,7 @@
179 186 </div>
180 187 </div>
181 188 <div class="conversation">
182 <textarea id="systemPrompt" class="box" placeholder="System prompt"></textarea>
189 <textarea id="chatPrompt" class="box" placeholder="System prompt"></textarea>
183 190 <div id="messages" class="box"></div>
184 191 <button class="slide-systemPrompt">
185 192 <i class="fa-solid fa-angles-up"></i>
Modified g4f/gui/client/static/css/style.css +13 -10
@@ -859,19 +859,22 @@ select:hover,
859 859 display: none;
860 860 }
861 861
862 #systemPrompt, .settings textarea, form textarea {
862 #chatPrompt{
863 min-height: 59px;
864 height: 59px;
865 resize: vertical;
866 padding: var(--inner-gap) var(--section-gap);
867 }
868
869 #systemPrompt, #chatPrompt, .settings textarea, form textarea {
863 870 font-size: 15px;
864 871 width: 100%;
865 872 color: var(--colour-3);
866 height: 59px;
867 873 outline: none;
868 padding: var(--inner-gap) var(--section-gap);
869 resize: vertical;
870 min-height: 59px;
871 874 transition: max-height 0.15s ease-out;
872 875 }
873 876
874 #systemPrompt:focus {
877 #systemPrompt:focus, #chatPrompt:focus {
875 878 min-height: 200px;
876 879 max-height: 1000px;
877 880 transition: max-height 0.25s ease-in;
@@ -940,7 +943,7 @@ select:hover,
940 943 body:not(.white) .gradient{
941 944 display: block;
942 945 }
943 .settings .label, form .label, .settings label, form label {
946 .settings .label:not([for="systemPrompt"]), form .label {
944 947 min-width: 200px;
945 948 }
946 949 }
@@ -1126,8 +1129,8 @@ ul {
1126 1129 display: flex;
1127 1130 }
1128 1131
1129 #systemPrompt::placeholder {
1130 text-align: center;
1132 #chatPrompt {
1133 padding-left: 60px;
1131 1134 }
1132 1135
1133 1136 .settings h3 {
@@ -1423,7 +1426,7 @@ form .field.saved .fa-xmark {
1423 1426 }
1424 1427
1425 1428 @media print {
1426 #systemPrompt:placeholder-shown,
1429 #chatPrompt:placeholder-shown,
1427 1430 .conversations,
1428 1431 .conversation .user-input,
1429 1432 .conversation .buttons,
Modified g4f/gui/client/static/js/chat.v1.js +64 -37
@@ -15,7 +15,7 @@ const inputCount = document.getElementById("input-count").querySelector("
15 15 const providerSelect = document.getElementById("provider");
16 16 const modelSelect = document.getElementById("model");
17 17 const modelProvider = document.getElementById("model2");
18 const systemPrompt = document.getElementById("systemPrompt");
18 const chatPrompt = document.getElementById("chatPrompt");
19 19 const settings = document.querySelector(".settings");
20 20 const chat = document.querySelector(".conversation");
21 21 const album = document.querySelector(".images");
@@ -486,10 +486,10 @@ const prepare_messages = (messages, message_index = -1, do_continue = false, do_
486 486
487 487 // Insert system prompt as first message
488 488 new_messages = [];
489 if (systemPrompt?.value) {
489 if (chatPrompt?.value) {
490 490 new_messages.push({
491 491 "role": "system",
492 "content": systemPrompt.value
492 "content": chatPrompt.value
493 493 });
494 494 }
495 495
@@ -625,7 +625,6 @@ async function load_provider_parameters(provider) {
625 625 } else if (["api_key", "proof_token"].includes(key)) {
626 626 input_el.value = input_el.dataset.text;
627 627 }
628 input_el.style.removeProperty("height");
629 628 input_el.style.height = (input_el.scrollHeight) + "px";
630 629 }
631 630 input_el.onblur = () => {
@@ -822,7 +821,6 @@ const ask_gpt = async (message_id, message_index = -1, regenerate = false, provi
822 821 highlight(content_map.inner);
823 822 if (imageInput) imageInput.value = "";
824 823 if (cameraInput) cameraInput.value = "";
825 if (fileInput) fileInput.value = "";
826 824 }
827 825 } catch (e) {
828 826 console.error(e);
@@ -984,8 +982,8 @@ const new_conversation = async () => {
984 982 document.title = window.title || document.title;
985 983
986 984 await clear_conversation();
987 if (systemPrompt) {
988 systemPrompt.value = "";
985 if (chatPrompt) {
986 chatPrompt.value = document.getElementById("systemPrompt")?.value;
989 987 }
990 988 load_conversations();
991 989 hide_sidebar();
@@ -1002,6 +1000,8 @@ function merge_messages(message1, message2) {
1002 1000 }
1003 1001 } else if (newContent.startsWith("...")) {
1004 1002 newContent = " " + newContent.substring(3);
1003 } else if (newContent.startsWith(message1)) {
1004 newContent = newContent.substring(message1.length);
1005 1005 } else {
1006 1006 // Remove duplicate lines
1007 1007 let lines = message1.trim().split("\n");
@@ -1014,9 +1014,8 @@ function merge_messages(message1, message2) {
1014 1014 }
1015 1015 if (foundLastLine != -1) {
1016 1016 newContent = newContent.substring(foundLastLine + lastLine.length);
1017 }
1018 // Remove duplicate words
1019 if (foundLastLine == -1 && newContent.indexOf(" ") > 0) {
1017 } // Remove duplicate words
1018 else if (newContent.indexOf(" ") > 0) {
1020 1019 let words = message1.trim().split(" ");
1021 1020 let lastWord = words[words.length - 1];
1022 1021 if (newContent.startsWith(lastWord)) {
@@ -1049,8 +1048,8 @@ const load_conversation = async (conversation_id, scroll=true) => {
1049 1048 document.title = title;
1050 1049 }
1051 1050
1052 if (systemPrompt) {
1053 systemPrompt.value = conversation.system || "";
1051 if (chatPrompt) {
1052 chatPrompt.value = conversation.system || "";
1054 1053 }
1055 1054
1056 1055 let elements = [];
@@ -1066,7 +1065,8 @@ const load_conversation = async (conversation_id, scroll=true) => {
1066 1065 buffer = "";
1067 1066 }
1068 1067 buffer = buffer.replace(/ \[aborted\]$/g, "").replace(/ \[error\]$/g, "");
1069 buffer += merge_messages(buffer, item.content);
1068 new_content = item.content.replace(/ \[aborted\]$/g, "").replace(/ \[error\]$/g, "");
1069 buffer += merge_messages(buffer, new_content);
1070 1070 last_model = item.provider?.model;
1071 1071 providers.push(item.provider?.name);
1072 1072 let next_i = parseInt(i) + 1;
@@ -1182,7 +1182,7 @@ const load_conversation = async (conversation_id, scroll=true) => {
1182 1182 last_model = last_model?.startsWith("gpt-3") ? "gpt-3.5-turbo" : "gpt-4"
1183 1183 let count_total = GPTTokenizer_cl100k_base?.encodeChat(filtered, last_model).length
1184 1184 if (count_total > 0) {
1185 elements.push(`<div class="count_total">(${count_total} tokens used)</div>`);
1185 elements.push(`<div class="count_total">(${count_total} total tokens)</div>`);
1186 1186 }
1187 1187 }
1188 1188 }
@@ -1243,7 +1243,7 @@ async function add_conversation(conversation_id) {
1243 1243 id: conversation_id,
1244 1244 title: "",
1245 1245 added: Date.now(),
1246 system: systemPrompt?.value,
1246 system: chatPrompt?.value,
1247 1247 items: [],
1248 1248 });
1249 1249 }
@@ -1260,7 +1260,7 @@ async function save_system_message() {
1260 1260 }
1261 1261 const conversation = await get_conversation(window.conversation_id);
1262 1262 if (conversation) {
1263 conversation.system = systemPrompt?.value;
1263 conversation.system = chatPrompt?.value;
1264 1264 await save_conversation(window.conversation_id, conversation);
1265 1265 }
1266 1266 }
@@ -1433,6 +1433,8 @@ window.addEventListener('popstate', hide_sidebar, false);
1433 1433
1434 1434 sidebar_button.addEventListener("click", async () => {
1435 1435 settings.classList.add("hidden");
1436 let provider_forms = document.querySelectorAll(".provider_forms from");
1437 Array.from(provider_forms).forEach((form) => form.classList.add("hidden"));
1436 1438 if (sidebar.classList.contains("shown")) {
1437 1439 await hide_sidebar();
1438 1440 } else {
@@ -1459,37 +1461,55 @@ function open_settings() {
1459 1461 const register_settings_storage = async () => {
1460 1462 const optionElements = document.querySelectorAll(optionElementsSelector);
1461 1463 optionElements.forEach((element) => {
1462 element.name = element.name || element.id;
1463 1464 if (element.type == "textarea") {
1464 1465 element.addEventListener('input', async (event) => {
1465 appStorage.setItem(element.name, element.value);
1466 appStorage.setItem(element.id, element.value);
1466 1467 });
1467 1468 } else {
1468 1469 element.addEventListener('change', async (event) => {
1469 1470 switch (element.type) {
1470 1471 case "checkbox":
1471 appStorage.setItem(element.name, element.checked);
1472 appStorage.setItem(element.id, element.checked);
1472 1473 break;
1473 1474 case "select-one":
1474 appStorage.setItem(element.name, element.value);
1475 appStorage.setItem(element.id, element.value);
1475 1476 break;
1476 1477 case "text":
1477 1478 case "number":
1478 appStorage.setItem(element.name, element.value);
1479 appStorage.setItem(element.id, element.value);
1479 1480 break;
1480 1481 default:
1481 1482 console.warn("Unresolved element type");
1482 1483 }
1483 1484 });
1484 1485 }
1486 if (element.id.endsWith("-api_key")) {
1487 element.addEventListener('focus', async (event) => {
1488 if (element.dataset.value) {
1489 element.value = element.dataset.value
1490 }
1491 });
1492 element.addEventListener('blur', async (event) => {
1493 element.dataset.value = element.value;
1494 if (element.value) {
1495 element.placeholder = element.value && element.value.length >= 22 ? (element.value.substring(0, 12)+"*".repeat(12)+element.value.substring(element.value.length-12)) : "*".repeat(element.value.length);
1496 } else if (element.placeholder != "api_key") {
1497 element.placeholder = "";
1498 }
1499 element.value = ""
1500 });
1501 }
1485 1502 });
1486 1503 }
1487 1504
1488 1505 const load_settings_storage = async () => {
1489 1506 const optionElements = document.querySelectorAll(optionElementsSelector);
1490 1507 optionElements.forEach((element) => {
1491 element.name = element.name || element.id;
1492 if (!(value = appStorage.getItem(element.name))) {
1508 if (element.name && element.name != element.id && (value = appStorage.getItem(element.name))) {
1509 appStorage.setItem(element.id, value);
1510 appStorage.removeItem(element.name);
1511 }
1512 if (!(value = appStorage.getItem(element.id))) {
1493 1513 return;
1494 1514 }
1495 1515 if (value) {
@@ -1503,8 +1523,12 @@ const load_settings_storage = async () => {
1503 1523 case "text":
1504 1524 case "number":
1505 1525 case "textarea":
1506 element.value = value;
1507 break;
1526 if (element.id.endsWith("-api_key")) {
1527 element.placeholder = value && value.length >= 22 ? (value.substring(0, 12)+"*".repeat(12)+value.substring(value.length-12)) : "*".repeat(value.length);
1528 element.dataset.value = value;
1529 } else {
1530 element.value = value;
1531 }
1508 1532 default:
1509 1533 console.warn("Unresolved element type");
1510 1534 }
@@ -1608,12 +1632,12 @@ const count_input = async () => {
1608 1632 }
1609 1633 };
1610 1634 messageInput.addEventListener("keyup", count_input);
1611 systemPrompt.addEventListener("keyup", count_input);
1612 systemPrompt.addEventListener("focus", function() {
1613 countFocus = systemPrompt;
1635 chatPrompt.addEventListener("keyup", count_input);
1636 chatPrompt.addEventListener("focus", function() {
1637 countFocus = chatPrompt;
1614 1638 count_input();
1615 1639 });
1616 systemPrompt.addEventListener("input", function() {
1640 chatPrompt.addEventListener("input", function() {
1617 1641 countFocus = messageInput;
1618 1642 count_input();
1619 1643 });
@@ -1636,6 +1660,7 @@ async function on_load() {
1636 1660 load_conversation(window.conversation_id);
1637 1661 } else {
1638 1662 say_hello()
1663 chatPrompt.value = document.getElementById("systemPrompt")?.value || "";
1639 1664 }
1640 1665 load_conversations();
1641 1666 }
@@ -1746,7 +1771,6 @@ async function on_api() {
1746 1771 option = document.createElement("div");
1747 1772 option.classList.add("field", "box", "hidden");
1748 1773 childs = childs.map((child)=>`${child}-api_key`).join(" ");
1749 console.log(childs);
1750 1774 option.innerHTML = `
1751 1775 <label for="${name}-api_key" class="label" title="">${label}:</label>
1752 1776 <input type="text" id="${name}-api_key" name="${name}[api_key]" class="${childs}" placeholder="api_key"/>
@@ -1785,21 +1809,21 @@ async function on_api() {
1785 1809 const hide_systemPrompt = document.getElementById("hide-systemPrompt")
1786 1810 const slide_systemPrompt_icon = document.querySelector(".slide-systemPrompt i");
1787 1811 if (hide_systemPrompt.checked) {
1788 systemPrompt.classList.add("hidden");
1812 chatPrompt.classList.add("hidden");
1789 1813 slide_systemPrompt_icon.classList.remove("fa-angles-up");
1790 1814 slide_systemPrompt_icon.classList.add("fa-angles-down");
1791 1815 }
1792 1816 hide_systemPrompt.addEventListener('change', async (event) => {
1793 1817 if (event.target.checked) {
1794 systemPrompt.classList.add("hidden");
1818 chatPrompt.classList.add("hidden");
1795 1819 } else {
1796 systemPrompt.classList.remove("hidden");
1820 chatPrompt.classList.remove("hidden");
1797 1821 }
1798 1822 });
1799 1823 document.querySelector(".slide-systemPrompt")?.addEventListener("click", () => {
1800 1824 hide_systemPrompt.click();
1801 1825 const checked = hide_systemPrompt.checked;
1802 systemPrompt.classList[checked ? "add": "remove"]("hidden");
1826 chatPrompt.classList[checked ? "add": "remove"]("hidden");
1803 1827 slide_systemPrompt_icon.classList[checked ? "remove": "add"]("fa-angles-up");
1804 1828 slide_systemPrompt_icon.classList[checked ? "add": "remove"]("fa-angles-down");
1805 1829 });
@@ -1993,7 +2017,7 @@ fileInput.addEventListener('change', async (event) => {
1993 2017 }
1994 2018 });
1995 2019
1996 systemPrompt?.addEventListener("input", async () => {
2020 chatPrompt?.addEventListener("input", async () => {
1997 2021 await save_system_message();
1998 2022 });
1999 2023
@@ -2072,9 +2096,12 @@ async function read_response(response, message_id, provider, scroll) {
2072 2096 function get_api_key_by_provider(provider) {
2073 2097 let api_key = null;
2074 2098 if (provider) {
2075 api_key = document.getElementById(`${provider}-api_key`)?.value || null;
2099 api_key = document.getElementById(`${provider}-api_key`)?.id || null;
2076 2100 if (api_key == null) {
2077 api_key = document.querySelector(`.${provider}-api_key`)?.value || null;
2101 api_key = document.querySelector(`.${provider}-api_key`)?.id || null;
2102 }
2103 if (api_key) {
2104 api_key = appStorage.getItem(api_key);
2078 2105 }
2079 2106 }
2080 2107 return api_key;