返回提交历史
Added
g4f/Provider/RubiksAI.py
+163
-0
Modified
g4f/Provider/__init__.py
+1
-0
Modified
g4f/models.py
+3
-2
XFEstudio/gpt4free
Added new provider (g4f/Provider/RubiksAI.py)
48e8cbfb
代码差异
3 个文件
+167
-2
@@ -0,0 +1,163 @@
1
from __future__ import annotations
2
3
import asyncio
4
import aiohttp
5
import random
6
import string
7
import json
8
from urllib.parse import urlencode
9
10
from aiohttp import ClientSession
11
12
from ..typing import AsyncResult, Messages
13
from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
14
from .helper import format_prompt
15
16
17
class RubiksAI(AsyncGeneratorProvider, ProviderModelMixin):
18
label = "Rubiks AI"
19
url = "https://rubiks.ai"
20
api_endpoint = "https://rubiks.ai/search/api.php"
21
working = True
22
supports_gpt_4 = True
23
supports_stream = True
24
supports_system_message = True
25
supports_message_history = True
26
27
default_model = 'llama-3.1-70b-versatile'
28
models = [default_model, 'gpt-4o-mini']
29
30
model_aliases = {
31
"llama-3.1-70b": "llama-3.1-70b-versatile",
32
}
33
34
@classmethod
35
def get_model(cls, model: str) -> str:
36
if model in cls.models:
37
return model
38
elif model in cls.model_aliases:
39
return cls.model_aliases[model]
40
else:
41
return cls.default_model
42
43
@staticmethod
44
def generate_mid() -> str:
45
"""
46
Generates a 'mid' string following the pattern:
47
6 characters - 4 characters - 4 characters - 4 characters - 12 characters
48
Example: 0r7v7b-quw4-kdy3-rvdu-ekief6xbuuq4
49
"""
50
parts = [
51
''.join(random.choices(string.ascii_lowercase + string.digits, k=6)),
52
''.join(random.choices(string.ascii_lowercase + string.digits, k=4)),
53
''.join(random.choices(string.ascii_lowercase + string.digits, k=4)),
54
''.join(random.choices(string.ascii_lowercase + string.digits, k=4)),
55
''.join(random.choices(string.ascii_lowercase + string.digits, k=12))
56
]
57
return '-'.join(parts)
58
59
@staticmethod
60
def create_referer(q: str, mid: str, model: str = '') -> str:
61
"""
62
Creates a Referer URL with dynamic q and mid values, using urlencode for safe parameter encoding.
63
"""
64
params = {'q': q, 'model': model, 'mid': mid}
65
encoded_params = urlencode(params)
66
return f'https://rubiks.ai/search/?{encoded_params}'
67
68
@classmethod
69
async def create_async_generator(
70
cls,
71
model: str,
72
messages: Messages,
73
proxy: str = None,
74
websearch: bool = False,
75
**kwargs
76
) -> AsyncResult:
77
"""
78
Creates an asynchronous generator that sends requests to the Rubiks AI API and yields the response.
79
80
Parameters:
81
- model (str): The model to use in the request.
82
- messages (Messages): The messages to send as a prompt.
83
- proxy (str, optional): Proxy URL, if needed.
84
- websearch (bool, optional): Indicates whether to include search sources in the response. Defaults to False.
85
"""
86
model = cls.get_model(model)
87
prompt = format_prompt(messages)
88
q_value = prompt
89
mid_value = cls.generate_mid()
90
referer = cls.create_referer(q=q_value, mid=mid_value, model=model)
91
92
url = cls.api_endpoint
93
params = {
94
'q': q_value,
95
'model': model,
96
'id': '',
97
'mid': mid_value
98
}
99
100
headers = {
101
'Accept': 'text/event-stream',
102
'Accept-Language': 'en-US,en;q=0.9',
103
'Cache-Control': 'no-cache',
104
'Connection': 'keep-alive',
105
'Pragma': 'no-cache',
106
'Referer': referer,
107
'Sec-Fetch-Dest': 'empty',
108
'Sec-Fetch-Mode': 'cors',
109
'Sec-Fetch-Site': 'same-origin',
110
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36',
111
'sec-ch-ua': '"Chromium";v="129", "Not=A?Brand";v="8"',
112
'sec-ch-ua-mobile': '?0',
113
'sec-ch-ua-platform': '"Linux"'
114
}
115
116
try:
117
timeout = aiohttp.ClientTimeout(total=None)
118
async with ClientSession(timeout=timeout) as session:
119
async with session.get(url, headers=headers, params=params, proxy=proxy) as response:
120
if response.status != 200:
121
yield f"Request ended with status code {response.status}"
122
return
123
124
assistant_text = ''
125
sources = []
126
127
async for line in response.content:
128
decoded_line = line.decode('utf-8').strip()
129
if not decoded_line.startswith('data: '):
130
continue
131
data = decoded_line[6:]
132
if data in ('[DONE]', '{"done": ""}'):
133
break
134
try:
135
json_data = json.loads(data)
136
except json.JSONDecodeError:
137
continue
138
139
if 'url' in json_data and 'title' in json_data:
140
if websearch:
141
sources.append({'title': json_data['title'], 'url': json_data['url']})
142
143
elif 'choices' in json_data:
144
for choice in json_data['choices']:
145
delta = choice.get('delta', {})
146
content = delta.get('content', '')
147
role = delta.get('role', '')
148
if role == 'assistant':
149
continue
150
assistant_text += content
151
152
if websearch and sources:
153
sources_text = '\n'.join([f"{i+1}. [{s['title']}]: {s['url']}" for i, s in enumerate(sources)])
154
assistant_text += f"\n\n**Source:**\n{sources_text}"
155
156
yield assistant_text
157
158
except asyncio.CancelledError:
159
yield "The request was cancelled."
160
except aiohttp.ClientError as e:
161
yield f"An error occurred during the request: {e}"
162
except Exception as e:
163
yield f"An unexpected error occurred: {e}"
@@ -63,6 +63,7 @@ from .Prodia import Prodia
63
63
from .Reka import Reka
64
64
from .Replicate import Replicate
65
65
from .ReplicateHome import ReplicateHome
66
from .RubiksAI import RubiksAI
66
67
from .TeachAnything import TeachAnything
67
68
from .Upstage import Upstage
68
69
from .WhiteRabbitNeo import WhiteRabbitNeo
@@ -58,6 +58,7 @@ from .Provider import (
58
58
Reka,
59
59
Replicate,
60
60
ReplicateHome,
61
RubiksAI,
61
62
TeachAnything,
62
63
Upstage,
63
64
)
@@ -135,7 +136,7 @@ gpt_4o = Model(
135
136
gpt_4o_mini = Model(
136
137
name = 'gpt-4o-mini',
137
138
base_provider = 'OpenAI',
138
best_provider = IterListProvider([DDG, ChatGptEs, FreeNetfly, Pizzagpt, MagickPen, AmigoChat, Liaobots, Airforce, ChatgptFree, Koala, OpenaiChat, ChatGpt])
139
best_provider = IterListProvider([DDG, ChatGptEs, FreeNetfly, Pizzagpt, MagickPen, AmigoChat, RubiksAI, Liaobots, Airforce, ChatgptFree, Koala, OpenaiChat, ChatGpt])
139
140
)
140
141
141
142
gpt_4_turbo = Model(
@@ -215,7 +216,7 @@ llama_3_1_8b = Model(
215
216
llama_3_1_70b = Model(
216
217
name = "llama-3.1-70b",
217
218
base_provider = "Meta Llama",
218
best_provider = IterListProvider([DDG, HuggingChat, Blackbox, FreeGpt, TeachAnything, Free2GPT, DeepInfraChat, DarkAI, Airforce, AiMathGPT, HuggingFace, PerplexityLabs])
219
best_provider = IterListProvider([DDG, HuggingChat, Blackbox, FreeGpt, TeachAnything, Free2GPT, DeepInfraChat, DarkAI, Airforce, AiMathGPT, RubiksAI, HuggingFace, PerplexityLabs])
219
220
)
220
221
221
222
llama_3_1_405b = Model(