diff options
Diffstat (limited to '')
-rw-r--r-- | etc/interference/app.py | 163 | ||||
-rw-r--r-- | etc/interference/requirements.txt (renamed from interference/requirements.txt) | 0 | ||||
-rw-r--r-- | etc/testing/log_time.py (renamed from testing/log_time.py) | 0 | ||||
-rw-r--r-- | etc/testing/test_async.py | 31 | ||||
-rw-r--r-- | etc/testing/test_chat_completion.py (renamed from testing/test_chat_completion.py) | 8 | ||||
-rw-r--r-- | etc/testing/test_interference.py (renamed from testing/test_interference.py) | 0 | ||||
-rw-r--r-- | etc/testing/test_needs_auth.py (renamed from testing/test_needs_auth.py) | 0 | ||||
-rw-r--r-- | etc/testing/test_providers.py (renamed from testing/test_providers.py) | 22 | ||||
-rw-r--r-- | etc/tool/create_provider.py | 114 | ||||
-rw-r--r-- | etc/tool/improve_code.py | 47 | ||||
-rw-r--r-- | etc/tool/provider_init.py (renamed from tool/provider_init.py) | 0 | ||||
-rw-r--r-- | etc/tool/readme_table.py (renamed from tool/readme_table.py) | 0 | ||||
-rw-r--r-- | etc/tool/vercel.py (renamed from tool/vercel.py) | 2 |
13 files changed, 366 insertions, 21 deletions
diff --git a/etc/interference/app.py b/etc/interference/app.py new file mode 100644 index 00000000..5abbcff2 --- /dev/null +++ b/etc/interference/app.py @@ -0,0 +1,163 @@ +import json +import time +import random +import string +import requests + +from typing import Any +from flask import Flask, request +from flask_cors import CORS +from transformers import AutoTokenizer +from g4f import ChatCompletion + +app = Flask(__name__) +CORS(app) + +@app.route('/chat/completions', methods=['POST']) +def chat_completions(): + model = request.get_json().get('model', 'gpt-3.5-turbo') + stream = request.get_json().get('stream', False) + messages = request.get_json().get('messages') + + response = ChatCompletion.create(model = model, + stream = stream, messages = messages) + + completion_id = ''.join(random.choices(string.ascii_letters + string.digits, k=28)) + completion_timestamp = int(time.time()) + + if not stream: + return { + 'id': f'chatcmpl-{completion_id}', + 'object': 'chat.completion', + 'created': completion_timestamp, + 'model': model, + 'choices': [ + { + 'index': 0, + 'message': { + 'role': 'assistant', + 'content': response, + }, + 'finish_reason': 'stop', + } + ], + 'usage': { + 'prompt_tokens': None, + 'completion_tokens': None, + 'total_tokens': None, + }, + } + + def streaming(): + for chunk in response: + completion_data = { + 'id': f'chatcmpl-{completion_id}', + 'object': 'chat.completion.chunk', + 'created': completion_timestamp, + 'model': model, + 'choices': [ + { + 'index': 0, + 'delta': { + 'content': chunk, + }, + 'finish_reason': None, + } + ], + } + + content = json.dumps(completion_data, separators=(',', ':')) + yield f'data: {content}\n\n' + time.sleep(0.1) + + end_completion_data: dict[str, Any] = { + 'id': f'chatcmpl-{completion_id}', + 'object': 'chat.completion.chunk', + 'created': completion_timestamp, + 'model': model, + 'choices': [ + { + 'index': 0, + 'delta': {}, + 'finish_reason': 'stop', + } + ], + } + content = json.dumps(end_completion_data, separators=(',', ':')) + yield f'data: {content}\n\n' + + return app.response_class(streaming(), mimetype='text/event-stream') + + +# Get the embedding from huggingface +def get_embedding(input_text, token): + huggingface_token = token + embedding_model = 'sentence-transformers/all-mpnet-base-v2' + max_token_length = 500 + + # Load the tokenizer for the 'all-mpnet-base-v2' model + tokenizer = AutoTokenizer.from_pretrained(embedding_model) + # Tokenize the text and split the tokens into chunks of 500 tokens each + tokens = tokenizer.tokenize(input_text) + token_chunks = [tokens[i:i + max_token_length] + for i in range(0, len(tokens), max_token_length)] + + # Initialize an empty list + embeddings = [] + + # Create embeddings for each chunk + for chunk in token_chunks: + # Convert the chunk tokens back to text + chunk_text = tokenizer.convert_tokens_to_string(chunk) + + # Use the Hugging Face API to get embeddings for the chunk + api_url = f'https://api-inference.huggingface.co/pipeline/feature-extraction/{embedding_model}' + headers = {'Authorization': f'Bearer {huggingface_token}'} + chunk_text = chunk_text.replace('\n', ' ') + + # Make a POST request to get the chunk's embedding + response = requests.post(api_url, headers=headers, json={ + 'inputs': chunk_text, 'options': {'wait_for_model': True}}) + + # Parse the response and extract the embedding + chunk_embedding = response.json() + # Append the embedding to the list + embeddings.append(chunk_embedding) + + # averaging all the embeddings + # this isn't very effective + # someone a better idea? + num_embeddings = len(embeddings) + average_embedding = [sum(x) / num_embeddings for x in zip(*embeddings)] + embedding = average_embedding + return embedding + + +@app.route('/embeddings', methods=['POST']) +def embeddings(): + input_text_list = request.get_json().get('input') + input_text = ' '.join(map(str, input_text_list)) + token = request.headers.get('Authorization').replace('Bearer ', '') + embedding = get_embedding(input_text, token) + + return { + 'data': [ + { + 'embedding': embedding, + 'index': 0, + 'object': 'embedding' + } + ], + 'model': 'text-embedding-ada-002', + 'object': 'list', + 'usage': { + 'prompt_tokens': None, + 'total_tokens': None + } + } + +def main(): + app.run(host='0.0.0.0', port=1337, debug=True) + +if __name__ == '__main__': + main()
\ No newline at end of file diff --git a/interference/requirements.txt b/etc/interference/requirements.txt index eaa3265b..eaa3265b 100644 --- a/interference/requirements.txt +++ b/etc/interference/requirements.txt diff --git a/testing/log_time.py b/etc/testing/log_time.py index 376ab86d..376ab86d 100644 --- a/testing/log_time.py +++ b/etc/testing/log_time.py diff --git a/etc/testing/test_async.py b/etc/testing/test_async.py new file mode 100644 index 00000000..2c15f6b0 --- /dev/null +++ b/etc/testing/test_async.py @@ -0,0 +1,31 @@ +import sys +from pathlib import Path +import asyncio + +sys.path.append(str(Path(__file__).parent.parent)) +sys.path.append(str(Path(__file__).parent.parent.parent)) + +import g4f +from testing.test_providers import get_providers +from testing.log_time import log_time_async + +async def create_async(provider): + try: + response = await log_time_async( + provider.create_async, + model=g4f.models.default.name, + messages=[{"role": "user", "content": "Hello, are you GPT 3.5?"}] + ) + print(f"{provider.__name__}:", response) + except Exception as e: + print(f"{provider.__name__}: {e.__class__.__name__}: {e}") + +async def run_async(): + responses: list = [ + create_async(provider) + for provider in get_providers() + if provider.working + ] + await asyncio.gather(*responses) + +print("Total:", asyncio.run(log_time_async(run_async)))
\ No newline at end of file diff --git a/testing/test_chat_completion.py b/etc/testing/test_chat_completion.py index 7600e46b..ee523b86 100644 --- a/testing/test_chat_completion.py +++ b/etc/testing/test_chat_completion.py @@ -1,14 +1,14 @@ import sys from pathlib import Path -sys.path.append(str(Path(__file__).parent.parent)) +sys.path.append(str(Path(__file__).parent.parent.parent)) import g4f, asyncio print("create:", end=" ", flush=True) for response in g4f.ChatCompletion.create( - model=g4f.models.gpt_4_32k_0613, - provider=g4f.Provider.Aivvm, + model=g4f.models.default, + provider=g4f.Provider.GptForLove, messages=[{"role": "user", "content": "send a bunch of emojis. i want to test something"}], temperature=0.0, stream=True @@ -19,7 +19,7 @@ print() async def run_async(): response = await g4f.ChatCompletion.create_async( model=g4f.models.gpt_35_turbo_16k_0613, - provider=g4f.Provider.Aivvm, + provider=g4f.Provider.GptGod, messages=[{"role": "user", "content": "hello!"}], ) print("create_async:", response) diff --git a/testing/test_interference.py b/etc/testing/test_interference.py index d8e85a6c..d8e85a6c 100644 --- a/testing/test_interference.py +++ b/etc/testing/test_interference.py diff --git a/testing/test_needs_auth.py b/etc/testing/test_needs_auth.py index 26630e23..26630e23 100644 --- a/testing/test_needs_auth.py +++ b/etc/testing/test_needs_auth.py diff --git a/testing/test_providers.py b/etc/testing/test_providers.py index cd82fe7c..ec0e0271 100644 --- a/testing/test_providers.py +++ b/etc/testing/test_providers.py @@ -33,21 +33,10 @@ def main(): def get_providers() -> list[type[BaseProvider]]: - provider_names = dir(Provider) - ignore_names = [ - "annotations", - "base_provider", - "retry_provider", - "BaseProvider", - "AsyncProvider", - "AsyncGeneratorProvider", - "RetryProvider", - ] - return [ - getattr(Provider, provider_name) - for provider_name in provider_names - if not provider_name.startswith("__") and provider_name not in ignore_names - ] + providers = dir(Provider) + providers = [getattr(Provider, provider) for provider in providers if provider != "RetryProvider"] + providers = [provider for provider in providers if isinstance(provider, type)] + return [provider for provider in providers if issubclass(provider, BaseProvider)] def create_response(_provider: type[BaseProvider]) -> str: @@ -73,4 +62,5 @@ def test(_provider: type[BaseProvider]) -> bool: if __name__ == "__main__": - main()
\ No newline at end of file + main() +
\ No newline at end of file diff --git a/etc/tool/create_provider.py b/etc/tool/create_provider.py new file mode 100644 index 00000000..4e3d7b02 --- /dev/null +++ b/etc/tool/create_provider.py @@ -0,0 +1,114 @@ + +import sys, re +from pathlib import Path +from os import path + +sys.path.append(str(Path(__file__).parent.parent.parent)) + +import g4f + +def read_code(text): + match = re.search(r"```(python|py|)\n(?P<code>[\S\s]+?)\n```", text) + if match: + return match.group("code") + +def read_result(result): + lines = [] + for line in result.split("\n"): + if (line.startswith("```")): + break + if (line): + lines.append(line) + explanation = "\n".join(lines) if lines else "" + return explanation, read_code(result) + +def input_command(): + print("Enter/Paste the cURL command. Ctrl-D or Ctrl-Z ( windows ) to save it.") + contents = [] + while True: + try: + line = input() + except: + break + contents.append(line) + return "\n".join(contents) + +name = input("Name: ") +provider_path = f"g4f/Provider/{name}.py" + +example = """ +from __future__ import annotations + +from aiohttp import ClientSession + +from ..typing import AsyncGenerator +from .base_provider import AsyncGeneratorProvider +from .helper import format_prompt + + +class ChatgptDuo(AsyncGeneratorProvider): + url = "https://chat-gpt.com" + supports_gpt_35_turbo = True + working = True + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: list[dict[str, str]], + **kwargs + ) -> AsyncGenerator: + headers = { + "authority": "chat-gpt.com", + "accept": "application/json", + "origin": cls.url, + "referer": f"{cls.url}/chat", + } + async with ClientSession(headers=headers) as session: + prompt = format_prompt(messages), + data = { + "prompt": prompt, + "purpose": "ask", + } + async with session.post(cls.url + "/api/chat", json=data) as response: + response.raise_for_status() + async for stream in response.content: + if stream: + yield stream.decode() +""" + +if not path.isfile(provider_path): + command = input_command() + + prompt = f""" +Create a provider from a cURL command. The command is: +```bash +{command} +``` +A example for a provider: +```py +{example} +``` +The name for the provider class: +{name} +Replace "hello" with `format_prompt(messages)`. +And replace "gpt-3.5-turbo" with `model`. +""" + + print("Create code...") + response = g4f.ChatCompletion.create( + model=g4f.models.gpt_35_long, + messages=[{"role": "user", "content": prompt}], + auth=True, + timeout=120, + ) + print(response) + explanation, code = read_result(response) + if code: + with open(provider_path, "w") as file: + file.write(code) + with open(f"g4f/Provider/__init__.py", "a") as file: + file.write(f"\nfrom .{name} import {name}") +else: + with open(provider_path, "r") as file: + code = file.read() diff --git a/etc/tool/improve_code.py b/etc/tool/improve_code.py new file mode 100644 index 00000000..9a940b51 --- /dev/null +++ b/etc/tool/improve_code.py @@ -0,0 +1,47 @@ + +import sys, re +from pathlib import Path +from os import path + +sys.path.append(str(Path(__file__).parent.parent.parent)) + +import g4f + +def read_code(text): + match = re.search(r"```(python|py|)\n(?P<code>[\S\s]+?)\n```", text) + if match: + return match.group("code") + +path = input("Path: ") + +with open(path, "r") as file: + code = file.read() + +prompt = f""" +Improve the code in this file: +```py +{code} +``` +Don't remove anything. +Add typehints if possible. +Don't add any typehints to kwargs. +Don't remove license comments. +""" + +print("Create code...") +response = [] +for chunk in g4f.ChatCompletion.create( + model=g4f.models.gpt_35_long, + messages=[{"role": "user", "content": prompt}], + timeout=300, + stream=True +): + response.append(chunk) + print(chunk, end="", flush=True) +print() +response = "".join(response) + +code = read_code(response) +if code: + with open(path, "w") as file: + file.write(code)
\ No newline at end of file diff --git a/tool/provider_init.py b/etc/tool/provider_init.py index 22f21d4d..22f21d4d 100644 --- a/tool/provider_init.py +++ b/etc/tool/provider_init.py diff --git a/tool/readme_table.py b/etc/tool/readme_table.py index b5b64cb1..b5b64cb1 100644 --- a/tool/readme_table.py +++ b/etc/tool/readme_table.py diff --git a/tool/vercel.py b/etc/tool/vercel.py index 7b87e298..75df6c70 100644 --- a/tool/vercel.py +++ b/etc/tool/vercel.py @@ -100,4 +100,4 @@ def main(): if __name__ == "__main__": - main() + main()
\ No newline at end of file |