返回提交历史
Added
g4f/Provider/AItianhuSpace.py
+73
-0
Modified
g4f/Provider/Aivvm.py
+3
-2
Modified
g4f/Provider/__init__.py
+2
-0
Added
g4f/requests.py
+78
-0
XFEstudio/gpt4free
"create_async" support for BaseProvider, by using ThreadPoolExecutor Default Model for Vercel
348670fe
代码差异
4 个文件
+156
-2
@@ -0,0 +1,73 @@
1
from __future__ import annotations
2
3
import random, json
4
5
from g4f.requests import AsyncSession, StreamRequest
6
from .base_provider import AsyncGeneratorProvider, format_prompt
7
8
domains = {
9
"gpt-3.5-turbo": ".aitianhu.space",
10
"gpt-4": ".aitianhu.website",
11
}
12
13
class AItianhuSpace(AsyncGeneratorProvider):
14
url = "https://chat3.aiyunos.top/"
15
working = True
16
supports_gpt_35_turbo = True
17
18
@classmethod
19
async def create_async_generator(
20
cls,
21
model: str,
22
messages: list[dict[str, str]],
23
stream: bool = True,
24
**kwargs
25
) -> str:
26
if not model:
27
model = "gpt-3.5-turbo"
28
elif not model in domains:
29
raise ValueError(f"Model are not supported: {model}")
30
31
chars = 'abcdefghijklmnopqrstuvwxyz0123456789'
32
rand = ''.join(random.choice(chars) for _ in range(6))
33
domain = domains[model]
34
url = f'https://{rand}{domain}/api/chat-process'
35
36
headers = {
37
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
38
}
39
async with AsyncSession(headers=headers, impersonate="chrome107", verify=False) as session:
40
data = {
41
"prompt": format_prompt(messages),
42
"options": {},
43
"systemMessage": "You are ChatGPT, a large language model trained by OpenAI. Follow the user's instructions carefully.",
44
"temperature": 0.8,
45
"top_p": 1,
46
**kwargs
47
}
48
async with StreamRequest(session, "POST", url, json=data) as response:
49
response.raise_for_status()
50
async for line in response.content:
51
line = json.loads(line.rstrip())
52
if "detail" in line:
53
content = line["detail"]["choices"][0]["delta"].get("content")
54
if content:
55
yield content
56
elif "message" in line and "AI-4接口非常昂贵" in line["message"]:
57
raise RuntimeError("Rate limit for GPT 4 reached")
58
else:
59
raise RuntimeError("Response: {line}")
60
61
62
@classmethod
63
@property
64
def params(cls):
65
params = [
66
("model", "str"),
67
("messages", "list[dict[str, str]]"),
68
("stream", "bool"),
69
("temperature", "float"),
70
("top_p", "int"),
71
]
72
param = ", ".join([": ".join(p) for p in params])
73
return f"g4f.provider.{cls.__name__} supports: ({param})"
@@ -60,9 +60,10 @@ class Aivvm(BaseProvider):
60
60
61
61
response = requests.post(
62
62
"https://chat.aivvm.com/api/chat", headers=headers, json=json_data, stream=True)
63
response.raise_for_status()
63
64
64
for line in response.iter_content(chunk_size=1048):
65
yield line.decode('utf-8')
65
for chunk in response.iter_content(chunk_size=None):
66
yield chunk.decode('utf-8')
66
67
67
68
@classmethod
68
69
@property
@@ -4,6 +4,7 @@ from .Aichat import Aichat
4
4
from .Ails import Ails
5
5
from .AiService import AiService
6
6
from .AItianhu import AItianhu
7
from .AItianhuSpace import AItianhuSpace
7
8
from .Aivvm import Aivvm
8
9
from .Bard import Bard
9
10
from .Bing import Bing
@@ -52,6 +53,7 @@ __all__ = [
52
53
'Ails',
53
54
'AiService',
54
55
'AItianhu',
56
'AItianhuSpace',
55
57
'Aivvm',
56
58
'Bard',
57
59
'Bing',
@@ -0,0 +1,78 @@
1
from __future__ import annotations
2
3
import json, sys
4
from aiohttp import StreamReader
5
from aiohttp.base_protocol import BaseProtocol
6
7
from curl_cffi.requests import AsyncSession
8
from curl_cffi.requests.cookies import Request
9
from curl_cffi.requests.cookies import Response
10
11
12
class StreamResponse:
13
def __init__(self, inner: Response, content: StreamReader, request: Request):
14
self.inner = inner
15
self.content = content
16
self.request = request
17
self.status_code = inner.status_code
18
self.reason = inner.reason
19
self.ok = inner.ok
20
21
async def text(self) -> str:
22
content = await self.content.read()
23
return content.decode()
24
25
def raise_for_status(self):
26
if not self.ok:
27
raise RuntimeError(f"HTTP Error {self.status_code}: {self.reason}")
28
29
async def json(self, **kwargs):
30
return json.loads(await self.content.read(), **kwargs)
31
32
33
class StreamRequest:
34
def __init__(self, session: AsyncSession, method: str, url: str, **kwargs):
35
self.session = session
36
self.loop = session.loop
37
self.content = StreamReader(
38
BaseProtocol(session.loop),
39
sys.maxsize,
40
loop=session.loop
41
)
42
self.method = method
43
self.url = url
44
self.options = kwargs
45
46
def on_content(self, data):
47
if not self.enter.done():
48
self.enter.set_result(None)
49
self.content.feed_data(data)
50
51
def on_done(self, task):
52
self.content.feed_eof()
53
54
async def __aenter__(self) -> StreamResponse:
55
self.curl = await self.session.pop_curl()
56
self.enter = self.session.loop.create_future()
57
request, _, header_buffer = self.session._set_curl_options(
58
self.curl,
59
self.method,
60
self.url,
61
content_callback=self.on_content,
62
**self.options
63
)
64
handle = self.session.acurl.add_handle(self.curl)
65
self.handle = self.session.loop.create_task(handle)
66
self.handle.add_done_callback(self.on_done)
67
await self.enter
68
return StreamResponse(
69
self.session._parse_response(self.curl, request, _, header_buffer),
70
self.content,
71
request
72
)
73
74
async def __aexit__(self, exc_type, exc, tb):
75
await self.handle
76
self.curl.clean_after_perform()
77
self.curl.reset()
78
self.session.push_curl(self.curl)