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

XFEstudio/gpt4free

Add Poe Provider, Update AItianhuSpace Porvider

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

代码差异

5 个文件 +249 -86
Modified g4f/Provider/AItianhuSpace.py +109 -76
@@ -1,95 +1,128 @@
1 1 from __future__ import annotations
2 2
3 import random, json
4 from .. import debug
5 from ..typing import AsyncResult, Messages
6 from ..requests import StreamSession
7 from .base_provider import AsyncGeneratorProvider, format_prompt, get_cookies
3 import time
4 import random
8 5
9 domains = {
10 "gpt-3.5-turbo": "aitianhu.space",
11 "gpt-4": "aitianhu.website",
12 }
6 from ..typing import CreateResult, Messages
7 from .base_provider import BaseProvider
8 from .helper import WebDriver, format_prompt, get_browser
9 from .. import debug
13 10
14 class AItianhuSpace(AsyncGeneratorProvider):
11 class AItianhuSpace(BaseProvider):
15 12 url = "https://chat3.aiyunos.top/"
16 13 working = True
17 14 supports_gpt_35_turbo = True
15 _domains = ["aitianhu.com", "aitianhu1.top"]
18 16
19 17 @classmethod
20 async def create_async_generator(cls,
21 model: str,
22 messages: Messages,
23 proxy: str = None,
24 domain: str = None,
25 cookies: dict = None,
26 timeout: int = 10, **kwargs) -> AsyncResult:
27
18 def create_completion(
19 cls,
20 model: str,
21 messages: Messages,
22 stream: bool,
23 domain: str = None,
24 proxy: str = None,
25 timeout: int = 120,
26 browser: WebDriver = None,
27 hidden_display: bool = True,
28 **kwargs
29 ) -> CreateResult:
28 30 if not model:
29 31 model = "gpt-3.5-turbo"
30
31 elif model not in domains:
32 raise ValueError(f"Model are not supported: {model}")
33
34 32 if not domain:
35 33 chars = 'abcdefghijklmnopqrstuvwxyz0123456789'
36 34 rand = ''.join(random.choice(chars) for _ in range(6))
37 domain = f"{rand}.{domains[model]}"
38
35 domain = random.choice(cls._domains)
36 domain = f"{rand}.{domain}"
39 37 if debug.logging:
40 38 print(f"AItianhuSpace | using domain: {domain}")
39 url = f"https://{domain}"
40 prompt = format_prompt(messages)
41 if browser:
42 driver = browser
43 else:
44 if hidden_display:
45 driver, display = get_browser("", True, proxy)
46 else:
47 driver = get_browser("", False, proxy)
41 48
42 if not cookies:
43 cookies = get_cookies('.aitianhu.space')
44 if not cookies:
45 raise RuntimeError(f"g4f.provider.{cls.__name__} requires cookies [refresh https://{domain} on chrome]")
49 from selenium.webdriver.common.by import By
50 from selenium.webdriver.support.ui import WebDriverWait
51 from selenium.webdriver.support import expected_conditions as EC
46 52
47 url = f'https://{domain}'
48 async with StreamSession(proxies={"https": proxy},
49 cookies=cookies, timeout=timeout, impersonate="chrome110", verify=False) as session:
50
51 data = {
52 "prompt": format_prompt(messages),
53 "options": {},
54 "systemMessage": "You are ChatGPT, a large language model trained by OpenAI. Follow the user's instructions carefully.",
55 "temperature": 0.8,
56 "top_p": 1,
57 **kwargs
58 }
59 headers = {
60 "Authority": url,
61 "Accept": "application/json, text/plain, */*",
62 "Origin": url,
63 "Referer": f"{url}/"
64 }
65 async with session.post(f"{url}/api/chat-process", json=data, headers=headers) as response:
66 response.raise_for_status()
67 async for line in response.iter_lines():
68 if line == b"<script>":
69 raise RuntimeError("Solve challenge and pass cookies and a fixed domain")
70 if b"platform's risk control" in line:
71 raise RuntimeError("Platform's Risk Control")
72 line = json.loads(line)
73 if "detail" in line:
74 if content := line["detail"]["choices"][0]["delta"].get(
75 "content"
76 ):
77 yield content
78 elif "message" in line and "AI-4接口非常昂贵" in line["message"]:
79 raise RuntimeError("Rate limit for GPT 4 reached")
80 else:
81 raise RuntimeError(f"Response: {line}")
82
53 wait = WebDriverWait(driver, timeout)
83 54
84 @classmethod
85 @property
86 def params(cls):
87 params = [
88 ("model", "str"),
89 ("messages", "list[dict[str, str]]"),
90 ("stream", "bool"),
91 ("temperature", "float"),
92 ("top_p", "int"),
93 ]
94 param = ", ".join([": ".join(p) for p in params])
95 return f"g4f.provider.{cls.__name__} supports: ({param})"
55 # Bypass devtools detection
56 driver.get("https://blank.page/")
57 wait.until(EC.visibility_of_element_located((By.ID, "sheet")))
58 driver.execute_script(f"""
59 document.getElementById('sheet').addEventListener('click', () => {{
60 window.open('{url}', '_blank');
61 }});
62 """)
63 driver.find_element(By.ID, "sheet").click()
64 time.sleep(10)
65
66 original_window = driver.current_window_handle
67 for window_handle in driver.window_handles:
68 if window_handle != original_window:
69 driver.switch_to.window(window_handle)
70 break
71
72 wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "textarea.n-input__textarea-el")))
73
74 try:
75 # Add hook in XMLHttpRequest
76 script = """
77 const _http_request_open = XMLHttpRequest.prototype.open;
78 window._last_message = window._message = "";
79 window._loadend = false;
80 XMLHttpRequest.prototype.open = function(method, url) {
81 if (url == "/api/chat-process") {
82 this.addEventListener("progress", (event) => {
83 const lines = this.responseText.split("\\n");
84 try {
85 window._message = JSON.parse(lines[lines.length-1])["text"];
86 } catch(e) { }
87 });
88 this.addEventListener("loadend", (event) => {
89 window._loadend = true;
90 });
91 }
92 return _http_request_open.call(this, method, url);
93 }
94 """
95 driver.execute_script(script)
96
97 # Input and submit prompt
98 driver.find_element(By.CSS_SELECTOR, "textarea.n-input__textarea-el").send_keys(prompt)
99 driver.find_element(By.CSS_SELECTOR, "button.n-button.n-button--primary-type.n-button--medium-type").click()
100
101 # Yield response
102 while True:
103 chunk = driver.execute_script("""
104 if (window._message && window._message != window._last_message) {
105 try {
106 return window._message.substring(window._last_message.length);
107 } finally {
108 window._last_message = window._message;
109 }
110 }
111 if (window._loadend) {
112 return null;
113 }
114 return "";
115 """)
116 if chunk:
117 yield chunk
118 elif chunk != "":
119 break
120 else:
121 time.sleep(0.1)
122 finally:
123 driver.close()
124 if not browser:
125 time.sleep(0.1)
126 driver.quit()
127 if hidden_display:
128 display.stop()
Modified g4f/Provider/MyShell.py +4 -4
@@ -38,11 +38,11 @@ class MyShell(BaseProvider):
38 38
39 39 driver.get(cls.url)
40 40 try:
41 # Wait for page load
41 # Wait for page load and cloudflare validation
42 42 WebDriverWait(driver, timeout).until(
43 43 EC.presence_of_element_located((By.CSS_SELECTOR, "body:not(.no-js)"))
44 44 )
45 # Send message
45 # Send request with message
46 46 script = """
47 47 response = await fetch("https://api.myshell.ai/v1/bot/chat/send_message", {
48 48 "headers": {
@@ -66,7 +66,7 @@ window.reader = response.body.getReader();
66 66 script = """
67 67 chunk = await window.reader.read();
68 68 if (chunk['done']) return null;
69 text = (new TextDecoder ()).decode(chunk['value']);
69 text = (new TextDecoder()).decode(chunk['value']);
70 70 content = '';
71 71 text.split('\\n').forEach((line, index) => {
72 72 if (line.startsWith('data: ')) {
@@ -81,7 +81,7 @@ text.split('\\n').forEach((line, index) => {
81 81 return content;
82 82 """
83 83 while True:
84 chunk = driver.execute_script(script):
84 chunk = driver.execute_script(script)
85 85 if chunk:
86 86 yield chunk
87 87 elif chunk != "":
Modified g4f/Provider/helper.py +5 -5
@@ -18,10 +18,10 @@ from browser_cookie3 import (
18 18 BrowserCookieError
19 19 )
20 20 try:
21 from selenium.webdriver.remote.webdriver import WebDriver
22 except ImportError:
23 class WebDriver():
24 pass
21 from selenium.webdriver.remote.webdriver import WebDriver
22 except ImportError:
23 class WebDriver():
24 pass
25 25 try:
26 26 from undetected_chromedriver import Chrome, ChromeOptions
27 27 except ImportError:
@@ -153,7 +153,7 @@ def get_browser(
153 153 if proxy:
154 154 if not options:
155 155 options = ChromeOptions()
156 options.add_argument(f'--proxy-server={proxy}')
156 options.add_argument(f'--proxy-server={proxy}')
157 157
158 158 browser = Chrome(user_data_dir=user_data_dir, options=options)
159 159 if hidden_display:
Added g4f/Provider/needs_auth/Poe.py +129 -0
@@ -0,0 +1,129 @@
1 from __future__ import annotations
2
3 import time
4
5 from ...typing import CreateResult, Messages
6 from ..base_provider import BaseProvider
7 from ..helper import WebDriver, format_prompt, get_browser
8
9 models = {
10 "meta-llama/Llama-2-7b-chat-hf": {"name": "Llama-2-7b"},
11 "meta-llama/Llama-2-13b-chat-hf": {"name": "Llama-2-13b"},
12 "meta-llama/Llama-2-70b-chat-hf": {"name": "Llama-2-70b"},
13 "codellama/CodeLlama-7b-Instruct-hf": {"name": "Code-Llama-7b"},
14 "codellama/CodeLlama-13b-Instruct-hf": {"name": "Code-Llama-13b"},
15 "codellama/CodeLlama-34b-Instruct-hf": {"name": "Code-Llama-34b"},
16 "gpt-3.5-turbo": {"name": "GPT-3.5-Turbo"},
17 "gpt-3.5-turbo-instruct": {"name": "GPT-3.5-Turbo-Instruct"},
18 "gpt-4": {"name": "GPT-4"},
19 "palm": {"name": "Google-PaLM"},
20 }
21
22 class Poe(BaseProvider):
23 url = "https://poe.com"
24 working = True
25 supports_gpt_35_turbo = True
26 supports_stream = True
27
28 @classmethod
29 def create_completion(
30 cls,
31 model: str,
32 messages: Messages,
33 stream: bool,
34 proxy: str = None,
35 browser: WebDriver = None,
36 hidden_display: bool = True,
37 **kwargs
38 ) -> CreateResult:
39 if not model:
40 model = "gpt-3.5-turbo"
41 elif model not in models:
42 raise ValueError(f"Model are not supported: {model}")
43 prompt = format_prompt(messages)
44 if browser:
45 driver = browser
46 else:
47 if hidden_display:
48 driver, display = get_browser(None, True, proxy)
49 else:
50 driver = get_browser(None, False, proxy)
51
52 script = """
53 window._message = window._last_message = "";
54 window._message_finished = false;
55 class ProxiedWebSocket extends WebSocket {
56 constructor(url, options) {
57 super(url, options);
58 this.addEventListener("message", (e) => {
59 const data = JSON.parse(JSON.parse(e.data)["messages"][0])["payload"]["data"];
60 if ("messageAdded" in data) {
61 if (data["messageAdded"]["author"] != "human") {
62 window._message = data["messageAdded"]["text"];
63 if (data["messageAdded"]["state"] == "complete") {
64 window._message_finished = true;
65 }
66 }
67 }
68 });
69 }
70 }
71 window.WebSocket = ProxiedWebSocket;
72 """
73 driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
74 "source": script
75 })
76
77 from selenium.webdriver.common.by import By
78 from selenium.webdriver.support.ui import WebDriverWait
79 from selenium.webdriver.support import expected_conditions as EC
80
81 try:
82 driver.get(f"{cls.url}/{models[model]['name']}")
83 wait = WebDriverWait(driver, 10 if hidden_display else 240)
84 wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "textarea[class^='GrowingTextArea']")))
85 except:
86 # Reopen browser for login
87 if not browser:
88 driver.quit()
89 if hidden_display:
90 display.stop()
91 driver = get_browser(None, False, proxy)
92 driver.get(f"{cls.url}/{models[model]['name']}")
93 wait = WebDriverWait(driver, 240)
94 wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "textarea[class^='GrowingTextArea']")))
95 else:
96 raise RuntimeError("Prompt textarea not found. You may not be logged in.")
97
98 driver.find_element(By.CSS_SELECTOR, "footer textarea[class^='GrowingTextArea']").send_keys(prompt)
99 driver.find_element(By.CSS_SELECTOR, "footer button[class*='ChatMessageSendButton']").click()
100
101 try:
102 script = """
103 if(window._message && window._message != window._last_message) {
104 try {
105 return window._message.substring(window._last_message.length);
106 } finally {
107 window._last_message = window._message;
108 }
109 } else if(window._message_finished) {
110 return null;
111 } else {
112 return '';
113 }
114 """
115 while True:
116 chunk = driver.execute_script(script)
117 if chunk:
118 yield chunk
119 elif chunk != "":
120 break
121 else:
122 time.sleep(0.1)
123 finally:
124 driver.close()
125 if not browser:
126 time.sleep(0.1)
127 driver.quit()
128 if hidden_display:
129 display.stop()
Modified g4f/Provider/needs_auth/__init__.py +2 -1
@@ -3,4 +3,5 @@ from .Raycast import Raycast
3 3 from .Theb import Theb
4 4 from .HuggingChat import HuggingChat
5 5 from .OpenaiChat import OpenaiChat
6 from .OpenAssistant import OpenAssistant
6 from .OpenAssistant import OpenAssistant
7 from .Poe import Poe