123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- 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:
- 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)
|