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

XFEstudio/gpt4free

Add screenshot URLs for various providers to enhance functionality

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

代码差异

12 个文件 +35 -47
Modified g4f/Provider/BraveSearch.py +1 -0
@@ -64,6 +64,7 @@ class BraveSearch(AsyncGeneratorProvider, ProviderModelMixin):
64 64
65 65 label = "Brave Search"
66 66 url = BRAVE_ASK_URL
67 screenshot_url = f"{BRAVE_ASK_URL}/?q=Hello"
67 68 working = True
68 69 needs_auth = False
69 70 supports_stream = True
Modified g4f/Provider/Cloudflare.py +1 -0
@@ -32,6 +32,7 @@ def clean_name(name: str) -> str:
32 32 class Cloudflare(AsyncGeneratorProvider, ProviderModelMixin):
33 33 label = "Cloudflare AI"
34 34 url = "https://playground.ai.cloudflare.com"
35 screenshot_url = f"{url}/models?q=Hello"
35 36 working = True
36 37 use_nodriver = False
37 38 active_by_default = True
Modified g4f/Provider/glm/__init__.py +1 -0
@@ -72,6 +72,7 @@ class _CaptchaRequired(Exception):
72 72
73 73 class GLM(AsyncGeneratorProvider, ProviderModelMixin, AuthFileMixin):
74 74 url = GLM_BASE_URL
75 screenshot_url = f"{GLM_BASE_URL}/#q=Hello"
75 76 api_endpoint = f"{GLM_BASE_URL}/api/v2/chat/completions"
76 77 working = True
77 78 active_by_default = True
Modified g4f/Provider/needs_auth/Gemini.py +1 -0
@@ -324,6 +324,7 @@ def _is_xsrf_error(error: Exception, status: int | None) -> bool:
324 324 class Gemini(AsyncGeneratorProvider, ProviderModelMixin):
325 325 label = "Google Gemini"
326 326 url = "https://gemini.google.com"
327 screenshot_url = f"{url}/app?q=Hello"
327 328
328 329 needs_auth = False
329 330 working = True
Modified g4f/Provider/needs_auth/LMArena.py +1 -0
@@ -109,6 +109,7 @@ async def click_trunstile(
109 109 class LMArena(AsyncGeneratorProvider, ProviderModelMixin, AuthFileMixin):
110 110 label = "LMArena"
111 111 url = "https://arena.ai"
112 screenshot_url = "https://arena.ai/?q=Hello"
112 113 share_url = None
113 114 create_evaluation = "https://arena.ai/nextjs-api/stream/create-evaluation"
114 115 post_to_evaluation = "https://arena.ai/nextjs-api/stream/post-to-evaluation/{id}"
Modified g4f/Provider/needs_auth/OpenaiChat.py +1 -0
@@ -151,6 +151,7 @@ class OpenaiChat(AsyncAuthedProvider, ProviderModelMixin):
151 151
152 152 label = "OpenAI ChatGPT"
153 153 url = "https://chatgpt.com"
154 screenshot_url = "https://chatgpt.com/?q=Hello"
154 155 working = True
155 156 active_by_default = True
156 157 use_nodriver = True
Modified g4f/Provider/search/GoogleAiMode.py +1 -0
@@ -14,6 +14,7 @@ from .GoogleSearch import GoogleSearch
14 14 class GoogleAiMode(GoogleSearch):
15 15 label = "Google AI Mode"
16 16 url = "https://google.com"
17 screenshot_url = f"{url}/search?q=Hello&ai-mode=true"
17 18 working = True
18 19 active_by_default = True
19 20 supports_native_tools = True
Modified g4f/Provider/search/GoogleSearch.py +1 -0
@@ -14,6 +14,7 @@ from ..helper import get_last_user_message
14 14 class GoogleSearch(AsyncGeneratorProvider, ProviderModelMixin):
15 15 label = "Google Search"
16 16 url = "https://google.com"
17 screenshot_url = f"{url}/search?q=Hello"
17 18 working = True
18 19 active_by_default = True
19 20 supports_native_tools = True
Modified g4f/Provider/search/YouTube.py +1 -0
@@ -18,6 +18,7 @@ from ..helper import format_media_prompt
18 18
19 19 class YouTube(AsyncGeneratorProvider, ProviderModelMixin):
20 20 url = "https://youtube.com"
21 screenshot_url = f"{url}/results?search_query=Hello"
21 22 working = has_yt_dlp
22 23
23 24 default_model = "search"
Modified g4f/client/__init__.py +2 -0
@@ -489,6 +489,8 @@ class Images:
489 489 api_key: Optional[str] = None,
490 490 **kwargs,
491 491 ) -> ImagesResponse:
492 from ..Provider import PollinationsImage
493
492 494 provider_handler = await self.get_provider_handler(
493 495 model, provider, PollinationsImage
494 496 )
Modified g4f/gui/server/website.py +6 -9
@@ -305,8 +305,9 @@ class Website:
305 305 return self._providers()
306 306
307 307 p = providers[idx]
308 prev_p = providers[idx - 1] if idx > 0 else providers[-1]
309 next_p = providers[idx + 1] if idx < len(providers) - 1 else providers[0]
308 working_providers = [p for p in providers if p["working"]]
309 prev_p = working_providers[idx - 1] if idx > 0 and idx < len(working_providers) - 1 else working_providers[-1]
310 next_p = working_providers[idx + 1] if idx < len(working_providers) - 1 else working_providers[0]
310 311
311 312 # Lazily load models for this single provider only
312 313 from g4f.Provider import ProviderLoader
@@ -368,7 +369,7 @@ class Website:
368 369
369 370 # Screenshot / logo section
370 371 screenshot_url = p.get("screenshot_url") or p.get("url") or ""
371 create_url = f"/screenshot?url={quote_plus(screenshot_url)}"
372 create_url = f"/screenshot?url={quote_plus(str(screenshot_url))}"
372 373 screenshot_url = screenshot_url.replace("https://", "").replace("http://", "")
373 374 logo_url = "https://g4f.space/logo/" + p.get("name", "").replace(
374 375 'MetaAIAccount', 'Facebook AI').replace(
@@ -449,12 +450,8 @@ class Website:
449 450 queryUrl.pathname = "/results";
450 451 queryUrl.searchParams.set('search_query', event.target.value);
451 452 newUrl = "/screenshot?url=" + encodeURIComponent(queryUrl.toString());
452 }} else if (['GoogleSearch', 'GoogleAiMode'].includes('{p["name"]}')) {{
453 const createUrl = new URL('{create_url}', location.origin);
454 const queryUrl = new URL(createUrl.searchParams.get('url'));
455 queryUrl.pathname = "/search";
456 const appendUrl = queryUrl.toString() + (queryUrl.toString().includes('?') ? '&q=' : '?q=') + event.target.value;
457 newUrl = "/screenshot?url=" + encodeURIComponent(appendUrl);
453 }} else if ('{create_url}'.includes('q=Hello')) {{
454 newUrl = "{create_url}".replace("q=Hello", "q=" + encodeURIComponent(event.target.value));
458 455 }} else {{
459 456 newUrl = createSrc + encodeURIComponent('?q=' + event.target.value);
460 457 }}
Modified g4f/requests/cdp.py +18 -38
@@ -776,7 +776,7 @@ debugEl.src = 'https://g4f.dev/dist/js/debug.js';
776 776 document.head.appendChild(debugEl);
777 777
778 778 // 2. Get the current URL's search parameters
779 const params = new URLSearchParams(window.location.search);
779 const params = new URLSearchParams(window.location.search || document.location.hash.substring(1));
780 780 const searchQuery = params.get('q');
781 781
782 782 // 2b. Insert prompt in Flux HF before clicking on run button
@@ -789,7 +789,7 @@ const targetTexts = [
789 789 'Accept All Cookies', 'Accept all cookies',
790 790 'Einwilligen', 'Alle akzeptieren',
791 791 'Zustimmen und weiter', 'Zustimmen',
792 'Run', 'Accept Cookies',
792 'Run', 'Accept Cookies', 'Skip for now',
793 793 ...params.getAll('click')
794 794 ];
795 795 const acceptBtns = (() => {
@@ -869,44 +869,19 @@ const fieldSelectors = [
869 869 'textarea[name="prompt"]',
870 870 '[class^="MessageInput__TextArea--"]',
871 871 '[placeholder="Type a message..."]',
872 '[placeholder="Ask anything…"]'
872 '#chat-input', // # z.ai
873 '[contenteditable="true"]',
874 '[placeholder="Message DeepSeek"]',
875 '.message-input-textarea',
876 '[placeholder="Ask anything…"]', // arena.ai
877 '[placeholder="Ask Meta AI..."]', // meta.ai
878 '[placeholder="Ask anything..."]', // cloudflare
873 879 ];
874 const textarea = document.querySelector(fieldSelectors.join(', '));
875
876 // 6. Only proceed if we found a query and the textarea exists
877 if (searchQuery && textarea) {
878 // Set the value
879 textarea.value = searchQuery;
880
881 // Dispatch an 'input' event to notify the page that the value has changed
882 // This is crucial for frameworks like React/Vue to recognize the update
883 const event = new Event('input', { bubbles: true });
884 textarea.dispatchEvent(event);
885
886 // Optional: dispatch 'change' event as well, in case the site relies on it
887 textarea.dispatchEvent(new Event('change', { bubbles: true }));
888
889 enableGoogleAiMode();
890 }
891
892 880 // 7. Handle special cases for specific sites (like DeepSeek, Gemini, etc.)
893 881 (function() {
894 // 1. Target the specific element Kimi uses
895 // Inspect the page; if it's the main input, it might be a div with contenteditable
896 const fields = [
897 '[contenteditable="true"]',
898 '[placeholder="Message DeepSeek"]',
899 '.message-input-textarea',
900 '#chat-input',
901 '[placeholder="Ask anything…"]' // arena.ai
902 ];
903 const editor = document.querySelector(fields.join(', '));
882 const editor = document.querySelector(fieldSelectors.join(', '));
904 883 if (!editor) return;
905 884
906 // 2. Get your query
907 const searchQuery = new URLSearchParams(window.location.search).get('q');
908 if (!searchQuery) return;
909
910 885 // 3. Focus the element first (some frameworks require this)
911 886 editor.focus();
912 887
@@ -925,6 +900,7 @@ if (searchQuery && textarea) {
925 900 nativeInputValueSetter.call(editor, searchQuery);
926 901
927 902 // Dispatch events to notify the framework
903 editor.dispatchEvent(new Event('keyup', { bubbles: true }));
928 904 editor.dispatchEvent(new Event('input', { bubbles: true }));
929 905 editor.dispatchEvent(new Event('change', { bubbles: true }));
930 906
@@ -935,17 +911,21 @@ if (searchQuery && textarea) {
935 911 // 8. Click the send / submit button if it exists
936 912 const sendButtonSelectors = [
937 913 '[data-send-label="Send message"]',
938 '[aria-label="Send message"]',
939 914 '[class^="MessageInput__Submit--"]',
940 915 '.send-button-container',
941 916 '.send-button',
942 917 '#send-message-button', // z.ai
943 918 '[data-testid="chat-submit"]', // grok.com
944 '[aria-label="Send message"]', // arena.ai
919 '[aria-label="Send"]', // meta.ai
920 '#send-message-button', // z.ai
921 '[aria-label="Send message"]', // arena.ai / gemini.google.com
922 '[aria-label="Nachricht senden"]', // gemini.google.com
945 923 ];
946 924 const sendButton = document.querySelector(sendButtonSelectors.join(', '));
947 925 if (sendButton) {
948 sendButton.click();
926 setTimeout(() => {
927 sendButton.click();
928 }, 1000);
949 929 }
950 930
951 931 // 8. Click the send button on gemini.google.com