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

XFEstudio/gpt4free

Support audio model in Azure provider

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

代码差异

7 个文件 +39 -19
Modified g4f/Provider/needs_auth/Azure.py +18 -4
@@ -4,7 +4,7 @@ import os
4 4 import json
5 5
6 6 from ...typing import Messages, AsyncResult
7 from ...errors import MissingAuthError
7 from ...errors import MissingAuthError, ModelNotFoundError
8 8 from ..template import OpenaiTemplate
9 9
10 10 class Azure(OpenaiTemplate):
@@ -15,9 +15,20 @@ class Azure(OpenaiTemplate):
15 15 active_by_default = True
16 16 login_url = "https://discord.gg/qXA4Wf4Fsm"
17 17 routes: dict[str, str] = {}
18 audio_models = ["gpt-4o-mini-audio-preview"]
19 model_extra_body = {
20 "gpt-4o-mini-audio-preview": {
21 "audio": {
22 "voice": "alloy",
23 "format": "mp3"
24 },
25 "modalities": ["text", "audio"],
26 "stream": False
27 }
28 }
18 29
19 30 @classmethod
20 def get_models(cls, **kwargs) -> list[str]:
31 def get_models(cls, api_key: str = None, **kwargs) -> list[str]:
21 32 routes = os.environ.get("AZURE_ROUTES")
22 33 if routes:
23 34 try:
@@ -27,7 +38,7 @@ class Azure(OpenaiTemplate):
27 38 cls.routes = routes
28 39 if cls.routes:
29 40 return list(cls.routes.keys())
30 return super().get_models(**kwargs)
41 return super().get_models(api_key=api_key, **kwargs)
31 42
32 43 @classmethod
33 44 async def create_async_generator(
@@ -40,6 +51,9 @@ class Azure(OpenaiTemplate):
40 51 ) -> AsyncResult:
41 52 if not model:
42 53 model = os.environ.get("AZURE_DEFAULT_MODEL", cls.default_model)
54 if model in cls.model_extra_body:
55 for key, value in cls.model_extra_body[model].items():
56 kwargs.setdefault(key, value)
43 57 if not api_key:
44 58 raise ValueError(f"API key is required for Azure provider. Ask for API key in the {cls.login_url} Discord server.")
45 59 if not api_endpoint:
@@ -47,7 +61,7 @@ class Azure(OpenaiTemplate):
47 61 cls.get_models()
48 62 api_endpoint = cls.routes.get(model)
49 63 if cls.routes and not api_endpoint:
50 raise ValueError(f"No API endpoint found for model: {model}")
64 raise ModelNotFoundError(f"No API endpoint found for model: {model}")
51 65 if not api_endpoint:
52 66 api_endpoint = os.environ.get("AZURE_API_ENDPOINT")
53 67 try:
Modified g4f/Provider/template/OpenaiTemplate.py +15 -6
@@ -7,6 +7,7 @@ from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin, RaiseErr
7 7 from ...typing import Union, AsyncResult, Messages, MediaListType
8 8 from ...requests import StreamSession, raise_for_status
9 9 from ...image import use_aspect_ratio
10 from ...image.copy_images import save_response_media
10 11 from ...providers.response import FinishReason, ToolCalls, Usage, ImageResponse, ProviderInfo
11 12 from ...tools.media import render_messages
12 13 from ...errors import MissingAuthError, ResponseError
@@ -62,7 +63,7 @@ class OpenaiTemplate(AsyncGeneratorProvider, ProviderModelMixin, RaiseErrorMixin
62 63 max_tokens: int = None,
63 64 top_p: float = None,
64 65 stop: Union[str, list[str]] = None,
65 stream: bool = False,
66 stream: bool = None,
66 67 prompt: str = None,
67 68 headers: dict = None,
68 69 impersonate: str = None,
@@ -115,7 +116,7 @@ class OpenaiTemplate(AsyncGeneratorProvider, ProviderModelMixin, RaiseErrorMixin
115 116 max_tokens=max_tokens,
116 117 top_p=top_p,
117 118 stop=stop,
118 stream=stream,
119 stream="audio" not in extra_parameters if stream is None else stream,
119 120 **extra_parameters,
120 121 **extra_body
121 122 )
@@ -136,10 +137,18 @@ class OpenaiTemplate(AsyncGeneratorProvider, ProviderModelMixin, RaiseErrorMixin
136 137 yield Usage(**data["usage"])
137 138 if "choices" in data:
138 139 choice = next(iter(data["choices"]), None)
139 if choice and "content" in choice["message"] and choice["message"]["content"]:
140 yield choice["message"]["content"].strip()
141 if "tool_calls" in choice["message"]:
142 yield ToolCalls(choice["message"]["tool_calls"])
140 message = choice.get("message", {})
141 if choice and "content" in message and message["content"]:
142 yield message["content"].strip()
143 if "tool_calls" in message:
144 yield ToolCalls(message["tool_calls"])
145 audio = message.get("audio", {})
146 if "data" in audio:
147 async for chunk in save_response_media(audio["data"], prompt, [model, extra_body.get("audio", {}).get("voice")]):
148 yield chunk
149 if "transcript" in audio:
150 yield "\n\n"
151 yield audio["transcript"]
143 152 if choice and "finish_reason" in choice and choice["finish_reason"] is not None:
144 153 yield FinishReason(choice["finish_reason"])
145 154 return
Modified g4f/client/service.py +1 -1
@@ -23,7 +23,7 @@ def convert_to_provider(provider: str) -> ProviderType:
23 23
24 24 def get_model_and_provider(model : Union[Model, str],
25 25 provider : Union[ProviderType, str, None],
26 stream : bool,
26 stream : bool = False,
27 27 ignore_working: bool = False,
28 28 ignore_stream: bool = False,
29 29 logging: bool = True,
Modified g4f/gui/server/api.py +0 -3
@@ -149,7 +149,6 @@ class Api:
149 149 "model": model,
150 150 "provider": provider,
151 151 "messages": messages,
152 "stream": True,
153 152 "ignore_stream": True,
154 153 **kwargs
155 154 }
@@ -166,8 +165,6 @@ class Api:
166 165 try:
167 166 model, provider_handler = get_model_and_provider(
168 167 kwargs.get("model"), provider,
169 stream=True,
170 ignore_stream=True,
171 168 has_images="media" in kwargs,
172 169 )
173 170 if "user" in kwargs:
Modified g4f/image/copy_images.py +1 -1
@@ -112,7 +112,7 @@ def get_filename(tags: list[str], alt: str, extension: str, image: str) -> str:
112 112 return "".join((
113 113 f"{int(time.time())}_",
114 114 f"{secure_filename(tags + alt)}_" if alt else secure_filename(tags),
115 hashlib.sha256(image.encode()).hexdigest()[:16],
115 hashlib.sha256(str(time.time()).encode() if image is None else image.encode()).hexdigest()[:16],
116 116 extension
117 117 ))
118 118
Modified g4f/providers/base_provider.py +2 -3
@@ -292,7 +292,7 @@ class AsyncGeneratorProvider(AbstractProvider):
292 292 cls,
293 293 model: str,
294 294 messages: Messages,
295 stream: bool = True,
295 stream: bool = None,
296 296 timeout: int = None,
297 297 **kwargs
298 298 ) -> CreateResult:
@@ -312,7 +312,7 @@ class AsyncGeneratorProvider(AbstractProvider):
312 312 """
313 313 return to_sync_generator(
314 314 cls.create_async_generator(model, messages, stream=stream, **kwargs),
315 stream=stream,
315 stream=stream is not False,
316 316 timeout=timeout
317 317 )
318 318
@@ -321,7 +321,6 @@ class AsyncGeneratorProvider(AbstractProvider):
321 321 async def create_async_generator(
322 322 model: str,
323 323 messages: Messages,
324 stream: bool = True,
325 324 **kwargs
326 325 ) -> AsyncResult:
327 326 """
Modified projects/windows/docker-compose.yml +2 -1
@@ -16,4 +16,5 @@ services:
16 16 stop_grace_period: 2m
17 17 restart: on-failure
18 18 volumes:
19 - /var/win:/storage
19 - /var/win:/storage
20 - ./:/data