返回提交历史
Modified
g4f/Provider/__init__.py
+5
-1
Added
g4f/Provider/retry_provider.py
+81
-0
Modified
g4f/__init__.py
+2
-8
Modified
g4f/models.py
+22
-7
XFEstudio/gpt4free
Add RetryProvider
e9f96ced
代码差异
4 个文件
+110
-16
@@ -38,10 +38,14 @@ from .FastGpt import FastGpt
38
38
from .V50 import V50
39
39
from .Wuguokai import Wuguokai
40
40
41
from .base_provider import BaseProvider, AsyncProvider, AsyncGeneratorProvider
41
from .base_provider import BaseProvider, AsyncProvider, AsyncGeneratorProvider
42
from .retry_provider import RetryProvider
42
43
43
44
__all__ = [
44
45
'BaseProvider',
46
'AsyncProvider',
47
'AsyncGeneratorProvider',
48
'RetryProvider',
45
49
'Acytoo',
46
50
'Aichat',
47
51
'Ails',
@@ -0,0 +1,81 @@
1
from __future__ import annotations
2
3
import random
4
5
from ..typing import CreateResult
6
from .base_provider import BaseProvider, AsyncProvider
7
8
9
class RetryProvider(AsyncProvider):
10
__name__ = "RetryProvider"
11
working = True
12
needs_auth = False
13
supports_stream = True
14
supports_gpt_35_turbo = False
15
supports_gpt_4 = False
16
17
def __init__(
18
self,
19
providers: list[type[BaseProvider]],
20
shuffle: bool = True
21
) -> None:
22
self.providers = providers
23
self.shuffle = shuffle
24
25
26
def create_completion(
27
self,
28
model: str,
29
messages: list[dict[str, str]],
30
stream: bool = False,
31
**kwargs
32
) -> CreateResult:
33
if stream:
34
providers = [provider for provider in self.providers if provider.supports_stream]
35
else:
36
providers = self.providers
37
if self.shuffle:
38
random.shuffle(providers)
39
40
self.exceptions = {}
41
started = False
42
for provider in providers:
43
try:
44
for token in provider.create_completion(model, messages, stream, **kwargs):
45
yield token
46
started = True
47
if started:
48
return
49
except Exception as e:
50
self.exceptions[provider.__name__] = e
51
if started:
52
break
53
54
self.raise_exceptions()
55
56
async def create_async(
57
self,
58
model: str,
59
messages: list[dict[str, str]],
60
**kwargs
61
) -> str:
62
providers = [provider for provider in self.providers if issubclass(provider, AsyncProvider)]
63
if self.shuffle:
64
random.shuffle(providers)
65
66
self.exceptions = {}
67
for provider in providers:
68
try:
69
return await provider.create_async(model, messages, **kwargs)
70
except Exception as e:
71
self.exceptions[provider.__name__] = e
72
73
self.raise_exceptions()
74
75
def raise_exceptions(self):
76
if self.exceptions:
77
raise RuntimeError("\n".join(["All providers failed:"] + [
78
f"{p}: {self.exceptions[p].__class__.__name__}: {self.exceptions[p]}" for p in self.exceptions
79
]))
80
81
raise RuntimeError("No provider found")
@@ -14,13 +14,7 @@ def get_model_and_provider(model: Union[models.Model, str], provider: type[BaseP
14
14
raise Exception(f'The model: {model} does not exist')
15
15
16
16
if not provider:
17
if isinstance(model.best_provider, list):
18
if stream:
19
provider = random.choice([p for p in model.best_provider if p.supports_stream])
20
else:
21
provider = random.choice(model.best_provider)
22
else:
23
provider = model.best_provider
17
provider = model.best_provider
24
18
25
19
if not provider:
26
20
raise Exception(f'No provider found for model: {model}')
@@ -70,7 +64,7 @@ class ChatCompletion:
70
64
71
65
model, provider = get_model_and_provider(model, provider, False)
72
66
73
if not issubclass(provider, AsyncProvider):
67
if not issubclass(type(provider), AsyncProvider):
74
68
raise Exception(f"Provider: {provider.__name__} doesn't support create_async")
75
69
76
70
return await provider.create_async(model.name, messages, **kwargs)
@@ -1,17 +1,23 @@
1
1
from __future__ import annotations
2
2
from dataclasses import dataclass
3
3
from .typing import Union
4
from .Provider import BaseProvider
4
from .Provider import BaseProvider, RetryProvider
5
5
from .Provider import (
6
6
ChatgptLogin,
7
CodeLinkAva,
8
7
ChatgptAi,
9
8
ChatBase,
10
9
Vercel,
11
10
DeepAi,
12
11
Aivvm,
13
12
Bard,
14
H2o
13
H2o,
14
GptGo,
15
Bing,
16
PerplexityAi,
17
Wewordle,
18
Yqcloud,
19
AItianhu,
20
Aichat,
15
21
)
16
22
17
23
@dataclass(unsafe_hash=True)
@@ -24,15 +30,24 @@ class Model:
24
30
# Works for Liaobots, H2o, OpenaiChat, Yqcloud, You
25
31
default = Model(
26
32
name = "",
27
base_provider = "huggingface")
33
base_provider = "",
34
best_provider = RetryProvider([
35
Bing, # Not fully GPT 3 or 4
36
PerplexityAi, # Adds references to sources
37
Wewordle, # Responds with markdown
38
Yqcloud, # Answers short questions in chinese
39
ChatBase, # Don't want to answer creatively
40
DeepAi, ChatgptLogin, ChatgptAi, Aivvm, GptGo, AItianhu, Aichat,
41
])
42
)
28
43
29
44
# GPT-3.5 / GPT-4
30
45
gpt_35_turbo = Model(
31
46
name = 'gpt-3.5-turbo',
32
47
base_provider = 'openai',
33
best_provider = [
34
DeepAi, CodeLinkAva, ChatgptLogin, ChatgptAi, ChatBase, Aivvm
35
]
48
best_provider = RetryProvider([
49
DeepAi, ChatgptLogin, ChatgptAi, Aivvm, GptGo, AItianhu, Aichat,
50
])
36
51
)
37
52
38
53
gpt_4 = Model(