22import hashlib
33import json
44import os
5+ import random
56import re
67import time
78import uuid
@@ -159,32 +160,28 @@ async def claim_yupp_reward(
159160def sync_record_model_feedback (
160161 scraper : CloudScraper ,
161162 account : Dict [str , Any ],
162- turn_id : str ,
163- left_message_id : str ,
164- right_message_id : str ,
163+ reward_kw : Dict [str , str ]
165164) -> Optional [str ]:
166165 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" ]}}}
187168 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+
188185 response = scraper .post (url , json = payload )
189186 response .raise_for_status ()
190187 data = response .json ()
@@ -206,19 +203,15 @@ def sync_record_model_feedback(
206203async def record_model_feedback (
207204 scraper : CloudScraper ,
208205 account : Dict [str , Any ],
209- turn_id : str ,
210- left_message_id : str ,
211- right_message_id : str ,
206+ reward_kw : Dict [str , str ]
212207) -> Optional [str ]:
213208 loop = asyncio .get_event_loop ()
214209 return await loop .run_in_executor (
215210 _executor ,
216211 sync_record_model_feedback ,
217212 scraper ,
218213 account ,
219- turn_id ,
220- left_message_id ,
221- right_message_id ,
214+ reward_kw
222215 )
223216
224217
@@ -289,6 +282,22 @@ async def make_chat_private(
289282 _executor , sync_make_chat_private , scraper , account , chat_id
290283 )
291284
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
292301
293302def log_debug (message : str ):
294303 if os .getenv ("DEBUG_MODE" , "false" ).lower () == "true" :
@@ -495,6 +504,26 @@ def sync_stream_request(
495504 )
496505 response .raise_for_status ()
497506 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+ }
498527
499528 @classmethod
500529 async def create_async_generator (
@@ -546,6 +575,14 @@ async def create_async_generator(
546575 scraper = create_scraper ()
547576 if proxy :
548577 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
549586
550587 # Initialize token extractor for automatic token swapping
551588 token_extractor = get_token_extractor (
@@ -943,6 +980,7 @@ def iter_lines():
943980 target_stream_id = extract_ref_id (
944981 select_stream [i ].get ("next" )
945982 )
983+ reward_kw ["selection" ] = "left" if i == 0 else "right"
946984 provider_info ["modelLabel" ] = selection .get (
947985 "shortLabel"
948986 )
@@ -1073,9 +1111,7 @@ def iter_lines():
10731111 eval_id = await record_model_feedback (
10741112 scraper ,
10751113 account ,
1076- reward_kw ["turn_id" ],
1077- reward_kw ["left_message_id" ],
1078- reward_kw ["right_message_id" ],
1114+ reward_kw
10791115 )
10801116 if eval_id :
10811117 await claim_yupp_reward (scraper , account , eval_id )
0 commit comments