Refactor Yupp provider: streamline API request handling, improve logging, and enhance model selection processing

This commit is contained in:
hlohaus 2025-10-06 18:11:51 +02:00
parent b2efb16b86
commit 73a3d3a48b

View file

@ -8,7 +8,7 @@ import threading
import requests import requests
from ..providers.base_provider import AbstractProvider, ProviderModelMixin from ..providers.base_provider import AbstractProvider, ProviderModelMixin
from ..providers.response import Reasoning, PlainTextResponse, PreviewResponse, JsonConversation, ImageResponse, VariantResponse from ..providers.response import Reasoning, PlainTextResponse, PreviewResponse, JsonConversation, ImageResponse, ProviderInfo
from ..errors import RateLimitError, ProviderException from ..errors import RateLimitError, ProviderException
from ..cookies import get_cookies from ..cookies import get_cookies
from ..tools.auth import AuthManager from ..tools.auth import AuthManager
@ -135,9 +135,7 @@ def claim_yupp_reward(account: Dict[str, Any], reward_id: str):
url = "https://yupp.ai/api/trpc/reward.claim?batch=1" url = "https://yupp.ai/api/trpc/reward.claim?batch=1"
payload = {"0": {"json": {"rewardId": reward_id}}} payload = {"0": {"json": {"rewardId": reward_id}}}
headers = { headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0",
"Content-Type": "application/json", "Content-Type": "application/json",
"sec-fetch-site": "same-origin",
"Cookie": f"__Secure-yupp.session-token={account['token']}", "Cookie": f"__Secure-yupp.session-token={account['token']}",
} }
session = create_requests_session() session = create_requests_session()
@ -192,24 +190,23 @@ class Yupp(AbstractProvider, ProviderModelMixin):
conversation: JsonConversation = None, conversation: JsonConversation = None,
**kwargs, **kwargs,
) -> Generator[str, Any, None]: ) -> Generator[str, Any, None]:
if not api_key:
api_key = get_cookies("yupp.ai", False).get("__Secure-yupp.session-token")
# Initialize Yupp accounts and models
if api_key:
load_yupp_accounts(api_key)
log_debug(f"Yupp provider initialized with {len(YUPP_ACCOUNTS)} accounts")
""" """
Create completion using Yupp.ai API with account rotation Create completion using Yupp.ai API with account rotation
""" """
# Initialize Yupp accounts and models
if not api_key and len(YUPP_ACCOUNTS) <= 1:
api_key = get_cookies("yupp.ai", False).get("__Secure-yupp.session-token")
if api_key:
load_yupp_accounts(api_key)
log_debug(f"Yupp provider initialized with {len(YUPP_ACCOUNTS)} accounts")
elif YUPP_ACCOUNTS:
log_debug(f"Yupp provider using existing accounts: {len(YUPP_ACCOUNTS)}")
else:
raise ProviderException("No Yupp accounts configured. Set YUPP_API_KEY environment variable.")
if messages is None: if messages is None:
messages = [] messages = []
if not YUPP_ACCOUNTS:
raise ProviderException("No Yupp accounts configured. Set YUPP_API_KEY environment variable.")
# Format messages # Format messages
if conversation is None or True: if conversation is None or True:
if prompt is None: if prompt is None:
@ -220,7 +217,7 @@ class Yupp(AbstractProvider, ProviderModelMixin):
if prompt is None: if prompt is None:
prompt = get_last_message(messages) prompt = get_last_message(messages)
url_uuid = conversation.url_uuid url_uuid = conversation.url_uuid
log_debug(f"Use url uuid: {url_uuid}, Formatted prompt length: {len(prompt)}") log_debug(f"Use url_uuid: {url_uuid}, Formatted prompt length: {len(prompt)}")
# Try all accounts with rotation # Try all accounts with rotation
max_attempts = len(YUPP_ACCOUNTS) max_attempts = len(YUPP_ACCOUNTS)
@ -275,18 +272,8 @@ class Yupp(AbstractProvider, ProviderModelMixin):
headers = { headers = {
"accept": "text/x-component", "accept": "text/x-component",
"accept-language": "en-US",
"cache-control": "no-cache",
"content-type": "text/plain;charset=UTF-8", "content-type": "text/plain;charset=UTF-8",
"next-action": next_action, "next-action": next_action,
"pragma": "no-cache",
"priority": "u=1, i",
"sec-ch-ua": "\"Chromium\";v=\"140\", \"Not=A?Brand\";v=\"24\", \"Google Chrome\";v=\"140\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Linux\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"cookie": f"__Secure-yupp.session-token={account['token']}", "cookie": f"__Secure-yupp.session-token={account['token']}",
} }
@ -318,7 +305,7 @@ class Yupp(AbstractProvider, ProviderModelMixin):
response.raise_for_status() response.raise_for_status()
yield from cls._process_stream_response( yield from cls._process_stream_response(
response.iter_lines(), account, session, question response.iter_lines(), account, session, question, model_id
) )
@classmethod @classmethod
@ -327,7 +314,8 @@ class Yupp(AbstractProvider, ProviderModelMixin):
response_lines: Iterable[bytes], response_lines: Iterable[bytes],
account: Dict[str, Any], account: Dict[str, Any],
session: requests.Session, session: requests.Session,
prompt: Optional[str] = None, prompt: str,
model_id: str
) -> Generator[str, Any, None]: ) -> Generator[str, Any, None]:
"""Process Yupp stream response and convert to OpenAI format""" """Process Yupp stream response and convert to OpenAI format"""
@ -379,7 +367,7 @@ class Yupp(AbstractProvider, ProviderModelMixin):
line_count = 0 line_count = 0
quick_response_id = None quick_response_id = None
variant_stream_id = None variant_stream_id = None
found_image: Optional[ImageResponse] = None is_started: bool = False
variant_image: Optional[ImageResponse] = None variant_image: Optional[ImageResponse] = None
variant_text = "" variant_text = ""
@ -419,13 +407,20 @@ class Yupp(AbstractProvider, ProviderModelMixin):
elif chunk_id == "e": elif chunk_id == "e":
yield PlainTextResponse(line.decode(errors="ignore")) yield PlainTextResponse(line.decode(errors="ignore"))
if isinstance(data, dict): if isinstance(data, dict):
provider_info = cls.get_dict()
provider_info['model'] = model_id
for i, selection in enumerate(data.get("modelSelections", [])): for i, selection in enumerate(data.get("modelSelections", [])):
if selection.get("selectionSource") == "USER_SELECTED": if selection.get("selectionSource") == "USER_SELECTED":
target_stream_id = extract_ref_id(select_stream[i].get("next")) target_stream_id = extract_ref_id(select_stream[i].get("next"))
provider_info["modelLabel"] = selection.get("shortLabel")
provider_info["modelUrl"] = selection.get("externalUrl")
log_debug(f"Found target stream ID: {target_stream_id}") log_debug(f"Found target stream ID: {target_stream_id}")
else: else:
variant_stream_id = extract_ref_id(select_stream[i].get("next")) variant_stream_id = extract_ref_id(select_stream[i].get("next"))
provider_info["variantLabel"] = selection.get("shortLabel")
provider_info["variantUrl"] = selection.get("externalUrl")
log_debug(f"Found variant stream ID: {variant_stream_id}") log_debug(f"Found variant stream ID: {variant_stream_id}")
yield ProviderInfo.from_dict(provider_info)
# Process target stream content # Process target stream content
elif target_stream_id and chunk_id == target_stream_id: elif target_stream_id and chunk_id == target_stream_id:
@ -435,8 +430,7 @@ class Yupp(AbstractProvider, ProviderModelMixin):
content = data.get("curr", "") content = data.get("curr", "")
if content: if content:
for chunk in process_content_chunk(content, chunk_id, line_count): for chunk in process_content_chunk(content, chunk_id, line_count):
if isinstance(chunk, ImageResponse): is_started = True
found_image = chunk
yield chunk yield chunk
elif variant_stream_id and chunk_id == variant_stream_id: elif variant_stream_id and chunk_id == variant_stream_id:
@ -449,9 +443,10 @@ class Yupp(AbstractProvider, ProviderModelMixin):
if isinstance(chunk, ImageResponse): if isinstance(chunk, ImageResponse):
variant_image = chunk variant_image = chunk
yield PreviewResponse(str(variant_image)) yield PreviewResponse(str(variant_image))
elif found_image is None: else:
variant_text += str(chunk) variant_text += str(chunk)
yield PreviewResponse(variant_text) if not is_started:
yield PreviewResponse(variant_text)
elif quick_response_id and chunk_id == quick_response_id: elif quick_response_id and chunk_id == quick_response_id:
yield PlainTextResponse("[Quick] " + line.decode(errors="ignore")) yield PlainTextResponse("[Quick] " + line.decode(errors="ignore"))
@ -468,6 +463,8 @@ class Yupp(AbstractProvider, ProviderModelMixin):
if variant_image is not None: if variant_image is not None:
yield variant_image yield variant_image
elif variant_text:
yield PreviewResponse(variant_text)
log_debug(f"Finished processing {line_count} lines") log_debug(f"Finished processing {line_count} lines")