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

XFEstudio/gpt4free

"create_async" support for BaseProvider, by using ThreadPoolExecutor Default Model for Vercel

348670fe
Heiner Lohaus <heiner@lohaus.eu>
提交于

代码差异

4 个文件 +156 -2
Added g4f/Provider/AItianhuSpace.py +73 -0
@@ -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})"
Modified g4f/Provider/Aivvm.py +3 -2
@@ -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
Modified g4f/Provider/__init__.py +2 -0
@@ -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',
Added g4f/requests.py +78 -0
@@ -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)