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

XFEstudio/gpt4free

fix: handle RuntimeError during asyncio.run in Cloudflare.py and rename key in PollinationsAI.py

- Added try-except block to catch RuntimeError around asyncio.run(nodriver_read_models()) in Cloudflare.py to set cls.models to fallback_models if encountered - Corrected indentation of "followups" key in PollinationsAI.py from 43 to 44, changing it from nested to proper dictionary key - No other code logic changed in these files

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

代码差异

5 个文件 +60 -21
Modified g4f/Provider/Cloudflare.py +5 -1
@@ -85,7 +85,11 @@ class Cloudflare(AsyncGeneratorProvider, ProviderModelMixin, AuthFileMixin):
85 85 debug.log(f"Nodriver is not available: {type(e).__name__}: {e}")
86 86 cls.models = cls.fallback_models
87 87 get_running_loop(check_nested=True)
88 asyncio.run(nodriver_read_models())
88 try:
89 asyncio.run(nodriver_read_models())
90 except RuntimeError:
91 debug.log("Nodriver is not available: RuntimeError")
92 cls.models = cls.fallback_models
89 93 else:
90 94 cls.models = cls.fallback_models
91 95 debug.log(f"Nodriver is not installed: {type(f).__name__}: {f}")
Modified g4f/Provider/PollinationsAI.py +1 -1
@@ -43,7 +43,7 @@ FOLLOWUPS_TOOLS = [{
43 43 "title": "Conversation Title",
44 44 "type": "string"
45 45 },
46 "followups": {
46 "followups": {
47 47 "items": {
48 48 "type": "string"
49 49 },
Modified g4f/gui/server/backend_api.py +48 -15
@@ -24,14 +24,14 @@ except ImportError as e:
24 24
25 25 from ...client.service import convert_to_provider
26 26 from ...providers.asyncio import to_sync_generator
27 from ...providers.response import FinishReason
27 from ...providers.response import FinishReason, AudioResponse, MediaResponse, Reasoning, HiddenResponse
28 28 from ...client.helper import filter_markdown
29 29 from ...tools.files import supports_filename, get_streaming, get_bucket_dir, get_tempfile
30 30 from ...tools.run_tools import iter_run_tools
31 31 from ...errors import ProviderNotFoundError
32 32 from ...image import is_allowed_extension, MEDIA_TYPE_MAP
33 33 from ...cookies import get_cookies_dir
34 from ...image.copy_images import secure_filename, get_source_url, get_media_dir
34 from ...image.copy_images import secure_filename, get_source_url, get_media_dir, copy_media
35 35 from ... import ChatCompletion
36 36 from ... import models
37 37 from .api import Api
@@ -233,23 +233,44 @@ class Backend_Api(Api):
233 233 parameters = {
234 234 "model": request.args.get("model"),
235 235 "messages": [{"role": "user", "content": request.args.get("prompt")}],
236 "provider": request.args.get("provider", None),
236 "provider": request.args.get("provider", request.args.get("audio_provider", "AnyProvider")),
237 237 "stream": not do_filter and not cache_id,
238 238 "ignore_stream": not request.args.get("stream"),
239 239 "tool_calls": tool_calls,
240 240 }
241 if request.args.get("audio_provider") or request.args.get("audio"):
242 parameters["audio"] = {}
241 243 def cast_str(response):
242 for chunk in response:
243 if isinstance(chunk, FinishReason):
244 yield f"[{chunk.reason}]" if chunk.reason != "stop" else ""
245 elif not isinstance(chunk, Exception):
246 chunk = str(chunk)
247 if chunk:
248 yield chunk
244 buffer = next(response)
245 while isinstance(buffer, (Reasoning, HiddenResponse)):
246 buffer = next(response)
247 if isinstance(buffer, MediaResponse):
248 if len(buffer.get_list()) == 1:
249 if not cache_id:
250 return buffer.get_list()[0]
251 return asyncio.run(copy_media(
252 buffer.get_list(),
253 buffer.get("cookies"),
254 buffer.get("headers"),
255 request.args.get("prompt")
256 )).pop()
257 elif isinstance(buffer, AudioResponse):
258 return buffer.data
259 def iter_response():
260 yield str(buffer)
261 for chunk in response:
262 if isinstance(chunk, FinishReason):
263 yield f"[{chunk.reason}]" if chunk.reason != "stop" else ""
264 elif not isinstance(chunk, Exception):
265 chunk = str(chunk)
266 if chunk:
267 yield chunk
268 return iter_response()
269
249 270 if cache_id:
250 271 cache_id = sha256(cache_id.encode() + json.dumps(parameters, sort_keys=True).encode()).hexdigest()
251 272 cache_dir = Path(get_cookies_dir()) / ".scrape_cache" / "create"
252 cache_file = cache_dir / f"{quote_plus(request.args.get('prompt').strip()[:20])}.{cache_id}.txt"
273 cache_file = cache_dir / f"{quote_plus(request.args.get('prompt', '').strip()[:20])}.{cache_id}.txt"
253 274 response = None
254 275 if cache_file.exists():
255 276 with cache_file.open("r") as f:
@@ -260,11 +281,22 @@ class Backend_Api(Api):
260 281 copy_response = cast_str(response)
261 282 if copy_response:
262 283 with cache_file.open("w") as f:
263 for chunk in copy_response:
284 for chunk in [copy_response] if isinstance(copy_response, str) else copy_response:
264 285 f.write(chunk)
265 286 response = copy_response
266 287 else:
267 288 response = cast_str(iter_run_tools(ChatCompletion.create, **parameters))
289 if isinstance(response, str):
290 if response.startswith("/media/"):
291 media_dir = get_media_dir()
292 filename = os.path.basename(response.split("?")[0])
293 try:
294 return send_from_directory(os.path.abspath(media_dir), filename)
295 finally:
296 if not cache_id:
297 os.remove(os.path.join(media_dir, filename))
298 elif response.startswith("https://") or response.startswith("http://"):
299 return redirect(response)
268 300 if do_filter:
269 301 is_true_filter = do_filter.lower() in ["true", "1"]
270 302 response = "".join(response)
@@ -320,7 +352,7 @@ class Backend_Api(Api):
320 352 result = md.convert(copyfile, stream_info=StreamInfo(
321 353 extension=suffix,
322 354 mimetype=file.mimetype,
323 ), language=language).text_content
355 ),recognition_language=language).text_content
324 356 except Exception as e:
325 357 logger.exception(e)
326 358 is_media = is_allowed_extension(filename)
@@ -336,7 +368,7 @@ class Backend_Api(Api):
336 368 os.makedirs(media_dir, exist_ok=True)
337 369 newfile = os.path.join(media_dir, filename)
338 370 media.append({"name": filename, "text": result})
339 elif not result and supports_filename(filename):
371 elif not result and is_supported:
340 372 newfile = os.path.join(bucket_dir, filename)
341 373 filenames.append(filename)
342 374 try:
@@ -345,7 +377,8 @@ class Backend_Api(Api):
345 377 shutil.copyfile(copyfile, newfile)
346 378 os.remove(copyfile)
347 379 with open(os.path.join(bucket_dir, "files.txt"), 'w') as f:
348 f.write("".join([f"{filename}\n" for filename in filenames]))
380 for filename in filenames:
381 f.write(f"{filename}\n")
349 382 return {"bucket_id": bucket_id, "files": filenames, "media": media}
350 383
351 384 @app.route('/files/<bucket_id>/media/<filename>', methods=['GET'])
Modified g4f/integration/markitdown/_audio_converter.py +2 -2
@@ -50,7 +50,7 @@ class AudioConverter(DocumentConverter):
50 50 self,
51 51 file_stream: BinaryIO,
52 52 stream_info: StreamInfo,
53 language: str = "en-US",
53 recognition_language: str = None,
54 54 **kwargs: Any, # Options to pass to the converter
55 55 ) -> DocumentConverterResult:
56 56 md_content = ""
@@ -97,7 +97,7 @@ class AudioConverter(DocumentConverter):
97 97 # Transcribe
98 98 if audio_format:
99 99 try:
100 md_content = transcribe_audio(file_stream, audio_format=audio_format, language=language)
100 md_content = transcribe_audio(file_stream, audio_format=audio_format, language=recognition_language)
101 101 except MissingDependencyException:
102 102 pass
103 103
Modified g4f/integration/markitdown/_transcribe_audio.py +4 -2
@@ -20,7 +20,7 @@ except ImportError:
20 20 _dependency_exc_info = sys.exc_info()
21 21
22 22
23 def transcribe_audio(file_stream: BinaryIO, *, audio_format: str = "wav", language: str = "en-US") -> str:
23 def transcribe_audio(file_stream: BinaryIO, *, audio_format: str = "wav", language: str = None) -> str:
24 24 # Check for installed dependencies
25 25 if _dependency_exc_info is not None:
26 26 raise MissingDependencyException(
@@ -45,5 +45,7 @@ def transcribe_audio(file_stream: BinaryIO, *, audio_format: str = "wav", langua
45 45 recognizer = sr.Recognizer()
46 46 with sr.AudioFile(audio_source) as source:
47 47 audio = recognizer.record(source)
48 if language is None:
49 language = "en-US"
48 50 transcript = recognizer.recognize_google(audio, language=language).strip()
49 return "[No speech detected]" if transcript == "" else transcript
51 return "[No speech detected]" if transcript == "" else transcript.strip()