From 19bf5b7ef6026069e70b9f1e236cee9112f4718b Mon Sep 17 00:00:00 2001
From: hlohaus <983577+hlohaus@users.noreply.github.com>
Date: Sun, 26 Jan 2025 21:56:31 +0100
Subject: Fix upload files in demo mode Updates for memory with mem0 Fix
asyncio import in nodriver function Add provider specific api endpoints
Support for open settings in UI at /chat/settings
---
g4f/gui/client/index.html | 19 ++++++++----
g4f/gui/client/static/css/style.css | 14 ++++++---
g4f/gui/client/static/js/chat.v1.js | 61 +++++++++++++++++++++++++------------
g4f/gui/server/api.py | 2 +-
g4f/gui/server/backend_api.py | 22 ++++++++-----
g4f/gui/server/website.py | 9 ++++--
6 files changed, 84 insertions(+), 43 deletions(-)
(limited to 'g4f/gui')
diff --git a/g4f/gui/client/index.html b/g4f/gui/client/index.html
index fe6eda18..5c857118 100644
--- a/g4f/gui/client/index.html
+++ b/g4f/gui/client/index.html
@@ -162,6 +162,19 @@
document.getElementById('recognition-language').placeholder = navigator.language;
+
diff --git a/g4f/gui/client/static/css/style.css b/g4f/gui/client/static/css/style.css
index 307fdc3a..45323999 100644
--- a/g4f/gui/client/static/css/style.css
+++ b/g4f/gui/client/static/css/style.css
@@ -221,12 +221,12 @@ body:not(.white) a:visited{
background-color: var(--blur-bg);
}
-.conversations i, .bottom_buttons i {
+.conversations i, .bottom_buttons i, .mem0 button i {
color: var(--conversations);
cursor: pointer;
}
-.bottom_buttons i {
+.bottom_buttons i, .mem0 button i {
width: 14px;
}
@@ -998,7 +998,7 @@ select:hover,
margin: 4px 0;
}
-.bottom_buttons button {
+.bottom_buttons button, .mem0 button {
padding: 8px 12px;
display: flex;
gap: 18px;
@@ -1011,10 +1011,15 @@ select:hover,
width: 100%;
}
+.mem0 button {
+ width: auto;
+}
+
.bottom_buttons button a,
.bottom_buttons button span,
.bottom_buttons .info a,
-.bottom_buttons .info i {
+.bottom_buttons .info i,
+.mem0 button span {
color: var(--colour-3);
font-weight: 500;
}
@@ -1129,7 +1134,6 @@ ul {
padding-left: 10px;
padding-top: 10px;
}
-
@media screen and (max-width: 990px) {
.conversations {
display: none;
diff --git a/g4f/gui/client/static/js/chat.v1.js b/g4f/gui/client/static/js/chat.v1.js
index 77d6075a..01c2e539 100644
--- a/g4f/gui/client/static/js/chat.v1.js
+++ b/g4f/gui/client/static/js/chat.v1.js
@@ -1533,7 +1533,7 @@ async function hide_sidebar() {
chat.classList.remove("hidden");
log_storage.classList.add("hidden");
await hide_settings();
- if (window.location.pathname == "/menu/" || window.location.pathname == "/settings/") {
+ if (window.location.pathname.endsWith("/menu/") || window.location.pathname.endsWith("/settings/")) {
history.back();
}
}
@@ -1550,10 +1550,7 @@ sidebar_button.addEventListener("click", async () => {
if (sidebar.classList.contains("shown")) {
await hide_sidebar();
} else {
- sidebar.classList.add("shown");
- sidebar_button.classList.add("rotated");
- await hide_settings();
- add_url_to_history("/menu/");
+ await show_menu();
}
window.scrollTo(0, 0);
});
@@ -1564,12 +1561,19 @@ function add_url_to_history(url) {
}
}
+async function show_menu() {
+ sidebar.classList.add("shown");
+ sidebar_button.classList.add("rotated");
+ await hide_settings();
+ add_url_to_history("/chat/menu/");
+}
+
function open_settings() {
if (settings.classList.contains("hidden")) {
chat.classList.add("hidden");
sidebar.classList.remove("shown");
settings.classList.remove("hidden");
- add_url_to_history("/settings/");
+ add_url_to_history("/chat/settings/");
} else {
settings.classList.add("hidden");
chat.classList.remove("hidden");
@@ -1782,7 +1786,9 @@ window.addEventListener('pywebviewready', async function() {
async function on_load() {
count_input();
- if (/\/chat\/[^?]+/.test(window.location.href)) {
+ if (/\/settings\//.test(window.location.href)) {
+ open_settings();
+ } else if (/\/chat\/[^?]+/.test(window.location.href)) {
load_conversation(window.conversation_id);
} else {
chatPrompt.value = document.getElementById("systemPrompt")?.value || "";
@@ -1878,7 +1884,7 @@ async function on_api() {
}
providerSelect.innerHTML = ''
document.getElementById("pin").disabled = true;
- document.getElementById("refine")?.parentElement.remove();
+ document.getElementById("refine")?.parentElement.classList.add("hidden")
const track_usage = document.getElementById("track_usage");
track_usage.checked = true;
track_usage.disabled = true;
@@ -2099,7 +2105,7 @@ async function upload_files(fileInput) {
body: formData
});
- let do_refine = document.getElementById("refine").checked;
+ let do_refine = document.getElementById("refine")?.checked;
function connectToSSE(url) {
const eventSource = new EventSource(url);
eventSource.onmessage = (event) => {
@@ -2417,7 +2423,18 @@ function save_storage() {
}
function import_memory() {
+ if (!appStorage.getItem("mem0-api_key")) {
+ return;
+ }
hide_sidebar();
+
+ let count = 0;
+ let user_id = appStorage.getItem("user") || appStorage.getItem("mem0-user_id");
+ if (!user_id) {
+ user_id = uuid();
+ appStorage.setItem("mem0-user_id", user_id);
+ }
+ inputCount.innerText = `Start importing to Mem0...`;
let conversations = [];
for (let i = 0; i < appStorage.length; i++) {
if (appStorage.key(i).startsWith("conversation:")) {
@@ -2426,17 +2443,21 @@ function import_memory() {
}
}
conversations.sort((a, b) => (a.updated||0)-(b.updated||0));
- let count = 0;
- conversations.forEach(async (conversation)=>{
- let body = JSON.stringify(conversation);
- response = await fetch("/backend-api/v2/memory", {
- method: 'POST',
- body: body,
- headers: {"content-type": "application/json"}
- });
- const result = await response.json();
- count += result.count;
- inputCount.innerText = `${count} Messages are imported`;
+ conversations.forEach(async (conversation, i)=>{
+ setTimeout(async ()=>{
+ let body = JSON.stringify(conversation);
+ response = await fetch(`/backend-api/v2/memory/${user_id}`, {
+ method: 'POST',
+ body: body,
+ headers: {
+ "content-type": "application/json",
+ "x_api_key": appStorage.getItem("mem0-api_key")
+ }
+ });
+ const result = await response.json();
+ count += result.count;
+ inputCount.innerText = `${count} Messages were imported`;
+ }, (i+1)*1000);
});
}
diff --git a/g4f/gui/server/api.py b/g4f/gui/server/api.py
index a21f7128..21c11988 100644
--- a/g4f/gui/server/api.py
+++ b/g4f/gui/server/api.py
@@ -42,7 +42,7 @@ class Api:
if provider in ProviderUtils.convert:
provider = ProviderUtils.convert[provider]
if issubclass(provider, ProviderModelMixin):
- if api_key is not None and "api_key" in signature(provider.get_models).parameters:
+ if "api_key" in signature(provider.get_models).parameters:
models = provider.get_models(api_key=api_key, api_base=api_base)
else:
models = provider.get_models()
diff --git a/g4f/gui/server/backend_api.py b/g4f/gui/server/backend_api.py
index 1789fbc9..34635b44 100644
--- a/g4f/gui/server/backend_api.py
+++ b/g4f/gui/server/backend_api.py
@@ -171,16 +171,16 @@ class Backend_Api(Api):
f.write(f"{json.dumps(request.json)}\n")
return {}
- @app.route('/backend-api/v2/memory', methods=['POST'])
- def add_memory():
+ @app.route('/backend-api/v2/memory/', methods=['POST'])
+ def add_memory(user_id: str):
api_key = request.headers.get("x_api_key")
json_data = request.json
from mem0 import MemoryClient
client = MemoryClient(api_key=api_key)
client.add(
[{"role": item["role"], "content": item["content"]} for item in json_data.get("items")],
- user_id="user",
- metadata={"conversation_id": json_data.get("id"), "title": json_data.get("title")}
+ user_id=user_id,
+ metadata={"conversation_id": json_data.get("id")}
)
return {"count": len(json_data.get("items"))}
@@ -189,13 +189,19 @@ class Backend_Api(Api):
api_key = request.headers.get("x_api_key")
from mem0 import MemoryClient
client = MemoryClient(api_key=api_key)
- if request.args.search:
+ if request.args.get("search"):
return client.search(
- request.args.search,
+ request.args.get("search"),
user_id=user_id,
- metadata=json.loads(request.args.metadata) if request.args.metadata else None
+ filters=json.loads(request.args.get("filters", "null")),
+ metadata=json.loads(request.args.get("metadata", "null"))
)
- return {}
+ return client.get_all(
+ user_id=user_id,
+ page=request.args.get("page", 1),
+ page_size=request.args.get("page_size", 100),
+ filters=json.loads(request.args.get("filters", "null")),
+ )
self.routes = {
'/backend-api/v2/version': {
diff --git a/g4f/gui/server/website.py b/g4f/gui/server/website.py
index 1382cb35..d89902da 100644
--- a/g4f/gui/server/website.py
+++ b/g4f/gui/server/website.py
@@ -16,12 +16,12 @@ class Website:
'function': self._chat,
'methods': ['GET', 'POST']
},
- '/menu/': {
+ '/chat/menu/': {
'function': redirect_home,
'methods': ['GET', 'POST']
},
- '/settings/': {
- 'function': redirect_home,
+ '/chat/settings/': {
+ 'function': self._settings,
'methods': ['GET', 'POST']
},
'/images/': {
@@ -36,4 +36,7 @@ class Website:
return render_template('index.html', chat_id=conversation_id)
def _index(self):
+ return render_template('index.html', chat_id=str(uuid.uuid4()))
+
+ def _settings(self):
return render_template('index.html', chat_id=str(uuid.uuid4()))
\ No newline at end of file
--
cgit v1.2.3