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

XFEstudio/gpt4free

Fix Phind and PerplexityAi - GPT-4 Providers Fix MyShell Provider Refactor Provider __init__ Add ChatAnywhere Provider Update models list

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

代码差异

9 个文件 +435 -402
Added g4f/Provider/ChatAnywhere.py +53 -0
@@ -0,0 +1,53 @@
1 from __future__ import annotations
2
3 from aiohttp import ClientSession
4
5 from ..typing import AsyncResult, Messages
6 from .base_provider import AsyncGeneratorProvider
7
8
9 class ChatAnywhere(AsyncGeneratorProvider):
10 url = "https://chatanywhere.cn"
11 supports_gpt_35_turbo = True
12 supports_message_history = True
13 working = True
14
15 @classmethod
16 async def create_async_generator(
17 cls,
18 model: str,
19 messages: Messages,
20 proxy: str = None,
21 temperature: float = 0.5,
22 **kwargs
23 ) -> AsyncResult:
24 headers = {
25 "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0",
26 "Accept": "application/json, text/plain, */*",
27 "Accept-Language": "de,en-US;q=0.7,en;q=0.3",
28 "Accept-Encoding": "gzip, deflate, br",
29 "Content-Type": "application/json",
30 "Referer": f"{cls.url}/",
31 "Origin": cls.url,
32 "Sec-Fetch-Dest": "empty",
33 "Sec-Fetch-Mode": "cors",
34 "Sec-Fetch-Site": "same-origin",
35 "Authorization": "",
36 "Connection": "keep-alive",
37 "TE": "trailers"
38 }
39 async with ClientSession(headers=headers) as session:
40 data = {
41 "list": messages,
42 "id": "s1_qYuOLXjI3rEpc7WHfQ",
43 "title": messages[-1]["content"],
44 "prompt": "",
45 "temperature": temperature,
46 "models": "61490748",
47 "continuous": True
48 }
49 async with session.post(f"{cls.url}/v1/chat/gpt/", json=data, proxy=proxy) as response:
50 response.raise_for_status()
51 async for chunk in response.content.iter_any():
52 if chunk:
53 yield chunk.decode()
Modified g4f/Provider/MyShell.py +75 -72
@@ -1,91 +1,94 @@
1 1 from __future__ import annotations
2 2
3 import time, random, json
3 import time, json
4 4
5 from ..requests import StreamSession
6 from ..typing import AsyncResult, Messages
7 from .base_provider import AsyncGeneratorProvider
8 from .helper import format_prompt
5 try:
6 from selenium.webdriver.remote.webdriver import WebDriver
7 except ImportError:
8 class WebDriver():
9 pass
9 10
10 class MyShell(AsyncGeneratorProvider):
11 from ..typing import CreateResult, Messages
12 from .base_provider import BaseProvider
13 from .helper import format_prompt, get_browser
14
15 class MyShell(BaseProvider):
11 16 url = "https://app.myshell.ai/chat"
12 17 working = True
13 18 supports_gpt_35_turbo = True
19 supports_stream = True
14 20
15 21 @classmethod
16 async def create_async_generator(
22 def create_completion(
17 23 cls,
18 24 model: str,
19 25 messages: Messages,
26 stream: bool,
20 27 proxy: str = None,
21 28 timeout: int = 120,
29 browser: WebDriver = None,
30 display: bool = True,
22 31 **kwargs
23 ) -> AsyncResult:
24 user_agent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
25 headers = {
26 "User-Agent": user_agent,
27 "Myshell-Service-Name": "organics-api",
28 "Visitor-Id": generate_visitor_id(user_agent)
29 }
30 async with StreamSession(
31 impersonate="chrome107",
32 proxies={"https": proxy},
33 timeout=timeout,
34 headers=headers
35 ) as session:
36 prompt = format_prompt(messages)
32 ) -> CreateResult:
33 if not browser:
34 if display:
35 driver, display = get_browser("", True, proxy)
36 else:
37 display = get_browser("", False, proxy)
38 else:
39 driver = browser
40
41 from selenium.webdriver.common.by import By
42 from selenium.webdriver.support.ui import WebDriverWait
43 from selenium.webdriver.support import expected_conditions as EC
44
45 driver.get(cls.url)
46 try:
47 WebDriverWait(driver, timeout).until(
48 EC.presence_of_element_located((By.CSS_SELECTOR, "body:not(.no-js)"))
49 )
50 script = """
51 response = await fetch("https://api.myshell.ai/v1/bot/chat/send_message", {
52 "headers": {
53 "accept": "application/json",
54 "content-type": "application/json",
55 "myshell-service-name": "organics-api",
56 "visitor-id": localStorage.getItem("mix_visitorId")
57 },
58 "body": '{body}',
59 "method": "POST"
60 })
61 window.reader = response.body.getReader();
62 """
37 63 data = {
38 "botId": "1",
64 "botId": "4738",
39 65 "conversation_scenario": 3,
40 "message": prompt,
66 "message": format_prompt(messages),
41 67 "messageType": 1
42 68 }
43 async with session.post("https://api.myshell.ai/v1/bot/chat/send_message", json=data) as response:
44 response.raise_for_status()
45 event = None
46 async for line in response.iter_lines():
47 if line.startswith(b"event: "):
48 event = line[7:]
49 elif event == b"MESSAGE_REPLY_SSE_ELEMENT_EVENT_NAME_TEXT":
50 if line.startswith(b"data: "):
51 yield json.loads(line[6:])["content"]
52 if event == b"MESSAGE_REPLY_SSE_ELEMENT_EVENT_NAME_TEXT_STREAM_PUSH_FINISHED":
53 break
54
55
56 def xor_hash(B: str):
57 r = []
58 i = 0
59
60 def o(e, t):
61 o_val = 0
62 for i in range(len(t)):
63 o_val |= r[i] << (8 * i)
64 return e ^ o_val
65
66 for e in range(len(B)):
67 t = ord(B[e])
68 r.insert(0, 255 & t)
69
70 if len(r) >= 4:
71 i = o(i, r)
72 r = []
73
74 if len(r) > 0:
75 i = o(i, r)
76
77 return hex(i)[2:]
78
79 def performance() -> str:
80 t = int(time.time() * 1000)
81 e = 0
82 while t == int(time.time() * 1000):
83 e += 1
84 return hex(t)[2:] + hex(e)[2:]
85
86 def generate_visitor_id(user_agent: str) -> str:
87 f = performance()
88 r = hex(int(random.random() * (16**16)))[2:-2]
89 d = xor_hash(user_agent)
90 e = hex(1080 * 1920)[2:]
91 return f"{f}-{r}-{d}-{e}-{f}"
69 driver.execute_script(script.replace("{body}", json.dumps(data)))
70 script = """
71 chunk = await window.reader.read();
72 text = await (new Response(chunk['value']).text());
73 content = '';
74 text.split('\\n').forEach((line, index) => {
75 if (line.startsWith('data: ')) {
76 try {
77 const data = JSON.parse(line.substring('data: '.length));
78 if ('content' in data) {
79 content += data['content'];
80 }
81 } catch(e) {}
82 }
83 });
84 return content;
85 """
86 while chunk := driver.execute_script(script):
87 yield chunk
88 finally:
89 driver.close()
90 if not browser:
91 time.sleep(0.1)
92 driver.quit()
93 if display:
94 display.stop()
Added g4f/Provider/PerplexityAi.py +121 -0
@@ -0,0 +1,121 @@
1 from __future__ import annotations
2
3 import time
4 try:
5 from selenium.webdriver.remote.webdriver import WebDriver
6 except ImportError:
7 class WebDriver():
8 pass
9
10 from ..typing import CreateResult, Messages
11 from .base_provider import BaseProvider
12 from .helper import format_prompt, get_browser
13
14 class PerplexityAi(BaseProvider):
15 url = "https://www.perplexity.ai"
16 working = True
17 supports_gpt_4 = True
18 supports_stream = True
19
20 @classmethod
21 def create_completion(
22 cls,
23 model: str,
24 messages: Messages,
25 stream: bool,
26 proxy: str = None,
27 timeout: int = 120,
28 browser: WebDriver = None,
29 copilot: bool = False,
30 display: bool = True,
31 **kwargs
32 ) -> CreateResult:
33 from selenium.webdriver.common.by import By
34 from selenium.webdriver.support.ui import WebDriverWait
35 from selenium.webdriver.support import expected_conditions as EC
36
37 if browser:
38 driver = browser
39 else:
40 if display:
41 driver, display = get_browser("", True, proxy)
42 else:
43 driver = get_browser("", False, proxy)
44
45 prompt = format_prompt(messages)
46
47 driver.get(f"{cls.url}/")
48 wait = WebDriverWait(driver, timeout)
49
50 script = """
51 window._message = window._last_message = "";
52 window._message_finished = false;
53 const _socket_send = WebSocket.prototype.send;
54 WebSocket.prototype.send = function(...args) {
55 if (!window.socket_onmessage) {
56 window._socket_onmessage = this;
57 this.addEventListener("message", (event) => {
58 if (event.data.startsWith("42")) {
59 let data = JSON.parse(event.data.substring(2));
60 if (data[0] =="query_progress" || data[0] == "query_answered") {
61 let content = JSON.parse(data[1]["text"]);
62 if (data[1]["mode"] == "copilot") {
63 content = content[content.length-1]["content"]["answer"];
64 content = JSON.parse(content);
65 }
66 window._message = content["answer"];
67 window._message_finished = data[0] == "query_answered";
68 window._web_results = content["web_results"];
69 }
70 }
71 });
72 }
73 return _socket_send.call(this, ...args);
74 };
75 """
76 driver.execute_script(script)
77
78 # Page loaded?
79 wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "textarea[placeholder='Ask anything...']")))
80
81 if copilot:
82 try:
83 driver.find_element(By.CSS_SELECTOR, "img[alt='User avatar']")
84 driver.find_element(By.CSS_SELECTOR, "button[data-testid='copilot-toggle']").click()
85 except:
86 pass
87
88 # Enter question
89 driver.find_element(By.CSS_SELECTOR, "textarea[placeholder='Ask anything...']").send_keys(prompt)
90 # Submit question
91 driver.find_element(By.CSS_SELECTOR, "button.bg-super svg[data-icon='arrow-right']").click()
92
93 try:
94 script = """
95 if(window._message && window._message != window._last_message) {
96 try {
97 return window._message.substring(window._last_message.length);
98 } finally {
99 window._last_message = window._message;
100 }
101 } else if(window._message_finished) {
102 return null;
103 } else {
104 return '';
105 }
106 """
107 while True:
108 chunk = driver.execute_script(script)
109 if chunk:
110 yield chunk
111 elif chunk != "":
112 break
113 else:
114 time.sleep(0.1)
115 finally:
116 driver.close()
117 if not browser:
118 time.sleep(0.1)
119 driver.quit()
120 if display:
121 display.stop()
Modified g4f/Provider/Phind.py +99 -66
@@ -1,83 +1,116 @@
1 1 from __future__ import annotations
2 2
3 import random, string
4 from datetime import datetime
3 import time
4 from urllib.parse import quote
5 try:
6 from selenium.webdriver.remote.webdriver import WebDriver
7 except ImportError:
8 class WebDriver():
9 pass
5 10
6 from ..typing import AsyncResult, Messages
7 from ..requests import StreamSession
8 from .base_provider import AsyncGeneratorProvider, format_prompt
11 from ..typing import CreateResult, Messages
12 from .base_provider import BaseProvider
13 from .helper import format_prompt, get_browser
9 14
10
11 class Phind(AsyncGeneratorProvider):
15 class Phind(BaseProvider):
12 16 url = "https://www.phind.com"
13 17 working = True
14 18 supports_gpt_4 = True
19 supports_stream = True
15 20
16 21 @classmethod
17 async def create_async_generator(
22 def create_completion(
18 23 cls,
19 24 model: str,
20 25 messages: Messages,
26 stream: bool,
21 27 proxy: str = None,
22 28 timeout: int = 120,
29 browser: WebDriver = None,
30 creative_mode: bool = None,
31 display: bool = True,
23 32 **kwargs
24 ) -> AsyncResult:
25 chars = string.ascii_lowercase + string.digits
26 user_id = ''.join(random.choice(chars) for _ in range(24))
27 data = {
28 "question": format_prompt(messages),
29 "webResults": [],
30 "options": {
31 "date": datetime.now().strftime("%d.%m.%Y"),
32 "language": "en",
33 "detailed": True,
34 "anonUserId": user_id,
35 "answerModel": "GPT-4",
36 "creativeMode": False,
37 "customLinks": []
38 },
39 "context":""
40 }
41 headers = {
42 "Authority": cls.url,
43 "Accept": "application/json, text/plain, */*",
44 "Origin": cls.url,
45 "Referer": f"{cls.url}/"
46 }
47 async with StreamSession(
48 headers=headers,
49 timeout=(5, timeout),
50 proxies={"https": proxy},
51 impersonate="chrome107"
52 ) as session:
53 async with session.post(f"{cls.url}/api/infer/answer", json=data) as response:
54 response.raise_for_status()
55 new_lines = 0
56 async for line in response.iter_lines():
57 if not line:
58 continue
59 if line.startswith(b"data: "):
60 line = line[6:]
61 if line.startswith(b"<PHIND_METADATA>"):
62 continue
63 if line:
64 if new_lines:
65 yield "".join(["\n" for _ in range(int(new_lines / 2))])
66 new_lines = 0
67 yield line.decode()
68 else:
69 new_lines += 1
33 ) -> CreateResult:
34 from selenium.webdriver.common.by import By
35 from selenium.webdriver.support.ui import WebDriverWait
36 from selenium.webdriver.support import expected_conditions as EC
70 37
38 if browser:
39 driver = browser
40 else:
41 if display:
42 driver, display = get_browser("", True, proxy)
43 else:
44 driver = get_browser("", False, proxy)
71 45
72 @classmethod
73 @property
74 def params(cls):
75 params = [
76 ("model", "str"),
77 ("messages", "list[dict[str, str]]"),
78 ("stream", "bool"),
79 ("proxy", "str"),
80 ("timeout", "int"),
81 ]
82 param = ", ".join([": ".join(p) for p in params])
83 return f"g4f.provider.{cls.__name__} supports: ({param})"
46 prompt = quote(format_prompt(messages))
47 driver.get(f"{cls.url}/search?q={prompt}&source=searchbox")
48
49 if model.startswith("gpt-4") or creative_mode:
50 wait = WebDriverWait(driver, timeout)
51 # Open dropdown
52 wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "button.text-dark.dropdown-toggle")))
53 driver.find_element(By.CSS_SELECTOR, "button.text-dark.dropdown-toggle").click()
54 # Enable GPT-4
55 wait.until(EC.visibility_of_element_located((By.XPATH, "//button[text()='GPT-4']")))
56 if model.startswith("gpt-4"):
57 driver.find_element(By.XPATH, "//button[text()='GPT-4']").click()
58 # Enable creative mode
59 if creative_mode or creative_mode == None:
60 driver.find_element(By.ID, "Creative Mode").click()
61 # Submit question
62 driver.find_element(By.CSS_SELECTOR, ".search-bar-input-group button[type='submit']").click()
63 wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".search-container")))
64
65 try:
66 script = """
67 window._fetch = window.fetch;
68 window.fetch = (url, options) => {
69 const result = window._fetch(url, options);
70 if (url != "/api/infer/answer") return result;
71 result.then((response) => {
72 if (!response.body.locked) {
73 window.reader = response.body.getReader();
74 }
75 });
76 return new Promise((resolve, reject) => {
77 resolve(new Response(new ReadableStream()))
78 });
79 }
80 """
81 driver.execute_script(script)
82 script = """
83 if(window.reader) {
84 chunk = await window.reader.read();
85 if (chunk['done']) return null;
86 text = await (new Response(chunk['value']).text());
87 content = '';
88 text.split('\\r\\n').forEach((line, index) => {
89 if (line.startsWith('data: ')) {
90 line = line.substring('data: '.length);
91 if (!line.startsWith('<PHIND_METADATA>')) {
92 if (line) content += line;
93 else content += '\\n';
94 }
95 }
96 });
97 return content.replace('\\n\\n', '\\n');
98 } else {
99 return ''
100 }
101 """
102 while True:
103 chunk = driver.execute_script(script)
104 if chunk:
105 yield chunk
106 elif chunk != "":
107 break
108 else:
109 time.sleep(0.1)
110 finally:
111 driver.close()
112 if not browser:
113 time.sleep(0.1)
114 driver.quit()
115 if display:
116 display.stop()
Modified g4f/Provider/__init__.py +22 -146
@@ -1,10 +1,12 @@
1 from __future__ import annotations
1 from __future__ import annotations
2
2 3 from .AiAsk import AiAsk
3 4 from .Aichat import Aichat
4 5 from .AItianhu import AItianhu
5 6 from .AItianhuSpace import AItianhuSpace
6 7 from .Berlin import Berlin
7 8 from .Bing import Bing
9 from .ChatAnywhere import ChatAnywhere
8 10 from .ChatBase import ChatBase
9 11 from .ChatForAi import ChatForAi
10 12 from .Chatgpt4Online import Chatgpt4Online
@@ -28,6 +30,7 @@ from .Llama2 import Llama2
28 30 from .MyShell import MyShell
29 31 from .NoowAi import NoowAi
30 32 from .Opchatgpts import Opchatgpts
33 from .PerplexityAi import PerplexityAi
31 34 from .Phind import Phind
32 35 from .Vercel import Vercel
33 36 from .Ylokh import Ylokh
@@ -41,150 +44,23 @@ from .deprecated import *
41 44 from .needs_auth import *
42 45 from .unfinished import *
43 46
44 class ProviderUtils:
45 convert: dict[str, BaseProvider] = {
46 'AItianhu': AItianhu,
47 'AItianhuSpace': AItianhuSpace,
48 'Acytoo': Acytoo,
49 'AiAsk': AiAsk,
50 'AiService': AiService,
51 'Aibn': Aibn,
52 'Aichat': Aichat,
53 'Ails': Ails,
54 'Aivvm': Aivvm,
55 'AsyncGeneratorProvider': AsyncGeneratorProvider,
56 'AsyncProvider': AsyncProvider,
57 'Bard': Bard,
58 'BaseProvider': BaseProvider,
59 'Berlin': Berlin,
60 'Bing': Bing,
61 'ChatBase': ChatBase,
62 'ChatForAi': ChatForAi,
63 'Chatgpt4Online': Chatgpt4Online,
64 'ChatgptAi': ChatgptAi,
65 'ChatgptDemo': ChatgptDemo,
66 'ChatgptDuo': ChatgptDuo,
67 'ChatgptFree': ChatgptFree,
68 'ChatgptLogin': ChatgptLogin,
69 'ChatgptX': ChatgptX,
70 'CodeLinkAva': CodeLinkAva,
71 'Cromicle': Cromicle,
72 'DeepInfra': DeepInfra,
73 'DfeHub': DfeHub,
74 'EasyChat': EasyChat,
75 'Equing': Equing,
76 'FastGpt': FastGpt,
77 'Forefront': Forefront,
78 'FakeGpt': FakeGpt,
79 'FreeGpt': FreeGpt,
80 'GPTalk': GPTalk,
81 'GptChatly': GptChatly,
82 'GetGpt': GetGpt,
83 'GptForLove': GptForLove,
84 'GptGo': GptGo,
85 'GptGod': GptGod,
86 'Hashnode': Hashnode,
87 'H2o': H2o,
88 'HuggingChat': HuggingChat,
89 'Komo': Komo,
90 'Koala': Koala,
91 'Liaobots': Liaobots,
92 'Llama2': Llama2,
93 'Lockchat': Lockchat,
94 'MikuChat': MikuChat,
95 'Myshell': Myshell,
96 'MyShell': MyShell,
97 'NoowAi': NoowAi,
98 'Opchatgpts': Opchatgpts,
99 'OpenAssistant': OpenAssistant,
100 'OpenaiChat': OpenaiChat,
101 'PerplexityAi': PerplexityAi,
102 'Phind': Phind,
103 'Raycast': Raycast,
104 'Theb': Theb,
105 'V50': V50,
106 'Vercel': Vercel,
107 'Vitalentum': Vitalentum,
108 'Wewordle': Wewordle,
109 'Wuguokai': Wuguokai,
110 'Ylokh': Ylokh,
111 'You': You,
112 'Yqcloud': Yqcloud,
113 'GeekGpt': GeekGpt,
114
115 'BaseProvider': BaseProvider,
116 'AsyncProvider': AsyncProvider,
117 'AsyncGeneratorProvider': AsyncGeneratorProvider,
118 'RetryProvider': RetryProvider,
119 }
47 import sys
120 48
121 __all__ = [
122 'BaseProvider',
123 'AsyncProvider',
124 'AsyncGeneratorProvider',
125 'RetryProvider',
126 'Acytoo',
127 'AiAsk',
128 'Aibn',
129 'Aichat',
130 'Ails',
131 'Aivvm',
132 'AiService',
133 'AItianhu',
134 'AItianhuSpace',
135 'Aivvm',
136 'Bard',
137 'Berlin',
138 'Bing',
139 'ChatBase',
140 'ChatForAi',
141 'Chatgpt4Online',
142 'ChatgptAi',
143 'ChatgptDemo',
144 'ChatgptDuo',
145 'ChatgptFree',
146 'ChatgptLogin',
147 'ChatgptX',
148 'Cromicle',
149 'DeepInfra',
150 'CodeLinkAva',
151 'DfeHub',
152 'EasyChat',
153 'Forefront',
154 'FakeGpt',
155 'FreeGpt',
156 'GPTalk',
157 'GptChatly',
158 'GptForLove',
159 'GetGpt',
160 'GptGo',
161 'GptGod',
162 'Hashnode',
163 'H2o',
164 'HuggingChat',
165 'Koala',
166 'Liaobots',
167 'Llama2',
168 'Lockchat',
169 'Myshell',
170 'MyShell',
171 'NoowAi',
172 'Opchatgpts',
173 'Raycast',
174 'OpenaiChat',
175 'OpenAssistant',
176 'PerplexityAi',
177 'Phind',
178 'Theb',
179 'Vercel',
180 'Vitalentum',
181 'Wewordle',
182 'Ylokh',
183 'You',
184 'Yqcloud',
185 'Equing',
186 'FastGpt',
187 'Wuguokai',
188 'V50',
189 'GeekGpt'
49 __modules__: list = [
50 getattr(sys.modules[__name__], provider) for provider in dir()
51 if not provider.startswith("__")
52 ]
53 __providers__: list[type[BaseProvider]] = [
54 provider for provider in __modules__
55 if isinstance(provider, type)
56 and issubclass(provider, BaseProvider)
190 57 ]
58 __all__: list[str] = [
59 provider.__name__ for provider in __providers__
60 ]
61 __map__: dict[str, BaseProvider] = dict([
62 (provider.__name__, provider) for provider in __providers__
63 ])
64
65 class ProviderUtils:
66 convert: dict[str, BaseProvider] = __map__
Modified g4f/Provider/helper.py +49 -8
@@ -3,13 +3,39 @@ from __future__ import annotations
3 3 import sys
4 4 import asyncio
5 5 import webbrowser
6
7 6 from os import path
8 7 from asyncio import AbstractEventLoop
9 8 from platformdirs import user_config_dir
9 from browser_cookie3 import (
10 chrome,
11 chromium,
12 opera,
13 opera_gx,
14 brave,
15 edge,
16 vivaldi,
17 firefox,
18 BrowserCookieError
19 )
20 try:
21 from undetected_chromedriver import Chrome, ChromeOptions
22 except ImportError:
23 class Chrome():
24 def __init__():
25 raise RuntimeError('Please install "undetected_chromedriver" and "pyvirtualdisplay" package')
26 class ChromeOptions():
27 def add_argument():
28 pass
29 try:
30 from pyvirtualdisplay import Display
31 except ImportError:
32 class Display():
33 def start():
34 pass
35 def stop():
36 pass
10 37
11 from ..typing import Dict, Messages
12 from browser_cookie3 import chrome, chromium, opera, opera_gx, brave, edge, vivaldi, firefox, BrowserCookieError
38 from ..typing import Dict, Messages, Union, Tuple
13 39 from .. import debug
14 40
15 41 # Change event loop policy on windows
@@ -106,10 +132,25 @@ def format_prompt(messages: Messages, add_special_tokens=False) -> str:
106 132 return f"{formatted}\nAssistant:"
107 133
108 134
109 def get_browser(user_data_dir: str = None):
110 from undetected_chromedriver import Chrome
111
112 if not user_data_dir:
135 def get_browser(
136 user_data_dir: str = None,
137 display: bool = False,
138 proxy: str = None
139 ) -> Union[Chrome, Tuple[Chrome, Display]] :
140 if user_data_dir == None:
113 141 user_data_dir = user_config_dir("g4f")
114 142
115 return Chrome(user_data_dir=user_data_dir)
143 if display:
144 display = Display(visible=0, size=(1920, 1080))
145 display.start()
146
147 options = None
148 if proxy:
149 options = ChromeOptions()
150 options.add_argument(f'--proxy-server={proxy}')
151
152 browser = Chrome(user_data_dir=user_data_dir, options=options)
153 if display:
154 return browser, display
155
156 return browser
Deleted g4f/Provider/unfinished/PerplexityAi.py +0 -100
@@ -1,100 +0,0 @@
1 from __future__ import annotations
2
3 import json
4 import time
5 import base64
6 from curl_cffi.requests import AsyncSession
7
8 from ..base_provider import AsyncProvider, format_prompt, get_cookies
9
10
11 class PerplexityAi(AsyncProvider):
12 url = "https://www.perplexity.ai"
13 supports_gpt_35_turbo = True
14 _sources = []
15
16 @classmethod
17 async def create_async(
18 cls,
19 model: str,
20 messages: list[dict[str, str]],
21 proxy: str = None,
22 **kwargs
23 ) -> str:
24 url = f"{cls.url}/socket.io/?EIO=4&transport=polling"
25 headers = {
26 "Referer": f"{cls.url}/"
27 }
28 async with AsyncSession(headers=headers, proxies={"https": proxy}, impersonate="chrome107") as session:
29 url_session = "https://www.perplexity.ai/api/auth/session"
30 response = await session.get(url_session)
31 response.raise_for_status()
32
33 url_session = "https://www.perplexity.ai/api/auth/session"
34 response = await session.get(url_session)
35 response.raise_for_status()
36
37 response = await session.get(url, params={"t": timestamp()})
38 response.raise_for_status()
39 sid = json.loads(response.text[1:])["sid"]
40
41 response = await session.get(url, params={"t": timestamp(), "sid": sid})
42 response.raise_for_status()
43
44 data = '40{"jwt":"anonymous-ask-user"}'
45 response = await session.post(url, params={"t": timestamp(), "sid": sid}, data=data)
46 response.raise_for_status()
47
48 response = await session.get(url, params={"t": timestamp(), "sid": sid})
49 response.raise_for_status()
50
51 data = "424" + json.dumps([
52 "perplexity_ask",
53 format_prompt(messages),
54 {
55 "version":"2.1",
56 "source":"default",
57 "language":"en",
58 "timezone": time.tzname[0],
59 "search_focus":"internet",
60 "mode":"concise"
61 }
62 ])
63 response = await session.post(url, params={"t": timestamp(), "sid": sid}, data=data)
64 response.raise_for_status()
65
66 while True:
67 response = await session.get(url, params={"t": timestamp(), "sid": sid})
68 response.raise_for_status()
69 for line in response.text.splitlines():
70 if line.startswith("434"):
71 result = json.loads(json.loads(line[3:])[0]["text"])
72
73 cls._sources = [{
74 "title": source["name"],
75 "url": source["url"],
76 "snippet": source["snippet"]
77 } for source in result["web_results"]]
78
79 return result["answer"]
80
81 @classmethod
82 def get_sources(cls):
83 return cls._sources
84
85
86 @classmethod
87 @property
88 def params(cls):
89 params = [
90 ("model", "str"),
91 ("messages", "list[dict[str, str]]"),
92 ("stream", "bool"),
93 ("proxy", "str"),
94 ]
95 param = ", ".join([": ".join(p) for p in params])
96 return f"g4f.provider.{cls.__name__} supports: ({param})"
97
98
99 def timestamp() -> str:
100 return base64.urlsafe_b64encode(int(time.time()-1407782612).to_bytes(4, 'big')).decode()
Modified g4f/Provider/unfinished/__init__.py +0 -1
@@ -1,5 +1,4 @@
1 1 from .MikuChat import MikuChat
2 from .PerplexityAi import PerplexityAi
3 2 from .Komo import Komo
4 3 from .TalkAi import TalkAi
5 4 from .ChatAiGpt import ChatAiGpt
Modified g4f/models.py +16 -9
@@ -3,6 +3,9 @@ from dataclasses import dataclass
3 3 from .typing import Union
4 4 from .Provider import BaseProvider, RetryProvider
5 5 from .Provider import (
6 Chatgpt4Online,
7 ChatAnywhere,
8 PerplexityAi,
6 9 GptForLove,
7 10 ChatgptAi,
8 11 DeepInfra,
@@ -11,14 +14,12 @@ from .Provider import (
11 14 GeekGpt,
12 15 FakeGpt,
13 16 FreeGpt,
14 NoowAi,
15 17 Berlin,
16 18 Llama2,
17 19 Vercel,
18 GPTalk,
20 Phind,
19 21 Koala,
20 22 GptGo,
21 Phind,
22 23 Bard,
23 24 Bing,
24 25 You,
@@ -39,20 +40,24 @@ default = Model(
39 40 name = "",
40 41 base_provider = "",
41 42 best_provider = RetryProvider([
42 Bing, # Not fully GPT 3 or 4
43 Bing,
43 44 ChatgptAi, GptGo, GeekGpt,
44 Phind, You
45 You,
46 Chatgpt4Online,
47 ChatAnywhere,
45 48 ])
46 49 )
47 50
48 # GPT-3.5 too, but all providers supports long responses and a custom timeouts
51 # GPT-3.5 too, but all providers supports long requests and responses
49 52 gpt_35_long = Model(
50 53 name = 'gpt-3.5-turbo',
51 54 base_provider = 'openai',
52 55 best_provider = RetryProvider([
53 56 FreeGpt, You,
54 57 GeekGpt, FakeGpt,
55 Berlin, Koala
58 Berlin, Koala,
59 Chatgpt4Online,
60 ChatAnywhere,
56 61 ])
57 62 )
58 63
@@ -62,7 +67,9 @@ gpt_35_turbo = Model(
62 67 base_provider = 'openai',
63 68 best_provider=RetryProvider([
64 69 ChatgptX, GptGo, You,
65 NoowAi, GPTalk, GptForLove, Phind, ChatBase
70 GptForLove, ChatBase,
71 Chatgpt4Online,
72 ChatAnywhere,
66 73 ])
67 74 )
68 75
@@ -70,7 +77,7 @@ gpt_4 = Model(
70 77 name = 'gpt-4',
71 78 base_provider = 'openai',
72 79 best_provider = RetryProvider([
73 Bing, GeekGpt, Phind
80 Bing, Phind, PerplexityAi
74 81 ])
75 82 )
76 83