AItianhuSpace.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. from __future__ import annotations
  2. import time
  3. import random
  4. from ..typing import CreateResult, Messages
  5. from .base_provider import AbstractProvider
  6. from .helper import format_prompt, get_random_string
  7. from ..webdriver import WebDriver, WebDriverSession
  8. from .. import debug
  9. class AItianhuSpace(AbstractProvider):
  10. url = "https://chat3.aiyunos.top/"
  11. working = True
  12. supports_stream = True
  13. supports_gpt_35_turbo = True
  14. _domains = ["aitianhu.com", "aitianhu1.top"]
  15. @classmethod
  16. def create_completion(
  17. cls,
  18. model: str,
  19. messages: Messages,
  20. stream: bool,
  21. domain: str = None,
  22. proxy: str = None,
  23. timeout: int = 120,
  24. webdriver: WebDriver = None,
  25. headless: bool = True,
  26. **kwargs
  27. ) -> CreateResult:
  28. if not model:
  29. model = "gpt-3.5-turbo"
  30. if not domain:
  31. rand = get_random_string(6)
  32. domain = random.choice(cls._domains)
  33. domain = f"{rand}.{domain}"
  34. if debug.logging:
  35. print(f"AItianhuSpace | using domain: {domain}")
  36. url = f"https://{domain}"
  37. prompt = format_prompt(messages)
  38. with WebDriverSession(webdriver, "", headless=headless, proxy=proxy) as driver:
  39. from selenium.webdriver.common.by import By
  40. from selenium.webdriver.support.ui import WebDriverWait
  41. from selenium.webdriver.support import expected_conditions as EC
  42. wait = WebDriverWait(driver, timeout)
  43. # Bypass devtools detection
  44. driver.get("https://blank.page/")
  45. wait.until(EC.visibility_of_element_located((By.ID, "sheet")))
  46. driver.execute_script(f"""
  47. document.getElementById('sheet').addEventListener('click', () => {{
  48. window.open('{url}', '_blank');
  49. }});
  50. """)
  51. driver.find_element(By.ID, "sheet").click()
  52. time.sleep(10)
  53. original_window = driver.current_window_handle
  54. for window_handle in driver.window_handles:
  55. if window_handle != original_window:
  56. driver.close()
  57. driver.switch_to.window(window_handle)
  58. break
  59. # Wait for page load
  60. wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "textarea.n-input__textarea-el")))
  61. # Register hook in XMLHttpRequest
  62. script = """
  63. const _http_request_open = XMLHttpRequest.prototype.open;
  64. window._last_message = window._message = "";
  65. window._loadend = false;
  66. XMLHttpRequest.prototype.open = function(method, url) {
  67. if (url == "/api/chat-process") {
  68. this.addEventListener("progress", (event) => {
  69. const lines = this.responseText.split("\\n");
  70. try {
  71. window._message = JSON.parse(lines[lines.length-1])["text"];
  72. } catch(e) { }
  73. });
  74. this.addEventListener("loadend", (event) => {
  75. window._loadend = true;
  76. });
  77. }
  78. return _http_request_open.call(this, method, url);
  79. }
  80. """
  81. driver.execute_script(script)
  82. # Submit prompt
  83. driver.find_element(By.CSS_SELECTOR, "textarea.n-input__textarea-el").send_keys(prompt)
  84. driver.find_element(By.CSS_SELECTOR, "button.n-button.n-button--primary-type.n-button--medium-type").click()
  85. # Read response
  86. while True:
  87. chunk = driver.execute_script("""
  88. if (window._message && window._message != window._last_message) {
  89. try {
  90. return window._message.substring(window._last_message.length);
  91. } finally {
  92. window._last_message = window._message;
  93. }
  94. }
  95. if (window._loadend) {
  96. return null;
  97. }
  98. return "";
  99. """)
  100. if chunk:
  101. yield chunk
  102. elif chunk != "":
  103. break
  104. else:
  105. time.sleep(0.1)