XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/gpt4free

Update model list, Fix model list in CablyAI

be8c3f7c
hlohaus <983577+hlohaus@users.noreply.github.com>
提交于

代码差异

3 个文件 +30 -142
Modified g4f/Provider/CablyAI.py +17 -135
@@ -1,27 +1,17 @@
1 1 from __future__ import annotations
2 2
3 import json
4 from typing import AsyncGenerator
5 from aiohttp import ClientSession
3 from ..errors import ModelNotSupportedError
4 from .template import OpenaiTemplate
6 5
7 from ..typing import AsyncResult, Messages
8 from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
9 from ..requests.raise_for_status import raise_for_status
10 from ..providers.response import FinishReason, Reasoning
11
12
13 class CablyAI(AsyncGeneratorProvider, ProviderModelMixin):
6 class CablyAI(OpenaiTemplate):
14 7 label = "CablyAI"
15 8 url = "https://cablyai.com"
16 9 login_url = url
17 api_endpoint = "https://cablyai.com/v1/chat/completions"
10 api_base = "https://cablyai.com/v1"
18 11 api_key = "sk-your-openai-api-key"
19 12
20 13 working = True
21 14 needs_auth = False
22 supports_stream = True
23 supports_system_message = True
24 supports_message_history = True
25 15
26 16 default_model = 'gpt-4o-mini'
27 17 reasoning_models = ['deepseek-r1-uncensored']
@@ -36,131 +26,23 @@ class CablyAI(AsyncGeneratorProvider, ProviderModelMixin):
36 26 ] + reasoning_models
37 27
38 28 model_aliases = {
29 "searchgpt": "searchgpt (free)",
39 30 "gpt-4o-mini": "searchgpt",
40 31 "llama-3.1-8b": "llama-3.1-8b-instruct",
41 32 "deepseek-r1": "deepseek-r1-uncensored",
42 33 }
43 34
44 35 @classmethod
45 async def create_async_generator(
46 cls,
47 model: str,
48 messages: Messages,
49 api_key: str = None,
50 stream: bool = True,
51 proxy: str = None,
52 **kwargs
53 ) -> AsyncResult:
54 model = cls.get_model(model)
55 api_key = api_key or cls.api_key
56
57 headers = {
58 "Accept": "*/*",
59 "Accept-Language": "en-US,en;q=0.9",
60 "Authorization": f"Bearer {api_key}",
61 "Content-Type": "application/json",
62 "Origin": cls.url,
63 "Referer": f"{cls.url}/chat",
64 "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
65 }
36 def get_models(cls, api_key: str = None, api_base: str = None) -> list[str]:
37 models = super().get_models(api_key, api_base);
38 return [f"{m} (free)" for m in models if m in cls.fallback_models] + models
66 39
67 async with ClientSession(headers=headers) as session:
68 data = {
69 "model": model,
70 "messages": messages,
71 "stream": stream
72 }
73
74 async with session.post(
75 cls.api_endpoint,
76 json=data,
77 proxy=proxy
78 ) as response:
79 await raise_for_status(response)
80
81 if stream:
82 reasoning_buffer = []
83 in_reasoning = False
84
85 async for line in response.content:
86 if not line:
87 continue
88
89 line = line.decode('utf-8').strip()
90
91 if not line.startswith("data: "):
92 continue
93
94 if line == "data: [DONE]":
95 if in_reasoning and reasoning_buffer:
96 yield Reasoning(status="".join(reasoning_buffer).strip())
97 yield FinishReason("stop")
98 return
99
100 try:
101 json_data = json.loads(line[6:])
102 delta = json_data["choices"][0].get("delta", {})
103 content = delta.get("content", "")
104 finish_reason = json_data["choices"][0].get("finish_reason")
105
106 if finish_reason:
107 if in_reasoning and reasoning_buffer:
108 yield Reasoning(status="".join(reasoning_buffer).strip())
109 yield FinishReason(finish_reason)
110 return
111
112 if model in cls.reasoning_models:
113 # Processing the beginning of a tag
114 if "<think>" in content:
115 pre, _, post = content.partition("<think>")
116 if pre:
117 yield pre
118 in_reasoning = True
119 content = post
120
121 # Tag end processing
122 if "</think>" in content:
123 in_reasoning = False
124 thought, _, post = content.partition("</think>")
125 if thought:
126 reasoning_buffer.append(thought)
127 if reasoning_buffer:
128 yield Reasoning(status="".join(reasoning_buffer).strip())
129 reasoning_buffer.clear()
130 if post:
131 yield post
132 continue
133
134 # Buffering content inside tags
135 if in_reasoning:
136 reasoning_buffer.append(content)
137 else:
138 if content:
139 yield content
140 else:
141 if content:
142 yield content
143
144 except json.JSONDecodeError:
145 continue
146 except Exception:
147 yield FinishReason("error")
148 return
149 else:
150 try:
151 response_data = await response.json()
152 message = response_data["choices"][0]["message"]
153 content = message["content"]
154
155 if model in cls.reasoning_models and "<think>" in content:
156 think_start = content.find("<think>") + 7
157 think_end = content.find("</think>")
158 if think_start > 6 and think_end > 0:
159 reasoning = content[think_start:think_end].strip()
160 yield Reasoning(status=reasoning)
161 content = content[think_end + 8:].strip()
162
163 yield content
164 yield FinishReason("stop")
165 except Exception:
166 yield FinishReason("error")
40 @classmethod
41 def get_model(cls, model: str, **kwargs) -> str:
42 try:
43 model = super().get_model(model, **kwargs)
44 return model.split(" (free)")[0]
45 except ModelNotSupportedError:
46 if f"f{model} (free)" in cls.models:
47 return model
48 raise
Modified g4f/Provider/template/OpenaiTemplate.py +5 -0
@@ -14,6 +14,7 @@ from ... import debug
14 14
15 15 class OpenaiTemplate(AsyncGeneratorProvider, ProviderModelMixin, RaiseErrorMixin):
16 16 api_base = ""
17 api_key = None
17 18 supports_message_history = True
18 19 supports_system_message = True
19 20 default_model = ""
@@ -28,6 +29,8 @@ class OpenaiTemplate(AsyncGeneratorProvider, ProviderModelMixin, RaiseErrorMixin
28 29 headers = {}
29 30 if api_base is None:
30 31 api_base = cls.api_base
32 if api_key is None and cls.api_key is not None:
33 api_key = cls.api_key
31 34 if api_key is not None:
32 35 headers["authorization"] = f"Bearer {api_key}"
33 36 response = requests.get(f"{api_base}/models", headers=headers, verify=cls.ssl)
@@ -66,6 +69,8 @@ class OpenaiTemplate(AsyncGeneratorProvider, ProviderModelMixin, RaiseErrorMixin
66 69 extra_data: dict = {},
67 70 **kwargs
68 71 ) -> AsyncResult:
72 if api_key is None and cls.api_key is not None:
73 api_key = cls.api_key
69 74 if cls.needs_auth and api_key is None:
70 75 raise MissingAuthError('Add a "api_key"')
71 76 async with StreamSession(
Modified g4f/models.py +8 -7
@@ -25,6 +25,7 @@ from .Provider import (
25 25 PerplexityLabs,
26 26 Pi,
27 27 PollinationsAI,
28 PollinationsImage,
28 29 TeachAnything,
29 30 Yqcloud,
30 31
@@ -536,7 +537,7 @@ evil = Model(
536 537 sdxl_turbo = ImageModel(
537 538 name = 'sdxl-turbo',
538 539 base_provider = 'Stability AI',
539 best_provider = IterListProvider([PollinationsAI, ImageLabs])
540 best_provider = IterListProvider([PollinationsImage, ImageLabs])
540 541 )
541 542
542 543 sd_3_5 = ImageModel(
@@ -549,13 +550,13 @@ sd_3_5 = ImageModel(
549 550 flux = ImageModel(
550 551 name = 'flux',
551 552 base_provider = 'Black Forest Labs',
552 best_provider = IterListProvider([Blackbox, PollinationsAI, HuggingSpace])
553 best_provider = IterListProvider([Blackbox, PollinationsImage, HuggingSpace])
553 554 )
554 555
555 556 flux_pro = ImageModel(
556 557 name = 'flux-pro',
557 558 base_provider = 'Black Forest Labs',
558 best_provider = PollinationsAI
559 best_provider = PollinationsImage
559 560 )
560 561
561 562 flux_dev = ImageModel(
@@ -575,14 +576,14 @@ flux_schnell = ImageModel(
575 576 dall_e_3 = ImageModel(
576 577 name = 'dall-e-3',
577 578 base_provider = 'OpenAI',
578 best_provider = IterListProvider([PollinationsAI, CopilotAccount, OpenaiAccount, MicrosoftDesigner, BingCreateImages])
579 best_provider = IterListProvider([PollinationsImage, CopilotAccount, OpenaiAccount, MicrosoftDesigner, BingCreateImages])
579 580 )
580 581
581 582 ### Midjourney ###
582 583 midjourney = ImageModel(
583 584 name = 'midjourney',
584 585 base_provider = 'Midjourney',
585 best_provider = PollinationsAI
586 best_provider = PollinationsImage
586 587 )
587 588
588 589 class ModelUtils:
@@ -754,8 +755,8 @@ demo_models = {
754 755 qwq_32b.name: [qwq_32b, [HuggingFace]],
755 756 llama_3_3_70b.name: [llama_3_3_70b, [HuggingFace]],
756 757 sd_3_5.name: [sd_3_5, [HuggingSpace, HuggingFace]],
757 flux_dev.name: [flux_dev, [PollinationsAI, HuggingSpace, HuggingFace]],
758 flux_schnell.name: [flux_schnell, [PollinationsAI, HuggingFace, HuggingSpace, PollinationsAI]],
758 flux_dev.name: [flux_dev, [PollinationsImage, HuggingSpace, HuggingFace]],
759 flux_schnell.name: [flux_schnell, [PollinationsImage, HuggingFace, HuggingSpace]],
759 760 }
760 761
761 762 # Create a list of all models and his providers