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

XFEstudio/gpt4free

Fix OpenaiChat provider, improve proofofwork

96e378e9
Heiner Lohaus <hlohaus@users.noreply.github.com>
提交于

代码差异

4 个文件 +62 -57
Modified g4f/Provider/needs_auth/OpenaiChat.py +48 -33
@@ -330,6 +330,7 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
330 330 image: ImageType = None,
331 331 image_name: str = None,
332 332 return_conversation: bool = False,
333 max_retries: int = 3,
333 334 **kwargs
334 335 ) -> AsyncResult:
335 336 """
@@ -409,36 +410,6 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
409 410 raise error
410 411 cls.default_model = cls.get_model(await cls.get_default_model(session, cls._headers))
411 412
412 async with session.post(
413 f"{cls.url}/backend-anon/sentinel/chat-requirements"
414 if cls._api_key is None else
415 f"{cls.url}/backend-api/sentinel/chat-requirements",
416 json={"conversation_mode_kind": "primary_assistant"},
417 #json={"p": generate_proof_token(True, user_agent=cls._headers["user-agent"], proofTokens=proofTokens)},
418 headers=cls._headers
419 ) as response:
420 cls._update_request_args(session)
421 await raise_for_status(response)
422 data = await response.json()
423 need_arkose = data.get("arkose", {}).get("required")
424 chat_token = data["token"]
425 proofofwork = ""
426 if "proofofwork" in data:
427 proofofwork = generate_proof_token(**data["proofofwork"], user_agent=cls._headers["user-agent"], proofTokens=proofTokens)
428
429 if need_arkose and arkose_token is None:
430 arkose_token, api_key, cookies, headers = await getArkoseAndAccessToken(proxy)
431 cls._create_request_args(cookies, headers)
432 cls._set_api_key(api_key)
433 if arkose_token is None:
434 raise MissingAuthError("No arkose token found in .har file")
435
436 if debug.logging:
437 print(
438 'Arkose:', False if not need_arkose else arkose_token[:12]+"...",
439 'Proofofwork:', False if proofofwork is None else proofofwork[:12]+"...",
440 )
441
442 413 try:
443 414 image_request = await cls.upload_image(session, cls._headers, image, image_name) if image else None
444 415 except Exception as e:
@@ -457,6 +428,43 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
457 428 auto_continue = False
458 429 conversation.finish_reason = None
459 430 while conversation.finish_reason is None:
431 async with session.post(
432 f"{cls.url}/backend-anon/sentinel/chat-requirements"
433 if cls._api_key is None else
434 f"{cls.url}/backend-api/sentinel/chat-requirements",
435 json={"p": generate_proof_token(True, user_agent=cls._headers["user-agent"], proofTokens=proofTokens)},
436 headers=cls._headers
437 ) as response:
438 cls._update_request_args(session)
439 await raise_for_status(response)
440 requirements = await response.json()
441 need_arkose = requirements.get("arkose", {}).get("required")
442 chat_token = requirements["token"]
443
444 if need_arkose and arkose_token is None:
445 arkose_token, api_key, cookies, headers, proofTokens = await getArkoseAndAccessToken(proxy)
446 cls._create_request_args(cookies, headers)
447 cls._set_api_key(api_key)
448 if arkose_token is None:
449 raise MissingAuthError("No arkose token found in .har file")
450
451 if "proofofwork" in requirements:
452 proofofwork = generate_proof_token(
453 **requirements["proofofwork"],
454 user_agent=cls._headers["user-agent"],
455 proofTokens=proofTokens
456 )
457 if debug.logging:
458 print(
459 'Arkose:', False if not need_arkose else arkose_token[:12]+"...",
460 'Proofofwork:', False if proofofwork is None else proofofwork[:12]+"...",
461 )
462 ws = None
463 if need_arkose:
464 async with session.post("https://chatgpt.com/backend-api/register-websocket", headers=cls._headers) as response:
465 wss_url = (await response.json()).get("wss_url")
466 if wss_url:
467 ws = await session.ws_connect(wss_url)
460 468 websocket_request_id = str(uuid.uuid4())
461 469 data = {
462 470 "action": action,
@@ -488,8 +496,14 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
488 496 headers=headers
489 497 ) as response:
490 498 cls._update_request_args(session)
499 if response.status == 403 and max_retries > 0:
500 max_retries -= 1
501 if debug.logging:
502 print(f"Retry: Error {response.status}: {await response.text()}")
503 await asyncio.sleep(5)
504 continue
491 505 await raise_for_status(response)
492 async for chunk in cls.iter_messages_chunk(response.iter_lines(), session, conversation):
506 async for chunk in cls.iter_messages_chunk(response.iter_lines(), session, conversation, ws):
493 507 if return_conversation:
494 508 history_disabled = False
495 509 return_conversation = False
@@ -519,13 +533,14 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
519 533 cls,
520 534 messages: AsyncIterator,
521 535 session: StreamSession,
522 fields: Conversation
536 fields: Conversation,
537 ws = None
523 538 ) -> AsyncIterator:
524 539 last_message: int = 0
525 540 async for message in messages:
526 541 if message.startswith(b'{"wss_url":'):
527 542 message = json.loads(message)
528 ws = await session.ws_connect(message["wss_url"])
543 ws = await session.ws_connect(message["wss_url"]) if ws is None else ws
529 544 try:
530 545 async for chunk in cls.iter_messages_chunk(
531 546 cls.iter_messages_ws(ws, message["conversation_id"], hasattr(ws, "recv")),
Modified g4f/Provider/openai/har_file.py +4 -3
@@ -35,6 +35,7 @@ headers: dict = None
35 35 proofTokens: list = []
36 36
37 37 def readHAR():
38 global proofTokens
38 39 dirPath = "./"
39 40 harPath = []
40 41 chatArks = []
@@ -77,8 +78,8 @@ def readHAR():
77 78 if not accessToken:
78 79 raise NoValidHarFileError("No accessToken found in .har files")
79 80 if not chatArks:
80 return None, accessToken, cookies, headers, proofTokens
81 return chatArks.pop(), accessToken, cookies, headers, proofTokens
81 return None, accessToken, cookies, headers
82 return chatArks.pop(), accessToken, cookies, headers
82 83
83 84 def get_headers(entry) -> dict:
84 85 return {h['name'].lower(): h['value'] for h in entry['request']['headers'] if h['name'].lower() not in ['content-length', 'cookie'] and not h['name'].startswith(':')}
@@ -145,7 +146,7 @@ def getN() -> str:
145 146 async def getArkoseAndAccessToken(proxy: str) -> tuple[str, str, dict, dict]:
146 147 global chatArk, accessToken, cookies, headers, proofTokens
147 148 if chatArk is None or accessToken is None:
148 chatArk, accessToken, cookies, headers, proofTokens = readHAR()
149 chatArk, accessToken, cookies, headers = readHAR()
149 150 if chatArk is None:
150 151 return None, accessToken, cookies, headers, proofTokens
151 152 newReq = genArkReq(chatArk)
Modified g4f/Provider/openai/proofofwork.py +9 -20
@@ -4,22 +4,18 @@ import json
4 4 import base64
5 5 from datetime import datetime, timezone
6 6
7 proof_token_cache: dict = {}
8 7
9 def generate_proof_token(required: bool, seed: str = None, difficulty: str = None, user_agent: str = None, proofTokens: list = None):
8 def generate_proof_token(required: bool, seed: str = "", difficulty: str = "", user_agent: str = None, proofTokens: list = None):
10 9 if not required:
11 10 return
12 if seed is not None and seed in proof_token_cache:
13 return proof_token_cache[seed]
14
15 # Get current UTC time
16 now_utc = datetime.now(timezone.utc)
17 parse_time = now_utc.strftime('%a, %d %b %Y %H:%M:%S GMT')
18 11
19 12 if proofTokens:
20 config = random.choice(proofTokens)
13 config = proofTokens[-1]
21 14 else:
22 15 screen = random.choice([3008, 4010, 6000]) * random.choice([1, 2, 4])
16 # Get current UTC time
17 now_utc = datetime.now(timezone.utc)
18 parse_time = now_utc.strftime('%a, %d %b %Y %H:%M:%S GMT')
23 19 config = [
24 20 screen, parse_time,
25 21 None, 0, user_agent,
@@ -31,22 +27,15 @@ def generate_proof_token(required: bool, seed: str = None, difficulty: str = Non
31 27 random.choice(["alert", "ontransitionend", "onprogress"])
32 28 ]
33 29
34 config[1] = parse_time
35 config[4] = user_agent
36 config[7] = random.randint(101, 2100)
37
38 diff_len = None if difficulty is None else len(difficulty)
30 diff_len = len(difficulty)
39 31 for i in range(100000):
40 32 config[3] = i
41 33 json_data = json.dumps(config)
42 34 base = base64.b64encode(json_data.encode()).decode()
43 hash_value = hashlib.sha3_512((seed or "" + base).encode()).digest()
35 hash_value = hashlib.sha3_512((seed + base).encode()).digest()
44 36
45 if difficulty is None or hash_value.hex()[:diff_len] <= difficulty:
46 if seed is None:
47 return "gAAAAAC" + base
48 proof_token_cache[seed] = "gAAAAAB" + base
49 return proof_token_cache[seed]
37 if hash_value.hex()[:diff_len] <= difficulty:
38 return "gAAAAAB" + base
50 39
51 40 fallback_base = base64.b64encode(f'"{seed}"'.encode()).decode()
52 41 return "gAAAAABwQ8Lk5FbGpA2NcR9dShT6gYjU7VxZ4D" + fallback_base
Modified g4f/Provider/you/har_file.py +1 -1
@@ -115,7 +115,7 @@ async def get_telemetry_ids(proxy: str = None) -> list:
115 115 if page is not None:
116 116 await page.close()
117 117 if browser is not None:
118 await browser.close()
118 await browser.stop()
119 119 except Exception as e:
120 120 if debug.logging:
121 121 logging.error(e)