Reka.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. from __future__ import annotations
  2. import os, requests, time, json
  3. from ...typing import CreateResult, Messages, ImageType
  4. from ..base_provider import AbstractProvider
  5. from ...cookies import get_cookies
  6. from ...image import to_bytes
  7. class Reka(AbstractProvider):
  8. domain = "space.reka.ai"
  9. url = f"https://{domain}"
  10. working = True
  11. needs_auth = True
  12. supports_stream = True
  13. default_vision_model = "reka"
  14. cookies = {}
  15. @classmethod
  16. def create_completion(
  17. cls,
  18. model: str,
  19. messages: Messages,
  20. stream: bool,
  21. proxy: str = None,
  22. api_key: str = None,
  23. image: ImageType = None,
  24. **kwargs
  25. ) -> CreateResult:
  26. cls.proxy = proxy
  27. if not api_key:
  28. cls.cookies = get_cookies(cls.domain)
  29. if not cls.cookies:
  30. raise ValueError(f"No cookies found for {cls.domain}")
  31. elif "appSession" not in cls.cookies:
  32. raise ValueError(f"No appSession found in cookies for {cls.domain}, log in or provide bearer_auth")
  33. api_key = cls.get_access_token(cls)
  34. conversation = []
  35. for message in messages:
  36. conversation.append({
  37. "type": "human",
  38. "text": message["content"],
  39. })
  40. if image:
  41. image_url = cls.upload_image(cls, api_key, image)
  42. conversation[-1]["image_url"] = image_url
  43. conversation[-1]["media_type"] = "image"
  44. headers = {
  45. 'accept': '*/*',
  46. 'accept-language': 'en,fr-FR;q=0.9,fr;q=0.8,es-ES;q=0.7,es;q=0.6,en-US;q=0.5,am;q=0.4,de;q=0.3',
  47. 'authorization': f'Bearer {api_key}',
  48. 'cache-control': 'no-cache',
  49. 'content-type': 'application/json',
  50. 'origin': cls.url,
  51. 'pragma': 'no-cache',
  52. 'priority': 'u=1, i',
  53. 'sec-ch-ua': '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"',
  54. 'sec-ch-ua-mobile': '?0',
  55. 'sec-ch-ua-platform': '"macOS"',
  56. 'sec-fetch-dest': 'empty',
  57. 'sec-fetch-mode': 'cors',
  58. 'sec-fetch-site': 'same-origin',
  59. 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
  60. }
  61. json_data = {
  62. 'conversation_history': conversation,
  63. 'stream': True,
  64. 'use_search_engine': False,
  65. 'use_code_interpreter': False,
  66. 'model_name': 'reka-core',
  67. 'random_seed': int(time.time() * 1000),
  68. }
  69. tokens = ''
  70. response = requests.post(f'{cls.url}/api/chat',
  71. cookies=cls.cookies, headers=headers, json=json_data, proxies=cls.proxy, stream=True)
  72. for completion in response.iter_lines():
  73. if b'data' in completion:
  74. token_data = json.loads(completion.decode('utf-8')[5:])['text']
  75. yield (token_data.replace(tokens, ''))
  76. tokens = token_data
  77. def upload_image(cls, access_token, image: ImageType) -> str:
  78. boundary_token = os.urandom(8).hex()
  79. headers = {
  80. 'accept': '*/*',
  81. 'accept-language': 'en,fr-FR;q=0.9,fr;q=0.8,es-ES;q=0.7,es;q=0.6,en-US;q=0.5,am;q=0.4,de;q=0.3',
  82. 'cache-control': 'no-cache',
  83. 'authorization': f'Bearer {access_token}',
  84. 'content-type': f'multipart/form-data; boundary=----WebKitFormBoundary{boundary_token}',
  85. 'origin': cls.url,
  86. 'pragma': 'no-cache',
  87. 'priority': 'u=1, i',
  88. 'referer': f'{cls.url}/chat/hPReZExtDOPvUfF8vCPC',
  89. 'sec-ch-ua': '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"',
  90. 'sec-ch-ua-mobile': '?0',
  91. 'sec-ch-ua-platform': '"macOS"',
  92. 'sec-fetch-dest': 'empty',
  93. 'sec-fetch-mode': 'cors',
  94. 'sec-fetch-site': 'same-origin',
  95. 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
  96. }
  97. image_data = to_bytes(image)
  98. boundary = f'----WebKitFormBoundary{boundary_token}'
  99. data = f'--{boundary}\r\nContent-Disposition: form-data; name="image"; filename="image.png"\r\nContent-Type: image/png\r\n\r\n'
  100. data += image_data.decode('latin-1')
  101. data += f'\r\n--{boundary}--\r\n'
  102. response = requests.post(f'{cls.url}/api/upload-image',
  103. cookies=cls.cookies, headers=headers, proxies=cls.proxy, data=data.encode('latin-1'))
  104. return response.json()['media_url']
  105. def get_access_token(cls):
  106. headers = {
  107. 'accept': '*/*',
  108. 'accept-language': 'en,fr-FR;q=0.9,fr;q=0.8,es-ES;q=0.7,es;q=0.6,en-US;q=0.5,am;q=0.4,de;q=0.3',
  109. 'cache-control': 'no-cache',
  110. 'pragma': 'no-cache',
  111. 'priority': 'u=1, i',
  112. 'referer': f'{cls.url}/chat',
  113. 'sec-ch-ua': '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"',
  114. 'sec-ch-ua-mobile': '?0',
  115. 'sec-ch-ua-platform': '"macOS"',
  116. 'sec-fetch-dest': 'empty',
  117. 'sec-fetch-mode': 'cors',
  118. 'sec-fetch-site': 'same-origin',
  119. 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
  120. }
  121. try:
  122. response = requests.get(f'{cls.url}/bff/auth/access_token',
  123. cookies=cls.cookies, headers=headers, proxies=cls.proxy)
  124. return response.json()['accessToken']
  125. except Exception as e:
  126. raise ValueError(f"Failed to get access token: {e}, refresh your cookies / log in into {cls.domain}")