返回提交历史
Modified
g4f/Provider/needs_auth/OpenaiChat.py
+44
-9
Added
g4f/Provider/openai/proofofwork.py
+39
-0
Modified
g4f/Provider/you/har_file.py
+8
-7
XFEstudio/gpt4free
Add proofofwork to OpenaiChat
10896102
代码差异
3 个文件
+91
-16
@@ -24,15 +24,31 @@ except ImportError:
24
24
from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin
25
25
from ...webdriver import get_browser
26
26
from ...typing import AsyncResult, Messages, Cookies, ImageType, AsyncIterator
27
from ...requests import DEFAULT_HEADERS, get_args_from_browser, raise_for_status
27
from ...requests import get_args_from_browser, raise_for_status
28
28
from ...requests.aiohttp import StreamSession
29
29
from ...image import to_image, to_bytes, ImageResponse, ImageRequest
30
30
from ...errors import MissingAuthError, ResponseError
31
31
from ...providers.conversation import BaseConversation
32
32
from ..helper import format_cookies
33
33
from ..openai.har_file import getArkoseAndAccessToken, NoValidHarFileError
34
from ..openai.proofofwork import generate_proof_token
34
35
from ... import debug
35
36
37
DEFAULT_HEADERS = {
38
"accept": "*/*",
39
"accept-encoding": "gzip, deflate, br, zstd",
40
"accept-language": "en-US,en;q=0.5",
41
"referer": "https://chat.openai.com/",
42
"sec-ch-ua": "\"Brave\";v=\"123\", \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"123\"",
43
"sec-ch-ua-mobile": "?0",
44
"sec-ch-ua-platform": "\"Windows\"",
45
"sec-fetch-dest": "empty",
46
"sec-fetch-mode": "cors",
47
"sec-fetch-site": "same-origin",
48
"sec-gpc": "1",
49
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
50
}
51
36
52
class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
37
53
"""A class for creating and managing conversations with OpenAI chat service"""
38
54
@@ -355,11 +371,21 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
355
371
cls._set_api_key(api_key)
356
372
357
373
if cls.default_model is None and (not cls.needs_auth or cls._api_key is not None):
374
if cls._api_key is None:
375
cls._create_request_args(cookies)
376
async with session.get(
377
f"{cls.url}/",
378
headers=DEFAULT_HEADERS
379
) as response:
380
cls._update_request_args(session)
381
await raise_for_status(response)
358
382
try:
359
383
if not model:
360
384
cls.default_model = cls.get_model(await cls.get_default_model(session, cls._headers))
361
385
else:
362
386
cls.default_model = cls.get_model(model)
387
except MissingAuthError:
388
pass
363
389
except Exception as e:
364
390
api_key = cls._api_key = None
365
391
cls._create_request_args()
@@ -395,9 +421,9 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
395
421
blob = data["arkose"]["dx"]
396
422
need_arkose = data["arkose"]["required"]
397
423
chat_token = data["token"]
398
399
if debug.logging:
400
print(f'Arkose: {need_arkose} Turnstile: {data["turnstile"]["required"]}')
424
proofofwork = ""
425
if "proofofwork" in data:
426
proofofwork = generate_proof_token(**data["proofofwork"], user_agent=cls._headers["user-agent"])
401
427
402
428
if need_arkose and arkose_token is None:
403
429
arkose_token, api_key, cookies, headers = await getArkoseAndAccessToken(proxy)
@@ -405,6 +431,13 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
405
431
cls._set_api_key(api_key)
406
432
if arkose_token is None:
407
433
raise MissingAuthError("No arkose token found in .har file")
434
435
if debug.logging:
436
print(
437
'Arkose:', False if not need_arkose else arkose_token[:12]+"...",
438
'Turnstile:', data["turnstile"]["required"],
439
'Proofofwork:', False if proofofwork is None else proofofwork[:12]+"...",
440
)
408
441
409
442
try:
410
443
image_request = await cls.upload_image(session, cls._headers, image, image_name) if image else None
@@ -439,12 +472,14 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
439
472
messages = messages if conversation_id is None else [messages[-1]]
440
473
data["messages"] = cls.create_messages(messages, image_request)
441
474
headers = {
442
"Accept": "text/event-stream",
443
"OpenAI-Sentinel-Chat-Requirements-Token": chat_token,
475
"accept": "text/event-stream",
476
"Openai-Sentinel-Chat-Requirements-Token": chat_token,
444
477
**cls._headers
445
478
}
446
479
if need_arkose:
447
headers["OpenAI-Sentinel-Arkose-Token"] = arkose_token
480
headers["Openai-Sentinel-Arkose-Token"] = arkose_token
481
if proofofwork is not None:
482
headers["Openai-Sentinel-Proof-Token"] = proofofwork
448
483
async with session.post(
449
484
f"{cls.url}/backend-anon/conversation" if cls._api_key is None else
450
485
f"{cls.url}/backend-api/conversation",
@@ -671,8 +706,6 @@ this.fetch = async (url, options) => {
671
706
return {
672
707
**DEFAULT_HEADERS,
673
708
"content-type": "application/json",
674
"oai-device-id": str(uuid.uuid4()),
675
"oai-language": "en-US",
676
709
}
677
710
678
711
@classmethod
@@ -698,6 +731,8 @@ this.fetch = async (url, options) => {
698
731
@classmethod
699
732
def _update_cookie_header(cls):
700
733
cls._headers["cookie"] = format_cookies(cls._cookies)
734
if "oai-did" in cls._cookies:
735
cls._headers["oai-device-id"] = cls._cookies["oai-did"]
701
736
702
737
class Conversation(BaseConversation):
703
738
"""
@@ -0,0 +1,39 @@
1
import random
2
import hashlib
3
import json
4
import base64
5
from datetime import datetime, timedelta, timezone
6
7
def generate_proof_token(required: bool, seed: str, difficulty: str, user_agent: str):
8
if not required:
9
return
10
11
cores = [8, 12, 16, 24]
12
screens = [3000, 4000, 6000]
13
14
core = random.choice(cores)
15
screen = random.choice(screens)
16
17
# Get current UTC time
18
now_utc = datetime.now(timezone.utc)
19
# Convert UTC time to Eastern Time
20
now_et = now_utc.astimezone(timezone(timedelta(hours=-5)))
21
22
parse_time = now_et.strftime('%a, %d %b %Y %H:%M:%S GMT')
23
24
config = [core + screen, parse_time, 4294705152, 0, user_agent]
25
26
diff_len = len(difficulty) // 2
27
28
for i in range(100000):
29
config[3] = i
30
json_data = json.dumps(config)
31
base = base64.b64encode(json_data.encode()).decode()
32
hash_value = hashlib.sha3_512((seed + base).encode()).digest()
33
34
if hash_value.hex()[:diff_len] <= difficulty:
35
result = "gAAAAAB" + base
36
return result
37
38
fallback_base = base64.b64encode(f'"{seed}"'.encode()).decode()
39
return "gAAAAABwQ8Lk5FbGpA2NcR9dShT6gYjU7VxZ4D" + fallback_base
@@ -85,20 +85,21 @@ async def get_telemetry_ids(proxy: str = None) -> list:
85
85
from nodriver import start
86
86
except ImportError:
87
87
raise MissingRequirementsError('Add .har file from you.com or install "nodriver" package | pip install -U nodriver')
88
page = None
88
89
try:
89
90
browser = await start()
90
tab = browser.main_tab
91
await browser.get("https://you.com")
91
page = await browser.get("https://you.com")
92
92
93
while not await tab.evaluate('"GetTelemetryID" in this'):
94
await tab.sleep(1)
93
while not await page.evaluate('"GetTelemetryID" in this'):
94
await page.sleep(1)
95
95
96
96
async def get_telemetry_id():
97
return await tab.evaluate(
97
return await page.evaluate(
98
98
f'this.GetTelemetryID("{public_token}", "{telemetry_url}");',
99
99
await_promise=True
100
100
)
101
101
102
return [await get_telemetry_id() for _ in range(1)]
102
return [await get_telemetry_id()]
103
103
finally:
104
await tab.close()
104
if page is not None:
105
await page.close()