summaryrefslogblamecommitdiffstats
path: root/g4f/Provider/Airforce.py
blob: e2b4be212fd21f0009c3e4037989ba82ba80e3bd (plain) (tree)
1
2
3
4
5
6
7
8
9
10
                                  
             
           
                                 

                                                                     
                                 


                                                                                


                                                           
                                                        
                                                               
                  


                                      




                                   
    
                   








































































































































































                                                                                            







                       
                  
                   
                   



                     
                      

                     












                                                          

                                                

                                              
                                               
                                             
                                          


                                                 




                                                               




                                                       



                                           

                                             
                                           

                
                                  







                                           
                                            


                                                             
                                         

                   
                                               
        

                                                   
        

                                             


                








                                                                  




                                     


                             


                                    



















                                                                                        


                                                
                                        

                                                  

         

                                            
 




                                                              
                               


                                 
             


                                                                                                        
 











                                                                                                                 

                













                                                      
         
 














                                                                                                   
                                               








                                                                                                 
                         










                                                                               
from __future__ import annotations
import random
import json
from aiohttp import ClientSession
from ..typing import AsyncResult, Messages
from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
from ..image import ImageResponse

def split_long_message(message: str, max_length: int = 4000) -> list[str]:
    return [message[i:i+max_length] for i in range(0, len(message), max_length)]

