AmigoChat.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. from __future__ import annotations
  2. import json
  3. import uuid
  4. from ..typing import AsyncResult, Messages
  5. from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
  6. from ..image import ImageResponse
  7. from ..requests import StreamSession, raise_for_status
  8. from ..errors import ResponseStatusError
  9. MODELS = {
  10. 'chat': {
  11. 'gpt-4o-2024-11-20': {'persona_id': "gpt"},
  12. 'gpt-4o': {'persona_id': "summarizer"},
  13. 'gpt-4o-mini': {'persona_id': "amigo"},
  14. 'o1-preview-': {'persona_id': "openai-o-one"}, # Amigo, your balance is not enough to make the request, wait until 12 UTC or upgrade your plan
  15. 'o1-preview-2024-09-12-': {'persona_id': "orion"}, # Amigo, your balance is not enough to make the request, wait until 12 UTC or upgrade your plan
  16. 'o1-mini-': {'persona_id': "openai-o-one-mini"}, # Amigo, your balance is not enough to make the request, wait until 12 UTC or upgrade your plan
  17. 'meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo': {'persona_id': "llama-three-point-one"},
  18. 'meta-llama/Llama-3.2-90B-Vision-Instruct-Turbo': {'persona_id': "llama-3-2"},
  19. 'codellama/CodeLlama-34b-Instruct-hf': {'persona_id': "codellama-CodeLlama-34b-Instruct-hf"},
  20. 'gemini-1.5-pro': {'persona_id': "gemini-1-5-pro"}, # Amigo, your balance is not enough to make the request, wait until 12 UTC or upgrade your plan
  21. 'gemini-1.5-flash': {'persona_id': "gemini-1.5-flash"},
  22. 'claude-3-5-sonnet-20240620': {'persona_id': "claude"},
  23. 'claude-3-5-sonnet-20241022': {'persona_id': "clude-claude-3-5-sonnet-20241022"},
  24. 'claude-3-5-haiku-latest': {'persona_id': "3-5-haiku"},
  25. 'Qwen/Qwen2.5-72B-Instruct-Turbo': {'persona_id': "qwen-2-5"},
  26. 'google/gemma-2b-it': {'persona_id': "google-gemma-2b-it"},
  27. 'google/gemma-7b': {'persona_id': "google-gemma-7b"}, # Error handling AIML chat completion stream
  28. 'Gryphe/MythoMax-L2-13b': {'persona_id': "Gryphe-MythoMax-L2-13b"},
  29. 'mistralai/Mistral-7B-Instruct-v0.3': {'persona_id': "mistralai-Mistral-7B-Instruct-v0.1"},
  30. 'mistralai/mistral-tiny': {'persona_id': "mistralai-mistral-tiny"},
  31. 'mistralai/mistral-nemo': {'persona_id': "mistralai-mistral-nemo"},
  32. 'deepseek-ai/deepseek-llm-67b-chat': {'persona_id': "deepseek-ai-deepseek-llm-67b-chat"},
  33. 'databricks/dbrx-instruct': {'persona_id': "databricks-dbrx-instruct"},
  34. 'NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO': {'persona_id': "NousResearch-Nous-Hermes-2-Mixtral-8x7B-DPO"},
  35. 'x-ai/grok-beta': {'persona_id': "x-ai-grok-beta"},
  36. 'anthracite-org/magnum-v4-72b': {'persona_id': "anthracite-org-magnum-v4-72b"},
  37. 'cohere/command-r-plus': {'persona_id': "cohere-command-r-plus"},
  38. 'ai21/jamba-1-5-mini': {'persona_id': "ai21-jamba-1-5-mini"},
  39. 'zero-one-ai/Yi-34B': {'persona_id': "zero-one-ai-Yi-34B"} # Error handling AIML chat completion stream
  40. },
  41. 'image': {
  42. 'flux-pro/v1.1': {'persona_id': "flux-1-1-pro"}, # Amigo, your balance is not enough to make the request, wait until 12 UTC or upgrade your plan
  43. 'flux-realism': {'persona_id': "flux-realism"},
  44. 'flux-pro': {'persona_id': "flux-pro"}, # Amigo, your balance is not enough to make the request, wait until 12 UTC or upgrade your plan
  45. 'flux-pro/v1.1-ultra': {'persona_id': "flux-pro-v1.1-ultra"}, # Amigo, your balance is not enough to make the request, wait until 12 UTC or upgrade your plan
  46. 'flux-pro/v1.1-ultra-raw': {'persona_id': "flux-pro-v1.1-ultra-raw"}, # Amigo, your balance is not enough to make the request, wait until 12 UTC or upgrade your plan
  47. 'flux/dev': {'persona_id': "flux-dev"},
  48. 'dall-e-3': {'persona_id': "dalle-three"},
  49. 'recraft-v3': {'persona_id': "recraft"}
  50. }
  51. }
  52. class AmigoChat(AsyncGeneratorProvider, ProviderModelMixin):
  53. url = "https://amigochat.io/chat/"
  54. chat_api_endpoint = "https://api.amigochat.io/v1/chat/completions"
  55. image_api_endpoint = "https://api.amigochat.io/v1/images/generations"
  56. working = True
  57. supports_stream = True
  58. supports_system_message = True
  59. supports_message_history = True
  60. default_model = 'gpt-4o-mini'
  61. chat_models = list(MODELS['chat'].keys())
  62. image_models = list(MODELS['image'].keys())
  63. models = chat_models + image_models
  64. model_aliases = {
  65. ### chat ###
  66. "gpt-4o": "gpt-4o-2024-11-20",
  67. "gpt-4o-mini": "gpt-4o-mini",
  68. "llama-3.1-405b": "meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo",
  69. "llama-3.2-90b": "meta-llama/Llama-3.2-90B-Vision-Instruct-Turbo",
  70. "codellama-34b": "codellama/CodeLlama-34b-Instruct-hf",
  71. "gemini-flash": "gemini-1.5-flash",
  72. "claude-3.5-sonnet": "claude-3-5-sonnet-20240620",
  73. "claude-3.5-sonnet": "claude-3-5-sonnet-20241022",
  74. "claude-3.5-haiku": "claude-3-5-haiku-latest",
  75. "qwen-2.5-72b": "Qwen/Qwen2.5-72B-Instruct-Turbo",
  76. "gemma-2b": "google/gemma-2b-it",
  77. "mythomax-13b": "Gryphe/MythoMax-L2-13b",
  78. "mixtral-7b": "mistralai/Mistral-7B-Instruct-v0.3",
  79. "mistral-nemo": "mistralai/mistral-nemo",
  80. "deepseek-chat": "deepseek-ai/deepseek-llm-67b-chat",
  81. "dbrx-instruct": "databricks/dbrx-instruct",
  82. "mixtral-8x7b-dpo": "NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO",
  83. "grok-beta": "x-ai/grok-beta",
  84. "magnum-72b": "anthracite-org/magnum-v4-72b",
  85. "command-r-plus": "cohere/command-r-plus",
  86. "jamba-mini": "ai21/jamba-1-5-mini",
  87. ### image ###
  88. "flux-dev": "flux/dev",
  89. }
  90. @classmethod
  91. def get_personaId(cls, model: str) -> str:
  92. if model in cls.chat_models:
  93. return MODELS['chat'][model]['persona_id']
  94. elif model in cls.image_models:
  95. return MODELS['image'][model]['persona_id']
  96. else:
  97. raise ValueError(f"Unknown model: {model}")
  98. @staticmethod
  99. def generate_chat_id() -> str:
  100. """Generate a chat ID in format: 8-4-4-4-12 hexadecimal digits"""
  101. return str(uuid.uuid4())
  102. @classmethod
  103. async def create_async_generator(
  104. cls,
  105. model: str,
  106. messages: Messages,
  107. proxy: str = None,
  108. stream: bool = False,
  109. timeout: int = 300,
  110. frequency_penalty: float = 0,
  111. max_tokens: int = 4000,
  112. presence_penalty: float = 0,
  113. temperature: float = 0.5,
  114. top_p: float = 0.95,
  115. **kwargs
  116. ) -> AsyncResult:
  117. model = cls.get_model(model)
  118. device_uuid = str(uuid.uuid4())
  119. max_retries = 3
  120. retry_count = 0
  121. while retry_count < max_retries:
  122. try:
  123. headers = {
  124. "accept": "*/*",
  125. "accept-language": "en-US,en;q=0.9",
  126. "authorization": "Bearer",
  127. "cache-control": "no-cache",
  128. "content-type": "application/json",
  129. "origin": cls.url,
  130. "pragma": "no-cache",
  131. "priority": "u=1, i",
  132. "referer": f"{cls.url}/",
  133. "sec-ch-ua": '"Chromium";v="129", "Not=A?Brand";v="8"',
  134. "sec-ch-ua-mobile": "?0",
  135. "sec-ch-ua-platform": '"Linux"',
  136. "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
  137. "x-device-language": "en-US",
  138. "x-device-platform": "web",
  139. "x-device-uuid": device_uuid,
  140. "x-device-version": "1.0.45"
  141. }
  142. async with StreamSession(headers=headers, proxy=proxy) as session:
  143. if model not in cls.image_models:
  144. data = {
  145. "chatId": cls.generate_chat_id(),
  146. "frequency_penalty": frequency_penalty,
  147. "max_tokens": max_tokens,
  148. "messages": messages,
  149. "model": model,
  150. "personaId": cls.get_personaId(model),
  151. "presence_penalty": presence_penalty,
  152. "stream": stream,
  153. "temperature": temperature,
  154. "top_p": top_p
  155. }
  156. async with session.post(cls.chat_api_endpoint, json=data, timeout=timeout) as response:
  157. await raise_for_status(response)
  158. async for line in response.iter_lines():
  159. line = line.decode('utf-8').strip()
  160. if line.startswith('data: '):
  161. if line == 'data: [DONE]':
  162. break
  163. try:
  164. chunk = json.loads(line[6:]) # Remove 'data: ' prefix
  165. if 'choices' in chunk and len(chunk['choices']) > 0:
  166. choice = chunk['choices'][0]
  167. if 'delta' in choice:
  168. content = choice['delta'].get('content')
  169. elif 'text' in choice:
  170. content = choice['text']
  171. else:
  172. content = None
  173. if content:
  174. yield content
  175. except json.JSONDecodeError:
  176. pass
  177. else:
  178. # Image generation
  179. prompt = messages[-1]['content']
  180. data = {
  181. "prompt": prompt,
  182. "model": model,
  183. "personaId": cls.get_personaId(model)
  184. }
  185. async with session.post(cls.image_api_endpoint, json=data) as response:
  186. await raise_for_status(response)
  187. response_data = await response.json()
  188. if "data" in response_data:
  189. image_urls = []
  190. for item in response_data["data"]:
  191. if "url" in item:
  192. image_url = item["url"]
  193. image_urls.append(image_url)
  194. if image_urls:
  195. yield ImageResponse(image_urls, prompt)
  196. else:
  197. yield None
  198. break
  199. except (ResponseStatusError, Exception) as e:
  200. retry_count += 1
  201. if retry_count >= max_retries:
  202. raise e
  203. device_uuid = str(uuid.uuid4())