summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md32
-rw-r--r--g4f/Provider/Bing.py2
-rw-r--r--g4f/gui/client/static/js/chat.v1.js16
-rw-r--r--g4f/gui/server/api.py8
-rw-r--r--g4f/gui/webview.py3
-rw-r--r--requirements.txt8
-rw-r--r--setup.py18
7 files changed, 59 insertions, 28 deletions
diff --git a/README.md b/README.md
index 451ec57d..c07a1d4b 100644
--- a/README.md
+++ b/README.md
@@ -41,7 +41,7 @@ As per the survey, here is a list of improvements to come
- [ ] 🚧 Improve Documentation (in /docs & Guides, Howtos, & Do video tutorials)
- [x] Improve the provider status list & updates
- [ ] Tutorials on how to reverse sites to write your own wrapper (PoC only ofc)
-- [ ] Improve the Bing wrapper. (might write a new wrapper in golang as it is very fast)
+- [x] Improve the Bing wrapper. (Wait and Retry or reuse conversation)
- [ ] Write a standard provider performance test to improve the stability
- [ ] Potential support and development of local models
- [ ] 🚧 Improve compatibility and error handling
@@ -170,7 +170,33 @@ image_url = response.data[0].url
- New Client API like the OpenAI Python library: [/docs/client](/docs/client.md)
- Legacy API with python modules: [/docs/legacy](/docs/legacy.md)
-#### Web UI
+### Webview GUI
+
+Open the GUI in a window of your OS. Runs on a local/static/ssl server with a js api. Supports login into the OpenAI Chat, Image Upload and streamed Text Generation.
+
+Supports all platforms, but only Linux tested.
+
+1. Install all requirements with:
+
+```bash
+pip install g4f[webview]
+```
+
+2. Follow the OS specific steps here:
+ [pywebview installation](https://pywebview.flowrl.com/guide/installation.html#dependencies)
+
+3. Run the app with:
+
+```python
+from g4f.gui.webview import run_webview
+run_webview(debug=True)
+```
+or execute the following command:
+```bash
+python -m g4f.gui.webview -debug
+```
+
+#### Webserver
To start the web interface, type the following codes in python:
@@ -237,7 +263,7 @@ set G4F_PROXY=http://host:port
| [bing.com](https://bing.com/chat) | `g4f.Provider.Bing` | ❌ | ✔️ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ |
| [chatgpt.ai](https://chatgpt.ai) | `g4f.Provider.ChatgptAi` | ❌ | ✔️ | ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ❌ |
| [liaobots.site](https://liaobots.site) | `g4f.Provider.Liaobots` | ✔️ | ✔️ | ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ❌ |
-| [chat.openai.com](https://chat.openai.com) | `g4f.Provider.OpenaiChat` | ✔️ | ✔️ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ✔️ |
+| [chat.openai.com](https://chat.openai.com) | `g4f.Provider.OpenaiChat` | ✔️ | ❌ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ✔️ |
| [raycast.com](https://raycast.com) | `g4f.Provider.Raycast` | ✔️ | ✔️ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ✔️ |
| [beta.theb.ai](https://beta.theb.ai) | `g4f.Provider.Theb` | ✔️ | ✔️ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ |
| [you.com](https://you.com) | `g4f.Provider.You` | ✔️ | ✔️ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ |
diff --git a/g4f/Provider/Bing.py b/g4f/Provider/Bing.py
index a1d14d87..f8b06dd1 100644
--- a/g4f/Provider/Bing.py
+++ b/g4f/Provider/Bing.py
@@ -414,7 +414,7 @@ async def stream_generate(
image_request = await upload_image(
session,
image,
- "Balanced" if Tones.copilot == "Copilot" else tone,
+ "Balanced" if tone == Tones.copilot else tone,
headers
) if image else None
async with session.ws_connect(
diff --git a/g4f/gui/client/static/js/chat.v1.js b/g4f/gui/client/static/js/chat.v1.js
index bcef4a78..f9bc4568 100644
--- a/g4f/gui/client/static/js/chat.v1.js
+++ b/g4f/gui/client/static/js/chat.v1.js
@@ -240,26 +240,26 @@ async function add_message_chunk(message) {
}
}
-cameraInput?.addEventListener("click", (e) => {
- if (window?.pywebview) {
- e.preventDefault();
- pywebview.api.choose_file();
- }
-})
+// fileInput?.addEventListener("click", (e) => {
+// if (window?.pywebview) {
+// e.preventDefault();
+// pywebview.api.choose_file();
+// }
+// });
cameraInput?.addEventListener("click", (e) => {
if (window?.pywebview) {
e.preventDefault();
pywebview.api.take_picture();
}
-})
+});
imageInput?.addEventListener("click", (e) => {
if (window?.pywebview) {
e.preventDefault();
pywebview.api.choose_image();
}
-})
+});
const ask_gpt = async () => {
regenerate.classList.add(`regenerate-hidden`);
diff --git a/g4f/gui/server/api.py b/g4f/gui/server/api.py
index 3adb88f4..e7683812 100644
--- a/g4f/gui/server/api.py
+++ b/g4f/gui/server/api.py
@@ -19,12 +19,12 @@ try:
filters=[["Image", "*.jpg", "*.jpeg", "*.png", "*.webp", "*.svg"]],
)
has_plyer = True
-except (ImportError, NameError):
+except ImportError:
has_plyer = False
try:
from android.runnable import run_on_ui_thread
- from android.storage import app_storage_path
- from android.permissions import request_permissions, Permission
+ import android.permissions
+ from android.permissions import Permission
from android.permissions import _RequestPermissionsManager
_RequestPermissionsManager.register_callback()
from .android_gallery import user_select_image
@@ -161,7 +161,7 @@ class Api():
def request_permissions(self):
if has_android:
- request_permissions([
+ android.permissions.request_permissions([
Permission.CAMERA,
Permission.READ_EXTERNAL_STORAGE,
Permission.WRITE_EXTERNAL_STORAGE
diff --git a/g4f/gui/webview.py b/g4f/gui/webview.py
index 36ad0e60..b015dbed 100644
--- a/g4f/gui/webview.py
+++ b/g4f/gui/webview.py
@@ -16,6 +16,7 @@ import g4f.debug
def run_webview(
debug: bool = False,
+ ssl: bool = True,
storage_path: str = None
):
if getattr(sys, 'frozen', False):
@@ -36,7 +37,7 @@ def run_webview(
private_mode=False,
storage_path=storage_path,
debug=debug,
- ssl=True
+ ssl=ssl
)
if __name__ == "__main__":
diff --git a/requirements.txt b/requirements.txt
index def8c7e3..671b2394 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -14,11 +14,9 @@ platformdirs
fastapi
uvicorn
flask
-py-arkose-generator
-undetected-chromedriver>=3.5.5
brotli
beautifulsoup4
-setuptools
aiohttp_socks
-selenium-wire
-gpt4all \ No newline at end of file
+gpt4all
+pywebview
+plyer \ No newline at end of file
diff --git a/setup.py b/setup.py
index b6c106c4..fa997b50 100644
--- a/setup.py
+++ b/setup.py
@@ -18,23 +18,24 @@ EXTRA_REQUIRE = {
'all': [
"curl_cffi>=0.6.2",
"certifi",
- "async-property", # openai
- "py-arkose-generator", # openai
+ #"py-arkose-generator", # not working
"browser_cookie3", # get_cookies
"PyExecJS", # GptForLove
"duckduckgo-search>=5.0" ,# internet.search
"beautifulsoup4", # internet.search and bing.create_images
"brotli", # openai
- "platformdirs", # webdriver
- "undetected-chromedriver>=3.5.5", # webdriver
- "setuptools", # webdriver
+ #"undetected-chromedriver>=3.5.5", # webdriver
+ #"setuptools", # webdriver
+ "pywebview",
+ "platformdirs",
+ "plyer",
"aiohttp_socks", # proxy
"pillow", # image
"cairosvg", # svg image
"werkzeug", "flask", # gui
"loguru", "fastapi",
"uvicorn", "nest_asyncio", # api
- "selenium-wire"
+ #"selenium-wire"
],
"image": [
"pillow",
@@ -47,6 +48,11 @@ EXTRA_REQUIRE = {
"setuptools",
"selenium-wire"
],
+ "webview": [
+ "webview",
+ "platformdirs",
+ "plyer"
+ ],
"openai": [
"async-property",
"py-arkose-generator",