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

XFEstudio/gpt4free

feat: enhance Copilot and Yupp classes with session ID and credit fetching functionality

4aa01b58
hlohaus <983577+hlohaus@users.noreply.github.com>
提交于

代码差异

3 个文件 +75 -34
Modified g4f/Provider/Copilot.py +2 -1
@@ -2,6 +2,7 @@ from __future__ import annotations
2 2
3 3 import os
4 4 import json
5 import uuid
5 6 import asyncio
6 7 import base64
7 8 import random
@@ -135,7 +136,7 @@ class Copilot(AsyncAuthedProvider, ProviderModelMixin):
135 136 if not has_curl_cffi:
136 137 raise MissingRequirementsError('Install or update "curl_cffi" package | pip install -U curl_cffi')
137 138 model = cls.get_model(model)
138 websocket_url = cls.websocket_url
139 websocket_url = cls.websocket_url + f"&clientSessionId={uuid.uuid4()}"
139 140 headers = DEFAULT_HEADERS.copy()
140 141 headers["origin"] = cls.url
141 142 headers["referer"] = cls.url + "/"
Modified g4f/Provider/CopilotSession.py +5 -1
@@ -69,6 +69,7 @@ class CopilotSession(AsyncAuthedProvider, ProviderModelMixin):
69 69 cls,
70 70 model: str,
71 71 messages: Messages,
72 auth_result: AuthResult,
72 73 proxy: str = None,
73 74 timeout: int = 30,
74 75 prompt: str = None,
@@ -87,9 +88,12 @@ class CopilotSession(AsyncAuthedProvider, ProviderModelMixin):
87 88 page = await session.get(url)
88 89 await page.send(cdp.network.enable())
89 90 queue = asyncio.Queue()
91 def handle_ws_message(event):
92 if hasattr(event, "response") and event.response.payload_data:
93 queue.put_nowait((event.request_id, event.response.payload_data))
90 94 page.add_handler(
91 95 cdp.network.WebSocketFrameReceived,
92 lambda event: queue.put_nowait((event.request_id, event.response.payload_data)),
96 handle_ws_message
93 97 )
94 98 textarea = await page.select("textarea")
95 99 if textarea is not None:
Modified g4f/Provider/Yupp.py +68 -32
@@ -2,6 +2,7 @@ import asyncio
2 2 import hashlib
3 3 import json
4 4 import os
5 import random
5 6 import re
6 7 import time
7 8 import uuid
@@ -159,32 +160,28 @@ async def claim_yupp_reward(
159 160 def sync_record_model_feedback(
160 161 scraper: CloudScraper,
161 162 account: Dict[str, Any],
162 turn_id: str,
163 left_message_id: str,
164 right_message_id: str,
163 reward_kw: Dict[str, str]
165 164 ) -> Optional[str]:
166 165 try:
167 log_debug(f"Recording model feedback for turn {turn_id}...")
168 url = "https://yupp.ai/api/trpc/evals.recordModelFeedback?batch=1"
169 payload = {
170 "0": {
171 "json": {
172 "turnId": turn_id,
173 "evalType": "SELECTION",
174 "messageEvals": [
175 {
176 "messageId": right_message_id,
177 "rating": "GOOD",
178 "reasons": ["Fast"],
179 },
180 {"messageId": left_message_id, "rating": "BAD", "reasons": []},
181 ],
182 "comment": "",
183 "requireReveal": False,
184 }
185 }
186 }
166 url = "https://yupp.ai/api/trpc/evals.getTurnAnnotations"
167 payload = {"0": {"json": {"turnId": reward_kw["turn_id"]}}}
187 168 scraper.cookies.set("__Secure-yupp.session-token", account["token"])
169 response = scraper.get(url, params={"batch": "1", "input": json.dumps(payload)})
170 data = response.json()
171 positive_notes = []
172 for result in data:
173 json_data = result.get("result", {}).get("data", {}).get("json", {})
174 positive_notes = [row[0] for row in json_data.get("positive_notes", [])]
175 positive_notes = [random.choice(positive_notes)] if positive_notes else []
176 log_debug(f"Recording feedback for turn {reward_kw['turn_id']}: {positive_notes}")
177 url = "https://yupp.ai/api/trpc/evals.recordModelFeedback?batch=1"
178 selected_message_id = reward_kw.get("left_message_id") if reward_kw.get("selection") == "left" else reward_kw.get("right_message_id")
179 variant_message_id = reward_kw.get("right_message_id") if reward_kw.get("selection") == "left" else reward_kw.get("left_message_id")
180 payload = {"0":{"json":{"turnId":reward_kw["turn_id"],"isOnboarding":False,"evalType":"SELECTION","messageEvals":[
181 {"messageId":selected_message_id,"rating":"GOOD","reasons":positive_notes},
182 {"messageId":variant_message_id,"rating":"BAD","reasons":[]}
183 ],"comment":"","requireReveal":False}}}
184
188 185 response = scraper.post(url, json=payload)
189 186 response.raise_for_status()
190 187 data = response.json()
@@ -206,9 +203,7 @@ def sync_record_model_feedback(
206 203 async def record_model_feedback(
207 204 scraper: CloudScraper,
208 205 account: Dict[str, Any],
209 turn_id: str,
210 left_message_id: str,
211 right_message_id: str,
206 reward_kw: Dict[str, str]
212 207 ) -> Optional[str]:
213 208 loop = asyncio.get_event_loop()
214 209 return await loop.run_in_executor(
@@ -216,9 +211,7 @@ async def record_model_feedback(
216 211 sync_record_model_feedback,
217 212 scraper,
218 213 account,
219 turn_id,
220 left_message_id,
221 right_message_id,
214 reward_kw
222 215 )
223 216
224 217
@@ -289,6 +282,22 @@ async def make_chat_private(
289 282 _executor, sync_make_chat_private, scraper, account, chat_id
290 283 )
291 284
285 async def get_credits(scraper: CloudScraper, account: Dict[str, Any]) -> Optional[float]:
286 try:
287 log_debug("Fetching credit balance...")
288 url = "https://yupp.ai/api/trpc/credits.getCredits?batch=1&input=%7B%220%22%3A%7B%22json%22%3Anull%2C%22meta%22%3A%7B%22values%22%3A%5B%22undefined%22%5D%2C%22v%22%3A1%7D%7D%7D"
289 scraper.cookies.set("__Secure-yupp.session-token", account["token"])
290 def sync_fetch_credits():
291 response = scraper.get(url)
292 response.raise_for_status()
293 data = response.json()
294 balance = data[0]["result"]["data"]["json"]
295 return balance
296 loop = asyncio.get_event_loop()
297 return await loop.run_in_executor(_executor, sync_fetch_credits)
298 except Exception as e:
299 log_debug(f"Failed to fetch credit balance: {e}")
300 return None
292 301
293 302 def log_debug(message: str):
294 303 if os.getenv("DEBUG_MODE", "false").lower() == "true":
@@ -495,6 +504,26 @@ class Yupp(AsyncGeneratorProvider, ProviderModelMixin):
495 504 )
496 505 response.raise_for_status()
497 506 return response
507
508 @classmethod
509 async def get_quota(cls, api_key: str = None) -> Optional[float]:
510 if not api_key:
511 api_key = AuthManager.load_api_key(cls)
512 if not api_key:
513 api_key = get_cookies("yupp.ai", False).get("__Secure-yupp.session-token")
514 if api_key:
515 load_yupp_accounts(api_key)
516 else:
517 raise MissingAuthError(
518 "No Yupp accounts configured. Set YUPP_API_KEY environment variable."
519 )
520 credits = await get_credits(create_scraper(), await get_best_yupp_account())
521 return {
522 "credits": {
523 "remaining": credits,
524 "total": 5000
525 }
526 }
498 527
499 528 @classmethod
500 529 async def create_async_generator(
@@ -546,6 +575,14 @@ class Yupp(AsyncGeneratorProvider, ProviderModelMixin):
546 575 scraper = create_scraper()
547 576 if proxy:
548 577 scraper.proxies = {"http": proxy, "https": proxy}
578
579 credits = await get_credits(scraper, account)
580 log_debug(f"Account ...{account['token'][-4:]} has {credits} credits")
581 if credits is not None and credits <= 100:
582 log_debug(f"Account ...{account['token'][-4:]} has low credits, rotating")
583 async with account_rotation_lock:
584 account["error_count"] += 1
585 continue
549 586
550 587 # Initialize token extractor for automatic token swapping
551 588 token_extractor = get_token_extractor(
@@ -943,6 +980,7 @@ class Yupp(AsyncGeneratorProvider, ProviderModelMixin):
943 980 target_stream_id = extract_ref_id(
944 981 select_stream[i].get("next")
945 982 )
983 reward_kw["selection"] = "left" if i == 0 else "right"
946 984 provider_info["modelLabel"] = selection.get(
947 985 "shortLabel"
948 986 )
@@ -1073,9 +1111,7 @@ class Yupp(AsyncGeneratorProvider, ProviderModelMixin):
1073 1111 eval_id = await record_model_feedback(
1074 1112 scraper,
1075 1113 account,
1076 reward_kw["turn_id"],
1077 reward_kw["left_message_id"],
1078 reward_kw["right_message_id"],
1114 reward_kw
1079 1115 )
1080 1116 if eval_id:
1081 1117 await claim_yupp_reward(scraper, account, eval_id)