diff options
Diffstat (limited to 'g4f/gui')
-rw-r--r-- | g4f/gui/client/index.html | 5 | ||||
-rw-r--r-- | g4f/gui/client/static/css/style.css | 11 | ||||
-rw-r--r-- | g4f/gui/client/static/js/chat.v1.js | 19 | ||||
-rw-r--r-- | g4f/gui/server/api.py | 12 |
4 files changed, 45 insertions, 2 deletions
diff --git a/g4f/gui/client/index.html b/g4f/gui/client/index.html index b256b0be..3a2197de 100644 --- a/g4f/gui/client/index.html +++ b/g4f/gui/client/index.html @@ -170,6 +170,10 @@ <i class="fa-solid fa-download"></i> <a href="" onclick="return false;">Export Conversations</a> </button> + <button id="showLog"> + <i class="fa-solid fa-terminal"></i> + <a href="" onclick="return false;">Show log</a> + </button> </div> </div> <div class="conversation"> @@ -257,6 +261,7 @@ </div> </div> </div> + <div class="log hidden"></div> </div> <div class="mobile-sidebar"> <i class="fa-solid fa-bars"></i> diff --git a/g4f/gui/client/static/css/style.css b/g4f/gui/client/static/css/style.css index 3ee033ea..8364216a 100644 --- a/g4f/gui/client/static/css/style.css +++ b/g4f/gui/client/static/css/style.css @@ -1051,13 +1051,22 @@ a:-webkit-any-link { padding: var(--inner-gap) var(--inner-gap) var(--inner-gap) 0; } -.settings, .images { +.settings, .log { width: 100%; display: flex; flex-direction: column; overflow: auto; } +.log { + white-space: pre-wrap; + font-family: Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier, monospace; +} + +.log.hidden { + display: none; +} + .settings .paper { flex-direction: column; min-width: 400px; diff --git a/g4f/gui/client/static/js/chat.v1.js b/g4f/gui/client/static/js/chat.v1.js index 9f6103fb..51bf8b81 100644 --- a/g4f/gui/client/static/js/chat.v1.js +++ b/g4f/gui/client/static/js/chat.v1.js @@ -19,6 +19,7 @@ const systemPrompt = document.getElementById("systemPrompt"); const settings = document.querySelector(".settings"); const chat = document.querySelector(".conversation"); const album = document.querySelector(".images"); +const log_storage = document.querySelector(".log"); const optionElements = document.querySelectorAll(".settings input, .settings textarea, #model, #model2, #provider") @@ -400,6 +401,9 @@ async function add_message_chunk(message, message_index) { error_storage[message_index] = message.error console.error(message.error); content_map.inner.innerHTML += `<p><strong>An error occured:</strong> ${message.error}</p>`; + let p = document.createElement("p"); + p.innerText = message.error; + log_storage.appendChild(p); } else if (message.type == "preview") { content_map.inner.innerHTML = markdown_render(message.preview); } else if (message.type == "content") { @@ -419,6 +423,10 @@ async function add_message_chunk(message, message_index) { content_map.inner.innerHTML = html; content_map.count.innerText = count_words_and_tokens(message_storage[message_index], provider_storage[message_index]?.model); highlight(content_map.inner); + } else if (message.type == "log") { + let p = document.createElement("p"); + p.innerText = message.log; + log_storage.appendChild(p); } window.scrollTo(0, 0); if (message_box.scrollTop >= message_box.scrollHeight - message_box.clientHeight - 100) { @@ -517,7 +525,7 @@ const ask_gpt = async (message_index = -1, message_id) => { } } delete controller_storage[message_index]; - if (!error && message_storage[message_index]) { + if (!error_storage[message_index] && message_storage[message_index]) { const message_provider = message_index in provider_storage ? provider_storage[message_index] : null; await add_message(window.conversation_id, "assistant", message_storage[message_index], message_provider); await safe_load_conversation(window.conversation_id); @@ -635,6 +643,7 @@ const set_conversation = async (conversation_id) => { await load_conversation(conversation_id); load_conversations(); hide_sidebar(); + log_storage.classList.add("hidden"); }; const new_conversation = async () => { @@ -647,6 +656,7 @@ const new_conversation = async () => { } load_conversations(); hide_sidebar(); + log_storage.classList.add("hidden"); say_hello(); }; @@ -945,6 +955,7 @@ function open_settings() { settings.classList.add("hidden"); chat.classList.remove("hidden"); } + log_storage.classList.add("hidden"); } function open_album() { @@ -1476,3 +1487,9 @@ if (SpeechRecognition) { } }); } + +document.getElementById("showLog").addEventListener("click", ()=> { + log_storage.classList.remove("hidden"); + settings.classList.add("hidden"); + log_storage.scrollTop = log_storage.scrollHeight; +});
\ No newline at end of file diff --git a/g4f/gui/server/api.py b/g4f/gui/server/api.py index ed8454c3..a6c4bef4 100644 --- a/g4f/gui/server/api.py +++ b/g4f/gui/server/api.py @@ -18,6 +18,7 @@ from g4f.requests.aiohttp import get_connector from g4f.Provider import ProviderType, __providers__, __map__ from g4f.providers.base_provider import ProviderModelMixin, FinishReason from g4f.providers.conversation import BaseConversation +from g4f import debug logger = logging.getLogger(__name__) @@ -140,6 +141,13 @@ class Api: } def _create_response_stream(self, kwargs: dict, conversation_id: str, provider: str) -> Iterator: + if debug.logging: + logs = [] + print_callback = debug.log_handler + def log_handler(text: str): + logs.append(text) + print_callback(text) + debug.log_handler = log_handler try: result = ChatCompletion.create(**kwargs) first = True @@ -168,6 +176,10 @@ class Api: yield self._format_json("content", str(ImageResponse(images, chunk.alt))) elif not isinstance(chunk, FinishReason): yield self._format_json("content", str(chunk)) + if logs: + for log in logs: + yield self._format_json("log", str(log)) + logs = [] except Exception as e: logger.exception(e) yield self._format_json('error', get_error_message(e)) |