返回提交历史
Modified
g4f/Provider/Blackbox.py
+1
-1
Modified
g4f/Provider/DDG.py
+2
-0
Modified
g4f/Provider/needs_auth/Custom.py
+5
-1
Modified
g4f/Provider/needs_auth/__init__.py
+1
-0
Modified
g4f/gui/client/static/js/chat.v1.js
+11
-6
Modified
g4f/gui/server/backend_api.py
+1
-1
Modified
g4f/tools/run_tools.py
+27
-3
XFEstudio/gpt4free
Add Feature provider in demo Support default provider in DDG Read api_key from config file
16e5d9ee
代码差异
7 个文件
+48
-12
@@ -239,7 +239,7 @@ class Blackbox(AsyncGeneratorProvider, ProviderModelMixin):
239
239
yield ImageResponse(images=[image_url], alt=prompt)
240
240
return
241
241
242
if conversation is None:
242
if conversation is None or not hasattr(conversation, "chat_id"):
243
243
conversation = Conversation(model)
244
244
conversation.validated_value = await cls.fetch_validated()
245
245
conversation.chat_id = cls.generate_chat_id()
@@ -50,6 +50,8 @@ class DDG(AsyncGeneratorProvider, ProviderModelMixin):
50
50
@classmethod
51
51
def validate_model(cls, model: str) -> str:
52
52
"""Validates and returns the correct model name"""
53
if not model:
54
return cls.default_model
53
55
if model in cls.model_aliases:
54
56
model = cls.model_aliases[model]
55
57
if model not in cls.models:
@@ -7,4 +7,8 @@ class Custom(OpenaiTemplate):
7
7
working = True
8
8
needs_auth = False
9
9
api_base = "http://localhost:8080/v1"
10
sort_models = False
10
sort_models = False
11
12
class Feature(Custom):
13
label = "Feature Provider"
14
working = False
@@ -3,6 +3,7 @@ from .BingCreateImages import BingCreateImages
3
3
from .Cerebras import Cerebras
4
4
from .CopilotAccount import CopilotAccount
5
5
from .Custom import Custom
6
from .Custom import Feature
6
7
from .DeepInfra import DeepInfra
7
8
from .DeepSeek import DeepSeek
8
9
from .Gemini import Gemini
@@ -937,15 +937,17 @@ const ask_gpt = async (message_id, message_index = -1, regenerate = false, provi
937
937
}
938
938
try {
939
939
let api_key;
940
if (is_demo && provider != "Custom") {
940
if (is_demo && provider == "Feature") {
941
api_key = localStorage.getItem("user");
942
} else if (is_demo && provider != "Custom") {
941
943
api_key = localStorage.getItem("HuggingFace-api_key");
942
if (!api_key) {
943
location.href = "/";
944
return;
945
}
946
944
} else {
947
945
api_key = get_api_key_by_provider(provider);
948
946
}
947
if (is_demo && !api_key && provider != "Custom") {
948
location.href = "/";
949
return;
950
}
949
951
const input = imageInput && imageInput.files.length > 0 ? imageInput : cameraInput;
950
952
const files = input && input.files.length > 0 ? input.files : null;
951
953
const download_images = document.getElementById("download_images")?.checked;
@@ -1897,7 +1899,10 @@ async function on_api() {
1897
1899
location.href = "/";
1898
1900
return;
1899
1901
}
1900
providerSelect.innerHTML = '<option value="">Demo Mode</option><option value="Custom">Custom Provider</option>';
1902
providerSelect.innerHTML = `
1903
<option value="">Demo Mode</option>
1904
<option value="Feature">Feature Provider</option>
1905
<option value="Custom">Custom Provider</option>`;
1901
1906
providerSelect.selectedIndex = 0;
1902
1907
document.getElementById("pin").disabled = true;
1903
1908
document.getElementById("refine")?.parentElement.classList.add("hidden")
@@ -134,7 +134,7 @@ class Backend_Api(Api):
134
134
else:
135
135
json_data = request.json
136
136
137
if app.demo and json_data.get("provider") != "Custom":
137
if app.demo and json_data.get("provider") not in ["Custom", "Feature"]:
138
138
model = json_data.get("model")
139
139
if model != "default" and model in models.demo_models:
140
140
json_data["provider"] = random.choice(models.demo_models[model][1])
@@ -3,11 +3,14 @@ from __future__ import annotations
3
3
import re
4
4
import json
5
5
import asyncio
6
from pathlib import Path
6
7
from typing import Optional, Callable, AsyncIterator
7
8
8
9
from ..typing import Messages
9
10
from ..providers.helper import filter_none
10
11
from ..providers.asyncio import to_async_iterator
12
from ..providers.types import ProviderType
13
from ..cookies import get_cookies_dir
11
14
from .web_search import do_search, get_search_message
12
15
from .files import read_bucket, get_bucket_dir
13
16
from .. import debug
@@ -27,7 +30,10 @@ def validate_arguments(data: dict) -> dict:
27
30
else:
28
31
return {}
29
32
30
async def async_iter_run_tools(async_iter_callback, model, messages, tool_calls: Optional[list] = None, **kwargs):
33
def get_api_key_file(cls) -> Path:
34
return Path(get_cookies_dir()) / f"api_key_{cls.parent if hasattr(cls, 'parent') else cls.__name__}.json"
35
36
async def async_iter_run_tools(provider: ProviderType, model: str, messages, tool_calls: Optional[list] = None, **kwargs):
31
37
# Handle web_search from kwargs
32
38
web_search = kwargs.get('web_search')
33
39
if web_search:
@@ -40,6 +46,15 @@ async def async_iter_run_tools(async_iter_callback, model, messages, tool_calls:
40
46
# Keep web_search in kwargs for provider native support
41
47
pass
42
48
49
# Read api_key from config file
50
if provider.needs_auth and "api_key" not in kwargs:
51
auth_file = get_api_key_file(provider)
52
if auth_file.exists():
53
with auth_file.open("r") as f:
54
auth_result = json.load(f)
55
if "api_key" in auth_result:
56
kwargs["api_key"] = auth_result["api_key"]
57
43
58
if tool_calls is not None:
44
59
for tool in tool_calls:
45
60
if tool.get("type") == "function":
@@ -66,8 +81,8 @@ async def async_iter_run_tools(async_iter_callback, model, messages, tool_calls:
66
81
message["content"] = new_message_content
67
82
if has_bucket and isinstance(messages[-1]["content"], str):
68
83
messages[-1]["content"] += BUCKET_INSTRUCTIONS
69
70
response = to_async_iterator(async_iter_callback(model=model, messages=messages, **kwargs))
84
create_function = provider.get_async_create_function()
85
response = to_async_iterator(create_function(model=model, messages=messages, **kwargs))
71
86
async for chunk in response:
72
87
yield chunk
73
88
@@ -91,6 +106,15 @@ def iter_run_tools(
91
106
# Keep web_search in kwargs for provider native support
92
107
pass
93
108
109
# Read api_key from config file
110
if provider is not None and provider.needs_auth and "api_key" not in kwargs:
111
auth_file = get_api_key_file(provider)
112
if auth_file.exists():
113
with auth_file.open("r") as f:
114
auth_result = json.load(f)
115
if "api_key" in auth_result:
116
kwargs["api_key"] = auth_result["api_key"]
117
94
118
if tool_calls is not None:
95
119
for tool in tool_calls:
96
120
if tool.get("type") == "function":