webscout 7.7__py3-none-any.whl → 7.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of webscout might be problematic. Click here for more details.

Files changed (134) hide show
  1. webscout/AIutel.py +2 -1
  2. webscout/Bard.py +12 -29
  3. webscout/DWEBS.py +477 -461
  4. webscout/Extra/__init__.py +2 -0
  5. webscout/Extra/autocoder/__init__.py +9 -9
  6. webscout/Extra/autocoder/{rawdog.py → autocoder.py} +849 -790
  7. webscout/Extra/autocoder/autocoder_utiles.py +332 -194
  8. webscout/Extra/gguf.py +682 -682
  9. webscout/Extra/tempmail/__init__.py +26 -0
  10. webscout/Extra/tempmail/async_utils.py +141 -0
  11. webscout/Extra/tempmail/base.py +156 -0
  12. webscout/Extra/tempmail/cli.py +187 -0
  13. webscout/Extra/tempmail/mail_tm.py +361 -0
  14. webscout/Extra/tempmail/temp_mail_io.py +292 -0
  15. webscout/Provider/AI21.py +1 -1
  16. webscout/Provider/AISEARCH/DeepFind.py +2 -2
  17. webscout/Provider/AISEARCH/ISou.py +2 -2
  18. webscout/Provider/AISEARCH/felo_search.py +6 -6
  19. webscout/Provider/AISEARCH/genspark_search.py +1 -1
  20. webscout/Provider/Aitopia.py +292 -0
  21. webscout/Provider/AllenAI.py +1 -1
  22. webscout/Provider/Andi.py +3 -3
  23. webscout/Provider/C4ai.py +1 -1
  24. webscout/Provider/ChatGPTES.py +3 -5
  25. webscout/Provider/ChatGPTGratis.py +4 -4
  26. webscout/Provider/Chatify.py +2 -2
  27. webscout/Provider/Cloudflare.py +3 -2
  28. webscout/Provider/DeepSeek.py +2 -2
  29. webscout/Provider/Deepinfra.py +288 -286
  30. webscout/Provider/ElectronHub.py +709 -634
  31. webscout/Provider/ExaChat.py +325 -0
  32. webscout/Provider/Free2GPT.py +2 -2
  33. webscout/Provider/Gemini.py +167 -179
  34. webscout/Provider/GithubChat.py +1 -1
  35. webscout/Provider/Glider.py +4 -4
  36. webscout/Provider/Groq.py +41 -27
  37. webscout/Provider/HF_space/qwen_qwen2.py +1 -1
  38. webscout/Provider/HeckAI.py +1 -1
  39. webscout/Provider/HuggingFaceChat.py +1 -1
  40. webscout/Provider/Hunyuan.py +1 -1
  41. webscout/Provider/Jadve.py +3 -3
  42. webscout/Provider/Koboldai.py +3 -3
  43. webscout/Provider/LambdaChat.py +3 -2
  44. webscout/Provider/Llama.py +3 -5
  45. webscout/Provider/Llama3.py +4 -12
  46. webscout/Provider/Marcus.py +3 -3
  47. webscout/Provider/OLLAMA.py +8 -8
  48. webscout/Provider/Openai.py +7 -3
  49. webscout/Provider/PI.py +1 -1
  50. webscout/Provider/Perplexitylabs.py +1 -1
  51. webscout/Provider/Phind.py +1 -1
  52. webscout/Provider/PizzaGPT.py +1 -1
  53. webscout/Provider/QwenLM.py +4 -7
  54. webscout/Provider/TTI/FreeAIPlayground/async_freeaiplayground.py +3 -1
  55. webscout/Provider/TTI/FreeAIPlayground/sync_freeaiplayground.py +3 -3
  56. webscout/Provider/TTI/ImgSys/__init__.py +23 -0
  57. webscout/Provider/TTI/ImgSys/async_imgsys.py +202 -0
  58. webscout/Provider/TTI/ImgSys/sync_imgsys.py +195 -0
  59. webscout/Provider/TTI/__init__.py +3 -1
  60. webscout/Provider/TTI/artbit/async_artbit.py +1 -1
  61. webscout/Provider/TTI/artbit/sync_artbit.py +1 -1
  62. webscout/Provider/TTI/huggingface/async_huggingface.py +1 -1
  63. webscout/Provider/TTI/huggingface/sync_huggingface.py +1 -1
  64. webscout/Provider/TTI/piclumen/__init__.py +22 -22
  65. webscout/Provider/TTI/piclumen/sync_piclumen.py +232 -232
  66. webscout/Provider/TTI/pixelmuse/__init__.py +4 -0
  67. webscout/Provider/TTI/pixelmuse/async_pixelmuse.py +249 -0
  68. webscout/Provider/TTI/pixelmuse/sync_pixelmuse.py +182 -0
  69. webscout/Provider/TTI/talkai/sync_talkai.py +1 -1
  70. webscout/Provider/TTS/utils.py +1 -1
  71. webscout/Provider/TeachAnything.py +1 -1
  72. webscout/Provider/TextPollinationsAI.py +232 -230
  73. webscout/Provider/TwoAI.py +1 -2
  74. webscout/Provider/Venice.py +4 -2
  75. webscout/Provider/VercelAI.py +234 -0
  76. webscout/Provider/WebSim.py +3 -2
  77. webscout/Provider/WiseCat.py +10 -12
  78. webscout/Provider/Youchat.py +1 -1
  79. webscout/Provider/__init__.py +10 -4
  80. webscout/Provider/ai4chat.py +1 -1
  81. webscout/Provider/aimathgpt.py +2 -6
  82. webscout/Provider/akashgpt.py +1 -1
  83. webscout/Provider/askmyai.py +4 -4
  84. webscout/Provider/{DARKAI.py → asksteve.py} +56 -77
  85. webscout/Provider/bagoodex.py +2 -2
  86. webscout/Provider/cerebras.py +1 -1
  87. webscout/Provider/chatglm.py +4 -4
  88. webscout/Provider/cleeai.py +1 -0
  89. webscout/Provider/copilot.py +21 -9
  90. webscout/Provider/elmo.py +1 -1
  91. webscout/Provider/flowith.py +1 -1
  92. webscout/Provider/freeaichat.py +64 -31
  93. webscout/Provider/gaurish.py +3 -5
  94. webscout/Provider/geminiprorealtime.py +1 -1
  95. webscout/Provider/granite.py +4 -4
  96. webscout/Provider/hermes.py +5 -5
  97. webscout/Provider/julius.py +1 -1
  98. webscout/Provider/koala.py +1 -1
  99. webscout/Provider/lepton.py +1 -1
  100. webscout/Provider/llama3mitril.py +4 -4
  101. webscout/Provider/llamatutor.py +1 -1
  102. webscout/Provider/llmchat.py +3 -3
  103. webscout/Provider/meta.py +1 -1
  104. webscout/Provider/multichat.py +10 -10
  105. webscout/Provider/promptrefine.py +1 -1
  106. webscout/Provider/searchchat.py +293 -0
  107. webscout/Provider/sonus.py +2 -2
  108. webscout/Provider/talkai.py +2 -2
  109. webscout/Provider/turboseek.py +1 -1
  110. webscout/Provider/tutorai.py +1 -1
  111. webscout/Provider/typegpt.py +5 -42
  112. webscout/Provider/uncovr.py +312 -297
  113. webscout/Provider/x0gpt.py +1 -1
  114. webscout/Provider/yep.py +64 -12
  115. webscout/__init__.py +3 -1
  116. webscout/cli.py +59 -98
  117. webscout/conversation.py +350 -17
  118. webscout/litprinter/__init__.py +59 -667
  119. webscout/optimizers.py +419 -419
  120. webscout/tempid.py +11 -11
  121. webscout/update_checker.py +14 -12
  122. webscout/utils.py +2 -2
  123. webscout/version.py +1 -1
  124. webscout/webscout_search.py +146 -87
  125. webscout/webscout_search_async.py +148 -27
  126. {webscout-7.7.dist-info → webscout-7.9.dist-info}/METADATA +92 -66
  127. webscout-7.9.dist-info/RECORD +248 -0
  128. webscout/Provider/EDITEE.py +0 -192
  129. webscout/litprinter/colors.py +0 -54
  130. webscout-7.7.dist-info/RECORD +0 -234
  131. {webscout-7.7.dist-info → webscout-7.9.dist-info}/LICENSE.md +0 -0
  132. {webscout-7.7.dist-info → webscout-7.9.dist-info}/WHEEL +0 -0
  133. {webscout-7.7.dist-info → webscout-7.9.dist-info}/entry_points.txt +0 -0
  134. {webscout-7.7.dist-info → webscout-7.9.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,293 @@
1
+ import requests
2
+ import json
3
+ from datetime import datetime
4
+ from typing import Any, Dict, Optional, Generator, Union
5
+
6
+ from webscout.AIutel import Optimizers
7
+ from webscout.AIutel import Conversation
8
+ from webscout.AIutel import AwesomePrompts
9
+ from webscout.AIbase import Provider
10
+ from webscout import exceptions
11
+ from webscout.litagent import LitAgent
12
+
13
+ class SearchChatAI(Provider):
14
+ """
15
+ A class to interact with the SearchChatAI API.
16
+ """
17
+ AVAILABLE_MODELS = ["gpt-4o-mini-2024-07-18"]
18
+ def __init__(
19
+ self,
20
+ is_conversation: bool = True,
21
+ max_tokens: int = 2049,
22
+ timeout: int = 30,
23
+ intro: str = None,
24
+ filepath: str = None,
25
+ update_file: bool = True,
26
+ proxies: dict = {},
27
+ history_offset: int = 10250,
28
+ act: str = None,
29
+ system_prompt: str = "You are a helpful assistant."
30
+ ):
31
+ """Initializes the SearchChatAI API client."""
32
+ self.url = "https://search-chat.ai/api/chat-test-stop.php"
33
+ self.timeout = timeout
34
+ self.is_conversation = is_conversation
35
+ self.max_tokens_to_sample = max_tokens
36
+ self.last_response = {}
37
+ self.system_prompt = system_prompt
38
+
39
+ # Initialize LitAgent for user agent generation
40
+ self.agent = LitAgent()
41
+ # Use fingerprinting to create a consistent browser identity
42
+ self.fingerprint = self.agent.generate_fingerprint("chrome")
43
+
44
+ # Use the fingerprint for headers
45
+ self.headers = {
46
+ "Accept": self.fingerprint["accept"],
47
+ "Accept-Encoding": "gzip, deflate, br, zstd",
48
+ "Accept-Language": self.fingerprint["accept_language"],
49
+ "Content-Type": "application/json",
50
+ "Origin": "https://search-chat.ai",
51
+ "Referer": "https://search-chat.ai/platform/?v2=2",
52
+ "Sec-Fetch-Dest": "empty",
53
+ "Sec-Fetch-Mode": "cors",
54
+ "Sec-Fetch-Site": "same-origin",
55
+ "Sec-CH-UA": self.fingerprint["sec_ch_ua"] or '"Not)A;Brand";v="99", "Microsoft Edge";v="127", "Chromium";v="127"',
56
+ "Sec-CH-UA-Mobile": "?0",
57
+ "Sec-CH-UA-Platform": f'"{self.fingerprint["platform"]}"',
58
+ "User-Agent": self.fingerprint["user_agent"],
59
+ }
60
+
61
+ self.session = requests.Session()
62
+ self.session.headers.update(self.headers)
63
+ self.session.proxies.update(proxies)
64
+
65
+ self.__available_optimizers = (
66
+ method
67
+ for method in dir(Optimizers)
68
+ if callable(getattr(Optimizers, method)) and not method.startswith("__")
69
+ )
70
+ Conversation.intro = (
71
+ AwesomePrompts().get_act(
72
+ act, raise_not_found=True, default=None, case_insensitive=True
73
+ )
74
+ if act
75
+ else intro or Conversation.intro
76
+ )
77
+
78
+ self.conversation = Conversation(
79
+ is_conversation, self.max_tokens_to_sample, filepath, update_file
80
+ )
81
+ self.conversation.history_offset = history_offset
82
+
83
+ def refresh_identity(self, browser: str = None):
84
+ """
85
+ Refreshes the browser identity fingerprint.
86
+
87
+ Args:
88
+ browser: Specific browser to use for the new fingerprint
89
+ """
90
+ browser = browser or self.fingerprint.get("browser_type", "chrome")
91
+ self.fingerprint = self.agent.generate_fingerprint(browser)
92
+
93
+ # Update headers with new fingerprint
94
+ self.headers.update({
95
+ "Accept": self.fingerprint["accept"],
96
+ "Accept-Language": self.fingerprint["accept_language"],
97
+ "Sec-CH-UA": self.fingerprint["sec_ch_ua"] or self.headers["Sec-CH-UA"],
98
+ "Sec-CH-UA-Platform": f'"{self.fingerprint["platform"]}"',
99
+ "User-Agent": self.fingerprint["user_agent"],
100
+ })
101
+
102
+ # Update session headers
103
+ for header, value in self.headers.items():
104
+ self.session.headers[header] = value
105
+
106
+ return self.fingerprint
107
+
108
+ def ask(
109
+ self,
110
+ prompt: str,
111
+ stream: bool = False,
112
+ raw: bool = False,
113
+ optimizer: str = None,
114
+ conversationally: bool = False,
115
+ ) -> Union[Dict[str, Any], Generator]:
116
+ """
117
+ Send a message to the API and get the response.
118
+
119
+ Args:
120
+ prompt: The message to send
121
+ stream: Whether to stream the response
122
+ raw: Whether to return raw response
123
+ optimizer: The optimizer to use
124
+ conversationally: Whether to use conversation history
125
+
126
+ Returns:
127
+ Either a dictionary with the response or a generator for streaming
128
+ """
129
+ conversation_prompt = self.conversation.gen_complete_prompt(prompt)
130
+ if optimizer:
131
+ if optimizer in self.__available_optimizers:
132
+ conversation_prompt = getattr(Optimizers, optimizer)(
133
+ conversation_prompt if conversationally else prompt
134
+ )
135
+ else:
136
+ raise Exception(f"Optimizer is not one of {self.__available_optimizers}")
137
+
138
+ payload = {
139
+ "messages": [
140
+ {
141
+ "role": "user",
142
+ "content": [
143
+ {
144
+ "type": "text",
145
+ "text": conversation_prompt
146
+ }
147
+ ],
148
+ "timestamp": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%fZ")
149
+ }
150
+ ]
151
+ }
152
+
153
+ def for_stream():
154
+ try:
155
+ with self.session.post(
156
+ self.url,
157
+ json=payload,
158
+ stream=True,
159
+ timeout=self.timeout
160
+ ) as response:
161
+ if response.status_code != 200:
162
+ raise exceptions.FailedToGenerateResponseError(
163
+ f"Request failed with status code {response.status_code}"
164
+ )
165
+
166
+ streaming_text = ""
167
+ for line in response.iter_lines():
168
+ if line:
169
+ line = line.decode('utf-8')
170
+ if line.startswith('data: '):
171
+ data_str = line[6:] # Remove 'data: ' prefix
172
+
173
+ if data_str == '[DONE]':
174
+ break
175
+
176
+ try:
177
+ data = json.loads(data_str)
178
+ if "choices" in data and len(data["choices"]) > 0:
179
+ delta = data["choices"][0].get("delta", {})
180
+ if "content" in delta:
181
+ content = delta["content"]
182
+ streaming_text += content
183
+ resp = dict(text=content)
184
+ yield resp if raw else content
185
+ except json.JSONDecodeError:
186
+ continue
187
+
188
+ self.last_response = {"text": streaming_text}
189
+ self.conversation.update_chat_history(prompt, streaming_text)
190
+
191
+ except requests.RequestException as e:
192
+ raise exceptions.FailedToGenerateResponseError(f"Request failed: {str(e)}")
193
+
194
+ def for_non_stream():
195
+ try:
196
+ response = self.session.post(
197
+ self.url,
198
+ json=payload,
199
+ stream=True, # Keep streaming enabled
200
+ timeout=self.timeout
201
+ )
202
+ if response.status_code != 200:
203
+ raise exceptions.FailedToGenerateResponseError(
204
+ f"Request failed with status code {response.status_code}"
205
+ )
206
+
207
+ full_text = ""
208
+ for line in response.iter_lines():
209
+ if line:
210
+ line = line.decode('utf-8')
211
+ if line.startswith('data: '):
212
+ data_str = line[6:] # Remove 'data: ' prefix
213
+
214
+ if data_str == '[DONE]':
215
+ break
216
+
217
+ try:
218
+ data = json.loads(data_str)
219
+ if "choices" in data and len(data["choices"]) > 0:
220
+ delta = data["choices"][0].get("delta", {})
221
+ if "content" in delta:
222
+ content = delta["content"]
223
+ full_text += content
224
+ except json.JSONDecodeError:
225
+ continue
226
+
227
+ if full_text:
228
+ self.last_response = {"text": full_text}
229
+ self.conversation.update_chat_history(prompt, full_text)
230
+ return {"text": full_text}
231
+ else:
232
+ raise exceptions.FailedToGenerateResponseError("No response content found")
233
+
234
+ except Exception as e:
235
+ raise exceptions.FailedToGenerateResponseError(f"Request failed: {str(e)}")
236
+
237
+ return for_stream() if stream else for_non_stream()
238
+
239
+ def chat(
240
+ self,
241
+ prompt: str,
242
+ stream: bool = False,
243
+ optimizer: str = None,
244
+ conversationally: bool = False,
245
+ ) -> Union[str, Generator[str, None, None]]:
246
+ """
247
+ Chat with the API.
248
+
249
+ Args:
250
+ prompt: The message to send
251
+ stream: Whether to stream the response
252
+ optimizer: The optimizer to use
253
+ conversationally: Whether to use conversation history
254
+
255
+ Returns:
256
+ Either a string response or a generator for streaming
257
+ """
258
+ def for_stream():
259
+ for response in self.ask(prompt, True, optimizer=optimizer, conversationally=conversationally):
260
+ yield self.get_message(response)
261
+
262
+ def for_non_stream():
263
+ return self.get_message(
264
+ self.ask(prompt, False, optimizer=optimizer, conversationally=conversationally)
265
+ )
266
+
267
+ return for_stream() if stream else for_non_stream()
268
+
269
+ def get_message(self, response: dict) -> str:
270
+ """Extract the message from the response."""
271
+ assert isinstance(response, dict), "Response should be of dict data-type only"
272
+ return response["text"]
273
+
274
+ if __name__ == "__main__":
275
+ print("-" * 80)
276
+ print(f"{'Status':<10} {'Response'}")
277
+ print("-" * 80)
278
+
279
+ try:
280
+ test_ai = SearchChatAI(timeout=60)
281
+ response = test_ai.chat("Say 'Hello' in one word")
282
+ response_text = response
283
+
284
+ if response_text and len(response_text.strip()) > 0:
285
+ status = "✓"
286
+ # Truncate response if too long
287
+ display_text = response_text.strip()[:50] + "..." if len(response_text.strip()) > 50 else response_text.strip()
288
+ else:
289
+ status = "✗"
290
+ display_text = "Empty or invalid response"
291
+ print(f"{status:<10} {display_text}")
292
+ except Exception as e:
293
+ print(f"{'✗':<10} {str(e)}")
@@ -6,7 +6,7 @@ from webscout.AIutel import Conversation
6
6
  from webscout.AIutel import AwesomePrompts
7
7
  from webscout.AIbase import Provider
8
8
  from webscout import exceptions
9
-
9
+ from webscout.litagent import LitAgent
10
10
  class SonusAI(Provider):
11
11
  """
12
12
  A class to interact with the Sonus AI chat API.
@@ -43,7 +43,7 @@ class SonusAI(Provider):
43
43
  'Accept-Language': 'en-US,en;q=0.9',
44
44
  'Origin': 'https://chat.sonus.ai',
45
45
  'Referer': 'https://chat.sonus.ai/',
46
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36'
46
+ 'User-Agent': LitAgent().random()
47
47
  }
48
48
 
49
49
  self.session = requests.Session()
@@ -1,7 +1,7 @@
1
1
  import uuid
2
2
  import cloudscraper
3
3
  import json
4
- from typing import Any, Dict, Optional, Generator
4
+ from typing import Union, Any, Dict, Optional, Generator
5
5
 
6
6
  from webscout.AIutel import Optimizers
7
7
  from webscout.AIutel import Conversation
@@ -146,7 +146,7 @@ class Talkai(Provider):
146
146
  stream: bool = False,
147
147
  optimizer: str = None,
148
148
  conversationally: bool = False,
149
- ) -> str | Generator[str, None, None]:
149
+ ) -> Union[str, Generator[str, None, None]]:
150
150
  """Generate response `str`
151
151
  Args:
152
152
  prompt (str): Prompt to be send.
@@ -6,7 +6,7 @@ from webscout.AIutel import Conversation
6
6
  from webscout.AIutel import AwesomePrompts, sanitize_stream
7
7
  from webscout.AIbase import Provider, AsyncProvider
8
8
  from webscout import exceptions
9
- from typing import Any, AsyncGenerator, Dict
9
+ from typing import Union, Any, AsyncGenerator, Dict
10
10
  from webscout.litagent import LitAgent
11
11
 
12
12
  class TurboSeek(Provider):
@@ -1,6 +1,6 @@
1
1
  import requests
2
2
  import os
3
- from typing import List, Optional
3
+ from typing import Union, List, Optional
4
4
  from string import punctuation
5
5
  from random import choice
6
6
  import json
@@ -1,6 +1,6 @@
1
1
  import requests
2
2
  import json
3
- from typing import *
3
+ from typing import Union, Any, Dict, Generator
4
4
  import requests.exceptions
5
5
 
6
6
  from webscout.AIutel import Optimizers
@@ -146,6 +146,7 @@ class TypeGPT(Provider):
146
146
  "deepseek-r1-distill-llama-70b",
147
147
  # "deepseek-reasoner", >>>> NOT WORKING
148
148
  "deepseek-v3",
149
+ "uncensored-r1",
149
150
 
150
151
  # Specialized Models and Tools
151
152
  "@cf/defog/sqlcoder-7b-2",
@@ -162,45 +163,7 @@ class TypeGPT(Provider):
162
163
  # "@hf/thebloke/neural-chat-7b-v3-1-awq", >>>> NOT WORKING
163
164
  # "@hf/thebloke/openhermes-2.5-mistral-7b-awq", >>>> NOT WORKING
164
165
  # "@hf/thebloke/zephyr-7b-beta-awq", >>>> NOT WORKING
165
-
166
- # Development Agents
167
- "AndroidDeveloper",
168
- "AngularJSAgent",
169
- "AzureAgent",
170
- "BitbucketAgent",
171
- "DigitalOceanAgent",
172
- "DockerAgent",
173
- "ElectronAgent",
174
- "ErlangAgent",
175
- "FastAPIAgent",
176
- "FirebaseAgent",
177
- "FlaskAgent",
178
- "FlutterAgent",
179
- "GitAgent",
180
- "GitlabAgent",
181
- "GoAgent",
182
- "GodotAgent",
183
- "GoogleCloudAgent",
184
- "HTMLAgent",
185
- "JavaAgent",
186
- "JavaScriptAgent",
187
- "MongoDBAgent",
188
- "Next.jsAgent",
189
- "PyTorchAgent",
190
- "PythonAgent",
191
- "ReactAgent",
192
- "RepoMap",
193
- "SwiftDeveloper",
194
- "XcodeAgent",
195
- # "YoutubeAgent", >>>> NOT WORKING
196
-
197
- # Other Models
198
- "blackboxai",
199
- "blackboxai-pro",
200
- "builderAgent",
201
- # "Cipher-20b", >>>> NOT WORKING
202
- # "dify", >>>> NOT WORKING
203
- "flux",
166
+ "Image-Generator",
204
167
  # "flux-1-schnell", >>>> NOT WORKING
205
168
  # "HelpingAI-15B", >>>> NOT WORKING
206
169
  # "HelpingAI2-3b", >>>> NOT WORKING
@@ -309,7 +272,7 @@ class TypeGPT(Provider):
309
272
  raw: bool = False,
310
273
  optimizer: str = None,
311
274
  conversationally: bool = False,
312
- ) -> Dict[str, Any] | Generator:
275
+ ) -> Union[Dict[str, Any], Generator[Any, None, None]]:
313
276
  """Sends a prompt to the TypeGPT.net API and returns the response."""
314
277
  conversation_prompt = self.conversation.gen_complete_prompt(prompt)
315
278
  if optimizer:
@@ -398,7 +361,7 @@ class TypeGPT(Provider):
398
361
  stream: bool = False,
399
362
  optimizer: str = None,
400
363
  conversationally: bool = False,
401
- ) -> str | Generator[str, None, None]:
364
+ ) -> Union[str, Generator[str, None, None]]:
402
365
  """Generate response string or stream."""
403
366
  if stream:
404
367
  gen = self.ask(