diff options
Diffstat (limited to 'g4f/Provider/selenium')
-rw-r--r-- | g4f/Provider/selenium/Bard.py | 80 | ||||
-rw-r--r-- | g4f/Provider/selenium/__init__.py | 3 |
2 files changed, 82 insertions, 1 deletions
diff --git a/g4f/Provider/selenium/Bard.py b/g4f/Provider/selenium/Bard.py new file mode 100644 index 00000000..459f6f37 --- /dev/null +++ b/g4f/Provider/selenium/Bard.py @@ -0,0 +1,80 @@ +from __future__ import annotations + +import time +import os + +try: + from selenium.webdriver.common.by import By + from selenium.webdriver.support.ui import WebDriverWait + from selenium.webdriver.support import expected_conditions as EC +except ImportError: + pass + +from ...typing import CreateResult, Messages +from ..base_provider import AbstractProvider +from ..helper import format_prompt +from ...webdriver import WebDriver, WebDriverSession, element_send_text + + +class Bard(AbstractProvider): + url = "https://bard.google.com" + working = True + needs_auth = True + webdriver = True + + @classmethod + def create_completion( + cls, + model: str, + messages: Messages, + stream: bool, + proxy: str = None, + webdriver: WebDriver = None, + user_data_dir: str = None, + headless: bool = True, + **kwargs + ) -> CreateResult: + prompt = format_prompt(messages) + session = WebDriverSession(webdriver, user_data_dir, headless, proxy=proxy) + with session as driver: + try: + driver.get(f"{cls.url}/chat") + wait = WebDriverWait(driver, 10 if headless else 240) + wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.ql-editor.textarea"))) + except: + # Reopen browser for login + if not webdriver: + driver = session.reopen() + driver.get(f"{cls.url}/chat") + login_url = os.environ.get("G4F_LOGIN_URL") + if login_url: + yield f"Please login: [Google Bard]({login_url})\n\n" + wait = WebDriverWait(driver, 240) + wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.ql-editor.textarea"))) + else: + raise RuntimeError("Prompt textarea not found. You may not be logged in.") + + # Add hook in XMLHttpRequest + script = """ +const _http_request_open = XMLHttpRequest.prototype.open; +window._message = ""; +XMLHttpRequest.prototype.open = function(method, url) { + if (url.includes("/assistant.lamda.BardFrontendService/StreamGenerate")) { + this.addEventListener("load", (event) => { + window._message = JSON.parse(JSON.parse(this.responseText.split("\\n")[3])[0][2])[4][0][1][0]; + }); + } + return _http_request_open.call(this, method, url); +} +""" + driver.execute_script(script) + + element_send_text(driver.find_element(By.CSS_SELECTOR, "div.ql-editor.textarea"), prompt) + + while True: + chunk = driver.execute_script("return window._message;") + if chunk: + yield chunk + return + else: + time.sleep(0.1)
\ No newline at end of file diff --git a/g4f/Provider/selenium/__init__.py b/g4f/Provider/selenium/__init__.py index a8c18a49..9a020460 100644 --- a/g4f/Provider/selenium/__init__.py +++ b/g4f/Provider/selenium/__init__.py @@ -2,4 +2,5 @@ from .AItianhuSpace import AItianhuSpace from .MyShell import MyShell from .PerplexityAi import PerplexityAi from .Phind import Phind -from .TalkAi import TalkAi
\ No newline at end of file +from .TalkAi import TalkAi +from .Bard import Bard
\ No newline at end of file |