XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 1
返回提交历史

XFEstudio/gpt4free

Fix Phind and GptGo Provider

ea3cb0d5
Heiner Lohaus <hlohaus@users.noreply.github.com>
提交于

代码差异

5 个文件 +188 -131
Modified g4f/Provider/GptGo.py +19 -39
@@ -2,6 +2,7 @@ from __future__ import annotations
2 2
3 3 from aiohttp import ClientSession
4 4 import json
5 import base64
5 6
6 7 from ..typing import AsyncResult, Messages
7 8 from .base_provider import AsyncGeneratorProvider, format_prompt
@@ -23,9 +24,12 @@ class GptGo(AsyncGeneratorProvider):
23 24 headers = {
24 25 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36",
25 26 "Accept": "*/*",
26 "Accept-language": "en,fr-FR;q=0.9,fr;q=0.8,es-ES;q=0.7,es;q=0.6,en-US;q=0.5,am;q=0.4,de;q=0.3",
27 "Accept-language": "en-US",
27 28 "Origin": cls.url,
28 29 "Referer": f"{cls.url}/",
30 "sec-ch-ua": '"Google Chrome";v="116", "Chromium";v="116", "Not?A_Brand";v="24"',
31 "sec-ch-ua-mobile": "?0",
32 "sec-ch-ua-platform": '"Windows"',
29 33 "Sec-Fetch-Dest": "empty",
30 34 "Sec-Fetch-Mode": "cors",
31 35 "Sec-Fetch-Site": "same-origin",
@@ -33,50 +37,26 @@ class GptGo(AsyncGeneratorProvider):
33 37 async with ClientSession(
34 38 headers=headers
35 39 ) as session:
36 async with session.get(
37 "https://gptgo.ai/action_get_token.php",
38 params={
39 "q": format_prompt(messages),
40 "hlgpt": "default",
41 "hl": "en"
42 },
40 async with session.post(
41 "https://gptgo.ai/get_token.php",
42 data={"ask": format_prompt(messages)},
43 43 proxy=proxy
44 44 ) as response:
45 45 response.raise_for_status()
46 token = (await response.json(content_type=None))["token"]
46 token = await response.text();
47 token = base64.b64decode(token[10:-20]).decode()
47 48
48 49 async with session.get(
49 "https://gptgo.ai/action_ai_gpt.php",
50 params={
51 "token": token,
52 },
53 proxy=proxy
54 ) as response:
50 "https://api.gptgo.ai/web.php",
51 params={"array_chat": token},
52 proxy=proxy
53 ) as response:
55 54 response.raise_for_status()
56 start = "data: "
57 55 async for line in response.content:
58 line = line.decode()
59 if line.startswith("data: "):
60 if line.startswith("data: [DONE]"):
61 break
62 line = json.loads(line[len(start):-1])
63 if line["choices"][0]["finish_reason"] == "stop":
64 break
65
56 if line.startswith(b"data: [DONE]"):
57 break
58 if line.startswith(b"data: "):
59 line = json.loads(line[6:])
66 60 content = line["choices"][0]["delta"].get("content")
67 if content:
61 if content and content != "\n#GPTGO ":
68 62 yield content
69
70
71 @classmethod
72 @property
73 def params(cls):
74 params = [
75 ("model", "str"),
76 ("messages", "list[dict[str, str]]"),
77 ("stream", "bool"),
78 ("proxy", "str"),
79 ("temperature", "float"),
80 ]
81 param = ", ".join([": ".join(p) for p in params])
82 return f"g4f.provider.{cls.__name__} supports: ({param})"
Modified g4f/Provider/Phind.py +57 -86
@@ -1,103 +1,74 @@
1 1 from __future__ import annotations
2 2
3 import time
4 from urllib.parse import quote
3 from datetime import datetime
5 4
6 from ..typing import CreateResult, Messages
7 from .base_provider import BaseProvider
8 from .helper import format_prompt
9 from .webdriver import WebDriver, WebDriverSession
5 from ..typing import AsyncResult, Messages
6 from .base_provider import AsyncGeneratorProvider
7 from ..requests import StreamSession
10 8
11 class Phind(BaseProvider):
9 class Phind(AsyncGeneratorProvider):
12 10 url = "https://www.phind.com"
13 11 working = True
14 12 supports_gpt_4 = True
15 13 supports_stream = True
14 supports_message_history = True
16 15
17 16 @classmethod
18 def create_completion(
17 async def create_async_generator(
19 18 cls,
20 19 model: str,
21 20 messages: Messages,
22 stream: bool,
23 21 proxy: str = None,
24 22 timeout: int = 120,
25 webdriver: WebDriver = None,
26 creative_mode: bool = None,
23 creative_mode: bool = False,
27 24 **kwargs
28 ) -> CreateResult:
29 with WebDriverSession(webdriver, "", proxy=proxy) as driver:
30 from selenium.webdriver.common.by import By
31 from selenium.webdriver.support.ui import WebDriverWait
32 from selenium.webdriver.support import expected_conditions as EC
33
34 prompt = quote(format_prompt(messages))
35 driver.get(f"{cls.url}/search?q={prompt}&source=searchbox")
36
37 # Register fetch hook
38 source = """
39 window._fetch = window.fetch;
40 window.fetch = async (url, options) => {
41 const response = await window._fetch(url, options);
42 if (url != "/api/infer/answer") {
43 return response;
44 }
45 copy = response.clone();
46 window._reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
47 return copy;
48 }
49 """
50 driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
51 "source": source
52 })
53
54 # Need to change settings
55 wait = WebDriverWait(driver, timeout)
56 def open_dropdown():
57 # Open settings dropdown
58 wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "button.text-dark.dropdown-toggle")))
59 driver.find_element(By.CSS_SELECTOR, "button.text-dark.dropdown-toggle").click()
60 # Wait for dropdown toggle
61 wait.until(EC.visibility_of_element_located((By.XPATH, "//button[text()='GPT-4']")))
62 if model.startswith("gpt-4") or creative_mode:
63 # Enable GPT-4
64 if model.startswith("gpt-4"):
65 open_dropdown()
66 driver.find_element(By.XPATH, "//button[text()='GPT-4']").click()
67 # Enable creative mode
68 if creative_mode or creative_mode == None:
69 open_dropdown()
70 driver.find_element(By.ID, "Creative Mode").click()
71 # Submit changes
72 driver.find_element(By.CSS_SELECTOR, ".search-bar-input-group button[type='submit']").click()
73 # Wait for page reload
74 wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".search-container")))
75
76 while True:
77 chunk = driver.execute_script("""
78 if(window._reader) {
79 chunk = await window._reader.read();
80 if (chunk['done']) {
81 return null;
82 }
83 content = '';
84 chunk['value'].split('\\r\\n').forEach((line, index) => {
85 if (line.startsWith('data: ')) {
86 line = line.substring('data: '.length);
87 if (!line.startsWith('<PHIND_METADATA>')) {
88 if (line) content += line;
89 else content += '\\n';
90 }
25 ) -> AsyncResult:
26 headers = {
27 "Accept": "*/*",
28 "Origin": cls.url,
29 "Referer": f"{cls.url}/search",
30 "Sec-Fetch-Dest": "empty",
31 "Sec-Fetch-Mode": "cors",
32 "Sec-Fetch-Site": "same-origin",
91 33 }
92 });
93 return content.replace('\\n\\n', '\\n');
94 } else {
95 return ''
96 }
97 """)
98 if chunk:
99 yield chunk
100 elif chunk != "":
101 break
102 else:
103 time.sleep(0.1)
34 async with StreamSession(
35 impersonate="chrome110",
36 proxies={"https": proxy},
37 timeout=timeout
38 ) as session:
39 prompt = messages[-1]["content"]
40 data = {
41 "question": prompt,
42 "questionHistory": [
43 message["content"] for message in messages[:-1] if message["role"] == "user"
44 ],
45 "answerHistory": [
46 message["content"] for message in messages if message["role"] == "assistant"
47 ],
48 "webResults": [],
49 "options": {
50 "date": datetime.now().strftime("%d.%m.%Y"),
51 "language": "en-US",
52 "detailed": True,
53 "anonUserId": "",
54 "answerModel": "GPT-4" if model.startswith("gpt-4") else "Phind Model",
55 "creativeMode": creative_mode,
56 "customLinks": []
57 },
58 "context": "",
59 "rewrittenQuestion": prompt
60 }
61 async with session.post(f"{cls.url}/api/infer/followup/answer", headers=headers, json=data) as response:
62 new_line = False
63 async for line in response.iter_lines():
64 if line.startswith(b"data: "):
65 chunk = line[6:]
66 if chunk.startswith(b"<PHIND_METADATA>"):
67 pass
68 elif chunk:
69 yield chunk.decode()
70 elif new_line:
71 yield "\n"
72 new_line = False
73 else:
74 new_line = True
Modified g4f/Provider/__init__.py +7 -6
@@ -1,5 +1,12 @@
1 1 from __future__ import annotations
2 2
3 from .base_provider import BaseProvider, AsyncProvider, AsyncGeneratorProvider
4 from .retry_provider import RetryProvider
5 from .deprecated import *
6 from .needs_auth import *
7 from .unfinished import *
8 from .selenium import *
9
3 10 from .AiAsk import AiAsk
4 11 from .Aichat import Aichat
5 12 from .AiChatOnline import AiChatOnline
@@ -43,12 +50,6 @@ from .You import You
43 50 from .Yqcloud import Yqcloud
44 51 from .GeekGpt import GeekGpt
45 52
46 from .base_provider import BaseProvider, AsyncProvider, AsyncGeneratorProvider
47 from .retry_provider import RetryProvider
48 from .deprecated import *
49 from .needs_auth import *
50 from .unfinished import *
51
52 53 import sys
53 54
54 55 __modules__: list = [
Added g4f/Provider/selenium/Phind.py +104 -0
@@ -0,0 +1,104 @@
1 from __future__ import annotations
2
3 import time
4 from urllib.parse import quote
5
6 from ...typing import CreateResult, Messages
7 from ..base_provider import BaseProvider
8 from ..helper import format_prompt
9 from ..webdriver import WebDriver, WebDriverSession
10
11 class Phind(BaseProvider):
12 url = "https://www.phind.com"
13 working = True
14 supports_gpt_4 = True
15 supports_stream = True
16
17 @classmethod
18 def create_completion(
19 cls,
20 model: str,
21 messages: Messages,
22 stream: bool,
23 proxy: str = None,
24 timeout: int = 120,
25 webdriver: WebDriver = None,
26 creative_mode: bool = None,
27 **kwargs
28 ) -> CreateResult:
29 driver.start_session
30 with WebDriverSession(webdriver, "", proxy=proxy) as driver:
31 from selenium.webdriver.common.by import By
32 from selenium.webdriver.support.ui import WebDriverWait
33 from selenium.webdriver.support import expected_conditions as EC
34
35 # Register fetch hook
36 source = """
37 window._fetch = window.fetch;
38 window.fetch = async (url, options) => {
39 const response = await window._fetch(url, options);
40 if (url != "/api/infer/answer") {
41 return response;
42 }
43 copy = response.clone();
44 window._reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
45 return copy;
46 }
47 """
48 driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
49 "source": source
50 })
51
52 prompt = quote(format_prompt(messages))
53 driver.get(f"{cls.url}/search?q={prompt}&source=searchbox")
54
55 # Need to change settings
56 wait = WebDriverWait(driver, timeout)
57 def open_dropdown():
58 # Open settings dropdown
59 wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "button.text-dark.dropdown-toggle")))
60 driver.find_element(By.CSS_SELECTOR, "button.text-dark.dropdown-toggle").click()
61 # Wait for dropdown toggle
62 wait.until(EC.visibility_of_element_located((By.XPATH, "//button[text()='GPT-4']")))
63 if model.startswith("gpt-4") or creative_mode:
64 # Enable GPT-4
65 if model.startswith("gpt-4"):
66 open_dropdown()
67 driver.find_element(By.XPATH, "//button[text()='GPT-4']").click()
68 # Enable creative mode
69 if creative_mode or creative_mode == None:
70 open_dropdown()
71 driver.find_element(By.ID, "Creative Mode").click()
72 # Submit changes
73 driver.find_element(By.CSS_SELECTOR, ".search-bar-input-group button[type='submit']").click()
74 # Wait for page reload
75 wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".search-container")))
76
77 while True:
78 chunk = driver.execute_script("""
79 if(window._reader) {
80 chunk = await window._reader.read();
81 if (chunk['done']) {
82 return null;
83 }
84 content = '';
85 chunk['value'].split('\\r\\n').forEach((line, index) => {
86 if (line.startsWith('data: ')) {
87 line = line.substring('data: '.length);
88 if (!line.startsWith('<PHIND_METADATA>')) {
89 if (line) content += line;
90 else content += '\\n';
91 }
92 }
93 });
94 return content.replace('\\n\\n', '\\n');
95 } else {
96 return ''
97 }
98 """)
99 if chunk:
100 yield chunk
101 elif chunk != "":
102 break
103 else:
104 time.sleep(0.1)
Added g4f/Provider/selenium/__init__.py +1 -0
@@ -0,0 +1 @@
1 from .Phind import Phind