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

XFEstudio/gpt4free

Enhance Perplexity provider to yield additional response types including sources, media items, and suggested follow-ups; update response formatting in response classes for improved data handling.

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

代码差异

3 个文件 +26 -7
Modified g4f/Provider/Perplexity.py +19 -1
@@ -6,7 +6,7 @@ import uuid
6 6 from ..typing import AsyncResult, Messages, Cookies
7 7 from ..requests import StreamSession, raise_for_status, sse_stream
8 8 from ..cookies import get_cookies
9 from ..providers.response import ProviderInfo, JsonConversation, JsonRequest, JsonResponse, Reasoning
9 from ..providers.response import ProviderInfo, JsonConversation, JsonRequest, JsonResponse, Reasoning, Sources, SuggestedFollowups, ImageResponse, PreviewResponse, YouTubeResponse
10 10 from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
11 11 from .. import debug
12 12
@@ -254,6 +254,19 @@ class Perplexity(AsyncGeneratorProvider, ProviderModelMixin):
254 254 async for json_data in sse_stream(response):
255 255 yield JsonResponse.from_dict(json_data)
256 256 for block in json_data.get("blocks", []):
257 if block.get("intended_usage") == "sources_answer_mode":
258 yield Sources(block.get("sources_mode_block", {}).get("web_results", []))
259 continue
260 if block.get("intended_usage") == "media_items":
261 yield PreviewResponse([
262 ImageResponse(item.get("url"), item.get("name"), {
263 "height": item.get("image_height"),
264 "width": item.get("image_width"),
265 **item
266 }) if item.get("medium") == "image" else YouTubeResponse(item.get("url").split("=").pop())
267 for item in block.get("media_block", {}).get("media_items", [])
268 ])
269 continue
257 270 for patch in block.get("diff_block", {}).get("patches", []):
258 271 if patch.get("path") == "/progress":
259 272 continue
@@ -278,3 +291,8 @@ class Perplexity(AsyncGeneratorProvider, ProviderModelMixin):
278 291 if value:
279 292 full_response += value
280 293 yield value
294 if "related_query_items" in json_data:
295 followups = []
296 for item in json_data["related_query_items"]:
297 followups.append(item.get("text", ""))
298 yield SuggestedFollowups(followups)
Modified g4f/api/__init__.py +3 -2
@@ -25,6 +25,7 @@ from starlette.status import (
25 25 HTTP_404_NOT_FOUND,
26 26 HTTP_401_UNAUTHORIZED,
27 27 HTTP_403_FORBIDDEN,
28 HTTP_429_TOO_MANY_REQUESTS,
28 29 HTTP_500_INTERNAL_SERVER_ERROR,
29 30 )
30 31 from starlette.staticfiles import NotModifiedResponse
@@ -442,7 +443,7 @@ class Api:
442 443 current_most_wanted = next(iter(most_wanted.values()), 0)
443 444 is_most_wanted = False
444 445 if x_forwarded_for in most_wanted:
445 if failure_counts.get(x_forwarded_for, 0) > 0:
446 if failure_counts.get(x_forwarded_for, 0) > 1:
446 447 failure_counts[x_forwarded_for] -= 1
447 448 most_wanted[x_forwarded_for] += 1
448 449 elif most_wanted[x_forwarded_for] >= current_most_wanted:
@@ -457,7 +458,7 @@ class Api:
457 458 sorted_most_wanted = dict(sorted(most_wanted.items(), key=lambda item: item[1], reverse=True))
458 459 debug.log(f"Most wanted IPs: {sorted_most_wanted}")
459 460 if is_most_wanted:
460 raise RateLimitError("You are most wanted! Please wait before making another request.")
461 return ErrorResponse.from_message("You are most wanted! Please wait before making another request.", status_code=HTTP_429_TOO_MANY_REQUESTS)
461 462 if provider is not None and provider not in Provider.__map__:
462 463 if provider in model_map:
463 464 config.model = provider
Modified g4f/providers/response.py +4 -4
@@ -303,7 +303,7 @@ class Sources(ResponseType):
303 303 if not self.list:
304 304 return ""
305 305 return "\n\n\n\n" + ("\n>\n".join([
306 f"> [{idx}] {format_link(link['url'], link.get('title', None))}"
306 f"> [{idx}] {format_link(link['url'], link.get('title', link.get('name', None)))}"
307 307 for idx, link in enumerate(self.list)
308 308 ]))
309 309
@@ -413,8 +413,8 @@ class ImageResponse(MediaResponse):
413 413 """Return images as markdown."""
414 414 if self.get("width") and self.get("height"):
415 415 return "\n".join([
416 f'<a href="{html.escape(url)}" data-width="{self.get("width")}" data-height="{self.get("height")}" data-source="{html.escape(self.get("source_url", ""))}">'
417 + f'<img src="{url.replace("/media/", "/thumbnail/")}" alt="{html.escape(" ".join(self.alt.split()))}"></a>'
416 f'<a href="{html.escape(url)}" data-src="{self.get("image", url)}" data-width="{self.get("width")}" data-height="{self.get("height")}" data-source="{html.escape(self.get("source_url", ""))}">'
417 + f'<img src="{self.get("thumbnail", url.replace("/media/", "/thumbnail/"))}" alt="{html.escape(self.alt)}" width="{html.escape(str(self.get("thumbnail_width", "")))}" height="{html.escape(str(self.get("thumbnail_height", "")))}"></a>'
418 418 for url in self.get_list()
419 419 ])
420 420 return format_images_markdown(self.urls, self.alt, self.get("preview"))
@@ -442,7 +442,7 @@ class PreviewResponse(HiddenResponse):
442 442
443 443 def to_string(self) -> str:
444 444 """Return data as a string."""
445 return self.data
445 return "".join([str(item) for item in self.data]) if isinstance(self.data, list) else str(self.data)
446 446
447 447 class Parameters(ResponseType, JsonMixin):
448 448 def __str__(self) -> str: