diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index c1240682..696be746 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,13 +1,3 @@ -# These are supported funding model platforms - github: [onlp] patreon: xtekky -open_collective: # Replace with a single Open Collective username ko_fi: xtekky -tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: tekky -issuehunt: xtekky -otechie: # Replace with a single Otechie username -lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry -custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/README.md b/README.md index 42f2e007..28a77b7e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,27 @@ gpt4free logo + +## Legal Notice + +This repository is _not_ associated with or endorsed by providers of the APIs contained in this GitHub repository. This project is intended **for educational purposes only**. This is just a little personal project. Sites may contact me to improve their security or request the removal of their site from this repository. + +Please note the following: + +1. **Disclaimer**: The APIs, services, and trademarks mentioned in this repository belong to their respective owners. This project is _not_ claiming any right over them nor is it affiliated with or endorsed by any of the providers mentioned. + +2. **Responsibility**: The author of this repository is _not_ responsible for any consequences, damages, or losses arising from the use or misuse of this repository or the content provided by the third-party APIs. Users are solely responsible for their actions and any repercussions that may follow. + +3. **Educational Purposes Only**: This repository and its content are provided strictly for educational purposes. By using the information and code provided, users acknowledge that they are using the APIs and models at their own risk and agree to comply with any applicable laws and regulations. + +4. **Copyright**: All content in this repository, including but not limited to code, images, and documentation, is the intellectual property of the repository author, unless otherwise stated. Unauthorized copying, distribution, or use of any content in this repository is strictly prohibited without the express written consent of the repository author. + +5. **Indemnification**: Users agree to indemnify, defend, and hold harmless the author of this repository from and against any and all claims, liabilities, damages, losses, or expenses, including legal fees and costs, arising out of or in any way connected with their use or misuse of this repository, its content, or related third-party APIs. + +6. **Updates and Changes**: The author reserves the right to modify, update, or remove any content, information, or features in this repository at any time without prior notice. Users are responsible for regularly reviewing the content and any changes made to this repository. + +By using this repository or any code related to it, you agree to these terms. The author is not responsible for any copies, forks, or reuploads made by other users. This is the author's only account and repository. To prevent impersonation or irresponsible actions, you may comply with the GNU GPL license this Repository uses. + +
+ Just API's from some language model sites.

Join our discord.gg/gpt4free Discord community! gpt4free Discord

@@ -32,11 +55,11 @@ Just API's from some language model sites. Pull Requests - ChatGpt Discord Bot - Stars - Forks - Issues - Pull Requests + ChatGpt Discord Bot + Stars + Forks + Issues + Pull Requests @@ -86,7 +109,6 @@ Just API's from some language model sites. | [sqlchat.ai](https://sqlchat.ai) | GPT-3.5 | | [bard.google.com](https://bard.google.com) | custom / search | | [bing.com/chat](https://bing.com/chat) | GPT-4/3.5 | -| [chat.forefront.ai/](https://chat.forefront.ai/) | GPT-4/3.5 | | [italygpt.it](https://italygpt.it) | GPT-3.5 | ## Best sites @@ -120,7 +142,7 @@ then run: Build ``` -docker build -t gpt4free:latest -f Docker/Dockerfile . +docker build -t gpt4free:latest . ``` Run @@ -128,37 +150,21 @@ Run ``` docker run -p 8501:8501 gpt4free:latest ``` -Another way - docker-compose (no docker build/run needed) -``` -docker-compose up -d -``` ## Deploy using docker-compose Run the following: ``` -docker-compose up -d +docker-compose up --build -d ``` ## ChatGPT clone -> currently implementing new features and trying to scale it, please be patient it may be unstable -> https://chat.chatbot.sex/chat +> Currently implementing new features and trying to scale it, please be patient it may be unstable +> https://chat.g4f.ai/chat > This site was developed by me and includes **gpt-4/3.5**, **internet access** and **gpt-jailbreak's** like DAN -> run locally here: https://github.com/xtekky/chatgpt-clone - -## Legal Notice - -This repository uses third-party APIs and is _not_ associated with or endorsed by the API providers. This project is intended **for educational purposes only**. This is just a little personal project. Sites may contact me to improve their security. - -Please note the following: - -1. **Disclaimer**: The APIs, services, and trademarks mentioned in this repository belong to their respective owners. This project is _not_ claiming any right over them. - -2. **Responsibility**: The author of this repository is _not_ responsible for any consequences arising from the use or misuse of this repository or the content provided by the third-party APIs and any damage or losses caused by users' actions. - -3. **Educational Purposes Only**: This repository and its content are provided strictly for educational purposes. By using the information and code provided, users acknowledge that they are using the APIs and models at their own risk and agree to comply with any applicable laws and regulations. +> Run locally here: https://github.com/xtekky/chatgpt-clone ## Copyright: diff --git a/docker-compose.yaml b/docker-compose.yaml index 3afd6cdf..8098f359 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -2,8 +2,14 @@ version: "3.9" services: gpt4free: - build: - context: . + build: + context: ./ dockerfile: Dockerfile + container_name: dc_gpt4free + # environment: + # - http_proxy=http://127.0.0.1:1080 # modify this for your proxy + # - https_proxy=http://127.0.0.1:1080 # modify this for your proxy + image: img_gpt4free ports: - - "8501:8501" + - 8501:8501 + restart: always \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index e8e7119b..00000000 --- a/docker-compose.yml +++ /dev/null @@ -1,12 +0,0 @@ -version: '3.8' - -services: - gpt4: - build: - context: . - dockerfile: Dockerfile - image: gpt4free:latest - container_name: gpt4 - ports: - - 8501:8501 - restart: unless-stopped diff --git a/gpt4free/__init__.py b/gpt4free/__init__.py index b4742b64..6df778e3 100644 --- a/gpt4free/__init__.py +++ b/gpt4free/__init__.py @@ -4,8 +4,8 @@ from gpt4free import cocalc from gpt4free import forefront from gpt4free import quora from gpt4free import theb -from gpt4free import you from gpt4free import usesless +from gpt4free import you class Provider(Enum): @@ -24,7 +24,6 @@ class Completion: @staticmethod def create(provider: Provider, prompt: str, **kwargs) -> str: - """ Invokes the given provider with given prompt and addition arguments and returns the string response @@ -47,10 +46,10 @@ class Completion: return Completion.__useless_service(prompt, **kwargs) else: raise Exception('Provider not exist, Please try again') - + @staticmethod def __useless_service(prompt: str, **kwargs) -> str: - return usesless.Completion.create(prompt = prompt, **kwargs) + return usesless.Completion.create(prompt=prompt, **kwargs) @staticmethod def __you_service(prompt: str, **kwargs) -> str: diff --git a/gpt4free/forefront/README.md b/gpt4free/forefront/README.md index 35ba9897..887097ec 100644 --- a/gpt4free/forefront/README.md +++ b/gpt4free/forefront/README.md @@ -6,8 +6,11 @@ from gpt4free import forefront token = forefront.Account.create(logging=False) print(token) # get a response -for response in forefront.StreamingCompletion.create(token=token, - prompt='hello world', model='gpt-4'): - print(response.completion.choices[0].text, end='') +for response in forefront.StreamingCompletion.create( + token=token, + prompt='hello world', + model='gpt-4' +): + print(response.choices[0].text, end='') print("") ``` \ No newline at end of file diff --git a/gpt4free/forefront/__init__.py b/gpt4free/forefront/__init__.py index 969b33b8..4d679a14 100644 --- a/gpt4free/forefront/__init__.py +++ b/gpt4free/forefront/__init__.py @@ -5,8 +5,8 @@ from typing import Generator, Optional from uuid import uuid4 from fake_useragent import UserAgent -from requests import post from pymailtm import MailTm, Message +from requests import post from tls_client import Session from .typing import ForeFrontResponse @@ -43,10 +43,7 @@ class Account: response = client.post( f'https://clerk.forefront.ai/v1/client/sign_ups/{trace_token}/prepare_verification?_clerk_js_version=4.38.4', - data={ - 'strategy': 'email_link', - 'redirect_url': 'https://accounts.forefront.ai/sign-up/verify' - }, + data={'strategy': 'email_link', 'redirect_url': 'https://accounts.forefront.ai/sign-up/verify'}, ) if logging: @@ -93,14 +90,14 @@ class StreamingCompletion: action_type='new', default_persona='607e41fe-95be-497e-8e97-010a59b2e2c0', # default model='gpt-4', - proxy=None + proxy=None, ) -> Generator[ForeFrontResponse, None, None]: if not token: raise Exception('Token is required!') if not chat_id: chat_id = str(uuid4()) - proxies = { 'http': 'http://' + proxy, 'https': 'http://' + proxy } if proxy else None + proxies = {'http': 'http://' + proxy, 'https': 'http://' + proxy} if proxy else None headers = { 'authority': 'chat-server.tenant-forefront-default.knative.chi.coreweave.com', @@ -168,7 +165,7 @@ class Completion: action_type='new', default_persona='607e41fe-95be-497e-8e97-010a59b2e2c0', # default model='gpt-4', - proxy=None + proxy=None, ) -> ForeFrontResponse: text = '' final_response = None @@ -179,7 +176,7 @@ class Completion: action_type=action_type, default_persona=default_persona, model=model, - proxy=proxy + proxy=proxy, ): if response: final_response = response @@ -191,4 +188,3 @@ class Completion: raise Exception('Unable to get the response, Please try again') return final_response - \ No newline at end of file diff --git a/gpt4free/forefront/typing.py b/gpt4free/forefront/typing.py index a9025419..23e90903 100644 --- a/gpt4free/forefront/typing.py +++ b/gpt4free/forefront/typing.py @@ -1,4 +1,5 @@ from typing import Any, List + from pydantic import BaseModel @@ -22,4 +23,4 @@ class ForeFrontResponse(BaseModel): model: str choices: List[Choice] usage: Usage - text: str \ No newline at end of file + text: str diff --git a/gpt4free/quora/README.md b/gpt4free/quora/README.md index 9c652c59..88fd0093 100644 --- a/gpt4free/quora/README.md +++ b/gpt4free/quora/README.md @@ -65,4 +65,13 @@ poe.chat('who won the football world cup most?') # new bot creation poe.create_bot('new_bot_name', prompt='You are new test bot', base_model='gpt-3.5-turbo') +# delete account +poe.delete_account() +``` + +### Deleting the Poe Account +```python +from gpt4free import quora + +quora.Account.delete(token='') ``` diff --git a/gpt4free/quora/__init__.py b/gpt4free/quora/__init__.py index afbfb68d..bc17ea5d 100644 --- a/gpt4free/quora/__init__.py +++ b/gpt4free/quora/__init__.py @@ -285,6 +285,11 @@ class Account: cookies = open(Path(__file__).resolve().parent / 'cookies.txt', 'r').read().splitlines() return choice(cookies) + @staticmethod + def delete(token: str, proxy: Optional[str] = None): + client = PoeClient(token, proxy=proxy) + client.delete_account() + class StreamingCompletion: @staticmethod @@ -293,11 +298,11 @@ class StreamingCompletion: custom_model: bool = None, prompt: str = 'hello world', token: str = '', - proxy: Optional[str] = None + proxy: Optional[str] = None, ) -> Generator[PoeResponse, None, None]: _model = MODELS[model] if not custom_model else custom_model - proxies = { 'http': 'http://' + proxy, 'https': 'http://' + proxy } if proxy else False + proxies = {'http': 'http://' + proxy, 'https': 'http://' + proxy} if proxy else False client = PoeClient(token) client.proxy = proxies @@ -333,7 +338,7 @@ class Completion: custom_model: str = None, prompt: str = 'hello world', token: str = '', - proxy: Optional[str] = None + proxy: Optional[str] = None, ) -> PoeResponse: _model = MODELS[model] if not custom_model else custom_model @@ -454,14 +459,7 @@ class Poe: response = chunk['text'] return response - def create_bot( - self, - name: str, - /, - prompt: str = '', - base_model: str = 'ChatGPT', - description: str = '', - ) -> None: + def create_bot(self, name: str, /, prompt: str = '', base_model: str = 'ChatGPT', description: str = '') -> None: if base_model not in MODELS: raise RuntimeError('Sorry, the base_model you provided does not exist. Please check and try again.') @@ -475,3 +473,6 @@ class Poe: def list_bots(self) -> list: return list(self.client.bot_names.values()) + + def delete_account(self) -> None: + self.client.delete_account() diff --git a/gpt4free/quora/api.py b/gpt4free/quora/api.py index 897215a8..d388baee 100644 --- a/gpt4free/quora/api.py +++ b/gpt4free/quora/api.py @@ -541,5 +541,11 @@ class Client: self.get_bots() return data + def delete_account(self) -> None: + response = self.send_query('SettingsDeleteAccountButton_deleteAccountMutation_Mutation', {}) + data = response['data']['deleteAccount'] + if 'viewer' not in data: + raise RuntimeError(f'Error occurred while deleting the account, Please try again!') + load_queries() diff --git a/gpt4free/quora/backup-mail.py b/gpt4free/quora/backup-mail.py index 0a2a5e94..25d526d7 100644 --- a/gpt4free/quora/backup-mail.py +++ b/gpt4free/quora/backup-mail.py @@ -1,7 +1,10 @@ -from requests import Session -from time import sleep from json import loads from re import findall +from time import sleep + +from requests import Session + + class Mail: def __init__(self) -> None: self.client = Session() @@ -9,29 +12,34 @@ class Mail: self.cookies = {'acceptcookie': 'true'} self.cookies["ci_session"] = self.client.cookies.get_dict()["ci_session"] self.email = None + def get_mail(self): - respone=self.client.post("https://etempmail.com/getEmailAddress") - #cookies + respone = self.client.post("https://etempmail.com/getEmailAddress") + # cookies self.cookies["lisansimo"] = eval(respone.text)["recover_key"] self.email = eval(respone.text)["address"] return self.email + def get_message(self): print("Waiting for message...") while True: sleep(5) - respone=self.client.post("https://etempmail.com/getInbox") - mail_token=loads(respone.text) + respone = self.client.post("https://etempmail.com/getInbox") + mail_token = loads(respone.text) print(self.client.cookies.get_dict()) if len(mail_token) == 1: break - - params = {'id': '1',} - self.mail_context = self.client.post("https://etempmail.com/getInbox",params=params) + + params = { + 'id': '1', + } + self.mail_context = self.client.post("https://etempmail.com/getInbox", params=params) self.mail_context = eval(self.mail_context.text)[0]["body"] return self.mail_context - #,cookies=self.cookies + + # ,cookies=self.cookies def get_verification_code(self): message = self.mail_context code = findall(r';">(\d{6,7})', message)[0] print(f"Verification code: {code}") - return code \ No newline at end of file + return code diff --git a/gpt4free/quora/graphql/SettingsDeleteAccountButton_deleteAccountMutation_Mutation.graphql b/gpt4free/quora/graphql/SettingsDeleteAccountButton_deleteAccountMutation_Mutation.graphql new file mode 100644 index 00000000..0af50950 --- /dev/null +++ b/gpt4free/quora/graphql/SettingsDeleteAccountButton_deleteAccountMutation_Mutation.graphql @@ -0,0 +1 @@ +mutation SettingsDeleteAccountButton_deleteAccountMutation_Mutation{ deleteAccount { viewer { uid id } }} \ No newline at end of file diff --git a/gpt4free/theb/README.md b/gpt4free/theb/README.md index a4abdf62..a7af9dd8 100644 --- a/gpt4free/theb/README.md +++ b/gpt4free/theb/README.md @@ -5,7 +5,10 @@ from gpt4free import theb # simple streaming completion -for token in theb.Completion.create('hello world'): - print(token, end='', flush=True) -print("") + +while True: + x = input() + for token in theb.Completion.create(x): + print(token, end='', flush=True) + print("") ``` diff --git a/gpt4free/theb/__init__.py b/gpt4free/theb/__init__.py index 75a15068..e3a7f783 100644 --- a/gpt4free/theb/__init__.py +++ b/gpt4free/theb/__init__.py @@ -17,9 +17,10 @@ class Completion: timer = None message_queue = Queue() stream_completed = False + last_msg_id = None @staticmethod - def request(prompt: str, proxy: Optional[str]=None): + def request(prompt: str, proxy: Optional[str] = None): headers = { 'authority': 'chatbot.theb.ai', 'content-type': 'application/json', @@ -28,26 +29,35 @@ class Completion: } proxies = {'http': 'http://' + proxy, 'https': 'http://' + proxy} if proxy else None - + + options = {} + if Completion.last_msg_id: + options['parentMessageId'] = Completion.last_msg_id + requests.post( 'https://chatbot.theb.ai/api/chat-process', headers=headers, proxies=proxies, content_callback=Completion.handle_stream_response, - json={'prompt': prompt, 'options': {}}, + json={'prompt': prompt, 'options': options}, ) Completion.stream_completed = True @staticmethod - def create(prompt: str, proxy: Optional[str]=None) -> Generator[str, None, None]: + + def create(prompt: str, proxy: Optional[str] = None) -> Generator[str, None, None]: + Completion.stream_completed = False + Thread(target=Completion.request, args=[prompt, proxy]).start() while not Completion.stream_completed or not Completion.message_queue.empty(): try: message = Completion.message_queue.get(timeout=0.01) for message in findall(Completion.regex, message): - yield loads(Completion.part1 + message + Completion.part2)['delta'] + message_json = loads(Completion.part1 + message + Completion.part2) + Completion.last_msg_id = message_json['id'] + yield message_json['delta'] except Empty: pass diff --git a/gpt4free/usesless/__init__.py b/gpt4free/usesless/__init__.py index 6029009d..40e99938 100644 --- a/gpt4free/usesless/__init__.py +++ b/gpt4free/usesless/__init__.py @@ -1,6 +1,7 @@ -import requests import json +import requests + class Completion: headers = { @@ -24,7 +25,7 @@ class Completion: model: str = "gpt-3.5-turbo", ): print(parentMessageId, prompt) - + json_data = { "openaiKey": "", "prompt": prompt, @@ -42,14 +43,14 @@ class Completion: url = "https://ai.usesless.com/api/chat-process" request = requests.post(url, headers=Completion.headers, json=json_data) content = request.content - + response = Completion.__response_to_json(content) return response @classmethod def __response_to_json(cls, text) -> dict: text = str(text.decode("utf-8")) - + split_text = text.rsplit("\n", 1)[1] to_json = json.loads(split_text) return to_json diff --git a/gpt4free/you/__init__.py b/gpt4free/you/__init__.py index d084a842..da22d05e 100644 --- a/gpt4free/you/__init__.py +++ b/gpt4free/you/__init__.py @@ -30,12 +30,12 @@ class Completion: include_links: bool = False, detailed: bool = False, debug: bool = False, - proxy: Optional[str] = None + proxy: Optional[str] = None, ) -> PoeResponse: if chat is None: chat = [] - proxies = { 'http': 'http://' + proxy, 'https': 'http://' + proxy } if proxy else {} + proxies = {'http': 'http://' + proxy, 'https': 'http://' + proxy} if proxy else {} client = Session(client_identifier='chrome_108') client.headers = Completion.__get_headers() diff --git a/gui/streamlit_chat_app.py b/gui/streamlit_chat_app.py index 7eb5a656..af3969e6 100644 --- a/gui/streamlit_chat_app.py +++ b/gui/streamlit_chat_app.py @@ -38,6 +38,17 @@ def save_conversations(conversations, current_conversation): os.replace(temp_conversations_file, conversations_file) +def delete_conversation(conversations, current_conversation): + for idx, conversation in enumerate(conversations): + conversations[idx] = current_conversation + break + conversations.remove(current_conversation) + + temp_conversations_file = "temp_" + conversations_file + with open(temp_conversations_file, "wb") as f: + pickle.dump(conversations, f) + + os.replace(temp_conversations_file, conversations_file) def exit_handler(): print("Exiting, saving data...") @@ -107,11 +118,15 @@ search_query = st.sidebar.text_input("Search Conversations:", value=st.session_s if search_query: filtered_conversations = [] - for conversation in st.session_state.conversations: + indices = [] + for idx, conversation in enumerate(st.session_state.conversations): if search_query in conversation['user_inputs'][0]: filtered_conversations.append(conversation) + indices.append(idx) + + filtered_conversations = list(zip(indices, filtered_conversations)) + conversations = sorted(filtered_conversations, key=lambda x: Levenshtein.distance(search_query, x[1]['user_inputs'][0])) - conversations = sorted(filtered_conversations, key=lambda c: Levenshtein.distance(search_query, c['user_inputs'][0])) sidebar_header = f"Search Results ({len(conversations)})" else: conversations = st.session_state.conversations @@ -119,12 +134,17 @@ else: # Sidebar st.sidebar.header(sidebar_header) - +sidebar_col1, sidebar_col2 = st.sidebar.columns([5,1]) for idx, conversation in enumerate(conversations): - if st.sidebar.button(f"Conversation {idx + 1}: {conversation['user_inputs'][0]}", key=f"sidebar_btn_{idx}"): + if sidebar_col1.button(f"Conversation {idx + 1}: {conversation['user_inputs'][0]}", key=f"sidebar_btn_{idx}"): st.session_state['selected_conversation'] = idx st.session_state['current_conversation'] = conversation - + if sidebar_col2.button('🗑️', key=f"sidebar_btn_delete_{idx}"): + if st.session_state['selected_conversation'] == idx: + st.session_state['selected_conversation'] = None + st.session_state['current_conversation'] = {'user_inputs': [], 'generated_responses': []} + delete_conversation(conversations, conversation) + st.experimental_rerun() if st.session_state['selected_conversation'] is not None: conversation_to_display = conversations[st.session_state['selected_conversation']] else: diff --git a/requirements.txt b/requirements.txt index 62e92d56..bc46bc70 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,3 +12,4 @@ twocaptcha https://github.com/AI-Yash/st-chat/archive/refs/pull/24/head.zip pydantic pymailtm +Levenshtein diff --git a/testing/poe_test.py b/testing/poe_test.py index 22d95f5f..6edc030c 100644 --- a/testing/poe_test.py +++ b/testing/poe_test.py @@ -1,6 +1,6 @@ from time import sleep -from gpt4free import quora +from gpt4free import quora token = quora.Account.create(proxy=None, logging=True) print('token', token) @@ -9,3 +9,5 @@ sleep(2) for response in quora.StreamingCompletion.create(model='ChatGPT', prompt='hello world', token=token): print(response.text, flush=True) + +quora.Account.delete(token) diff --git a/testing/theb_test.py b/testing/theb_test.py index 0fd2ec8b..5fa80908 100644 --- a/testing/theb_test.py +++ b/testing/theb_test.py @@ -2,4 +2,4 @@ from gpt4free import theb for token in theb.Completion.create('hello world'): print(token, end='', flush=True) - print('asdsos') \ No newline at end of file + print('asdsos') diff --git a/testing/useless_test.py b/testing/useless_test.py index 9b613aac..47c92386 100644 --- a/testing/useless_test.py +++ b/testing/useless_test.py @@ -11,7 +11,6 @@ while True: print(f"Answer: {req['text']}") message_id = req["id"] - import gpt4free message_id = "" @@ -20,8 +19,7 @@ while True: if prompt == "!stop": break - req = gpt4free.Completion.create(provider = gpt4free.Provider.UseLess, - prompt=prompt, parentMessageId=message_id) + req = gpt4free.Completion.create(provider=gpt4free.Provider.UseLess, prompt=prompt, parentMessageId=message_id) print(f"Answer: {req['text']}") - message_id = req["id"] \ No newline at end of file + message_id = req["id"]