summaryrefslogtreecommitdiffstats
path: root/g4f/gui
diff options
context:
space:
mode:
Diffstat (limited to 'g4f/gui')
-rw-r--r--g4f/gui/client/index.html5
-rw-r--r--g4f/gui/client/static/css/style.css11
-rw-r--r--g4f/gui/client/static/js/chat.v1.js19
-rw-r--r--g4f/gui/server/api.py12
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))