返回提交历史
Modified
g4f/Provider/GizAI.py
+0
-1
Modified
g4f/Provider/Mhystical.py
+3
-1
Modified
g4f/Provider/PollinationsAI.py
+11
-12
Modified
g4f/Provider/needs_auth/DeepInfra.py
+1
-0
Added
g4f/Provider/needs_auth/DeepSeek.py
+14
-0
Modified
g4f/Provider/needs_auth/GlhfChat.py
+1
-0
Modified
g4f/Provider/needs_auth/OpenaiAPI.py
+1
-1
Modified
g4f/Provider/needs_auth/__init__.py
+1
-0
Modified
g4f/gui/client/index.html
+0
-48
Modified
g4f/gui/client/static/css/style.css
+4
-0
Modified
g4f/gui/client/static/js/chat.v1.js
+31
-0
Modified
g4f/gui/server/api.py
+1
-0
Modified
g4f/models.py
+1
-1
XFEstudio/gpt4free
Add DeepSeek Provider Add get api keys urls to GUI
f05d0698
代码差异
13 个文件
+69
-64
@@ -6,7 +6,6 @@ from ..typing import AsyncResult, Messages
6
6
from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
7
7
from .helper import format_prompt
8
8
9
10
9
class GizAI(AsyncGeneratorProvider, ProviderModelMixin):
11
10
url = "https://app.giz.ai/assistant"
12
11
api_endpoint = "https://app.giz.ai/api/data/users/inferenceServer.infer"
@@ -18,6 +18,7 @@ class Mhystical(OpenaiAPI):
18
18
label = "Mhystical"
19
19
url = "https://mhystical.cc"
20
20
api_endpoint = "https://api.mhystical.cc/v1/completions"
21
login_url = "https://mhystical.cc/dashboard"
21
22
working = True
22
23
needs_auth = False
23
24
supports_stream = False # Set to False, as streaming is not specified in ChatifyAI
@@ -37,11 +38,12 @@ class Mhystical(OpenaiAPI):
37
38
model: str,
38
39
messages: Messages,
39
40
stream: bool = False,
41
api_key: str = "mhystical",
40
42
**kwargs
41
43
) -> AsyncResult:
42
44
model = cls.get_model(model)
43
45
headers = {
44
"x-api-key": "mhystical",
46
"x-api-key": api_key,
45
47
"Content-Type": "application/json",
46
48
"accept": "*/*",
47
49
"cache-control": "no-cache",
@@ -7,12 +7,12 @@ from urllib.parse import quote
7
7
from typing import Optional
8
8
from aiohttp import ClientSession
9
9
10
from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
10
11
from ..requests.raise_for_status import raise_for_status
11
12
from ..typing import AsyncResult, Messages
12
13
from ..image import ImageResponse
13
from .needs_auth.OpenaiAPI import OpenaiAPI
14
14
15
class PollinationsAI(OpenaiAPI):
15
class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
16
16
label = "Pollinations AI"
17
17
url = "https://pollinations.ai"
18
18
@@ -21,21 +21,21 @@ class PollinationsAI(OpenaiAPI):
21
21
supports_stream = True
22
22
supports_system_message = True
23
23
supports_message_history = True
24
24
25
25
# API endpoints base
26
26
api_base = "https://text.pollinations.ai/openai"
27
27
28
28
# API endpoints
29
29
text_api_endpoint = "https://text.pollinations.ai"
30
30
image_api_endpoint = "https://image.pollinations.ai"
31
31
32
32
# Models configuration
33
33
default_model = "openai"
34
34
default_image_model = "flux"
35
35
36
36
image_models = []
37
37
models = []
38
38
39
39
additional_models_image = ["midjourney", "dall-e-3"]
40
40
additional_models_text = ["sur", "sur-mistral", "claude"]
41
41
model_aliases = {
@@ -100,7 +100,7 @@ class PollinationsAI(OpenaiAPI):
100
100
**kwargs
101
101
) -> AsyncResult:
102
102
model = cls.get_model(model)
103
103
104
104
# Check if models
105
105
# Image generation
106
106
if model in cls.image_models:
@@ -151,7 +151,6 @@ class PollinationsAI(OpenaiAPI):
151
151
if seed is None:
152
152
seed = random.randint(0, 10000)
153
153
154
155
154
headers = {
156
155
'Accept': '*/*',
157
156
'Accept-Language': 'en-US,en;q=0.9',
@@ -177,7 +176,7 @@ class PollinationsAI(OpenaiAPI):
177
176
178
177
async with session.head(url, proxy=proxy) as response:
179
178
if response.status == 200:
180
image_response = ImageResponse(images=url, alt=messages[-1]["content"])
179
image_response = ImageResponse(images=url, alt=messages[-1]["content"] if prompt is None else prompt)
181
180
yield image_response
182
181
183
182
@classmethod
@@ -195,7 +194,7 @@ class PollinationsAI(OpenaiAPI):
195
194
) -> AsyncResult:
196
195
if api_key is None:
197
196
api_key = "dummy" # Default value if api_key is not provided
198
197
199
198
headers = {
200
199
"accept": "*/*",
201
200
"accept-language": "en-US,en;q=0.9",
@@ -215,7 +214,7 @@ class PollinationsAI(OpenaiAPI):
215
214
"jsonMode": False,
216
215
"stream": stream
217
216
}
218
217
219
218
async with session.post(cls.text_api_endpoint, json=data, proxy=proxy) as response:
220
219
response.raise_for_status()
221
220
async for chunk in response.content:
@@ -7,6 +7,7 @@ from .OpenaiAPI import OpenaiAPI
7
7
class DeepInfra(OpenaiAPI):
8
8
label = "DeepInfra"
9
9
url = "https://deepinfra.com"
10
login_url = "https://deepinfra.com/dash/api_keys"
10
11
working = True
11
12
api_base = "https://api.deepinfra.com/v1/openai",
12
13
needs_auth = True
@@ -0,0 +1,14 @@
1
from __future__ import annotations
2
3
from .OpenaiAPI import OpenaiAPI
4
5
class DeepSeek(OpenaiAPI):
6
label = "DeepSeek"
7
url = "https://platform.deepseek.com"
8
login_url = "https://platform.deepseek.com/api_keys"
9
working = True
10
api_base = "https://api.deepseek.com"
11
needs_auth = True
12
supports_stream = True
13
supports_message_history = True
14
default_model = "deepseek-chat"
@@ -5,6 +5,7 @@ from .OpenaiAPI import OpenaiAPI
5
5
class GlhfChat(OpenaiAPI):
6
6
label = "GlhfChat"
7
7
url = "https://glhf.chat"
8
login_url = "https://glhf.chat/users/settings/api"
8
9
api_base = "https://glhf.chat/api/openai/v1"
9
10
working = True
10
11
model_aliases = {
@@ -8,7 +8,7 @@ from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin, RaiseErr
8
8
from ...typing import Union, Optional, AsyncResult, Messages, ImagesType
9
9
from ...requests import StreamSession, raise_for_status
10
10
from ...providers.response import FinishReason, ToolCalls, Usage
11
from ...errors import MissingAuthError, ResponseError
11
from ...errors import MissingAuthError
12
12
from ...image import to_data_uri
13
13
from ... import debug
14
14
@@ -5,6 +5,7 @@ from .Cerebras import Cerebras
5
5
from .CopilotAccount import CopilotAccount
6
6
from .DeepInfra import DeepInfra
7
7
from .DeepInfraImage import DeepInfraImage
8
from .DeepSeek import DeepSeek
8
9
from .Gemini import Gemini
9
10
from .GeminiPro import GeminiPro
10
11
from .GithubCopilot import GithubCopilot
@@ -154,54 +154,6 @@
154
154
<label for="BingCreateImages-api_key" class="label" title="">Microsoft Designer in Bing:</label>
155
155
<textarea id="BingCreateImages-api_key" name="BingCreateImages[api_key]" placeholder=""_U" cookie"></textarea>
156
156
</div>
157
<div class="field box hidden">
158
<label for="Cerebras-api_key" class="label" title="">Cerebras Inference:</label>
159
<textarea id="Cerebras-api_key" name="Cerebras[api_key]" placeholder="api_key"></textarea>
160
</div>
161
<div class="field box hidden">
162
<label for="Anthropic-api_key" class="label" title="">Anthropic API:</label>
163
<textarea id="Anthropic-api_key" name="Anthropic[api_key]" placeholder="api_key"></textarea>
164
</div>
165
<div class="field box hidden">
166
<label for="DeepInfra-api_key" class="label" title="">DeepInfra:</label>
167
<textarea id="DeepInfra-api_key" name="DeepInfra[api_key]" class="DeepInfraImage-api_key" placeholder="api_key"></textarea>
168
</div>
169
<div class="field box hidden">
170
<label for="GeminiPro-api_key" class="label" title="">Gemini API:</label>
171
<textarea id="GeminiPro-api_key" name="GeminiPro[api_key]" placeholder="api_key"></textarea>
172
</div>
173
<div class="field box hidden">
174
<label for="Groq-api_key" class="label" title="">Groq:</label>
175
<textarea id="Groq-api_key" name="Groq[api_key]" placeholder="api_key"></textarea>
176
</div>
177
<div class="field box hidden">
178
<label for="GlhfChat-api_key" class="label" title="">GlhfChat:</label>
179
<textarea id="GlhfChat-api_key" name="GlhfChat[api_key]" placeholder="api_key"></textarea>
180
</div>
181
<div class="field box hidden">
182
<label for="HuggingFace-api_key" class="label" title="">HuggingFace:</label>
183
<textarea id="HuggingFace-api_key" name="HuggingFace[api_key]" class="HuggingFaceAPI-api_key" placeholder="api_key"></textarea>
184
</div>
185
<div class="field box hidden">
186
<label for="OpenaiAPI-api_key" class="label" title="">OpenAI API:</label>
187
<textarea id="OpenaiAPI-api_key" name="OpenaiAPI[api_key]" placeholder="api_key"></textarea>
188
</div>
189
<div class="field box hidden">
190
<label for="OpenRouter-api_key" class="label" title="">OpenRouter:</label>
191
<textarea id="OpenRouter-api_key" name="OpenRouter[api_key]" placeholder="api_key"></textarea>
192
</div>
193
<div class="field box hidden">
194
<label for="PerplexityApi-api_key" class="label" title="">Perplexity API:</label>
195
<textarea id="PerplexityApi-api_key" name="PerplexityApi[api_key]" placeholder="api_key"></textarea>
196
</div>
197
<div class="field box hidden">
198
<label for="Replicate-api_key" class="label" title="">Replicate:</label>
199
<textarea id="Replicate-api_key" name="Replicate[api_key]" class="ReplicateImage-api_key" placeholder="api_key"></textarea>
200
</div>
201
<div class="field box hidden">
202
<label for="xAI-api_key" class="label" title="">xAI:</label>
203
<textarea id="xAI-api_key" name="xAI[api_key]" placeholder="api_key"></textarea>
204
</div>
205
157
</div>
206
158
<div class="bottom_buttons">
207
159
<button onclick="delete_conversations()">
@@ -1312,6 +1312,10 @@ form textarea {
1312
1312
padding: 6px;
1313
1313
}
1314
1314
1315
.field a {
1316
text-wrap: nowrap;
1317
}
1318
1315
1319
form .field .fa-xmark {
1316
1320
line-height: 20px;
1317
1321
cursor: pointer;
@@ -1710,6 +1710,7 @@ async function on_api() {
1710
1710
});
1711
1711
providers = await api("providers")
1712
1712
providers.sort((a, b) => a.label.localeCompare(b.label));
1713
let login_urls = {};
1713
1714
providers.forEach((provider) => {
1714
1715
let option = document.createElement("option");
1715
1716
option.value = provider.name;
@@ -1723,6 +1724,36 @@ async function on_api() {
1723
1724
option.dataset.parent = provider.parent;
1724
1725
providerSelect.appendChild(option);
1725
1726
1727
if (provider.login_url) {
1728
if (!login_urls[provider.name]) {
1729
login_urls[provider.name] = [provider.label, provider.login_url, []];
1730
} else {
1731
login_urls[provider.name][0] = provider.label;
1732
login_urls[provider.name][1] = provider.login_url;
1733
}
1734
} else if (provider.parent) {
1735
if (!login_urls[provider.parent]) {
1736
login_urls[provider.parent] = [provider.label, provider.login_url, [provider.name]];
1737
} else {
1738
login_urls[provider.parent][2].push(provider.name);
1739
}
1740
}
1741
});
1742
for (let [name, [label, login_url, childs]] of Object.entries(login_urls)) {
1743
if (!login_url) {
1744
continue;
1745
}
1746
option = document.createElement("div");
1747
option.classList.add("field", "box", "hidden");
1748
childs = childs.map((child)=>`${child}-api_key`).join(" ");
1749
option.innerHTML = `
1750
<label for="${name}-api_key" class="label" title="">${label}:</label>
1751
<textarea id="${name}-api_key" name="${name}[api_key]" class="${childs}" placeholder="api_key"></textarea>
1752
<a href="${login_url}" target="_blank" title="Login to ${label}">Get API key</a>
1753
`;
1754
settings.querySelector(".paper").appendChild(option);
1755
}
1756
providers.forEach((provider) => {
1726
1757
if (!provider.parent) {
1727
1758
option = document.createElement("div");
1728
1759
option.classList.add("field");
@@ -65,6 +65,7 @@ class Api:
65
65
"image": getattr(provider, "image_models", None) is not None,
66
66
"vision": getattr(provider, "default_vision_model", None) is not None,
67
67
"auth": provider.needs_auth,
68
"login_url": getattr(provider, "login_url", None),
68
69
} for provider in __providers__ if provider.working]
69
70
70
71
@staticmethod