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

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
Heiner Lohaus <heiner.lohaus@netformic.com>
提交于

代码差异

15 个文件 +554 -371
Modified g4f/Provider/Bard.py +11 -14
@@ -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',
Modified g4f/Provider/Bing.py +6 -14
@@ -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)
Modified g4f/Provider/H2o.py +70 -63
@@ -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
Deleted g4f/Provider/Hugchat.py +0 -65
@@ -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})"
Added g4f/Provider/HuggingChat.py +107 -0
@@ -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})"
Modified g4f/Provider/Liaobots.py +66 -47
@@ -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])
Added g4f/Provider/OpenAssistant.py +98 -0
@@ -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})"
Modified g4f/Provider/OpenaiChat.py +24 -17
@@ -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}")
Modified g4f/Provider/You.py +29 -47
@@ -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])
Modified g4f/Provider/Yqcloud.py +23 -29
@@ -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 }
Modified g4f/Provider/__init__.py +4 -2
@@ -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',
Modified g4f/Provider/base_provider.py +23 -13
@@ -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
Modified g4f/models.py +7 -0
Added testing/log_time.py +25 -0
Modified testing/test_needs_auth.py +61 -60