返回提交历史
Modified
g4f/Provider/AItianhuSpace.py
+109
-76
Modified
g4f/Provider/MyShell.py
+4
-4
Modified
g4f/Provider/helper.py
+5
-5
Added
g4f/Provider/needs_auth/Poe.py
+129
-0
Modified
g4f/Provider/needs_auth/__init__.py
+2
-1
XFEstudio/gpt4free
Add Poe Provider, Update AItianhuSpace Porvider
92908b43
代码差异
5 个文件
+249
-86
@@ -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()
@@ -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 != "":
@@ -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:
@@ -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()
@@ -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