class Airforce(AsyncGeneratorProvider, ProviderModelMixin):
    url = "https://api.airforce"
    image_api_endpoint = "https://api.airforce/imagine2"
    text_api_endpoint = "https://api.airforce/chat/completions"
    working = True
    
    default_model = 'llama-3-70b-chat'
    
    supports_gpt_35_turbo = True
    supports_gpt_4 = True
    supports_stream = True
    supports_system_message = True
    supports_message_history = True
    
    text_models = [
        # anthorpic
        'claude-3-haiku-20240307', 
        'claude-3-sonnet-20240229', 
        'claude-3-5-sonnet-20240620', 
        'claude-3-opus-20240229', 
        
        # openai
        'chatgpt-4o-latest', 
        'gpt-4', 
        #'gpt-4-0613', 
        'gpt-4-turbo', 
        'gpt-4o-mini-2024-07-18', 
        'gpt-4o-mini', 
        'gpt-3.5-turbo', 
        'gpt-3.5-turbo-0125', 
        'gpt-3.5-turbo-1106', 
        #'gpt-3.5-turbo-16k', # No response from the API.
        #'gpt-3.5-turbo-0613', # No response from the API.
        #'gpt-3.5-turbo-16k-0613', # No response from the API.
        'gpt-4o', 
        #'o1-mini', # No response from the API.
        
        # meta-llama
        'llama-3-70b-chat', 
        'llama-3-70b-chat-turbo', 
        'llama-3-8b-chat', 
        'llama-3-8b-chat-turbo', 
        'llama-3-70b-chat-lite', 
        'llama-3-8b-chat-lite', 
        #'llama-2-70b-chat', # Failed to load response after multiple retries.
        'llama-2-13b-chat', 
        #'llama-2-7b-chat', # Failed to load response after multiple retries.
        'llama-3.1-405b-turbo', 
        'llama-3.1-70b-turbo', 
        'llama-3.1-8b-turbo', 
        'LlamaGuard-2-8b', 
        'Llama-Guard-7b', 
        'Llama-3.2-90B-Vision-Instruct-Turbo',
        
        # codellama
        #'CodeLlama-7b-Python-hf', # Failed to load response after multiple retries.
        #'CodeLlama-7b-Python', 
        #'CodeLlama-13b-Python-hf', # Failed to load response after multiple retries.
        #'CodeLlama-34b-Python-hf', # Failed to load response after multiple retries.
        #'CodeLlama-70b-Python-hf', # Failed to load response after multiple retries.
        
        # 01-ai
        #'Yi-34B-Chat', # Failed to load response after multiple retries.
        #'Yi-34B', # Failed to load response after multiple retries.
        #'Yi-6B', # Failed to load response after multiple retries.
        
        # mistral-ai
        #'Mixtral-8x7B-v0.1', 
        #'Mixtral-8x22B', # Failed to load response after multiple retries.
        'Mixtral-8x7B-Instruct-v0.1', 
        'Mixtral-8x22B-Instruct-v0.1', 
        'Mistral-7B-Instruct-v0.1', 
        'Mistral-7B-Instruct-v0.2', 
        'Mistral-7B-Instruct-v0.3', 
        
        # openchat
        #'openchat-3.5', # Failed to load response after multiple retries.
        
        # wizardlm
        #'WizardLM-13B-V1.2', # Failed to load response after multiple retries.
        #'WizardCoder-Python-34B-V1.0', # Failed to load response after multiple retries.
        
        # qwen
        #'Qwen1.5-0.5B-Chat', # Failed to load response after multiple retries.
        #'Qwen1.5-1.8B-Chat', # Failed to load response after multiple retries.
        #'Qwen1.5-4B-Chat', # Failed to load response after multiple retries.
        'Qwen1.5-7B-Chat', 
        'Qwen1.5-14B-Chat', 
        'Qwen1.5-72B-Chat', 
        'Qwen1.5-110B-Chat', 
        'Qwen2-72B-Instruct', 
        
        # google
        'gemma-2b-it', 
        #'gemma-7b-it', # Failed to load response after multiple retries.
        #'gemma-2b', # Failed to load response after multiple retries.
        #'gemma-7b', # Failed to load response after multiple retries.
        'gemma-2-9b-it', # fix bug
        'gemma-2-27b-it', 
        
        # gemini
        'gemini-1.5-flash', 
        'gemini-1.5-pro', 
        
        # databricks
        'dbrx-instruct', 
        
        # lmsys
        #'vicuna-7b-v1.5', # Failed to load response after multiple retries.
        #'vicuna-13b-v1.5', # Failed to load response after multiple retries.
        
        # cognitivecomputations
        #'dolphin-2.5-mixtral-8x7b', # Failed to load response after multiple retries.
        
        # deepseek-ai
        #'deepseek-coder-33b-instruct', # No response from the API.
        #'deepseek-coder-67b-instruct', # Failed to load response after multiple retries.
        'deepseek-llm-67b-chat', 
        
        # NousResearch
        #'Nous-Capybara-7B-V1p9', # Failed to load response after multiple retries.
        'Nous-Hermes-2-Mixtral-8x7B-DPO', 
        #'Nous-Hermes-2-Mixtral-8x7B-SFT', # Failed to load response after multiple retries.
        #'Nous-Hermes-llama-2-7b', # Failed to load response after multiple retries.
        #'Nous-Hermes-Llama2-13b', # Failed to load response after multiple retries.
        'Nous-Hermes-2-Yi-34B', 
        
        # Open-Orca
        #'Mistral-7B-OpenOrca', # Failed to load response after multiple retries.
        
        # togethercomputer
        #'alpaca-7b', # Failed to load response after multiple retries.
        
        # teknium
        #'OpenHermes-2-Mistral-7B', # Failed to load response after multiple retries.
        #'OpenHermes-2.5-Mistral-7B', # Failed to load response after multiple retries.
        
        # microsoft
        'WizardLM-2-8x22B', 
        
        # Nexusflow
        #'NexusRaven-V2-13B', # Failed to load response after multiple retries.
        
        # Phind
        #'Phind-CodeLlama-34B-v2', # Failed to load response after multiple retries.
        
        # Snoflake
        #'snowflake-arctic-instruct', # No response from the API.
        
        # upstage
        'SOLAR-10.7B-Instruct-v1.0', 
        
        # togethercomputer
        #'StripedHyena-Hessian-7B', # Failed to load response after multiple retries.
        #'StripedHyena-Nous-7B', # Failed to load response after multiple retries.
        #'Llama-2-7B-32K-Instruct', # Failed to load response after multiple retries.
        #'CodeLlama-13b-Instruct', # No response from the API.
        #'evo-1-131k-base', # Failed to load response after multiple retries.
        #'OLMo-7B-Instruct', # Failed to load response after multiple retries.
        
        # garage-bAInd
        #'Platypus2-70B-instruct', # Failed to load response after multiple retries.
        
        # snorkelai
        #'Snorkel-Mistral-PairRM-DPO', # Failed to load response after multiple retries.
        
        # Undi95
        #'ReMM-SLERP-L2-13B', # Failed to load response after multiple retries.
        
        # Gryphe
        'MythoMax-L2-13b', 
        
        # Autism
        #'chronos-hermes-13b', # Failed to load response after multiple retries.
        
        # Undi95
        #'Toppy-M-7B', # Failed to load response after multiple retries.
        
        # iFlytek
        #'sparkdesk', # Failed to load response after multiple retries.
        
        # pawan
        'cosmosrp', 
        
    ]
    image_models = [
        'flux',
        'flux-realism',
        'flux-anime',
        'flux-3d',
        'flux-disney',
        'flux-pixel',
        'flux-4o',
        'any-dark',
        'dall-e-3',
    ]
    
    models = [
        *text_models,
        *image_models,
    ]
    model_aliases = {
        # anthorpic
        "claude-3-haiku": "claude-3-haiku-20240307",
        "claude-3-sonnet": "claude-3-sonnet-20240229",
        "claude-3-5-sonnet": "claude-3-5-sonnet-20240620",
        "claude-3-opus": "claude-3-opus-20240229",
        
        # openai
        "gpt-4o": "chatgpt-4o-latest",
        "gpt-4o-mini": "gpt-4o-mini-2024-07-18",
        "gpt-3.5-turbo": "gpt-3.5-turbo-0125",
        "gpt-3.5-turbo": "gpt-3.5-turbo-1106",
        
        # meta-llama
        "llama-3-70b": "llama-3-70b-chat",
        "llama-3-70b": "llama-3-70b-chat-turbo",
        "llama-3-8b": "llama-3-8b-chat",
        "llama-3-8b": "llama-3-8b-chat-turbo",
        "llama-3-70b": "llama-3-70b-chat-lite",
        "llama-3-8b": "llama-3-8b-chat-lite",
        "llama-2-13b": "llama-2-13b-chat",
        "llama-3.1-405b": "llama-3.1-405b-turbo",
        "llama-3.1-70b": "llama-3.1-70b-turbo",
        "llama-3.1-8b": "llama-3.1-8b-turbo",
        "llamaguard-2-8b": "LlamaGuard-2-8b",
        "llamaguard-7b": "Llama-Guard-7b",
        "llama-3.2-90b": "Llama-3.2-90B-Vision-Instruct-Turbo",
        
        # mistral-ai
        "mixtral-8x7b": "Mixtral-8x7B-Instruct-v0.1",
        "mixtral-8x22b": "Mixtral-8x22B-Instruct-v0.1",
        "mistral-7b": "Mistral-7B-Instruct-v0.1",
        "mistral-7b": "Mistral-7B-Instruct-v0.2",
        "mistral-7b": "Mistral-7B-Instruct-v0.3",
        
        # qwen
        "qwen-1.5-7b": "Qwen1.5-7B-Chat",
        "qwen-1.5-14b": "Qwen1.5-14B-Chat",
        "qwen-1.5-72b": "Qwen1.5-72B-Chat",
        "qwen-1.5-110b": "Qwen1.5-110B-Chat",
        "qwen-2-72b": "Qwen2-72B-Instruct",
        
        # google
        "gemma-2b": "gemma-2b-it",
        "gemma-2-9b": "gemma-2-9b-it",
        "gemma-2-27b": "gemma-2-27b-it",
        
        # gemini
        "gemini-flash": "gemini-1.5-flash",
        "gemini-pro": "gemini-1.5-pro",
        
        # deepseek-ai
        "deepseek": "deepseek-llm-67b-chat",
        
        # NousResearch
        "mixtral-8x7b-dpo": "Nous-Hermes-2-Mixtral-8x7B-DPO",
        "yi-34b": "Nous-Hermes-2-Yi-34B",
        
        # microsoft
        "wizardlm-2-8x22b": "WizardLM-2-8x22B",
        
        # upstage
        "solar-10.7b": "SOLAR-10.7B-Instruct-v1.0",
        
        # Gryphe
        "mythomax-l2-13b": "MythoMax-L2-13b",
    }

    @classmethod
    def get_model(cls, model: str) -> str:
        if model in cls.models:
            return model
        elif model in cls.model_aliases:
            return cls.model_aliases.get(model, cls.default_model)
        else:
            return cls.default_model

    @classmethod
    async def create_async_generator(
        cls,
        model: str,
        messages: Messages,
        proxy: str = None,
        seed: int = None,
        size: str = "1:1",
        stream: bool = False,
        **kwargs
    ) -> AsyncResult:
        model = cls.get_model(model)

        # If the model is an image model, use the image API
        if model in cls.image_models:
            async for result in cls._generate_image(model, messages, proxy, seed, size):
                yield result
        # If the model is a text model, use the text API
        elif model in cls.text_models:
            async for result in cls._generate_text(model, messages, proxy, stream):
                yield result
    
    @classmethod
    async def _generate_image(
        cls,
        model: str,
        messages: Messages,
        proxy: str = None,
        seed: int = None,
        size: str = "1:1",
        **kwargs
    ) -> AsyncResult:
        headers = {
            "accept": "*/*",
            "accept-language": "en-US,en;q=0.9",
            "cache-control": "no-cache",
            "origin": "https://llmplayground.net",
            "user-agent": "Mozilla/5.0"
        }

        if seed is None:
            seed = random.randint(0, 100000)

        # Assume the first message is the prompt for the image
        prompt = messages[0]['content']

        async with ClientSession(headers=headers) as session:
            params = {
                "model": model,
                "prompt": prompt,
                "size": size,
                "seed": seed
            }
            async with session.get(f"{cls.image_api_endpoint}", params=params, proxy=proxy) as response:
                response.raise_for_status()
                content_type = response.headers.get('Content-Type', '').lower()

                if 'application/json' in content_type:
                    async for chunk in response.content.iter_chunked(1024):
                        if chunk:
                            yield chunk.decode('utf-8')
                elif 'image' in content_type:
                    image_data = b""
                    async for chunk in response.content.iter_chunked(1024):
                        if chunk:
                            image_data += chunk
                    image_url = f"{cls.image_api_endpoint}?model={model}&prompt={prompt}&size={size}&seed={seed}"
                    alt_text = f"Generated image for prompt: {prompt}"
                    yield ImageResponse(images=image_url, alt=alt_text)

    @classmethod
    async def _generate_text(
        cls,
        model: str,
        messages: Messages,
        proxy: str = None,
        stream: bool = False,
        **kwargs
    ) -> AsyncResult:
        headers = {
            "accept": "*/*",
            "accept-language": "en-US,en;q=0.9",
            "authorization": "Bearer missing api key",
            "content-type": "application/json",
            "user-agent": "Mozilla/5.0"
        }

        async with ClientSession(headers=headers) as session:
            formatted_prompt = cls._format_messages(messages)
            prompt_parts = split_long_message(formatted_prompt)
            full_response = ""

            for part in prompt_parts:
                data = {
                    "messages": [{"role": "user", "content": part}],
                    "model": model,
                    "max_tokens": 4096,
                    "temperature": 1,
                    "top_p": 1,
                    "stream": stream
                }
                async with session.post(cls.text_api_endpoint, json=data, proxy=proxy) as response:
                    response.raise_for_status()
                    part_response = ""
                    if stream:
                        async for line in response.content:
                            if line:
                                line = line.decode('utf-8').strip()
                                if line.startswith("data: ") and line != "data: [DONE]":
                                    json_data = json.loads(line[6:])
                                    content = json_data['choices'][0]['delta'].get('content', '')
                                    part_response += content
                    else:
                        json_data = await response.json()
                        content = json_data['choices'][0]['message']['content']
                        part_response = content

                    full_response += part_response
            yield full_response

    @classmethod
    def _format_messages(cls, messages: Messages) -> str:
        """Formats messages for text generation."""
        return " ".join([msg['content'] for msg in messages])