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

XFEstudio/gpt4free

Add proofofwork to OpenaiChat

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

代码差异

3 个文件 +91 -16
Modified g4f/Provider/needs_auth/OpenaiChat.py +44 -9
@@ -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 """
Added g4f/Provider/openai/proofofwork.py +39 -0
@@ -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
Modified g4f/Provider/you/har_file.py +8 -7
@@ -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()