返回提交历史
Modified
g4f/Provider/GptFree.py
+40
-32
XFEstudio/gpt4free
fix(Provider/GptFree): add retry option in case of _id_token failure
07acf08a
代码差异
1 个文件
+40
-32
@@ -15,6 +15,8 @@ class GptFree(AsyncGeneratorProvider, ProviderModelMixin):
15
15
16
16
default_model = ""
17
17
18
_id_token: str = None
19
18
20
@classmethod
19
21
async def create_async_generator(
20
22
cls,
@@ -26,16 +28,18 @@ class GptFree(AsyncGeneratorProvider, ProviderModelMixin):
26
28
headers = {
27
29
"accept": "*/*",
28
30
"accept-language": "en-US,en;q=0.9",
31
"cache-control": "no-cache",
29
32
"content-type": "application/json",
30
33
"origin": "https://gptfree.com",
34
"pragma": "no-cache",
31
35
"referer": "https://gptfree.com/",
32
"sec-ch-ua": '"Chromium";v="148", "Google Chrome";v="148", "Not/A)Brand";v="99"',
36
"sec-ch-ua": '"Not;A=Brand";v="8", "Chromium";v="150", "Google Chrome";v="150"',
33
37
"sec-ch-ua-mobile": "?0",
34
38
"sec-ch-ua-platform": '"Linux"',
35
39
"sec-fetch-dest": "empty",
36
40
"sec-fetch-mode": "cors",
37
41
"sec-fetch-site": "cross-site",
38
"user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36"
42
"user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36"
39
43
}
40
44
41
45
history = []
@@ -58,7 +62,6 @@ class GptFree(AsyncGeneratorProvider, ProviderModelMixin):
58
62
content = "\n".join(text_parts)
59
63
60
64
if msg["role"] == "system":
61
# Provider doesn't support system message directly, append it to the first user message or history
62
65
history.append({"type": "user", "content": content})
63
66
elif msg["role"] == "user":
64
67
current_message = content
@@ -94,34 +97,39 @@ class GptFree(AsyncGeneratorProvider, ProviderModelMixin):
94
97
firebase_api_key = "AIzaSyBdU-Np8RSh1tPSsPOWg3qIm6PnVK5PQb4"
95
98
96
99
async with ClientSession() as session:
97
if not hasattr(cls, '_id_token'):
98
auth_url = f"https://identitytoolkit.googleapis.com/v1/accounts:signUp?key={firebase_api_key}"
99
async with session.post(auth_url, json={"returnSecureToken": True}, proxy=proxy) as auth_resp:
100
auth_resp.raise_for_status()
101
auth_data = await auth_resp.json()
102
cls._id_token = auth_data["idToken"]
100
for attempt in range(2):
101
if not cls._id_token:
102
auth_url = f"https://identitytoolkit.googleapis.com/v1/accounts:signUp?key={firebase_api_key}"
103
async with session.post(auth_url, json={"returnSecureToken": True}, proxy=proxy) as auth_resp:
104
auth_resp.raise_for_status()
105
auth_data = await auth_resp.json()
106
cls._id_token = auth_data["idToken"]
103
107
104
headers["Authorization"] = f"Bearer {cls._id_token}"
108
headers["Authorization"] = f"Bearer {cls._id_token}"
105
109
106
async with session.post(
107
cls.api_endpoint,
108
headers=headers,
109
json=payload,
110
proxy=proxy
111
) as response:
112
if response.status == 401 and hasattr(cls, '_id_token'):
113
delattr(cls, '_id_token')
114
response.raise_for_status()
115
116
async for line in response.content:
117
line = line.decode('utf-8').strip()
118
if line.startswith('data: '):
119
data_str = line[6:]
120
if data_str == '{}':
121
continue
122
try:
123
data = json.loads(data_str)
124
if "response" in data:
125
yield data["response"]
126
except json.JSONDecodeError:
127
pass
110
async with session.post(
111
cls.api_endpoint,
112
headers=headers,
113
json=payload,
114
proxy=proxy
115
) as response:
116
if response.status == 401:
117
# Token expired or invalid, clear it and retry
118
cls._id_token = None
119
continue
120
121
response.raise_for_status()
122
123
async for line in response.content:
124
line = line.decode('utf-8').strip()
125
if line.startswith('data: '):
126
data_str = line[6:]
127
if data_str == '{}':
128
continue
129
try:
130
data = json.loads(data_str)
131
if "response" in data:
132
yield data["response"]
133
except json.JSONDecodeError:
134
pass
135
break