summaryrefslogtreecommitdiffstats
path: root/g4f/Provider/selenium
diff options
context:
space:
mode:
Diffstat (limited to 'g4f/Provider/selenium')
-rw-r--r--g4f/Provider/selenium/Phind.py104
-rw-r--r--g4f/Provider/selenium/__init__.py1
2 files changed, 105 insertions, 0 deletions
diff --git a/g4f/Provider/selenium/Phind.py b/g4f/Provider/selenium/Phind.py
new file mode 100644
index 00000000..b9a37f97
--- /dev/null
+++ b/g4f/Provider/selenium/Phind.py
@@ -0,0 +1,104 @@
+from __future__ import annotations
+
+import time
+from urllib.parse import quote
+
+from ...typing import CreateResult, Messages
+from ..base_provider import BaseProvider
+from ..helper import format_prompt
+from ..webdriver import WebDriver, WebDriverSession
+
+class Phind(BaseProvider):
+ url = "https://www.phind.com"
+ working = True
+ supports_gpt_4 = True
+ supports_stream = True
+
+ @classmethod
+ def create_completion(
+ cls,
+ model: str,
+ messages: Messages,
+ stream: bool,
+ proxy: str = None,
+ timeout: int = 120,
+ webdriver: WebDriver = None,
+ creative_mode: bool = None,
+ **kwargs
+ ) -> CreateResult:
+ driver.start_session
+ with WebDriverSession(webdriver, "", proxy=proxy) as driver:
+ from selenium.webdriver.common.by import By
+ from selenium.webdriver.support.ui import WebDriverWait
+ from selenium.webdriver.support import expected_conditions as EC
+
+ # Register fetch hook
+ source = """
+window._fetch = window.fetch;
+window.fetch = async (url, options) => {
+ const response = await window._fetch(url, options);
+ if (url != "/api/infer/answer") {
+ return response;
+ }
+ copy = response.clone();
+ window._reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
+ return copy;
+}
+"""
+ driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
+ "source": source
+ })
+
+ prompt = quote(format_prompt(messages))
+ driver.get(f"{cls.url}/search?q={prompt}&source=searchbox")
+
+ # Need to change settings
+ wait = WebDriverWait(driver, timeout)
+ def open_dropdown():
+ # Open settings dropdown
+ wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "button.text-dark.dropdown-toggle")))
+ driver.find_element(By.CSS_SELECTOR, "button.text-dark.dropdown-toggle").click()
+ # Wait for dropdown toggle
+ wait.until(EC.visibility_of_element_located((By.XPATH, "//button[text()='GPT-4']")))
+ if model.startswith("gpt-4") or creative_mode:
+ # Enable GPT-4
+ if model.startswith("gpt-4"):
+ open_dropdown()
+ driver.find_element(By.XPATH, "//button[text()='GPT-4']").click()
+ # Enable creative mode
+ if creative_mode or creative_mode == None:
+ open_dropdown()
+ driver.find_element(By.ID, "Creative Mode").click()
+ # Submit changes
+ driver.find_element(By.CSS_SELECTOR, ".search-bar-input-group button[type='submit']").click()
+ # Wait for page reload
+ wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".search-container")))
+
+ while True:
+ chunk = driver.execute_script("""
+if(window._reader) {
+ chunk = await window._reader.read();
+ if (chunk['done']) {
+ return null;
+ }
+ content = '';
+ chunk['value'].split('\\r\\n').forEach((line, index) => {
+ if (line.startsWith('data: ')) {
+ line = line.substring('data: '.length);
+ if (!line.startsWith('<PHIND_METADATA>')) {
+ if (line) content += line;
+ else content += '\\n';
+ }
+ }
+ });
+ return content.replace('\\n\\n', '\\n');
+} else {
+ return ''
+}
+""")
+ if chunk:
+ yield chunk
+ elif chunk != "":
+ break
+ 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
new file mode 100644
index 00000000..80c48d14
--- /dev/null
+++ b/g4f/Provider/selenium/__init__.py
@@ -0,0 +1 @@
+from .Phind import Phind \ No newline at end of file