返回提交历史
Modified
g4f/Provider/Bard.py
+11
-14
Modified
g4f/Provider/Bing.py
+6
-14
Modified
g4f/Provider/H2o.py
+70
-63
Deleted
g4f/Provider/Hugchat.py
+0
-65
Added
g4f/Provider/HuggingChat.py
+107
-0
Modified
g4f/Provider/Liaobots.py
+66
-47
Added
g4f/Provider/OpenAssistant.py
+98
-0
Modified
g4f/Provider/OpenaiChat.py
+24
-17
Modified
g4f/Provider/You.py
+29
-47
Modified
g4f/Provider/Yqcloud.py
+23
-29
Modified
g4f/Provider/__init__.py
+4
-2
Modified
g4f/Provider/base_provider.py
+23
-13
Modified
g4f/models.py
+7
-0
Added
testing/log_time.py
+25
-0
Modified
testing/test_needs_auth.py
+61
-60
XFEstudio/gpt4free
Add async support for H2o Add format_prompt helper Fix create_completion in AsyncGeneratorProvider Move get_cookies from constructor to function Add ow HuggingChat implement Remove need auth form Liabots Add staic cache for access_token in OpenaiChat Add OpenAssistant provider Support stream and async in You Support async and add userId in Yqcloud Add log_time module
7294abc8
代码差异
15 个文件
+554
-371
@@ -1,12 +1,9 @@
1
1
import json
2
2
import random
3
3
import re
4
5
4
from aiohttp import ClientSession
6
import asyncio
7
5
8
from ..typing import Any, CreateResult
9
from .base_provider import AsyncProvider, get_cookies
6
from .base_provider import AsyncProvider, get_cookies, format_prompt
10
7
11
8
class Bard(AsyncProvider):
12
9
url = "https://bard.google.com"
@@ -19,15 +16,14 @@ class Bard(AsyncProvider):
19
16
model: str,
20
17
messages: list[dict[str, str]],
21
18
proxy: str = None,
22
cookies: dict = get_cookies(".google.com"), **kwargs: Any,) -> str:
23
24
formatted = "\n".join(
25
["%s: %s" % (message["role"], message["content"]) for message in messages]
26
)
27
prompt = f"{formatted}\nAssistant:"
28
19
cookies: dict = None,
20
**kwargs
21
) -> str:
22
prompt = format_prompt(messages)
29
23
if proxy and "://" not in proxy:
30
24
proxy = f"http://{proxy}"
25
if not cookies:
26
cookies = get_cookies(".google.com")
31
27
32
28
headers = {
33
29
'authority': 'bard.google.com',
@@ -44,10 +40,11 @@ class Bard(AsyncProvider):
44
40
) as session:
45
41
async with session.get(cls.url, proxy=proxy) as response:
46
42
text = await response.text()
47
43
48
44
match = re.search(r'SNlM0e\":\"(.*?)\"', text)
49
if match:
50
snlm0e = match.group(1)
45
if not match:
46
raise RuntimeError("No snlm0e value.")
47
snlm0e = match.group(1)
51
48
52
49
params = {
53
50
'bl': 'boq_assistant-bard-web-server_20230326.21_p0',
@@ -15,8 +15,11 @@ class Bing(AsyncGeneratorProvider):
15
15
def create_async_generator(
16
16
model: str,
17
17
messages: list[dict[str, str]],
18
cookies: dict = get_cookies(".bing.com"), **kwargs) -> AsyncGenerator:
19
18
cookies: dict = None,
19
**kwargs
20
) -> AsyncGenerator:
21
if not cookies:
22
cookies = get_cookies(".bing.com")
20
23
if len(messages) < 2:
21
24
prompt = messages[0]["content"]
22
25
context = None
@@ -273,15 +276,4 @@ async def stream_generate(
273
276
final = True
274
277
break
275
278
finally:
276
await delete_conversation(session, conversation)
277
278
def run(generator: AsyncGenerator[Union[Any, str], Any]):
279
loop = asyncio.get_event_loop()
280
gen = generator.__aiter__()
281
282
while True:
283
try:
284
yield loop.run_until_complete(gen.__anext__())
285
286
except StopAsyncIteration:
287
break
279
await delete_conversation(session, conversation)
@@ -1,78 +1,85 @@
1
import json, uuid, requests
1
import json
2
import uuid
3
from aiohttp import ClientSession
2
4
3
from ..typing import Any, CreateResult
4
from .base_provider import BaseProvider
5
from ..typing import AsyncGenerator
6
from .base_provider import AsyncGeneratorProvider, format_prompt
5
7
6
8
7
class H2o(BaseProvider):
8
url = "https://gpt-gm.h2o.ai"
9
working = True
9
class H2o(AsyncGeneratorProvider):
10
url = "https://gpt-gm.h2o.ai"
11
working = True
10
12
supports_stream = True
11
13
model = "h2oai/h2ogpt-gm-oasst1-en-2048-falcon-40b-v1"
12
14
13
@staticmethod
14
def create_completion(
15
@classmethod
16
async def create_async_generator(
17
cls,
15
18
model: str,
16
19
messages: list[dict[str, str]],
17
stream: bool, **kwargs: Any) -> CreateResult:
18
19
conversation = ""
20
for message in messages:
21
conversation += "%s: %s\n" % (message["role"], message["content"])
22
conversation += "assistant: "
23
24
session = requests.Session()
25
26
headers = {"Referer": "https://gpt-gm.h2o.ai/r/jGfKSwU"}
27
data = {
28
"ethicsModalAccepted" : "true",
29
"shareConversationsWithModelAuthors": "true",
30
"ethicsModalAcceptedAt" : "",
31
"activeModel" : model,
32
"searchEnabled" : "true",
33
}
34
35
session.post("https://gpt-gm.h2o.ai/settings",
36
headers=headers, data=data)
37
20
proxy: str = None,
21
**kwargs
22
) -> AsyncGenerator:
23
model = model if model else cls.model
38
24
headers = {"Referer": "https://gpt-gm.h2o.ai/"}
39
data = {"model": model}
40
41
response = session.post("https://gpt-gm.h2o.ai/conversation",
42
headers=headers, json=data).json()
43
44
if "conversationId" not in response:
45
return
46
25
47
data = {
48
"inputs": conversation,
49
"parameters": {
50
"temperature" : kwargs.get("temperature", 0.4),
51
"truncate" : kwargs.get("truncate", 2048),
52
"max_new_tokens" : kwargs.get("max_new_tokens", 1024),
53
"do_sample" : kwargs.get("do_sample", True),
54
"repetition_penalty": kwargs.get("repetition_penalty", 1.2),
55
"return_full_text" : kwargs.get("return_full_text", False),
56
},
57
"stream" : True,
58
"options": {
59
"id" : kwargs.get("id", str(uuid.uuid4())),
60
"response_id" : kwargs.get("response_id", str(uuid.uuid4())),
61
"is_retry" : False,
62
"use_cache" : False,
63
"web_search_id": "",
64
},
65
}
26
async with ClientSession(
27
headers=headers
28
) as session:
29
data = {
30
"ethicsModalAccepted": "true",
31
"shareConversationsWithModelAuthors": "true",
32
"ethicsModalAcceptedAt": "",
33
"activeModel": model,
34
"searchEnabled": "true",
35
}
36
async with session.post(
37
"https://gpt-gm.h2o.ai/settings",
38
proxy=proxy,
39
data=data
40
) as response:
41
response.raise_for_status()
66
42
67
response = session.post(f"https://gpt-gm.h2o.ai/conversation/{response['conversationId']}",
68
headers=headers, json=data)
69
70
response.raise_for_status()
71
response.encoding = "utf-8"
72
generated_text = response.text.replace("\n", "").split("data:")
73
generated_text = json.loads(generated_text[-1])
43
async with session.post(
44
"https://gpt-gm.h2o.ai/conversation",
45
proxy=proxy,
46
json={"model": model},
47
) as response:
48
response.raise_for_status()
49
conversationId = (await response.json())["conversationId"]
74
50
75
yield generated_text["generated_text"]
51
data = {
52
"inputs": format_prompt(messages),
53
"parameters": {
54
"temperature": 0.4,
55
"truncate": 2048,
56
"max_new_tokens": 1024,
57
"do_sample": True,
58
"repetition_penalty": 1.2,
59
"return_full_text": False,
60
**kwargs
61
},
62
"stream": True,
63
"options": {
64
"id": str(uuid.uuid4()),
65
"response_id": str(uuid.uuid4()),
66
"is_retry": False,
67
"use_cache": False,
68
"web_search_id": "",
69
},
70
}
71
async with session.post(
72
f"https://gpt-gm.h2o.ai/conversation/{conversationId}",
73
proxy=proxy,
74
json=data
75
) as response:
76
start = "data:"
77
async for line in response.content:
78
line = line.decode("utf-8")
79
if line and line.startswith(start):
80
line = json.loads(line[len(start):-1])
81
if not line["token"]["special"]:
82
yield line["token"]["text"]
76
83
77
84
@classmethod
78
85
@property
@@ -1,65 +0,0 @@
1
has_module = False
2
try:
3
from hugchat.hugchat import ChatBot
4
except ImportError:
5
has_module = False
6
7
from .base_provider import BaseProvider, get_cookies
8
from g4f.typing import CreateResult
9
10
class Hugchat(BaseProvider):
11
url = "https://huggingface.co/chat/"
12
needs_auth = True
13
working = has_module
14
llms = ['OpenAssistant/oasst-sft-6-llama-30b-xor', 'meta-llama/Llama-2-70b-chat-hf']
15
16
@classmethod
17
def create_completion(
18
cls,
19
model: str,
20
messages: list[dict[str, str]],
21
stream: bool = False,
22
proxy: str = None,
23
cookies: str = get_cookies(".huggingface.co"), **kwargs) -> CreateResult:
24
25
bot = ChatBot(
26
cookies=cookies)
27
28
if proxy and "://" not in proxy:
29
proxy = f"http://{proxy}"
30
bot.session.proxies = {"http": proxy, "https": proxy}
31
32
if model:
33
try:
34
if not isinstance(model, int):
35
model = cls.llms.index(model)
36
bot.switch_llm(model)
37
except:
38
raise RuntimeError(f"Model are not supported: {model}")
39
40
if len(messages) > 1:
41
formatted = "\n".join(
42
["%s: %s" % (message["role"], message["content"]) for message in messages]
43
)
44
prompt = f"{formatted}\nAssistant:"
45
else:
46
prompt = messages.pop()["content"]
47
48
try:
49
yield bot.chat(prompt, **kwargs)
50
finally:
51
bot.delete_conversation(bot.current_conversation)
52
bot.current_conversation = ""
53
pass
54
55
@classmethod
56
@property
57
def params(cls):
58
params = [
59
("model", "str"),
60
("messages", "list[dict[str, str]]"),
61
("stream", "bool"),
62
("proxy", "str"),
63
]
64
param = ", ".join([": ".join(p) for p in params])
65
return f"g4f.provider.{cls.__name__} supports: ({param})"
@@ -0,0 +1,107 @@
1
import json
2
from aiohttp import ClientSession
3
4
from ..typing import AsyncGenerator
5
from .base_provider import AsyncGeneratorProvider, get_cookies, format_prompt
6
7
8
class HuggingChat(AsyncGeneratorProvider):
9
url = "https://huggingface.co/chat/"
10
needs_auth = True
11
working = True
12
model = "OpenAssistant/oasst-sft-6-llama-30b-xor"
13
14
@classmethod
15
async def create_async_generator(
16
cls,
17
model: str,
18
messages: list[dict[str, str]],
19
stream: bool = True,
20
proxy: str = None,
21
cookies: dict = None,
22
**kwargs
23
) -> AsyncGenerator:
24
if not cookies:
25
cookies = get_cookies(".huggingface.co")
26
model = model if model else cls.model
27
if proxy and "://" not in proxy:
28
proxy = f"http://{proxy}"
29
30
headers = {
31
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36',
32
}
33
async with ClientSession(
34
cookies=cookies,
35
headers=headers
36
) as session:
37
async with session.post("https://huggingface.co/chat/conversation", proxy=proxy, json={"model": model}) as response:
38
conversation_id = (await response.json())["conversationId"]
39
40
send = {
41
"inputs": format_prompt(messages),
42
"parameters": {
43
"temperature": 0.2,
44
"truncate": 1000,
45
"max_new_tokens": 1024,
46
"stop": ["</s>"],
47
"top_p": 0.95,
48
"repetition_penalty": 1.2,
49
"top_k": 50,
50
"return_full_text": False,
51
**kwargs
52
},
53
"stream": stream,
54
"options": {
55
"id": "9e9b8bc4-6604-40c6-994e-8eb78fa32e37",
56
"response_id": "04ce2602-3bea-45e8-8efc-cef00680376a",
57
"is_retry": False,
58
"use_cache": False,
59
"web_search_id": ""
60
}
61
}
62
start = "data:"
63
first = True
64
async with session.post(f"https://huggingface.co/chat/conversation/{conversation_id}", proxy=proxy, json=send) as response:
65
async for line in response.content:
66
line = line.decode("utf-8")
67
if not line:
68
continue
69
if not stream:
70
try:
71
data = json.loads(line)
72
except json.decoder.JSONDecodeError:
73
raise RuntimeError(f"No json: {line}")
74
if "error" in data:
75
raise RuntimeError(data["error"])
76
elif isinstance(data, list):
77
yield data[0]["generated_text"]
78
else:
79
raise RuntimeError(f"Response: {line}")
80
elif line.startswith(start):
81
line = json.loads(line[len(start):-1])
82
if not line:
83
continue
84
if "token" not in line:
85
raise RuntimeError(f"Response: {line}")
86
if not line["token"]["special"]:
87
if first:
88
yield line["token"]["text"].lstrip()
89
first = False
90
else:
91
yield line["token"]["text"]
92
93
async with session.delete(f"https://huggingface.co/chat/conversation/{conversation_id}", proxy=proxy) as response:
94
response.raise_for_status()
95
96
97
@classmethod
98
@property
99
def params(cls):
100
params = [
101
("model", "str"),
102
("messages", "list[dict[str, str]]"),
103
("stream", "bool"),
104
("proxy", "str"),
105
]
106
param = ", ".join([": ".join(p) for p in params])
107
return f"g4f.provider.{cls.__name__} supports: ({param})"
@@ -1,59 +1,77 @@
1
import uuid, requests
1
import uuid
2
import json
3
from aiohttp import ClientSession
2
4
3
from ..typing import Any, CreateResult
4
from .base_provider import BaseProvider
5
from ..typing import AsyncGenerator
6
from .base_provider import AsyncGeneratorProvider
5
7
8
models = {
9
"gpt-4": {
10
"id": "gpt-4",
11
"name": "GPT-4",
12
"maxLength": 24000,
13
"tokenLimit": 8000,
14
},
15
"gpt-3.5-turbo": {
16
"id": "gpt-3.5-turbo",
17
"name": "GPT-3.5",
18
"maxLength": 12000,
19
"tokenLimit": 4000,
20
},
21
"gpt-3.5-turbo-16k": {
22
"id": "gpt-3.5-turbo-16k",
23
"name": "GPT-3.5-16k",
24
"maxLength": 48000,
25
"tokenLimit": 16000,
26
},
27
}
6
28
7
class Liaobots(BaseProvider):
8
url: str = "https://liaobots.com"
9
supports_stream = True
10
needs_auth = True
11
supports_gpt_35_turbo = True
12
supports_gpt_4 = True
29
class Liaobots(AsyncGeneratorProvider):
30
url = "https://liaobots.com"
31
supports_stream = True
32
supports_gpt_35_turbo = True
33
supports_gpt_4 = True
34
_auth_code = None
13
35
14
@staticmethod
15
def create_completion(
36
@classmethod
37
async def create_async_generator(
38
cls,
16
39
model: str,
17
40
messages: list[dict[str, str]],
18
stream: bool, **kwargs: Any) -> CreateResult:
19
41
auth: str = None,
42
proxy: str = None,
43
**kwargs
44
) -> AsyncGenerator:
45
if proxy and "://" not in proxy:
46
proxy = f"http://{proxy}"
20
47
headers = {
21
"authority" : "liaobots.com",
22
"content-type" : "application/json",
23
"origin" : "https://liaobots.com",
24
"referer" : "https://liaobots.com/",
25
"user-agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
26
"x-auth-code" : str(kwargs.get("auth")),
27
}
28
29
models = {
30
"gpt-4": {
31
"id": "gpt-4",
32
"name": "GPT-4",
33
"maxLength": 24000,
34
"tokenLimit": 8000,
35
},
36
"gpt-3.5-turbo": {
37
"id": "gpt-3.5-turbo",
38
"name": "GPT-3.5",
39
"maxLength": 12000,
40
"tokenLimit": 4000,
41
},
42
}
43
json_data = {
44
"conversationId": str(uuid.uuid4()),
45
"model" : models[model],
46
"messages" : messages,
47
"key" : "",
48
"prompt" : "You are ChatGPT, a large language model trained by OpenAI. Follow the user's instructions carefully. Respond using markdown.",
48
"authority": "liaobots.com",
49
"content-type": "application/json",
50
"origin": "https://liaobots.com",
51
"referer": "https://liaobots.com/",
52
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
49
53
}
54
async with ClientSession(
55
headers=headers
56
) as session:
57
model = model if model in models else "gpt-3.5-turbo"
58
auth_code = auth if isinstance(auth, str) else cls._auth_code
59
if not auth_code:
60
async with session.post("https://liaobots.com/api/user", proxy=proxy, json={"authcode": ""}) as response:
61
response.raise_for_status()
62
auth_code = cls._auth_code = json.loads((await response.text()))["authCode"]
63
data = {
64
"conversationId": str(uuid.uuid4()),
65
"model": models[model],
66
"messages": messages,
67
"key": "",
68
"prompt": "You are ChatGPT, a large language model trained by OpenAI. Follow the user's instructions carefully.",
69
}
70
async with session.post("https://liaobots.com/api/chat", proxy=proxy, json=data, headers={"x-auth-code": auth_code}) as response:
71
response.raise_for_status()
72
async for line in response.content:
73
yield line.decode("utf-8")
50
74
51
response = requests.post("https://liaobots.com/api/chat",
52
headers=headers, json=json_data, stream=True)
53
54
response.raise_for_status()
55
for token in response.iter_content(chunk_size=2046):
56
yield token.decode("utf-8")
57
75
58
76
@classmethod
59
77
@property
@@ -62,6 +80,7 @@ class Liaobots(BaseProvider):
62
80
("model", "str"),
63
81
("messages", "list[dict[str, str]]"),
64
82
("stream", "bool"),
83
("proxy", "str"),
65
84
("auth", "str"),
66
85
]
67
86
param = ", ".join([": ".join(p) for p in params])
@@ -0,0 +1,98 @@
1
import json
2
from aiohttp import ClientSession
3
4
from ..typing import Any, AsyncGenerator
5
from .base_provider import AsyncGeneratorProvider, get_cookies, format_prompt
6
7
class OpenAssistant(AsyncGeneratorProvider):
8
url = "https://open-assistant.io/chat"
9
needs_auth = True
10
working = True
11
model = "OA_SFT_Llama_30B_6"
12
13
@classmethod
14
async def create_async_generator(
15
cls,
16
model: str,
17
messages: list[dict[str, str]],
18
proxy: str = None,
19
cookies: dict = None,
20
**kwargs: Any
21
) -> AsyncGenerator:
22
if proxy and "://" not in proxy:
23
proxy = f"http://{proxy}"
24
if not cookies:
25
cookies = get_cookies("open-assistant.io")
26
27
headers = {
28
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36',
29
}
30
async with ClientSession(
31
cookies=cookies,
32
headers=headers
33
) as session:
34
async with session.post("https://open-assistant.io/api/chat", proxy=proxy) as response:
35
chat_id = (await response.json())["id"]
36
37
data = {
38
"chat_id": chat_id,
39
"content": f"<s>[INST]\n{format_prompt(messages)}\n[/INST]",
40
"parent_id": None
41
}
42
async with session.post("https://open-assistant.io/api/chat/prompter_message", proxy=proxy, json=data) as response:
43
parent_id = (await response.json())["id"]
44
45
data = {
46
"chat_id": chat_id,
47
"parent_id": parent_id,
48
"model_config_name": model if model else cls.model,
49
"sampling_parameters":{
50
"top_k": 50,
51
"top_p": None,
52
"typical_p": None,
53
"temperature": 0.35,
54
"repetition_penalty": 1.1111111111111112,
55
"max_new_tokens": 1024,
56
**kwargs
57
},
58
"plugins":[]
59
}
60
async with session.post("https://open-assistant.io/api/chat/assistant_message", proxy=proxy, json=data) as response:
61
data = await response.json()
62
if "id" in data:
63
message_id = data["id"]
64
elif "message" in data:
65
raise RuntimeError(data["message"])
66
else:
67
response.raise_for_status()
68
69
params = {
70
'chat_id': chat_id,
71
'message_id': message_id,
72
}
73
async with session.post("https://open-assistant.io/api/chat/events", proxy=proxy, params=params) as response:
74
start = "data: "
75
async for line in response.content:
76
line = line.decode("utf-8")
77
if line and line.startswith(start):
78
line = json.loads(line[len(start):])
79
if line["event_type"] == "token":
80
yield line["text"]
81
82
params = {
83
'chat_id': chat_id,
84
}
85
async with session.delete("https://open-assistant.io/api/chat", proxy=proxy, params=params) as response:
86
response.raise_for_status()
87
88
@classmethod
89
@property
90
def params(cls):
91
params = [
92
("model", "str"),
93
("messages", "list[dict[str, str]]"),
94
("stream", "bool"),
95
("proxy", "str"),
96
]
97
param = ", ".join([": ".join(p) for p in params])
98
return f"g4f.provider.{cls.__name__} supports: ({param})"
@@ -4,8 +4,11 @@ try:
4
4
except ImportError:
5
5
has_module = False
6
6
7
from .base_provider import AsyncGeneratorProvider, get_cookies
8
from ..typing import AsyncGenerator
7
from .base_provider import AsyncGeneratorProvider, get_cookies, format_prompt
8
from ..typing import AsyncGenerator
9
from httpx import AsyncClient
10
import json
11
9
12
10
13
class OpenaiChat(AsyncGeneratorProvider):
11
14
url = "https://chat.openai.com"
@@ -14,6 +17,7 @@ class OpenaiChat(AsyncGeneratorProvider):
14
17
supports_gpt_35_turbo = True
15
18
supports_gpt_4 = True
16
19
supports_stream = True
20
_access_token = None
17
21
18
22
@classmethod
19
23
async def create_async_generator(
@@ -21,9 +25,9 @@ class OpenaiChat(AsyncGeneratorProvider):
21
25
model: str,
22
26
messages: list[dict[str, str]],
23
27
proxy: str = None,
24
access_token: str = None,
28
access_token: str = _access_token,
25
29
cookies: dict = None,
26
**kwargs
30
**kwargs: dict
27
31
) -> AsyncGenerator:
28
32
29
33
config = {"access_token": access_token, "model": model}
@@ -37,21 +41,12 @@ class OpenaiChat(AsyncGeneratorProvider):
37
41
)
38
42
39
43
if not access_token:
40
cookies = cookies if cookies else get_cookies("chat.openai.com")
41
response = await bot.session.get("https://chat.openai.com/api/auth/session", cookies=cookies)
42
access_token = response.json()["accessToken"]
43
bot.set_access_token(access_token)
44
45
if len(messages) > 1:
46
formatted = "\n".join(
47
["%s: %s" % ((message["role"]).capitalize(), message["content"]) for message in messages]
48
)
49
prompt = f"{formatted}\nAssistant:"
50
else:
51
prompt = messages.pop()["content"]
44
cookies = cookies if cookies else get_cookies("chat.openai.com")
45
cls._access_token = await get_access_token(bot.session, cookies)
46
bot.set_access_token(cls._access_token)
52
47
53
48
returned = None
54
async for message in bot.ask(prompt):
49
async for message in bot.ask(format_prompt(messages)):
55
50
message = message["message"]
56
51
if returned:
57
52
if message.startswith(returned):
@@ -61,6 +56,9 @@ class OpenaiChat(AsyncGeneratorProvider):
61
56
else:
62
57
yield message
63
58
returned = message
59
60
await bot.delete_conversation(bot.conversation_id)
61
64
62
65
63
@classmethod
66
64
@property
@@ -73,3 +71,12 @@ class OpenaiChat(AsyncGeneratorProvider):
73
71
]
74
72
param = ", ".join([": ".join(p) for p in params])
75
73
return f"g4f.provider.{cls.__name__} supports: ({param})"
74
75
76
async def get_access_token(session: AsyncClient, cookies: dict):
77
response = await session.get("https://chat.openai.com/api/auth/session", cookies=cookies)
78
response.raise_for_status()
79
try:
80
return response.json()["accessToken"]
81
except json.decoder.JSONDecodeError:
82
raise RuntimeError(f"Response: {response.text}")
@@ -1,55 +1,37 @@
1
import urllib.parse, json
1
from aiohttp import ClientSession
2
import json
2
3
3
from curl_cffi import requests
4
from ..typing import Any, CreateResult
5
from .base_provider import BaseProvider
4
from ..typing import AsyncGenerator
5
from .base_provider import AsyncGeneratorProvider, format_prompt, get_cookies
6
6
7
7
8
class You(BaseProvider):
9
url = "https://you.com"
10
working = True
8
class You(AsyncGeneratorProvider):
9
url = "https://you.com"
10
working = True
11
11
supports_gpt_35_turbo = True
12
supports_stream = True
12
13
13
14
@staticmethod
14
def create_completion(
15
async def create_async_generator(
15
16
model: str,
16
17
messages: list[dict[str, str]],
17
stream: bool, **kwargs: Any) -> CreateResult:
18
19
url_param = _create_url_param(messages, kwargs.get("history", []))
20
headers = _create_header()
21
22
response = requests.get(f"https://you.com/api/streamingSearch?{url_param}",
23
headers=headers, impersonate="chrome107")
24
25
response.raise_for_status()
26
27
start = 'data: {"youChatToken": '
28
for line in response.content.splitlines():
29
line = line.decode('utf-8')
30
if line.startswith(start):
31
yield json.loads(line[len(start): -1])
32
33
def _create_url_param(messages: list[dict[str, str]], history: list[dict[str, str]]):
34
prompt = ""
35
for message in messages:
36
prompt += "%s: %s\n" % (message["role"], message["content"])
37
prompt += "assistant:"
38
chat = _convert_chat(history)
39
param = {"q": prompt, "domain": "youchat", "chat": chat}
40
return urllib.parse.urlencode(param)
41
42
43
def _convert_chat(messages: list[dict[str, str]]):
44
message_iter = iter(messages)
45
return [
46
{"question": user["content"], "answer": assistant["content"]}
47
for user, assistant in zip(message_iter, message_iter)
48
]
49
50
51
def _create_header():
52
return {
53
"accept": "text/event-stream",
54
"referer": "https://you.com/search?fromSearchBar=true&tbm=youchat",
55
}
18
cookies: dict = None,
19
**kwargs,
20
) -> AsyncGenerator:
21
if not cookies:
22
cookies = get_cookies("you.com")
23
headers = {
24
"Accept": "text/event-stream",
25
"Referer": "https://you.com/search?fromSearchBar=true&tbm=youchat",
26
"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/116.0"
27
}
28
async with ClientSession(headers=headers, cookies=cookies) as session:
29
async with session.get(
30
"https://you.com/api/streamingSearch",
31
params={"q": format_prompt(messages), "domain": "youchat", "chat": ""},
32
) as response:
33
start = 'data: {"youChatToken": '
34
async for line in response.content:
35
line = line.decode('utf-8')
36
if line.startswith(start):
37
yield json.loads(line[len(start): -2])
@@ -1,29 +1,27 @@
1
import requests
1
from aiohttp import ClientSession
2
2
3
from ..typing import Any, CreateResult
4
from .base_provider import BaseProvider
3
from .base_provider import AsyncProvider, format_prompt
5
4
6
5
7
class Yqcloud(BaseProvider):
8
url = "https://chat9.yqcloud.top/"
9
working = True
10
supports_gpt_35_turbo = True
6
class Yqcloud(AsyncProvider):
7
url = "https://chat9.yqcloud.top/"
8
working = True
9
supports_gpt_35_turbo = True
11
10
12
11
@staticmethod
13
def create_completion(
12
async def create_async(
14
13
model: str,
15
14
messages: list[dict[str, str]],
16
stream: bool, **kwargs: Any) -> CreateResult:
17
18
headers = _create_header()
19
payload = _create_payload(messages)
20
21
response = requests.post("https://api.aichatos.cloud/api/generateStream",
22
headers=headers, json=payload)
23
24
response.raise_for_status()
25
response.encoding = 'utf-8'
26
yield response.text
15
proxy: str = None,
16
**kwargs,
17
) -> str:
18
async with ClientSession(
19
headers=_create_header()
20
) as session:
21
payload = _create_payload(messages)
22
async with session.post("https://api.aichatos.cloud/api/generateStream", proxy=proxy, json=payload) as response:
23
response.raise_for_status()
24
return await response.text()
27
25
28
26
29
27
def _create_header():
@@ -35,15 +33,11 @@ def _create_header():
35
33
36
34
37
35
def _create_payload(messages: list[dict[str, str]]):
38
prompt = ""
39
for message in messages:
40
prompt += "%s: %s\n" % (message["role"], message["content"])
41
prompt += "assistant:"
42
43
36
return {
44
"prompt" : prompt,
45
"network" : True,
46
"system" : "",
37
"prompt": format_prompt(messages),
38
"network": True,
39
"system": "",
47
40
"withoutContext": False,
48
"stream" : False,
49
}
41
"stream": False,
42
"userId": "#/chat/1693025544336"
43
}
@@ -13,11 +13,12 @@ from .EasyChat import EasyChat
13
13
from .Forefront import Forefront
14
14
from .GetGpt import GetGpt
15
15
from .H2o import H2o
16
from .Hugchat import Hugchat
16
from .HuggingChat import HuggingChat
17
17
from .Liaobots import Liaobots
18
18
from .Lockchat import Lockchat
19
19
from .Opchatgpts import Opchatgpts
20
20
from .OpenaiChat import OpenaiChat
21
from .OpenAssistant import OpenAssistant
21
22
from .Raycast import Raycast
22
23
from .Theb import Theb
23
24
from .Vercel import Vercel
@@ -48,12 +49,13 @@ __all__ = [
48
49
'Forefront',
49
50
'GetGpt',
50
51
'H2o',
51
'Hugchat',
52
'HuggingChat',
52
53
'Liaobots',
53
54
'Lockchat',
54
55
'Opchatgpts',
55
56
'Raycast',
56
57
'OpenaiChat',
58
'OpenAssistant',
57
59
'Theb',
58
60
'Vercel',
59
61
'Wewordle',
@@ -4,8 +4,7 @@ from ..typing import Any, CreateResult, AsyncGenerator, Union
4
4
5
5
import browser_cookie3
6
6
import asyncio
7
from time import time
8
import math
7
9
8
10
9
class BaseProvider(ABC):
11
10
url: str
@@ -48,6 +47,17 @@ def get_cookies(cookie_domain: str) -> dict:
48
47
return _cookies[cookie_domain]
49
48
50
49
50
def format_prompt(messages: list[dict[str, str]], add_special_tokens=False):
51
if add_special_tokens or len(messages) > 1:
52
formatted = "\n".join(
53
["%s: %s" % ((message["role"]).capitalize(), message["content"]) for message in messages]
54
)
55
return f"{formatted}\nAssistant:"
56
else:
57
return messages.pop()["content"]
58
59
60
51
61
class AsyncProvider(BaseProvider):
52
62
@classmethod
53
63
def create_completion(
@@ -72,20 +82,19 @@ class AsyncGeneratorProvider(AsyncProvider):
72
82
cls,
73
83
model: str,
74
84
messages: list[dict[str, str]],
75
stream: bool = True, **kwargs: Any) -> CreateResult:
76
77
if stream:
78
yield from run_generator(cls.create_async_generator(model, messages, **kwargs))
79
else:
80
yield from AsyncProvider.create_completion(cls=cls, model=model, messages=messages, **kwargs)
85
stream: bool = True,
86
**kwargs
87
) -> CreateResult:
88
yield from run_generator(cls.create_async_generator(model, messages, stream=stream, **kwargs))
81
89
82
90
@classmethod
83
91
async def create_async(
84
92
cls,
85
93
model: str,
86
messages: list[dict[str, str]], **kwargs: Any) -> str:
87
88
chunks = [chunk async for chunk in cls.create_async_generator(model, messages, **kwargs)]
94
messages: list[dict[str, str]],
95
**kwargs
96
) -> str:
97
chunks = [chunk async for chunk in cls.create_async_generator(model, messages, stream=False, **kwargs)]
89
98
if chunks:
90
99
return "".join(chunks)
91
100
@@ -93,8 +102,9 @@ class AsyncGeneratorProvider(AsyncProvider):
93
102
@abstractmethod
94
103
def create_async_generator(
95
104
model: str,
96
messages: list[dict[str, str]]) -> AsyncGenerator:
97
105
messages: list[dict[str, str]],
106
**kwargs
107
) -> AsyncGenerator:
98
108
raise NotImplementedError()
99
109
100
110