webscout 1.3.8__py3-none-any.whl → 1.3.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.

webscout/AI.py CHANGED
@@ -20,21 +20,24 @@ import json
20
20
  import yaml
21
21
  from webscout.AIutel import Optimizers
22
22
  from webscout.AIutel import Conversation
23
- from webscout.AIutel import AwesomePrompts
24
- from webscout.AIbase import Provider
23
+ from webscout.AIutel import AwesomePrompts, sanitize_stream
24
+ from webscout.AIbase import Provider, AsyncProvider
25
25
  from Helpingai_T2 import Perplexity
26
- from typing import Any
26
+ from webscout import exceptions
27
+ from typing import Any, AsyncGenerator
27
28
  import logging
28
- #-----------------------------------------------Cohere--------------------------------------------
29
- class Cohere(Provider):
29
+ import httpx
30
+ #-----------------------------------------------llama 3-------------------------------------------
31
+ class LLAMA2(Provider):
30
32
  def __init__(
31
33
  self,
32
- api_key: str,
33
34
  is_conversation: bool = True,
34
- max_tokens: int = 600,
35
- model: str = "command-r-plus",
36
- temperature: float = 0.7,
37
- system_prompt: str = "You are helpful AI",
35
+ max_tokens: int = 800,
36
+ temperature: float = 0.75,
37
+ presence_penalty: int = 0,
38
+ frequency_penalty: int = 0,
39
+ top_p: float = 0.9,
40
+ model: str = "meta/meta-llama-3-70b-instruct",
38
41
  timeout: int = 30,
39
42
  intro: str = None,
40
43
  filepath: str = None,
@@ -42,20 +45,17 @@ class Cohere(Provider):
42
45
  proxies: dict = {},
43
46
  history_offset: int = 10250,
44
47
  act: str = None,
45
- top_k: int = -1,
46
- top_p: float = 0.999,
47
48
  ):
48
- """Initializes Cohere
49
+ """Instantiates LLAMA2
49
50
 
50
51
  Args:
51
- api_key (str): Cohere API key.
52
52
  is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True.
53
- max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
54
- model (str, optional): Model to use for generating text. Defaults to "command-r-plus".
55
- temperature (float, optional): Diversity of the generated text. Higher values produce more diverse outputs.
56
- Defaults to 0.7.
57
- system_prompt (str, optional): A system_prompt or context to set the style or tone of the generated text.
58
- Defaults to "You are helpful AI".
53
+ max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 800.
54
+ temperature (float, optional): Charge of the generated text's randomness. Defaults to 0.75.
55
+ presence_penalty (int, optional): Chances of topic being repeated. Defaults to 0.
56
+ frequency_penalty (int, optional): Chances of word being repeated. Defaults to 0.
57
+ top_p (float, optional): Sampling threshold during inference time. Defaults to 0.9.
58
+ model (str, optional): LLM model name. Defaults to "meta/llama-2-70b-chat".
59
59
  timeout (int, optional): Http request timeout. Defaults to 30.
60
60
  intro (str, optional): Conversation introductory prompt. Defaults to None.
61
61
  filepath (str, optional): Path to file containing conversation history. Defaults to None.
@@ -64,20 +64,22 @@ class Cohere(Provider):
64
64
  history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
65
65
  act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
66
66
  """
67
- self.session = requests.Session()
68
67
  self.is_conversation = is_conversation
69
68
  self.max_tokens_to_sample = max_tokens
70
- self.api_key = api_key
71
69
  self.model = model
72
70
  self.temperature = temperature
73
- self.system_prompt = system_prompt
74
- self.chat_endpoint = "https://production.api.os.cohere.ai/coral/v1/chat"
71
+ self.presence_penalty = presence_penalty
72
+ self.frequency_penalty = frequency_penalty
73
+ self.top_p = top_p
74
+ self.chat_endpoint = "https://www.llama2.ai/api"
75
75
  self.stream_chunk_size = 64
76
76
  self.timeout = timeout
77
77
  self.last_response = {}
78
78
  self.headers = {
79
79
  "Content-Type": "application/json",
80
- "Authorization": f"Bearer {self.api_key}",
80
+ "Referer": "https://www.llama2.ai/",
81
+ "Content-Type": "text/plain;charset=UTF-8",
82
+ "Origin": "https://www.llama2.ai",
81
83
  }
82
84
 
83
85
  self.__available_optimizers = (
@@ -119,7 +121,7 @@ class Cohere(Provider):
119
121
  dict : {}
120
122
  ```json
121
123
  {
122
- "text" : "How may I assist you today?"
124
+ "text" : "How may I help you today?"
123
125
  }
124
126
  ```
125
127
  """
@@ -134,30 +136,43 @@ class Cohere(Provider):
134
136
  f"Optimizer is not one of {self.__available_optimizers}"
135
137
  )
136
138
  self.session.headers.update(self.headers)
139
+
137
140
  payload = {
138
- "message": conversation_prompt,
141
+ "prompt": f"{conversation_prompt}<s>[INST] {prompt} [/INST]",
139
142
  "model": self.model,
143
+ "systemPrompt": "You are a helpful assistant.",
140
144
  "temperature": self.temperature,
141
- "preamble": self.system_prompt,
145
+ "topP": self.top_p,
146
+ "maxTokens": self.max_tokens_to_sample,
147
+ "image": None,
148
+ "audio": None,
142
149
  }
143
150
 
144
151
  def for_stream():
145
152
  response = self.session.post(
146
153
  self.chat_endpoint, json=payload, stream=True, timeout=self.timeout
147
154
  )
148
- if not response.ok:
149
- raise Exception(
150
- f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
155
+ if (
156
+ not response.ok
157
+ or not response.headers.get("Content-Type")
158
+ == "text/plain; charset=utf-8"
159
+ ):
160
+ raise exceptions.FailedToGenerateResponseError(
161
+ f"Failed to generate response - ({response.status_code}, {response.reason})"
151
162
  )
152
163
 
164
+ message_load: str = ""
153
165
  for value in response.iter_lines(
154
166
  decode_unicode=True,
167
+ delimiter="\n",
155
168
  chunk_size=self.stream_chunk_size,
156
169
  ):
157
170
  try:
158
- resp = json.loads(value.strip().split("\n")[-1])
159
- self.last_response.update(resp)
160
- yield value if raw else resp
171
+ if bool(value.strip()):
172
+ message_load += value + "\n"
173
+ resp: dict = dict(text=message_load)
174
+ yield value if raw else resp
175
+ self.last_response.update(resp)
161
176
  except json.decoder.JSONDecodeError:
162
177
  pass
163
178
  self.conversation.update_chat_history(
@@ -165,7 +180,6 @@ class Cohere(Provider):
165
180
  )
166
181
 
167
182
  def for_non_stream():
168
- # let's make use of stream
169
183
  for _ in for_stream():
170
184
  pass
171
185
  return self.last_response
@@ -211,20 +225,23 @@ class Cohere(Provider):
211
225
  """Retrieves message only from response
212
226
 
213
227
  Args:
214
- response (dict): Response generated by `self.ask`
228
+ response (str): Response generated by `self.ask`
215
229
 
216
230
  Returns:
217
231
  str: Message extracted
218
232
  """
219
233
  assert isinstance(response, dict), "Response should be of dict data-type only"
220
- return response["result"]["chatStreamEndEvent"]["response"]["text"]
221
- #-----------------------------------------------REKA-----------------------------------------------
222
- class REKA(Provider):
234
+ return response["text"]
235
+ class AsyncLLAMA2(AsyncProvider):
223
236
  def __init__(
224
237
  self,
225
- api_key: str,
226
238
  is_conversation: bool = True,
227
- max_tokens: int = 600,
239
+ max_tokens: int = 800,
240
+ temperature: float = 0.75,
241
+ presence_penalty: int = 0,
242
+ frequency_penalty: int = 0,
243
+ top_p: float = 0.9,
244
+ model: str = "meta/meta-llama-3-70b-instruct",
228
245
  timeout: int = 30,
229
246
  intro: str = None,
230
247
  filepath: str = None,
@@ -232,16 +249,17 @@ class REKA(Provider):
232
249
  proxies: dict = {},
233
250
  history_offset: int = 10250,
234
251
  act: str = None,
235
- model: str = "reka-core",
236
- system_prompt: str = "Be Helpful and Friendly. Keep your response straightforward, short and concise",
237
- use_search_engine: bool = False,
238
- use_code_interpreter: bool = False,
239
252
  ):
240
- """Instantiates REKA
253
+ """Instantiates LLAMA2
241
254
 
242
255
  Args:
243
- is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True
244
- max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
256
+ is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True.
257
+ max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 800.
258
+ temperature (float, optional): Charge of the generated text's randomness. Defaults to 0.75.
259
+ presence_penalty (int, optional): Chances of topic being repeated. Defaults to 0.
260
+ frequency_penalty (int, optional): Chances of word being repeated. Defaults to 0.
261
+ top_p (float, optional): Sampling threshold during inference time. Defaults to 0.9.
262
+ model (str, optional): LLM model name. Defaults to "meta/llama-2-70b-chat".
245
263
  timeout (int, optional): Http request timeout. Defaults to 30.
246
264
  intro (str, optional): Conversation introductory prompt. Defaults to None.
247
265
  filepath (str, optional): Path to file containing conversation history. Defaults to None.
@@ -249,25 +267,23 @@ class REKA(Provider):
249
267
  proxies (dict, optional): Http request proxies. Defaults to {}.
250
268
  history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
251
269
  act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
252
- model (str, optional): REKA model name. Defaults to "reka-core".
253
- system_prompt (str, optional): System prompt for REKA. Defaults to "Be Helpful and Friendly. Keep your response straightforward, short and concise".
254
- use_search_engine (bool, optional): Whether to use the search engine. Defaults to False.
255
- use_code_interpreter (bool, optional): Whether to use the code interpreter. Defaults to False.
256
270
  """
257
- self.session = requests.Session()
258
271
  self.is_conversation = is_conversation
259
272
  self.max_tokens_to_sample = max_tokens
260
- self.api_endpoint = "https://chat.reka.ai/api/chat"
273
+ self.model = model
274
+ self.temperature = temperature
275
+ self.presence_penalty = presence_penalty
276
+ self.frequency_penalty = frequency_penalty
277
+ self.top_p = top_p
278
+ self.chat_endpoint = "https://www.llama2.ai/api"
261
279
  self.stream_chunk_size = 64
262
280
  self.timeout = timeout
263
281
  self.last_response = {}
264
- self.model = model
265
- self.system_prompt = system_prompt
266
- self.use_search_engine = use_search_engine
267
- self.use_code_interpreter = use_code_interpreter
268
- self.access_token = api_key
269
282
  self.headers = {
270
- "Authorization": f"Bearer {self.access_token}",
283
+ "Content-Type": "application/json",
284
+ "Referer": "https://www.llama2.ai/",
285
+ "Content-Type": "text/plain;charset=UTF-8",
286
+ "Origin": "https://www.llama2.ai",
271
287
  }
272
288
 
273
289
  self.__available_optimizers = (
@@ -275,7 +291,6 @@ class REKA(Provider):
275
291
  for method in dir(Optimizers)
276
292
  if callable(getattr(Optimizers, method)) and not method.startswith("__")
277
293
  )
278
- self.session.headers.update(self.headers)
279
294
  Conversation.intro = (
280
295
  AwesomePrompts().get_act(
281
296
  act, raise_not_found=True, default=None, case_insensitive=True
@@ -287,17 +302,20 @@ class REKA(Provider):
287
302
  is_conversation, self.max_tokens_to_sample, filepath, update_file
288
303
  )
289
304
  self.conversation.history_offset = history_offset
290
- self.session.proxies = proxies
305
+ self.session = httpx.AsyncClient(
306
+ headers=self.headers,
307
+ proxies=proxies,
308
+ )
291
309
 
292
- def ask(
310
+ async def ask(
293
311
  self,
294
312
  prompt: str,
295
313
  stream: bool = False,
296
314
  raw: bool = False,
297
315
  optimizer: str = None,
298
316
  conversationally: bool = False,
299
- ) -> dict:
300
- """Chat with AI
317
+ ) -> dict | AsyncGenerator:
318
+ """Chat with AI asynchronously.
301
319
 
302
320
  Args:
303
321
  prompt (str): Prompt to be send.
@@ -306,10 +324,10 @@ class REKA(Provider):
306
324
  optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
307
325
  conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
308
326
  Returns:
309
- dict : {}
327
+ dict|AsyncGeneraror[dict] : ai content
310
328
  ```json
311
329
  {
312
- "text" : "How may I assist you today?"
330
+ "text" : "How may I help you today?"
313
331
  }
314
332
  ```
315
333
  """
@@ -324,76 +342,77 @@ class REKA(Provider):
324
342
  f"Optimizer is not one of {self.__available_optimizers}"
325
343
  )
326
344
 
327
- self.session.headers.update(self.headers)
328
345
  payload = {
329
-
330
- "conversation_history": [
331
- {"type": "human", "text": f"## SYSTEM PROMPT: {self.system_prompt}\n\n## QUERY: {conversation_prompt}"},
332
- ],
333
-
334
- "stream": stream,
335
- "use_search_engine": self.use_search_engine,
336
- "use_code_interpreter": self.use_code_interpreter,
337
- "model_name": self.model,
338
- # "model_name": "reka-flash",
339
- # "model_name": "reka-edge",
346
+ "prompt": f"{conversation_prompt}<s>[INST] {prompt} [/INST]",
347
+ "model": self.model,
348
+ "systemPrompt": "You are a helpful assistant.",
349
+ "temperature": self.temperature,
350
+ "topP": self.top_p,
351
+ "maxTokens": self.max_tokens_to_sample,
352
+ "image": None,
353
+ "audio": None,
340
354
  }
341
355
 
342
- def for_stream():
343
- response = self.session.post(self.api_endpoint, json=payload, stream=True, timeout=self.timeout)
344
- if not response.ok:
345
- raise Exception(
346
- f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
347
- )
348
-
349
- for value in response.iter_lines(
350
- decode_unicode=True,
351
- chunk_size=self.stream_chunk_size,
352
- ):
353
- try:
354
- resp = json.loads(value)
355
- self.last_response.update(resp)
356
- yield value if raw else resp
357
- except json.decoder.JSONDecodeError:
358
- pass
356
+ async def for_stream():
357
+ async with self.session.stream(
358
+ "POST", self.chat_endpoint, json=payload, timeout=self.timeout
359
+ ) as response:
360
+ if (
361
+ not response.is_success
362
+ or not response.headers.get("Content-Type")
363
+ == "text/plain; charset=utf-8"
364
+ ):
365
+ raise exceptions.FailedToGenerateResponseError(
366
+ f"Failed to generate response - ({response.status_code}, {response.reason_phrase})"
367
+ )
368
+ message_load: str = ""
369
+ async for value in response.aiter_lines():
370
+ try:
371
+ if bool(value.strip()):
372
+ message_load += value + "\n"
373
+ resp: dict = dict(text=message_load)
374
+ yield value if raw else resp
375
+ self.last_response.update(resp)
376
+ except json.decoder.JSONDecodeError:
377
+ pass
359
378
  self.conversation.update_chat_history(
360
- prompt, self.get_message(self.last_response)
379
+ prompt, await self.get_message(self.last_response)
361
380
  )
362
381
 
363
- def for_non_stream():
364
- # let's make use of stream
365
- for _ in for_stream():
382
+ async def for_non_stream():
383
+ async for _ in for_stream():
366
384
  pass
367
385
  return self.last_response
368
386
 
369
- return for_stream() if stream else for_non_stream()
387
+ return for_stream() if stream else await for_non_stream()
370
388
 
371
- def chat(
389
+ async def chat(
372
390
  self,
373
391
  prompt: str,
374
392
  stream: bool = False,
375
393
  optimizer: str = None,
376
394
  conversationally: bool = False,
377
- ) -> str:
378
- """Generate response `str`
395
+ ) -> str | AsyncGenerator:
396
+ """Generate response `str` asynchronously.
379
397
  Args:
380
398
  prompt (str): Prompt to be send.
381
399
  stream (bool, optional): Flag for streaming response. Defaults to False.
382
400
  optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
383
401
  conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
384
402
  Returns:
385
- str: Response generated
403
+ str|AsyncGenerator: Response generated
386
404
  """
387
405
 
388
- def for_stream():
389
- for response in self.ask(
406
+ async def for_stream():
407
+ async_ask = await self.ask(
390
408
  prompt, True, optimizer=optimizer, conversationally=conversationally
391
- ):
392
- yield self.get_message(response)
409
+ )
410
+ async for response in async_ask:
411
+ yield await self.get_message(response)
393
412
 
394
- def for_non_stream():
395
- return self.get_message(
396
- self.ask(
413
+ async def for_non_stream():
414
+ return await self.get_message(
415
+ await self.ask(
397
416
  prompt,
398
417
  False,
399
418
  optimizer=optimizer,
@@ -401,31 +420,29 @@ class REKA(Provider):
401
420
  )
402
421
  )
403
422
 
404
- return for_stream() if stream else for_non_stream()
423
+ return for_stream() if stream else await for_non_stream()
405
424
 
406
- def get_message(self, response: dict) -> str:
425
+ async def get_message(self, response: dict) -> str:
407
426
  """Retrieves message only from response
408
427
 
409
428
  Args:
410
- response (dict): Response generated by `self.ask`
429
+ response (str): Response generated by `self.ask`
411
430
 
412
431
  Returns:
413
432
  str: Message extracted
414
433
  """
415
434
  assert isinstance(response, dict), "Response should be of dict data-type only"
416
- return response.get("text")
417
- #-----------------------------------------------GROQ-----------------------------------------------
418
- class GROQ(Provider):
435
+ return response["text"]
436
+ #-----------------------------------------------Cohere--------------------------------------------
437
+ class Cohere(Provider):
419
438
  def __init__(
420
439
  self,
421
440
  api_key: str,
422
441
  is_conversation: bool = True,
423
442
  max_tokens: int = 600,
424
- temperature: float = 1,
425
- presence_penalty: int = 0,
426
- frequency_penalty: int = 0,
427
- top_p: float = 1,
428
- model: str = "mixtral-8x7b-32768",
443
+ model: str = "command-r-plus",
444
+ temperature: float = 0.7,
445
+ system_prompt: str = "You are helpful AI",
429
446
  timeout: int = 30,
430
447
  intro: str = None,
431
448
  filepath: str = None,
@@ -433,18 +450,20 @@ class GROQ(Provider):
433
450
  proxies: dict = {},
434
451
  history_offset: int = 10250,
435
452
  act: str = None,
453
+ top_k: int = -1,
454
+ top_p: float = 0.999,
436
455
  ):
437
- """Instantiates GROQ
456
+ """Initializes Cohere
438
457
 
439
458
  Args:
440
- api_key (key): GROQ's API key.
459
+ api_key (str): Cohere API key.
441
460
  is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True.
442
461
  max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
443
- temperature (float, optional): Charge of the generated text's randomness. Defaults to 1.
444
- presence_penalty (int, optional): Chances of topic being repeated. Defaults to 0.
445
- frequency_penalty (int, optional): Chances of word being repeated. Defaults to 0.
446
- top_p (float, optional): Sampling threshold during inference time. Defaults to 0.999.
447
- model (str, optional): LLM model name. Defaults to "gpt-3.5-turbo".
462
+ model (str, optional): Model to use for generating text. Defaults to "command-r-plus".
463
+ temperature (float, optional): Diversity of the generated text. Higher values produce more diverse outputs.
464
+ Defaults to 0.7.
465
+ system_prompt (str, optional): A system_prompt or context to set the style or tone of the generated text.
466
+ Defaults to "You are helpful AI".
448
467
  timeout (int, optional): Http request timeout. Defaults to 30.
449
468
  intro (str, optional): Conversation introductory prompt. Defaults to None.
450
469
  filepath (str, optional): Path to file containing conversation history. Defaults to None.
@@ -459,10 +478,8 @@ class GROQ(Provider):
459
478
  self.api_key = api_key
460
479
  self.model = model
461
480
  self.temperature = temperature
462
- self.presence_penalty = presence_penalty
463
- self.frequency_penalty = frequency_penalty
464
- self.top_p = top_p
465
- self.chat_endpoint = "https://api.groq.com/openai/v1/chat/completions"
481
+ self.system_prompt = system_prompt
482
+ self.chat_endpoint = "https://production.api.os.cohere.ai/coral/v1/chat"
466
483
  self.stream_chunk_size = 64
467
484
  self.timeout = timeout
468
485
  self.last_response = {}
@@ -500,42 +517,19 @@ class GROQ(Provider):
500
517
  ) -> dict:
501
518
  """Chat with AI
502
519
 
503
- Args:
504
- prompt (str): Prompt to be send.
505
- stream (bool, optional): Flag for streaming response. Defaults to False.
506
- raw (bool, optional): Stream back raw response as received. Defaults to False.
507
- optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
508
- conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
509
- Returns:
510
- dict : {}
511
- ```json
520
+ Args:
521
+ prompt (str): Prompt to be send.
522
+ stream (bool, optional): Flag for streaming response. Defaults to False.
523
+ raw (bool, optional): Stream back raw response as received. Defaults to False.
524
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
525
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
526
+ Returns:
527
+ dict : {}
528
+ ```json
512
529
  {
513
- "id": "c0c8d139-d2b9-9909-8aa1-14948bc28404",
514
- "object": "chat.completion",
515
- "created": 1710852779,
516
- "model": "mixtral-8x7b-32768",
517
- "choices": [
518
- {
519
- "index": 0,
520
- "message": {
521
- "role": "assistant",
522
- "content": "Hello! How can I assist you today? I'm here to help answer your questions and engage in conversation on a wide variety of topics. Feel free to ask me anything!"
523
- },
524
- "logprobs": null,
525
- "finish_reason": "stop"
526
- }
527
- ],
528
- "usage": {
529
- "prompt_tokens": 47,
530
- "prompt_time": 0.03,
531
- "completion_tokens": 37,
532
- "completion_time": 0.069,
533
- "total_tokens": 84,
534
- "total_time": 0.099
535
- },
536
- "system_fingerprint": null
530
+ "text" : "How may I assist you today?"
537
531
  }
538
- ```
532
+ ```
539
533
  """
540
534
  conversation_prompt = self.conversation.gen_complete_prompt(prompt)
541
535
  if optimizer:
@@ -549,13 +543,10 @@ class GROQ(Provider):
549
543
  )
550
544
  self.session.headers.update(self.headers)
551
545
  payload = {
552
- "frequency_penalty": self.frequency_penalty,
553
- "messages": [{"content": conversation_prompt, "role": "user"}],
546
+ "message": conversation_prompt,
554
547
  "model": self.model,
555
- "presence_penalty": self.presence_penalty,
556
- "stream": stream,
557
548
  "temperature": self.temperature,
558
- "top_p": self.top_p,
549
+ "preamble": self.system_prompt,
559
550
  }
560
551
 
561
552
  def for_stream():
@@ -567,22 +558,14 @@ class GROQ(Provider):
567
558
  f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
568
559
  )
569
560
 
570
- message_load = ""
571
561
  for value in response.iter_lines(
572
562
  decode_unicode=True,
573
- delimiter="" if raw else "data:",
574
563
  chunk_size=self.stream_chunk_size,
575
564
  ):
576
565
  try:
577
- resp = json.loads(value)
578
- incomplete_message = self.get_message(resp)
579
- if incomplete_message:
580
- message_load += incomplete_message
581
- resp["choices"][0]["delta"]["content"] = message_load
582
- self.last_response.update(resp)
583
- yield value if raw else resp
584
- elif raw:
585
- yield value
566
+ resp = json.loads(value.strip().split("\n")[-1])
567
+ self.last_response.update(resp)
568
+ yield value if raw else resp
586
569
  except json.decoder.JSONDecodeError:
587
570
  pass
588
571
  self.conversation.update_chat_history(
@@ -590,19 +573,10 @@ class GROQ(Provider):
590
573
  )
591
574
 
592
575
  def for_non_stream():
593
- response = self.session.post(
594
- self.chat_endpoint, json=payload, stream=False, timeout=self.timeout
595
- )
596
- if not response.ok:
597
- raise Exception(
598
- f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
599
- )
600
- resp = response.json()
601
- self.last_response.update(resp)
602
- self.conversation.update_chat_history(
603
- prompt, self.get_message(self.last_response)
604
- )
605
- return resp
576
+ # let's make use of stream
577
+ for _ in for_stream():
578
+ pass
579
+ return self.last_response
606
580
 
607
581
  return for_stream() if stream else for_non_stream()
608
582
 
@@ -651,26 +625,14 @@ class GROQ(Provider):
651
625
  str: Message extracted
652
626
  """
653
627
  assert isinstance(response, dict), "Response should be of dict data-type only"
654
- try:
655
- if response["choices"][0].get("delta"):
656
- return response["choices"][0]["delta"]["content"]
657
- return response["choices"][0]["message"]["content"]
658
- except KeyError:
659
- return ""
660
-
661
- #----------------------------------------------------------OpenAI-----------------------------------
662
- class OPENAI(Provider):
663
- model = "gpt-3.5-turbo"
628
+ return response["result"]["chatStreamEndEvent"]["response"]["text"]
629
+ #-----------------------------------------------REKA-----------------------------------------------
630
+ class REKA(Provider):
664
631
  def __init__(
665
632
  self,
666
633
  api_key: str,
667
634
  is_conversation: bool = True,
668
635
  max_tokens: int = 600,
669
- temperature: float = 1,
670
- presence_penalty: int = 0,
671
- frequency_penalty: int = 0,
672
- top_p: float = 1,
673
- model: str = model,
674
636
  timeout: int = 30,
675
637
  intro: str = None,
676
638
  filepath: str = None,
@@ -678,18 +640,16 @@ class OPENAI(Provider):
678
640
  proxies: dict = {},
679
641
  history_offset: int = 10250,
680
642
  act: str = None,
643
+ model: str = "reka-core",
644
+ system_prompt: str = "Be Helpful and Friendly. Keep your response straightforward, short and concise",
645
+ use_search_engine: bool = False,
646
+ use_code_interpreter: bool = False,
681
647
  ):
682
- """Instantiates OPENAI
648
+ """Instantiates REKA
683
649
 
684
650
  Args:
685
- api_key (key): OpenAI's API key.
686
- is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True.
651
+ is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True
687
652
  max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
688
- temperature (float, optional): Charge of the generated text's randomness. Defaults to 1.
689
- presence_penalty (int, optional): Chances of topic being repeated. Defaults to 0.
690
- frequency_penalty (int, optional): Chances of word being repeated. Defaults to 0.
691
- top_p (float, optional): Sampling threshold during inference time. Defaults to 0.999.
692
- model (str, optional): LLM model name. Defaults to "gpt-3.5-turbo".
693
653
  timeout (int, optional): Http request timeout. Defaults to 30.
694
654
  intro (str, optional): Conversation introductory prompt. Defaults to None.
695
655
  filepath (str, optional): Path to file containing conversation history. Defaults to None.
@@ -697,23 +657,25 @@ class OPENAI(Provider):
697
657
  proxies (dict, optional): Http request proxies. Defaults to {}.
698
658
  history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
699
659
  act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
660
+ model (str, optional): REKA model name. Defaults to "reka-core".
661
+ system_prompt (str, optional): System prompt for REKA. Defaults to "Be Helpful and Friendly. Keep your response straightforward, short and concise".
662
+ use_search_engine (bool, optional): Whether to use the search engine. Defaults to False.
663
+ use_code_interpreter (bool, optional): Whether to use the code interpreter. Defaults to False.
700
664
  """
701
665
  self.session = requests.Session()
702
666
  self.is_conversation = is_conversation
703
667
  self.max_tokens_to_sample = max_tokens
704
- self.api_key = api_key
705
- self.model = model
706
- self.temperature = temperature
707
- self.presence_penalty = presence_penalty
708
- self.frequency_penalty = frequency_penalty
709
- self.top_p = top_p
710
- self.chat_endpoint = "https://api.openai.com/v1/chat/completions"
668
+ self.api_endpoint = "https://chat.reka.ai/api/chat"
711
669
  self.stream_chunk_size = 64
712
670
  self.timeout = timeout
713
671
  self.last_response = {}
672
+ self.model = model
673
+ self.system_prompt = system_prompt
674
+ self.use_search_engine = use_search_engine
675
+ self.use_code_interpreter = use_code_interpreter
676
+ self.access_token = api_key
714
677
  self.headers = {
715
- "Content-Type": "application/json",
716
- "Authorization": f"Bearer {self.api_key}",
678
+ "Authorization": f"Bearer {self.access_token}",
717
679
  }
718
680
 
719
681
  self.__available_optimizers = (
@@ -755,25 +717,7 @@ class OPENAI(Provider):
755
717
  dict : {}
756
718
  ```json
757
719
  {
758
- "id": "chatcmpl-TaREJpBZsRVQFRFic1wIA7Q7XfnaD",
759
- "object": "chat.completion",
760
- "created": 1704623244,
761
- "model": "gpt-3.5-turbo",
762
- "usage": {
763
- "prompt_tokens": 0,
764
- "completion_tokens": 0,
765
- "total_tokens": 0
766
- },
767
- "choices": [
768
- {
769
- "message": {
770
- "role": "assistant",
771
- "content": "Hello! How can I assist you today?"
772
- },
773
- "finish_reason": "stop",
774
- "index": 0
775
- }
776
- ]
720
+ "text" : "How may I assist you today?"
777
721
  }
778
722
  ```
779
723
  """
@@ -787,42 +731,37 @@ class OPENAI(Provider):
787
731
  raise Exception(
788
732
  f"Optimizer is not one of {self.__available_optimizers}"
789
733
  )
734
+
790
735
  self.session.headers.update(self.headers)
791
736
  payload = {
792
- "frequency_penalty": self.frequency_penalty,
793
- "messages": [{"content": conversation_prompt, "role": "user"}],
794
- "model": self.model,
795
- "presence_penalty": self.presence_penalty,
737
+
738
+ "conversation_history": [
739
+ {"type": "human", "text": f"## SYSTEM PROMPT: {self.system_prompt}\n\n## QUERY: {conversation_prompt}"},
740
+ ],
741
+
796
742
  "stream": stream,
797
- "temperature": self.temperature,
798
- "top_p": self.top_p,
743
+ "use_search_engine": self.use_search_engine,
744
+ "use_code_interpreter": self.use_code_interpreter,
745
+ "model_name": self.model,
746
+ # "model_name": "reka-flash",
747
+ # "model_name": "reka-edge",
799
748
  }
800
749
 
801
750
  def for_stream():
802
- response = self.session.post(
803
- self.chat_endpoint, json=payload, stream=True, timeout=self.timeout
804
- )
751
+ response = self.session.post(self.api_endpoint, json=payload, stream=True, timeout=self.timeout)
805
752
  if not response.ok:
806
753
  raise Exception(
807
754
  f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
808
755
  )
809
756
 
810
- message_load = ""
811
757
  for value in response.iter_lines(
812
758
  decode_unicode=True,
813
- delimiter="" if raw else "data:",
814
759
  chunk_size=self.stream_chunk_size,
815
760
  ):
816
761
  try:
817
762
  resp = json.loads(value)
818
- incomplete_message = self.get_message(resp)
819
- if incomplete_message:
820
- message_load += incomplete_message
821
- resp["choices"][0]["delta"]["content"] = message_load
822
- self.last_response.update(resp)
823
- yield value if raw else resp
824
- elif raw:
825
- yield value
763
+ self.last_response.update(resp)
764
+ yield value if raw else resp
826
765
  except json.decoder.JSONDecodeError:
827
766
  pass
828
767
  self.conversation.update_chat_history(
@@ -830,22 +769,10 @@ class OPENAI(Provider):
830
769
  )
831
770
 
832
771
  def for_non_stream():
833
- response = self.session.post(
834
- self.chat_endpoint, json=payload, stream=False, timeout=self.timeout
835
- )
836
- if (
837
- not response.ok
838
- or not response.headers.get("Content-Type", "") == "application/json"
839
- ):
840
- raise Exception(
841
- f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
842
- )
843
- resp = response.json()
844
- self.last_response.update(resp)
845
- self.conversation.update_chat_history(
846
- prompt, self.get_message(self.last_response)
847
- )
848
- return resp
772
+ # let's make use of stream
773
+ for _ in for_stream():
774
+ pass
775
+ return self.last_response
849
776
 
850
777
  return for_stream() if stream else for_non_stream()
851
778
 
@@ -894,27 +821,19 @@ class OPENAI(Provider):
894
821
  str: Message extracted
895
822
  """
896
823
  assert isinstance(response, dict), "Response should be of dict data-type only"
897
- try:
898
- if response["choices"][0].get("delta"):
899
- return response["choices"][0]["delta"]["content"]
900
- return response["choices"][0]["message"]["content"]
901
- except KeyError:
902
- return ""
903
- #--------------------------------------LEO-----------------------------------------
904
- class LEO(Provider):
905
-
906
- # model = "llama-2-13b-chat"
907
-
908
- # key = "qztbjzBqJueQZLFkwTTJrieu8Vw3789u"
824
+ return response.get("text")
825
+ #-----------------------------------------------GROQ-----------------------------------------------
826
+ class GROQ(Provider):
909
827
  def __init__(
910
828
  self,
829
+ api_key: str,
911
830
  is_conversation: bool = True,
912
831
  max_tokens: int = 600,
913
- temperature: float = 0.2,
914
- top_k: int = -1,
915
- top_p: float = 0.999,
916
- model: str = "llama-2-13b-chat",
917
- brave_key: str = "qztbjzBqJueQZLFkwTTJrieu8Vw3789u",
832
+ temperature: float = 1,
833
+ presence_penalty: int = 0,
834
+ frequency_penalty: int = 0,
835
+ top_p: float = 1,
836
+ model: str = "mixtral-8x7b-32768",
918
837
  timeout: int = 30,
919
838
  intro: str = None,
920
839
  filepath: str = None,
@@ -923,43 +842,43 @@ class LEO(Provider):
923
842
  history_offset: int = 10250,
924
843
  act: str = None,
925
844
  ):
926
- """Instantiate TGPT
845
+ """Instantiates GROQ
927
846
 
928
847
  Args:
929
- is_conversation (str, optional): Flag for chatting conversationally. Defaults to True.
930
- brave_key (str, optional): Brave API access key. Defaults to "qztbjzBqJueQZLFkwTTJrieu8Vw3789u".
931
- model (str, optional): Text generation model name. Defaults to "llama-2-13b-chat".
848
+ api_key (key): GROQ's API key.
849
+ is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True.
932
850
  max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
933
- temperature (float, optional): Charge of the generated text's randomness. Defaults to 0.2.
934
- top_k (int, optional): Chance of topic being repeated. Defaults to -1.
851
+ temperature (float, optional): Charge of the generated text's randomness. Defaults to 1.
852
+ presence_penalty (int, optional): Chances of topic being repeated. Defaults to 0.
853
+ frequency_penalty (int, optional): Chances of word being repeated. Defaults to 0.
935
854
  top_p (float, optional): Sampling threshold during inference time. Defaults to 0.999.
936
- timeput (int, optional): Http requesting timeout. Defaults to 30
937
- intro (str, optional): Conversation introductory prompt. Defaults to `Conversation.intro`.
855
+ model (str, optional): LLM model name. Defaults to "gpt-3.5-turbo".
856
+ timeout (int, optional): Http request timeout. Defaults to 30.
857
+ intro (str, optional): Conversation introductory prompt. Defaults to None.
938
858
  filepath (str, optional): Path to file containing conversation history. Defaults to None.
939
859
  update_file (bool, optional): Add new prompts and responses to the file. Defaults to True.
940
- proxies (dict, optional) : Http reqiuest proxies (socks). Defaults to {}.
860
+ proxies (dict, optional): Http request proxies. Defaults to {}.
941
861
  history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
942
862
  act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
943
863
  """
944
864
  self.session = requests.Session()
945
865
  self.is_conversation = is_conversation
946
866
  self.max_tokens_to_sample = max_tokens
867
+ self.api_key = api_key
947
868
  self.model = model
948
- self.stop_sequences = ["</response>", "</s>"]
949
869
  self.temperature = temperature
950
- self.top_k = top_k
870
+ self.presence_penalty = presence_penalty
871
+ self.frequency_penalty = frequency_penalty
951
872
  self.top_p = top_p
952
- self.chat_endpoint = "https://ai-chat.bsg.brave.com/v1/complete"
873
+ self.chat_endpoint = "https://api.groq.com/openai/v1/chat/completions"
953
874
  self.stream_chunk_size = 64
954
875
  self.timeout = timeout
955
876
  self.last_response = {}
956
877
  self.headers = {
957
878
  "Content-Type": "application/json",
958
- "accept": "text/event-stream",
959
- "x-brave-key": brave_key,
960
- "accept-language": "en-US,en;q=0.9",
961
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/110.0",
879
+ "Authorization": f"Bearer {self.api_key}",
962
880
  }
881
+
963
882
  self.__available_optimizers = (
964
883
  method
965
884
  for method in dir(Optimizers)
@@ -978,14 +897,6 @@ class LEO(Provider):
978
897
  )
979
898
  self.conversation.history_offset = history_offset
980
899
  self.session.proxies = proxies
981
- self.system_prompt = (
982
- "\n\nYour name is Leo, a helpful"
983
- "respectful and honest AI assistant created by the company Brave. You will be replying to a user of the Brave browser. "
984
- "Always respond in a neutral tone. Be polite and courteous. Answer concisely in no more than 50-80 words."
985
- "\n\nPlease ensure that your responses are socially unbiased and positive in nature."
986
- "If a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. "
987
- "If you don't know the answer to a question, please don't share false information.\n"
988
- )
989
900
 
990
901
  def ask(
991
902
  self,
@@ -997,25 +908,42 @@ class LEO(Provider):
997
908
  ) -> dict:
998
909
  """Chat with AI
999
910
 
1000
- Args:
1001
- prompt (str): Prompt to be send.
1002
- stream (bool, optional): Flag for streaming response. Defaults to False.
1003
- raw (bool, optional): Stream back raw response as received. Defaults to False.
1004
- optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
1005
- conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
1006
- Returns:
1007
- dict : {}
1008
- ```json
911
+ Args:
912
+ prompt (str): Prompt to be send.
913
+ stream (bool, optional): Flag for streaming response. Defaults to False.
914
+ raw (bool, optional): Stream back raw response as received. Defaults to False.
915
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
916
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
917
+ Returns:
918
+ dict : {}
919
+ ```json
1009
920
  {
1010
- "completion": "\nNext: domestic cat breeds with short hair >>",
1011
- "stop_reason": null,
1012
- "truncated": false,
1013
- "stop": null,
1014
- "model": "llama-2-13b-chat",
1015
- "log_id": "cmpl-3kYiYxSNDvgMShSzFooz6t",
1016
- "exception": null
921
+ "id": "c0c8d139-d2b9-9909-8aa1-14948bc28404",
922
+ "object": "chat.completion",
923
+ "created": 1710852779,
924
+ "model": "mixtral-8x7b-32768",
925
+ "choices": [
926
+ {
927
+ "index": 0,
928
+ "message": {
929
+ "role": "assistant",
930
+ "content": "Hello! How can I assist you today? I'm here to help answer your questions and engage in conversation on a wide variety of topics. Feel free to ask me anything!"
931
+ },
932
+ "logprobs": null,
933
+ "finish_reason": "stop"
934
+ }
935
+ ],
936
+ "usage": {
937
+ "prompt_tokens": 47,
938
+ "prompt_time": 0.03,
939
+ "completion_tokens": 37,
940
+ "completion_time": 0.069,
941
+ "total_tokens": 84,
942
+ "total_time": 0.099
943
+ },
944
+ "system_fingerprint": null
1017
945
  }
1018
- ```
946
+ ```
1019
947
  """
1020
948
  conversation_prompt = self.conversation.gen_complete_prompt(prompt)
1021
949
  if optimizer:
@@ -1027,15 +955,14 @@ class LEO(Provider):
1027
955
  raise Exception(
1028
956
  f"Optimizer is not one of {self.__available_optimizers}"
1029
957
  )
1030
-
1031
958
  self.session.headers.update(self.headers)
1032
959
  payload = {
1033
- "max_tokens_to_sample": self.max_tokens_to_sample,
960
+ "frequency_penalty": self.frequency_penalty,
961
+ "messages": [{"content": conversation_prompt, "role": "user"}],
1034
962
  "model": self.model,
1035
- "prompt": f"<s>[INST] <<SYS>>{self.system_prompt}<</SYS>>{conversation_prompt} [/INST]",
1036
- "self.stop_sequence": self.stop_sequences,
963
+ "presence_penalty": self.presence_penalty,
1037
964
  "stream": stream,
1038
- "top_k": self.top_k,
965
+ "temperature": self.temperature,
1039
966
  "top_p": self.top_p,
1040
967
  }
1041
968
 
@@ -1043,15 +970,12 @@ class LEO(Provider):
1043
970
  response = self.session.post(
1044
971
  self.chat_endpoint, json=payload, stream=True, timeout=self.timeout
1045
972
  )
1046
- if (
1047
- not response.ok
1048
- or not response.headers.get("Content-Type")
1049
- == "text/event-stream; charset=utf-8"
1050
- ):
973
+ if not response.ok:
1051
974
  raise Exception(
1052
975
  f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
1053
976
  )
1054
977
 
978
+ message_load = ""
1055
979
  for value in response.iter_lines(
1056
980
  decode_unicode=True,
1057
981
  delimiter="" if raw else "data:",
@@ -1059,8 +983,14 @@ class LEO(Provider):
1059
983
  ):
1060
984
  try:
1061
985
  resp = json.loads(value)
1062
- self.last_response.update(resp)
1063
- yield value if raw else resp
986
+ incomplete_message = self.get_message(resp)
987
+ if incomplete_message:
988
+ message_load += incomplete_message
989
+ resp["choices"][0]["delta"]["content"] = message_load
990
+ self.last_response.update(resp)
991
+ yield value if raw else resp
992
+ elif raw:
993
+ yield value
1064
994
  except json.decoder.JSONDecodeError:
1065
995
  pass
1066
996
  self.conversation.update_chat_history(
@@ -1071,10 +1001,7 @@ class LEO(Provider):
1071
1001
  response = self.session.post(
1072
1002
  self.chat_endpoint, json=payload, stream=False, timeout=self.timeout
1073
1003
  )
1074
- if (
1075
- not response.ok
1076
- or not response.headers.get("Content-Type", "") == "application/json"
1077
- ):
1004
+ if not response.ok:
1078
1005
  raise Exception(
1079
1006
  f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
1080
1007
  )
@@ -1132,15 +1059,23 @@ class LEO(Provider):
1132
1059
  str: Message extracted
1133
1060
  """
1134
1061
  assert isinstance(response, dict), "Response should be of dict data-type only"
1135
- return response.get("completion")
1136
- #------------------------------------------------------KOBOLDAI-----------------------------------------------------------
1137
- class KOBOLDAI(Provider):
1062
+ try:
1063
+ if response["choices"][0].get("delta"):
1064
+ return response["choices"][0]["delta"]["content"]
1065
+ return response["choices"][0]["message"]["content"]
1066
+ except KeyError:
1067
+ return ""
1068
+ class AsyncGROQ(AsyncProvider):
1138
1069
  def __init__(
1139
1070
  self,
1071
+ api_key: str,
1140
1072
  is_conversation: bool = True,
1141
1073
  max_tokens: int = 600,
1142
1074
  temperature: float = 1,
1075
+ presence_penalty: int = 0,
1076
+ frequency_penalty: int = 0,
1143
1077
  top_p: float = 1,
1078
+ model: str = "mixtral-8x7b-32768",
1144
1079
  timeout: int = 30,
1145
1080
  intro: str = None,
1146
1081
  filepath: str = None,
@@ -1149,35 +1084,40 @@ class KOBOLDAI(Provider):
1149
1084
  history_offset: int = 10250,
1150
1085
  act: str = None,
1151
1086
  ):
1152
- """Instantiate TGPT
1087
+ """Instantiates GROQ
1153
1088
 
1154
1089
  Args:
1155
- is_conversation (str, optional): Flag for chatting conversationally. Defaults to True.
1090
+ api_key (key): GROQ's API key.
1091
+ is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True.
1156
1092
  max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
1157
- temperature (float, optional): Charge of the generated text's randomness. Defaults to 0.2.
1093
+ temperature (float, optional): Charge of the generated text's randomness. Defaults to 1.
1094
+ presence_penalty (int, optional): Chances of topic being repeated. Defaults to 0.
1095
+ frequency_penalty (int, optional): Chances of word being repeated. Defaults to 0.
1158
1096
  top_p (float, optional): Sampling threshold during inference time. Defaults to 0.999.
1159
- timeout (int, optional): Http requesting timeout. Defaults to 30
1160
- intro (str, optional): Conversation introductory prompt. Defaults to `Conversation.intro`.
1097
+ model (str, optional): LLM model name. Defaults to "gpt-3.5-turbo".
1098
+ timeout (int, optional): Http request timeout. Defaults to 30.
1099
+ intro (str, optional): Conversation introductory prompt. Defaults to None.
1161
1100
  filepath (str, optional): Path to file containing conversation history. Defaults to None.
1162
1101
  update_file (bool, optional): Add new prompts and responses to the file. Defaults to True.
1163
- proxies (dict, optional) : Http reqiuest proxies (socks). Defaults to {}.
1102
+ proxies (dict, optional): Http request proxies. Defaults to {}.
1164
1103
  history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
1165
1104
  act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
1166
1105
  """
1167
- self.session = requests.Session()
1168
1106
  self.is_conversation = is_conversation
1169
1107
  self.max_tokens_to_sample = max_tokens
1108
+ self.api_key = api_key
1109
+ self.model = model
1170
1110
  self.temperature = temperature
1111
+ self.presence_penalty = presence_penalty
1112
+ self.frequency_penalty = frequency_penalty
1171
1113
  self.top_p = top_p
1172
- self.chat_endpoint = (
1173
- "https://koboldai-koboldcpp-tiefighter.hf.space/api/extra/generate/stream"
1174
- )
1114
+ self.chat_endpoint = "https://api.groq.com/openai/v1/chat/completions"
1175
1115
  self.stream_chunk_size = 64
1176
1116
  self.timeout = timeout
1177
1117
  self.last_response = {}
1178
1118
  self.headers = {
1179
1119
  "Content-Type": "application/json",
1180
- "Accept": "application/json",
1120
+ "Authorization": f"Bearer {self.api_key}",
1181
1121
  }
1182
1122
 
1183
1123
  self.__available_optimizers = (
@@ -1185,7 +1125,6 @@ class KOBOLDAI(Provider):
1185
1125
  for method in dir(Optimizers)
1186
1126
  if callable(getattr(Optimizers, method)) and not method.startswith("__")
1187
1127
  )
1188
- self.session.headers.update(self.headers)
1189
1128
  Conversation.intro = (
1190
1129
  AwesomePrompts().get_act(
1191
1130
  act, raise_not_found=True, default=None, case_insensitive=True
@@ -1197,31 +1136,54 @@ class KOBOLDAI(Provider):
1197
1136
  is_conversation, self.max_tokens_to_sample, filepath, update_file
1198
1137
  )
1199
1138
  self.conversation.history_offset = history_offset
1200
- self.session.proxies = proxies
1139
+ self.session = httpx.AsyncClient(headers=self.headers, proxies=proxies)
1201
1140
 
1202
- def ask(
1141
+ async def ask(
1203
1142
  self,
1204
1143
  prompt: str,
1205
1144
  stream: bool = False,
1206
1145
  raw: bool = False,
1207
1146
  optimizer: str = None,
1208
1147
  conversationally: bool = False,
1209
- ) -> dict:
1210
- """Chat with AI
1148
+ ) -> dict | AsyncGenerator:
1149
+ """Chat with AI asynchronously.
1211
1150
 
1212
- Args:
1213
- prompt (str): Prompt to be send.
1214
- stream (bool, optional): Flag for streaming response. Defaults to False.
1215
- raw (bool, optional): Stream back raw response as received. Defaults to False.
1216
- optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
1217
- conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
1218
- Returns:
1219
- dict : {}
1220
- ```json
1151
+ Args:
1152
+ prompt (str): Prompt to be send.
1153
+ stream (bool, optional): Flag for streaming response. Defaults to False.
1154
+ raw (bool, optional): Stream back raw response as received. Defaults to False.
1155
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
1156
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
1157
+ Returns:
1158
+ dict|AsyncGenerator : ai content
1159
+ ```json
1221
1160
  {
1222
- "token" : "How may I assist you today?"
1161
+ "id": "c0c8d139-d2b9-9909-8aa1-14948bc28404",
1162
+ "object": "chat.completion",
1163
+ "created": 1710852779,
1164
+ "model": "mixtral-8x7b-32768",
1165
+ "choices": [
1166
+ {
1167
+ "index": 0,
1168
+ "message": {
1169
+ "role": "assistant",
1170
+ "content": "Hello! How can I assist you today? I'm here to help answer your questions and engage in conversation on a wide variety of topics. Feel free to ask me anything!"
1171
+ },
1172
+ "logprobs": null,
1173
+ "finish_reason": "stop"
1174
+ }
1175
+ ],
1176
+ "usage": {
1177
+ "prompt_tokens": 47,
1178
+ "prompt_time": 0.03,
1179
+ "completion_tokens": 37,
1180
+ "completion_time": 0.069,
1181
+ "total_tokens": 84,
1182
+ "total_time": 0.099
1183
+ },
1184
+ "system_fingerprint": null
1223
1185
  }
1224
- ```
1186
+ ```
1225
1187
  """
1226
1188
  conversation_prompt = self.conversation.gen_complete_prompt(prompt)
1227
1189
  if optimizer:
@@ -1233,75 +1195,90 @@ class KOBOLDAI(Provider):
1233
1195
  raise Exception(
1234
1196
  f"Optimizer is not one of {self.__available_optimizers}"
1235
1197
  )
1236
-
1237
- self.session.headers.update(self.headers)
1238
1198
  payload = {
1239
- "prompt": conversation_prompt,
1199
+ "frequency_penalty": self.frequency_penalty,
1200
+ "messages": [{"content": conversation_prompt, "role": "user"}],
1201
+ "model": self.model,
1202
+ "presence_penalty": self.presence_penalty,
1203
+ "stream": stream,
1240
1204
  "temperature": self.temperature,
1241
1205
  "top_p": self.top_p,
1242
1206
  }
1243
1207
 
1244
- def for_stream():
1245
- response = self.session.post(
1246
- self.chat_endpoint, json=payload, stream=True, timeout=self.timeout
1208
+ async def for_stream():
1209
+ async with self.session.stream(
1210
+ "POST", self.chat_endpoint, json=payload, timeout=self.timeout
1211
+ ) as response:
1212
+ if not response.is_success:
1213
+ raise Exception(
1214
+ f"Failed to generate response - ({response.status_code}, {response.reason_phrase})"
1215
+ )
1216
+
1217
+ message_load = ""
1218
+ intro_value = "data:"
1219
+ async for value in response.aiter_lines():
1220
+ try:
1221
+ if value.startswith(intro_value):
1222
+ value = value[len(intro_value) :]
1223
+ resp = json.loads(value)
1224
+ incomplete_message = await self.get_message(resp)
1225
+ if incomplete_message:
1226
+ message_load += incomplete_message
1227
+ resp["choices"][0]["delta"]["content"] = message_load
1228
+ self.last_response.update(resp)
1229
+ yield value if raw else resp
1230
+ elif raw:
1231
+ yield value
1232
+ except json.decoder.JSONDecodeError:
1233
+ pass
1234
+ self.conversation.update_chat_history(
1235
+ prompt, await self.get_message(self.last_response)
1247
1236
  )
1248
- if not response.ok:
1237
+
1238
+ async def for_non_stream():
1239
+ response = httpx.post(
1240
+ self.chat_endpoint, json=payload, timeout=self.timeout
1241
+ )
1242
+ if not response.is_success:
1249
1243
  raise Exception(
1250
- f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
1244
+ f"Failed to generate response - ({response.status_code}, {response.reason_phrase})"
1251
1245
  )
1252
-
1253
- message_load = ""
1254
- for value in response.iter_lines(
1255
- decode_unicode=True,
1256
- delimiter="" if raw else "event: message\ndata:",
1257
- chunk_size=self.stream_chunk_size,
1258
- ):
1259
- try:
1260
- resp = json.loads(value)
1261
- message_load += self.get_message(resp)
1262
- resp["token"] = message_load
1263
- self.last_response.update(resp)
1264
- yield value if raw else resp
1265
- except json.decoder.JSONDecodeError:
1266
- pass
1246
+ resp = response.json()
1247
+ self.last_response.update(resp)
1267
1248
  self.conversation.update_chat_history(
1268
- prompt, self.get_message(self.last_response)
1249
+ prompt, await self.get_message(self.last_response)
1269
1250
  )
1251
+ return resp
1270
1252
 
1271
- def for_non_stream():
1272
- # let's make use of stream
1273
- for _ in for_stream():
1274
- pass
1275
- return self.last_response
1276
-
1277
- return for_stream() if stream else for_non_stream()
1253
+ return for_stream() if stream else await for_non_stream()
1278
1254
 
1279
- def chat(
1255
+ async def chat(
1280
1256
  self,
1281
1257
  prompt: str,
1282
1258
  stream: bool = False,
1283
1259
  optimizer: str = None,
1284
1260
  conversationally: bool = False,
1285
- ) -> str:
1286
- """Generate response `str`
1261
+ ) -> str | AsyncGenerator:
1262
+ """Generate response `str` asynchronously.
1287
1263
  Args:
1288
1264
  prompt (str): Prompt to be send.
1289
1265
  stream (bool, optional): Flag for streaming response. Defaults to False.
1290
1266
  optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
1291
1267
  conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
1292
1268
  Returns:
1293
- str: Response generated
1269
+ str|AsyncGenerator: Response generated
1294
1270
  """
1295
1271
 
1296
- def for_stream():
1297
- for response in self.ask(
1272
+ async def for_stream():
1273
+ async_ask = await self.ask(
1298
1274
  prompt, True, optimizer=optimizer, conversationally=conversationally
1299
- ):
1300
- yield self.get_message(response)
1275
+ )
1276
+ async for response in async_ask:
1277
+ yield await self.get_message(response)
1301
1278
 
1302
- def for_non_stream():
1303
- return self.get_message(
1304
- self.ask(
1279
+ async def for_non_stream():
1280
+ return await self.get_message(
1281
+ await self.ask(
1305
1282
  prompt,
1306
1283
  False,
1307
1284
  optimizer=optimizer,
@@ -1309,9 +1286,9 @@ class KOBOLDAI(Provider):
1309
1286
  )
1310
1287
  )
1311
1288
 
1312
- return for_stream() if stream else for_non_stream()
1289
+ return for_stream() if stream else await for_non_stream()
1313
1290
 
1314
- def get_message(self, response: dict) -> str:
1291
+ async def get_message(self, response: dict) -> str:
1315
1292
  """Retrieves message only from response
1316
1293
 
1317
1294
  Args:
@@ -1321,13 +1298,24 @@ class KOBOLDAI(Provider):
1321
1298
  str: Message extracted
1322
1299
  """
1323
1300
  assert isinstance(response, dict), "Response should be of dict data-type only"
1324
- return response.get("token")
1325
- #------------------------------------------------------OpenGPT-----------------------------------------------------------
1326
- class OPENGPT:
1301
+ try:
1302
+ if response["choices"][0].get("delta"):
1303
+ return response["choices"][0]["delta"]["content"]
1304
+ return response["choices"][0]["message"]["content"]
1305
+ except KeyError:
1306
+ return ""
1307
+ #----------------------------------------------------------OpenAI-----------------------------------
1308
+ class OPENAI(Provider):
1327
1309
  def __init__(
1328
1310
  self,
1311
+ api_key: str,
1329
1312
  is_conversation: bool = True,
1330
1313
  max_tokens: int = 600,
1314
+ temperature: float = 1,
1315
+ presence_penalty: int = 0,
1316
+ frequency_penalty: int = 0,
1317
+ top_p: float = 1,
1318
+ model: str = "gpt-3.5-turbo",
1331
1319
  timeout: int = 30,
1332
1320
  intro: str = None,
1333
1321
  filepath: str = None,
@@ -1336,11 +1324,17 @@ class OPENGPT:
1336
1324
  history_offset: int = 10250,
1337
1325
  act: str = None,
1338
1326
  ):
1339
- """Instantiates OPENGPT
1327
+ """Instantiates OPENAI
1340
1328
 
1341
1329
  Args:
1342
- is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True
1330
+ api_key (key): OpenAI's API key.
1331
+ is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True.
1343
1332
  max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
1333
+ temperature (float, optional): Charge of the generated text's randomness. Defaults to 1.
1334
+ presence_penalty (int, optional): Chances of topic being repeated. Defaults to 0.
1335
+ frequency_penalty (int, optional): Chances of word being repeated. Defaults to 0.
1336
+ top_p (float, optional): Sampling threshold during inference time. Defaults to 0.999.
1337
+ model (str, optional): LLM model name. Defaults to "gpt-3.5-turbo".
1344
1338
  timeout (int, optional): Http request timeout. Defaults to 30.
1345
1339
  intro (str, optional): Conversation introductory prompt. Defaults to None.
1346
1340
  filepath (str, optional): Path to file containing conversation history. Defaults to None.
@@ -1349,30 +1343,21 @@ class OPENGPT:
1349
1343
  history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
1350
1344
  act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
1351
1345
  """
1352
- self.session = requests.Session()
1353
- self.max_tokens_to_sample = max_tokens
1354
1346
  self.is_conversation = is_conversation
1355
- self.chat_endpoint = (
1356
- "https://opengpts-example-vz4y4ooboq-uc.a.run.app/runs/stream"
1357
- )
1347
+ self.max_tokens_to_sample = max_tokens
1348
+ self.api_key = api_key
1349
+ self.model = model
1350
+ self.temperature = temperature
1351
+ self.presence_penalty = presence_penalty
1352
+ self.frequency_penalty = frequency_penalty
1353
+ self.top_p = top_p
1354
+ self.chat_endpoint = "https://api.openai.com/v1/chat/completions"
1358
1355
  self.stream_chunk_size = 64
1359
1356
  self.timeout = timeout
1360
1357
  self.last_response = {}
1361
- self.assistant_id = "bca37014-6f97-4f2b-8928-81ea8d478d88"
1362
- self.authority = "opengpts-example-vz4y4ooboq-uc.a.run.app"
1363
-
1364
1358
  self.headers = {
1365
- "authority": self.authority,
1366
- "accept": "text/event-stream",
1367
- "accept-language": "en-US,en;q=0.7",
1368
- "cache-control": "no-cache",
1369
- "content-type": "application/json",
1370
- "origin": "https://opengpts-example-vz4y4ooboq-uc.a.run.app",
1371
- "pragma": "no-cache",
1372
- "referer": "https://opengpts-example-vz4y4ooboq-uc.a.run.app/",
1373
- "sec-fetch-site": "same-origin",
1374
- "sec-gpc": "1",
1375
- "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
1359
+ "Content-Type": "application/json",
1360
+ "Authorization": f"Bearer {self.api_key}",
1376
1361
  }
1377
1362
 
1378
1363
  self.__available_optimizers = (
@@ -1414,27 +1399,25 @@ class OPENGPT:
1414
1399
  dict : {}
1415
1400
  ```json
1416
1401
  {
1417
- "messages": [
1418
- {
1419
- "content": "Hello there",
1420
- "additional_kwargs": {},
1421
- "type": "human",
1422
- "example": false
1402
+ "id": "chatcmpl-TaREJpBZsRVQFRFic1wIA7Q7XfnaD",
1403
+ "object": "chat.completion",
1404
+ "created": 1704623244,
1405
+ "model": "gpt-3.5-turbo",
1406
+ "usage": {
1407
+ "prompt_tokens": 0,
1408
+ "completion_tokens": 0,
1409
+ "total_tokens": 0
1423
1410
  },
1411
+ "choices": [
1424
1412
  {
1425
- "content": "Hello! How can I assist you today?",
1426
- "additional_kwargs": {
1427
- "agent": {
1428
- "return_values": {
1429
- "output": "Hello! How can I assist you today?"
1430
- },
1431
- "log": "Hello! How can I assist you today?",
1432
- "type": "AgentFinish"
1433
- }
1413
+ "message": {
1414
+ "role": "assistant",
1415
+ "content": "Hello! How can I assist you today?"
1434
1416
  },
1435
- "type": "ai",
1436
- "example": false
1437
- }]
1417
+ "finish_reason": "stop",
1418
+ "index": 0
1419
+ }
1420
+ ]
1438
1421
  }
1439
1422
  ```
1440
1423
  """
@@ -1445,10 +1428,1301 @@ class OPENGPT:
1445
1428
  conversation_prompt if conversationally else prompt
1446
1429
  )
1447
1430
  else:
1448
- raise Exception(
1431
+ raise exceptions.FailedToGenerateResponseError(
1449
1432
  f"Optimizer is not one of {self.__available_optimizers}"
1450
1433
  )
1451
-
1434
+ self.session.headers.update(self.headers)
1435
+ payload = {
1436
+ "frequency_penalty": self.frequency_penalty,
1437
+ "messages": [{"content": conversation_prompt, "role": "user"}],
1438
+ "model": self.model,
1439
+ "presence_penalty": self.presence_penalty,
1440
+ "stream": stream,
1441
+ "temperature": self.temperature,
1442
+ "top_p": self.top_p,
1443
+ }
1444
+
1445
+ def for_stream():
1446
+ response = self.session.post(
1447
+ self.chat_endpoint, json=payload, stream=True, timeout=self.timeout
1448
+ )
1449
+ if not response.ok:
1450
+ raise exceptions.FailedToGenerateResponseError(
1451
+ f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
1452
+ )
1453
+
1454
+ message_load = ""
1455
+ for value in response.iter_lines(
1456
+ decode_unicode=True,
1457
+ delimiter="" if raw else "data:",
1458
+ chunk_size=self.stream_chunk_size,
1459
+ ):
1460
+ try:
1461
+ resp = json.loads(value)
1462
+ incomplete_message = self.get_message(resp)
1463
+ if incomplete_message:
1464
+ message_load += incomplete_message
1465
+ resp["choices"][0]["delta"]["content"] = message_load
1466
+ self.last_response.update(resp)
1467
+ yield value if raw else resp
1468
+ elif raw:
1469
+ yield value
1470
+ except json.decoder.JSONDecodeError:
1471
+ pass
1472
+ self.conversation.update_chat_history(
1473
+ prompt, self.get_message(self.last_response)
1474
+ )
1475
+
1476
+ def for_non_stream():
1477
+ response = self.session.post(
1478
+ self.chat_endpoint, json=payload, stream=False, timeout=self.timeout
1479
+ )
1480
+ if (
1481
+ not response.ok
1482
+ or not response.headers.get("Content-Type", "") == "application/json"
1483
+ ):
1484
+ raise exceptions.FailedToGenerateResponseError(
1485
+ f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
1486
+ )
1487
+ resp = response.json()
1488
+ self.last_response.update(resp)
1489
+ self.conversation.update_chat_history(
1490
+ prompt, self.get_message(self.last_response)
1491
+ )
1492
+ return resp
1493
+
1494
+ return for_stream() if stream else for_non_stream()
1495
+
1496
+ def chat(
1497
+ self,
1498
+ prompt: str,
1499
+ stream: bool = False,
1500
+ optimizer: str = None,
1501
+ conversationally: bool = False,
1502
+ ) -> str:
1503
+ """Generate response `str`
1504
+ Args:
1505
+ prompt (str): Prompt to be send.
1506
+ stream (bool, optional): Flag for streaming response. Defaults to False.
1507
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
1508
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
1509
+ Returns:
1510
+ str: Response generated
1511
+ """
1512
+
1513
+ def for_stream():
1514
+ for response in self.ask(
1515
+ prompt, True, optimizer=optimizer, conversationally=conversationally
1516
+ ):
1517
+ yield self.get_message(response)
1518
+
1519
+ def for_non_stream():
1520
+ return self.get_message(
1521
+ self.ask(
1522
+ prompt,
1523
+ False,
1524
+ optimizer=optimizer,
1525
+ conversationally=conversationally,
1526
+ )
1527
+ )
1528
+
1529
+ return for_stream() if stream else for_non_stream()
1530
+
1531
+ def get_message(self, response: dict) -> str:
1532
+ """Retrieves message only from response
1533
+
1534
+ Args:
1535
+ response (dict): Response generated by `self.ask`
1536
+
1537
+ Returns:
1538
+ str: Message extracted
1539
+ """
1540
+ assert isinstance(response, dict), "Response should be of dict data-type only"
1541
+ try:
1542
+ if response["choices"][0].get("delta"):
1543
+ return response["choices"][0]["delta"]["content"]
1544
+ return response["choices"][0]["message"]["content"]
1545
+ except KeyError:
1546
+ return ""
1547
+ class AsyncOPENAI(AsyncProvider):
1548
+ def __init__(
1549
+ self,
1550
+ api_key: str,
1551
+ is_conversation: bool = True,
1552
+ max_tokens: int = 600,
1553
+ temperature: float = 1,
1554
+ presence_penalty: int = 0,
1555
+ frequency_penalty: int = 0,
1556
+ top_p: float = 1,
1557
+ model: str = "gpt-3.5-turbo",
1558
+ timeout: int = 30,
1559
+ intro: str = None,
1560
+ filepath: str = None,
1561
+ update_file: bool = True,
1562
+ proxies: dict = {},
1563
+ history_offset: int = 10250,
1564
+ act: str = None,
1565
+ ):
1566
+ """Instantiates OPENAI
1567
+
1568
+ Args:
1569
+ api_key (key): OpenAI's API key.
1570
+ is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True.
1571
+ max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
1572
+ temperature (float, optional): Charge of the generated text's randomness. Defaults to 1.
1573
+ presence_penalty (int, optional): Chances of topic being repeated. Defaults to 0.
1574
+ frequency_penalty (int, optional): Chances of word being repeated. Defaults to 0.
1575
+ top_p (float, optional): Sampling threshold during inference time. Defaults to 0.999.
1576
+ model (str, optional): LLM model name. Defaults to "gpt-3.5-turbo".
1577
+ timeout (int, optional): Http request timeout. Defaults to 30.
1578
+ intro (str, optional): Conversation introductory prompt. Defaults to None.
1579
+ filepath (str, optional): Path to file containing conversation history. Defaults to None.
1580
+ update_file (bool, optional): Add new prompts and responses to the file. Defaults to True.
1581
+ proxies (dict, optional): Http request proxies. Defaults to {}.
1582
+ history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
1583
+ act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
1584
+ """
1585
+ self.is_conversation = is_conversation
1586
+ self.max_tokens_to_sample = max_tokens
1587
+ self.api_key = api_key
1588
+ self.model = model
1589
+ self.temperature = temperature
1590
+ self.presence_penalty = presence_penalty
1591
+ self.frequency_penalty = frequency_penalty
1592
+ self.top_p = top_p
1593
+ self.chat_endpoint = "https://api.openai.com/v1/chat/completions"
1594
+ self.stream_chunk_size = 64
1595
+ self.timeout = timeout
1596
+ self.last_response = {}
1597
+ self.headers = {
1598
+ "Content-Type": "application/json",
1599
+ "Authorization": f"Bearer {self.api_key}",
1600
+ }
1601
+
1602
+ self.__available_optimizers = (
1603
+ method
1604
+ for method in dir(Optimizers)
1605
+ if callable(getattr(Optimizers, method)) and not method.startswith("__")
1606
+ )
1607
+ Conversation.intro = (
1608
+ AwesomePrompts().get_act(
1609
+ act, raise_not_found=True, default=None, case_insensitive=True
1610
+ )
1611
+ if act
1612
+ else intro or Conversation.intro
1613
+ )
1614
+ self.conversation = Conversation(
1615
+ is_conversation, self.max_tokens_to_sample, filepath, update_file
1616
+ )
1617
+ self.conversation.history_offset = history_offset
1618
+ self.session = httpx.AsyncClient(
1619
+ headers=self.headers,
1620
+ proxies=proxies,
1621
+ )
1622
+
1623
+ async def ask(
1624
+ self,
1625
+ prompt: str,
1626
+ stream: bool = False,
1627
+ raw: bool = False,
1628
+ optimizer: str = None,
1629
+ conversationally: bool = False,
1630
+ ) -> dict | AsyncGenerator:
1631
+ """Chat with AI asynchronously.
1632
+
1633
+ Args:
1634
+ prompt (str): Prompt to be send.
1635
+ stream (bool, optional): Flag for streaming response. Defaults to False.
1636
+ raw (bool, optional): Stream back raw response as received. Defaults to False.
1637
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
1638
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
1639
+ Returns:
1640
+ dict|AsyncGenerator : ai content.
1641
+ ```json
1642
+ {
1643
+ "id": "chatcmpl-TaREJpBZsRVQFRFic1wIA7Q7XfnaD",
1644
+ "object": "chat.completion",
1645
+ "created": 1704623244,
1646
+ "model": "gpt-3.5-turbo",
1647
+ "usage": {
1648
+ "prompt_tokens": 0,
1649
+ "completion_tokens": 0,
1650
+ "total_tokens": 0
1651
+ },
1652
+ "choices": [
1653
+ {
1654
+ "message": {
1655
+ "role": "assistant",
1656
+ "content": "Hello! How can I assist you today?"
1657
+ },
1658
+ "finish_reason": "stop",
1659
+ "index": 0
1660
+ }
1661
+ ]
1662
+ }
1663
+ ```
1664
+ """
1665
+ conversation_prompt = self.conversation.gen_complete_prompt(prompt)
1666
+ if optimizer:
1667
+ if optimizer in self.__available_optimizers:
1668
+ conversation_prompt = getattr(Optimizers, optimizer)(
1669
+ conversation_prompt if conversationally else prompt
1670
+ )
1671
+ else:
1672
+ raise Exception(
1673
+ f"Optimizer is not one of {self.__available_optimizers}"
1674
+ )
1675
+ payload = {
1676
+ "frequency_penalty": self.frequency_penalty,
1677
+ "messages": [{"content": conversation_prompt, "role": "user"}],
1678
+ "model": self.model,
1679
+ "presence_penalty": self.presence_penalty,
1680
+ "stream": stream,
1681
+ "temperature": self.temperature,
1682
+ "top_p": self.top_p,
1683
+ }
1684
+
1685
+ async def for_stream():
1686
+ async with self.session.stream(
1687
+ "POST", self.chat_endpoint, json=payload, timeout=self.timeout
1688
+ ) as response:
1689
+ if not response.is_success:
1690
+ raise Exception(
1691
+ f"Failed to generate response - ({response.status_code}, {response.reason_phrase})"
1692
+ )
1693
+
1694
+ message_load = ""
1695
+ async for value in response.aiter_lines():
1696
+ try:
1697
+
1698
+ resp = sanitize_stream(value)
1699
+ incomplete_message = await self.get_message(resp)
1700
+ if incomplete_message:
1701
+ message_load += incomplete_message
1702
+ resp["choices"][0]["delta"]["content"] = message_load
1703
+ self.last_response.update(resp)
1704
+ yield value if raw else resp
1705
+ elif raw:
1706
+ yield value
1707
+ except json.decoder.JSONDecodeError:
1708
+ pass
1709
+ self.conversation.update_chat_history(
1710
+ prompt, await self.get_message(self.last_response)
1711
+ )
1712
+
1713
+ async def for_non_stream():
1714
+ response = httpx.post(
1715
+ self.chat_endpoint,
1716
+ json=payload,
1717
+ timeout=self.timeout,
1718
+ headers=self.headers,
1719
+ )
1720
+ if (
1721
+ not response.is_success
1722
+ or not response.headers.get("Content-Type", "") == "application/json"
1723
+ ):
1724
+ raise Exception(
1725
+ f"Failed to generate response - ({response.status_code}, {response.reason_phrase})"
1726
+ )
1727
+ resp = response.json()
1728
+ self.last_response.update(resp)
1729
+ self.conversation.update_chat_history(
1730
+ prompt, await self.get_message(self.last_response)
1731
+ )
1732
+ return resp
1733
+
1734
+ return for_stream() if stream else await for_non_stream()
1735
+
1736
+ async def chat(
1737
+ self,
1738
+ prompt: str,
1739
+ stream: bool = False,
1740
+ optimizer: str = None,
1741
+ conversationally: bool = False,
1742
+ ) -> str | AsyncGenerator:
1743
+ """Generate response `str` asynchronously.
1744
+ Args:
1745
+ prompt (str): Prompt to be send.
1746
+ stream (bool, optional): Flag for streaming response. Defaults to False.
1747
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
1748
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
1749
+ Returns:
1750
+ str|AsyncGenerator: Response generated
1751
+ """
1752
+
1753
+ async def for_stream():
1754
+ async_ask = await self.ask(
1755
+ prompt, True, optimizer=optimizer, conversationally=conversationally
1756
+ )
1757
+ async for response in async_ask:
1758
+ yield await self.get_message(response)
1759
+
1760
+ async def for_non_stream():
1761
+ return await self.get_message(
1762
+ await self.ask(
1763
+ prompt,
1764
+ False,
1765
+ optimizer=optimizer,
1766
+ conversationally=conversationally,
1767
+ )
1768
+ )
1769
+
1770
+ return for_stream() if stream else await for_non_stream()
1771
+
1772
+ async def get_message(self, response: dict) -> str:
1773
+ """Retrieves message only from response asynchronously.
1774
+
1775
+ Args:
1776
+ response (dict): Response generated by `self.ask`
1777
+
1778
+ Returns:
1779
+ str: Message extracted
1780
+ """
1781
+ assert isinstance(response, dict), "Response should be of dict data-type only"
1782
+ try:
1783
+ if response["choices"][0].get("delta"):
1784
+ return response["choices"][0]["delta"]["content"]
1785
+ return response["choices"][0]["message"]["content"]
1786
+ except KeyError:
1787
+ return ""
1788
+ #--------------------------------------LEO-----------------------------------------
1789
+ class LEO(Provider):
1790
+
1791
+ def __init__(
1792
+ self,
1793
+ is_conversation: bool = True,
1794
+ max_tokens: int = 600,
1795
+ temperature: float = 0.2,
1796
+ top_k: int = -1,
1797
+ top_p: float = 0.999,
1798
+ model: str = "llama-2-13b-chat",
1799
+ brave_key: str = "qztbjzBqJueQZLFkwTTJrieu8Vw3789u",
1800
+ timeout: int = 30,
1801
+ intro: str = None,
1802
+ filepath: str = None,
1803
+ update_file: bool = True,
1804
+ proxies: dict = {},
1805
+ history_offset: int = 10250,
1806
+ act: str = None,
1807
+ ):
1808
+ """Instantiate TGPT
1809
+
1810
+ Args:
1811
+ is_conversation (str, optional): Flag for chatting conversationally. Defaults to True.
1812
+ brave_key (str, optional): Brave API access key. Defaults to "qztbjzBqJueQZLFkwTTJrieu8Vw3789u".
1813
+ model (str, optional): Text generation model name. Defaults to "llama-2-13b-chat".
1814
+ max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
1815
+ temperature (float, optional): Charge of the generated text's randomness. Defaults to 0.2.
1816
+ top_k (int, optional): Chance of topic being repeated. Defaults to -1.
1817
+ top_p (float, optional): Sampling threshold during inference time. Defaults to 0.999.
1818
+ timeput (int, optional): Http requesting timeout. Defaults to 30
1819
+ intro (str, optional): Conversation introductory prompt. Defaults to `Conversation.intro`.
1820
+ filepath (str, optional): Path to file containing conversation history. Defaults to None.
1821
+ update_file (bool, optional): Add new prompts and responses to the file. Defaults to True.
1822
+ proxies (dict, optional) : Http reqiuest proxies (socks). Defaults to {}.
1823
+ history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
1824
+ act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
1825
+ """
1826
+ self.session = requests.Session()
1827
+ self.is_conversation = is_conversation
1828
+ self.max_tokens_to_sample = max_tokens
1829
+ self.model = model
1830
+ self.stop_sequences = ["</response>", "</s>"]
1831
+ self.temperature = temperature
1832
+ self.top_k = top_k
1833
+ self.top_p = top_p
1834
+ self.chat_endpoint = "https://ai-chat.bsg.brave.com/v1/complete"
1835
+ self.stream_chunk_size = 64
1836
+ self.timeout = timeout
1837
+ self.last_response = {}
1838
+ self.headers = {
1839
+ "Content-Type": "application/json",
1840
+ "accept": "text/event-stream",
1841
+ "x-brave-key": brave_key,
1842
+ "accept-language": "en-US,en;q=0.9",
1843
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/110.0",
1844
+ }
1845
+ self.__available_optimizers = (
1846
+ method
1847
+ for method in dir(Optimizers)
1848
+ if callable(getattr(Optimizers, method)) and not method.startswith("__")
1849
+ )
1850
+ self.session.headers.update(self.headers)
1851
+ Conversation.intro = (
1852
+ AwesomePrompts().get_act(
1853
+ act, raise_not_found=True, default=None, case_insensitive=True
1854
+ )
1855
+ if act
1856
+ else intro or Conversation.intro
1857
+ )
1858
+ self.conversation = Conversation(
1859
+ is_conversation, self.max_tokens_to_sample, filepath, update_file
1860
+ )
1861
+ self.conversation.history_offset = history_offset
1862
+ self.session.proxies = proxies
1863
+ self.system_prompt = (
1864
+ "\n\nYour name is Leo, a helpful"
1865
+ "respectful and honest AI assistant created by the company Brave. You will be replying to a user of the Brave browser. "
1866
+ "Always respond in a neutral tone. Be polite and courteous. Answer concisely in no more than 50-80 words."
1867
+ "\n\nPlease ensure that your responses are socially unbiased and positive in nature."
1868
+ "If a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. "
1869
+ "If you don't know the answer to a question, please don't share false information.\n"
1870
+ )
1871
+
1872
+ def ask(
1873
+ self,
1874
+ prompt: str,
1875
+ stream: bool = False,
1876
+ raw: bool = False,
1877
+ optimizer: str = None,
1878
+ conversationally: bool = False,
1879
+ ) -> dict:
1880
+ """Chat with AI
1881
+
1882
+ Args:
1883
+ prompt (str): Prompt to be send.
1884
+ stream (bool, optional): Flag for streaming response. Defaults to False.
1885
+ raw (bool, optional): Stream back raw response as received. Defaults to False.
1886
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
1887
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
1888
+ Returns:
1889
+ dict : {}
1890
+ ```json
1891
+ {
1892
+ "completion": "\nNext: domestic cat breeds with short hair >>",
1893
+ "stop_reason": null,
1894
+ "truncated": false,
1895
+ "stop": null,
1896
+ "model": "llama-2-13b-chat",
1897
+ "log_id": "cmpl-3kYiYxSNDvgMShSzFooz6t",
1898
+ "exception": null
1899
+ }
1900
+ ```
1901
+ """
1902
+ conversation_prompt = self.conversation.gen_complete_prompt(prompt)
1903
+ if optimizer:
1904
+ if optimizer in self.__available_optimizers:
1905
+ conversation_prompt = getattr(Optimizers, optimizer)(
1906
+ conversation_prompt if conversationally else prompt
1907
+ )
1908
+ else:
1909
+ raise Exception(
1910
+ f"Optimizer is not one of {self.__available_optimizers}"
1911
+ )
1912
+
1913
+ self.session.headers.update(self.headers)
1914
+ payload = {
1915
+ "max_tokens_to_sample": self.max_tokens_to_sample,
1916
+ "model": self.model,
1917
+ "prompt": f"<s>[INST] <<SYS>>{self.system_prompt}<</SYS>>{conversation_prompt} [/INST]",
1918
+ "self.stop_sequence": self.stop_sequences,
1919
+ "stream": stream,
1920
+ "top_k": self.top_k,
1921
+ "top_p": self.top_p,
1922
+ }
1923
+
1924
+ def for_stream():
1925
+ response = self.session.post(
1926
+ self.chat_endpoint, json=payload, stream=True, timeout=self.timeout
1927
+ )
1928
+ if (
1929
+ not response.ok
1930
+ or not response.headers.get("Content-Type")
1931
+ == "text/event-stream; charset=utf-8"
1932
+ ):
1933
+ raise Exception(
1934
+ f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
1935
+ )
1936
+
1937
+ for value in response.iter_lines(
1938
+ decode_unicode=True,
1939
+ delimiter="" if raw else "data:",
1940
+ chunk_size=self.stream_chunk_size,
1941
+ ):
1942
+ try:
1943
+ resp = json.loads(value)
1944
+ self.last_response.update(resp)
1945
+ yield value if raw else resp
1946
+ except json.decoder.JSONDecodeError:
1947
+ pass
1948
+ self.conversation.update_chat_history(
1949
+ prompt, self.get_message(self.last_response)
1950
+ )
1951
+
1952
+ def for_non_stream():
1953
+ response = self.session.post(
1954
+ self.chat_endpoint, json=payload, stream=False, timeout=self.timeout
1955
+ )
1956
+ if (
1957
+ not response.ok
1958
+ or not response.headers.get("Content-Type", "") == "application/json"
1959
+ ):
1960
+ raise Exception(
1961
+ f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
1962
+ )
1963
+ resp = response.json()
1964
+ self.last_response.update(resp)
1965
+ self.conversation.update_chat_history(
1966
+ prompt, self.get_message(self.last_response)
1967
+ )
1968
+ return resp
1969
+
1970
+ return for_stream() if stream else for_non_stream()
1971
+
1972
+ def chat(
1973
+ self,
1974
+ prompt: str,
1975
+ stream: bool = False,
1976
+ optimizer: str = None,
1977
+ conversationally: bool = False,
1978
+ ) -> str:
1979
+ """Generate response `str`
1980
+ Args:
1981
+ prompt (str): Prompt to be send.
1982
+ stream (bool, optional): Flag for streaming response. Defaults to False.
1983
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
1984
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
1985
+ Returns:
1986
+ str: Response generated
1987
+ """
1988
+
1989
+ def for_stream():
1990
+ for response in self.ask(
1991
+ prompt, True, optimizer=optimizer, conversationally=conversationally
1992
+ ):
1993
+ yield self.get_message(response)
1994
+
1995
+ def for_non_stream():
1996
+ return self.get_message(
1997
+ self.ask(
1998
+ prompt,
1999
+ False,
2000
+ optimizer=optimizer,
2001
+ conversationally=conversationally,
2002
+ )
2003
+ )
2004
+
2005
+ return for_stream() if stream else for_non_stream()
2006
+
2007
+ def get_message(self, response: dict) -> str:
2008
+ """Retrieves message only from response
2009
+
2010
+ Args:
2011
+ response (dict): Response generated by `self.ask`
2012
+
2013
+ Returns:
2014
+ str: Message extracted
2015
+ """
2016
+ assert isinstance(response, dict), "Response should be of dict data-type only"
2017
+ return response.get("completion")
2018
+ class AsyncLEO(AsyncProvider):
2019
+ def __init__(
2020
+ self,
2021
+ is_conversation: bool = True,
2022
+ max_tokens: int = 600,
2023
+ temperature: float = 0.2,
2024
+ top_k: int = -1,
2025
+ top_p: float = 0.999,
2026
+ model: str = "llama-2-13b-chat",
2027
+ brave_key: str = "qztbjzBqJueQZLFkwTTJrieu8Vw3789u",
2028
+ timeout: int = 30,
2029
+ intro: str = None,
2030
+ filepath: str = None,
2031
+ update_file: bool = True,
2032
+ proxies: dict = {},
2033
+ history_offset: int = 10250,
2034
+ act: str = None,
2035
+ ):
2036
+ """Instantiate TGPT
2037
+
2038
+ Args:
2039
+ is_conversation (str, optional): Flag for chatting conversationally. Defaults to True.
2040
+ brave_key (str, optional): Brave API access key. Defaults to "qztbjzBqJueQZLFkwTTJrieu8Vw3789u".
2041
+ model (str, optional): Text generation model name. Defaults to "llama-2-13b-chat".
2042
+ max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
2043
+ temperature (float, optional): Charge of the generated text's randomness. Defaults to 0.2.
2044
+ top_k (int, optional): Chance of topic being repeated. Defaults to -1.
2045
+ top_p (float, optional): Sampling threshold during inference time. Defaults to 0.999.
2046
+ timeput (int, optional): Http requesting timeout. Defaults to 30
2047
+ intro (str, optional): Conversation introductory prompt. Defaults to `Conversation.intro`.
2048
+ filepath (str, optional): Path to file containing conversation history. Defaults to None.
2049
+ update_file (bool, optional): Add new prompts and responses to the file. Defaults to True.
2050
+ proxies (dict, optional) : Http reqiuest proxies (socks). Defaults to {}.
2051
+ history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
2052
+ act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
2053
+ """
2054
+ self.is_conversation = is_conversation
2055
+ self.max_tokens_to_sample = max_tokens
2056
+ self.model = model
2057
+ self.stop_sequences = ["</response>", "</s>"]
2058
+ self.temperature = temperature
2059
+ self.top_k = top_k
2060
+ self.top_p = top_p
2061
+ self.chat_endpoint = "https://ai-chat.bsg.brave.com/v1/complete"
2062
+ self.stream_chunk_size = 64
2063
+ self.timeout = timeout
2064
+ self.last_response = {}
2065
+ self.headers = {
2066
+ "Content-Type": "application/json",
2067
+ "accept": "text/event-stream",
2068
+ "x-brave-key": brave_key,
2069
+ "accept-language": "en-US,en;q=0.9",
2070
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/110.0",
2071
+ }
2072
+ self.__available_optimizers = (
2073
+ method
2074
+ for method in dir(Optimizers)
2075
+ if callable(getattr(Optimizers, method)) and not method.startswith("__")
2076
+ )
2077
+ Conversation.intro = (
2078
+ AwesomePrompts().get_act(
2079
+ act, raise_not_found=True, default=None, case_insensitive=True
2080
+ )
2081
+ if act
2082
+ else intro or Conversation.intro
2083
+ )
2084
+ self.conversation = Conversation(
2085
+ is_conversation, self.max_tokens_to_sample, filepath, update_file
2086
+ )
2087
+ self.conversation.history_offset = history_offset
2088
+ self.system_prompt = (
2089
+ "\n\nYour name is Leo, a helpful"
2090
+ "respectful and honest AI assistant created by the company Brave. You will be replying to a user of the Brave browser. "
2091
+ "Always respond in a neutral tone. Be polite and courteous. Answer concisely in no more than 50-80 words."
2092
+ "\n\nPlease ensure that your responses are socially unbiased and positive in nature."
2093
+ "If a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. "
2094
+ "If you don't know the answer to a question, please don't share false information.\n"
2095
+ )
2096
+ self.session = httpx.AsyncClient(headers=self.headers, proxies=proxies)
2097
+
2098
+ async def ask(
2099
+ self,
2100
+ prompt: str,
2101
+ stream: bool = False,
2102
+ raw: bool = False,
2103
+ optimizer: str = None,
2104
+ conversationally: bool = False,
2105
+ ) -> dict | AsyncGenerator:
2106
+ """Chat with AI asynchronously.
2107
+
2108
+ Args:
2109
+ prompt (str): Prompt to be send.
2110
+ stream (bool, optional): Flag for streaming response. Defaults to False.
2111
+ raw (bool, optional): Stream back raw response as received. Defaults to False.
2112
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
2113
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
2114
+ Returns:
2115
+ dict|AsyncGenerator : ai content
2116
+ ```json
2117
+ {
2118
+ "completion": "\nNext: domestic cat breeds with short hair >>",
2119
+ "stop_reason": null,
2120
+ "truncated": false,
2121
+ "stop": null,
2122
+ "model": "llama-2-13b-chat",
2123
+ "log_id": "cmpl-3kYiYxSNDvgMShSzFooz6t",
2124
+ "exception": null
2125
+ }
2126
+ ```
2127
+ """
2128
+ conversation_prompt = self.conversation.gen_complete_prompt(prompt)
2129
+ if optimizer:
2130
+ if optimizer in self.__available_optimizers:
2131
+ conversation_prompt = getattr(Optimizers, optimizer)(
2132
+ conversation_prompt if conversationally else prompt
2133
+ )
2134
+ else:
2135
+ raise Exception(
2136
+ f"Optimizer is not one of {self.__available_optimizers}"
2137
+ )
2138
+
2139
+ payload = {
2140
+ "max_tokens_to_sample": self.max_tokens_to_sample,
2141
+ "model": self.model,
2142
+ "prompt": f"<s>[INST] <<SYS>>{self.system_prompt}<</SYS>>{conversation_prompt} [/INST]",
2143
+ "self.stop_sequence": self.stop_sequences,
2144
+ "stream": stream,
2145
+ "top_k": self.top_k,
2146
+ "top_p": self.top_p,
2147
+ }
2148
+
2149
+ async def for_stream():
2150
+ async with self.session.stream(
2151
+ "POST", self.chat_endpoint, json=payload, timeout=self.timeout
2152
+ ) as response:
2153
+ if (
2154
+ not response.is_success
2155
+ or not response.headers.get("Content-Type")
2156
+ == "text/event-stream; charset=utf-8"
2157
+ ):
2158
+ raise exceptions.FailedToGenerateResponseError(
2159
+ f"Failed to generate response - ({response.status_code}, {response.reason_phrase})"
2160
+ )
2161
+ async for value in response.aiter_lines():
2162
+ try:
2163
+ resp = sanitize_stream(value)
2164
+ self.last_response.update(resp)
2165
+ yield value if raw else resp
2166
+ except json.decoder.JSONDecodeError:
2167
+ pass
2168
+
2169
+ self.conversation.update_chat_history(
2170
+ prompt, await self.get_message(self.last_response)
2171
+ )
2172
+
2173
+ async def for_non_stream():
2174
+ async for _ in for_stream():
2175
+ pass
2176
+ return self.last_response
2177
+
2178
+ return for_stream() if stream else await for_non_stream()
2179
+
2180
+ async def chat(
2181
+ self,
2182
+ prompt: str,
2183
+ stream: bool = False,
2184
+ optimizer: str = None,
2185
+ conversationally: bool = False,
2186
+ ) -> str | AsyncGenerator:
2187
+ """Generate response `str` asynchronously.
2188
+ Args:
2189
+ prompt (str): Prompt to be send.
2190
+ stream (bool, optional): Flag for streaming response. Defaults to False.
2191
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
2192
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
2193
+ Returns:
2194
+ str|AsyncGenerator: Response generated
2195
+ """
2196
+
2197
+ async def for_stream():
2198
+ async_ask = await self.ask(
2199
+ prompt, True, optimizer=optimizer, conversationally=conversationally
2200
+ )
2201
+ async for response in async_ask:
2202
+ yield await self.get_message(response)
2203
+
2204
+ async def for_non_stream():
2205
+ return await self.get_message(
2206
+ await self.ask(
2207
+ prompt,
2208
+ False,
2209
+ optimizer=optimizer,
2210
+ conversationally=conversationally,
2211
+ )
2212
+ )
2213
+
2214
+ return for_stream() if stream else await for_non_stream()
2215
+
2216
+ async def get_message(self, response: dict) -> str:
2217
+ """Retrieves message only from response
2218
+
2219
+ Args:
2220
+ response (dict): Response generated by `self.ask`
2221
+
2222
+ Returns:
2223
+ str: Message extracted
2224
+ """
2225
+ assert isinstance(response, dict), "Response should be of dict data-type only"
2226
+ return response.get("completion")
2227
+ #------------------------------------------------------KOBOLDAI-----------------------------------------------------------
2228
+ class KOBOLDAI(Provider):
2229
+ def __init__(
2230
+ self,
2231
+ is_conversation: bool = True,
2232
+ max_tokens: int = 600,
2233
+ temperature: float = 1,
2234
+ top_p: float = 1,
2235
+ timeout: int = 30,
2236
+ intro: str = None,
2237
+ filepath: str = None,
2238
+ update_file: bool = True,
2239
+ proxies: dict = {},
2240
+ history_offset: int = 10250,
2241
+ act: str = None,
2242
+ ):
2243
+ """Instantiate TGPT
2244
+
2245
+ Args:
2246
+ is_conversation (str, optional): Flag for chatting conversationally. Defaults to True.
2247
+ max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
2248
+ temperature (float, optional): Charge of the generated text's randomness. Defaults to 0.2.
2249
+ top_p (float, optional): Sampling threshold during inference time. Defaults to 0.999.
2250
+ timeout (int, optional): Http requesting timeout. Defaults to 30
2251
+ intro (str, optional): Conversation introductory prompt. Defaults to `Conversation.intro`.
2252
+ filepath (str, optional): Path to file containing conversation history. Defaults to None.
2253
+ update_file (bool, optional): Add new prompts and responses to the file. Defaults to True.
2254
+ proxies (dict, optional) : Http reqiuest proxies (socks). Defaults to {}.
2255
+ history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
2256
+ act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
2257
+ """
2258
+ self.session = requests.Session()
2259
+ self.is_conversation = is_conversation
2260
+ self.max_tokens_to_sample = max_tokens
2261
+ self.temperature = temperature
2262
+ self.top_p = top_p
2263
+ self.chat_endpoint = (
2264
+ "https://koboldai-koboldcpp-tiefighter.hf.space/api/extra/generate/stream"
2265
+ )
2266
+ self.stream_chunk_size = 64
2267
+ self.timeout = timeout
2268
+ self.last_response = {}
2269
+ self.headers = {
2270
+ "Content-Type": "application/json",
2271
+ "Accept": "application/json",
2272
+ }
2273
+
2274
+ self.__available_optimizers = (
2275
+ method
2276
+ for method in dir(Optimizers)
2277
+ if callable(getattr(Optimizers, method)) and not method.startswith("__")
2278
+ )
2279
+ self.session.headers.update(self.headers)
2280
+ Conversation.intro = (
2281
+ AwesomePrompts().get_act(
2282
+ act, raise_not_found=True, default=None, case_insensitive=True
2283
+ )
2284
+ if act
2285
+ else intro or Conversation.intro
2286
+ )
2287
+ self.conversation = Conversation(
2288
+ is_conversation, self.max_tokens_to_sample, filepath, update_file
2289
+ )
2290
+ self.conversation.history_offset = history_offset
2291
+ self.session.proxies = proxies
2292
+
2293
+ def ask(
2294
+ self,
2295
+ prompt: str,
2296
+ stream: bool = False,
2297
+ raw: bool = False,
2298
+ optimizer: str = None,
2299
+ conversationally: bool = False,
2300
+ ) -> dict:
2301
+ """Chat with AI
2302
+
2303
+ Args:
2304
+ prompt (str): Prompt to be send.
2305
+ stream (bool, optional): Flag for streaming response. Defaults to False.
2306
+ raw (bool, optional): Stream back raw response as received. Defaults to False.
2307
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
2308
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
2309
+ Returns:
2310
+ dict : {}
2311
+ ```json
2312
+ {
2313
+ "token" : "How may I assist you today?"
2314
+ }
2315
+ ```
2316
+ """
2317
+ conversation_prompt = self.conversation.gen_complete_prompt(prompt)
2318
+ if optimizer:
2319
+ if optimizer in self.__available_optimizers:
2320
+ conversation_prompt = getattr(Optimizers, optimizer)(
2321
+ conversation_prompt if conversationally else prompt
2322
+ )
2323
+ else:
2324
+ raise Exception(
2325
+ f"Optimizer is not one of {self.__available_optimizers}"
2326
+ )
2327
+
2328
+ self.session.headers.update(self.headers)
2329
+ payload = {
2330
+ "prompt": conversation_prompt,
2331
+ "temperature": self.temperature,
2332
+ "top_p": self.top_p,
2333
+ }
2334
+
2335
+ def for_stream():
2336
+ response = self.session.post(
2337
+ self.chat_endpoint, json=payload, stream=True, timeout=self.timeout
2338
+ )
2339
+ if not response.ok:
2340
+ raise Exception(
2341
+ f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
2342
+ )
2343
+
2344
+ message_load = ""
2345
+ for value in response.iter_lines(
2346
+ decode_unicode=True,
2347
+ delimiter="" if raw else "event: message\ndata:",
2348
+ chunk_size=self.stream_chunk_size,
2349
+ ):
2350
+ try:
2351
+ resp = json.loads(value)
2352
+ message_load += self.get_message(resp)
2353
+ resp["token"] = message_load
2354
+ self.last_response.update(resp)
2355
+ yield value if raw else resp
2356
+ except json.decoder.JSONDecodeError:
2357
+ pass
2358
+ self.conversation.update_chat_history(
2359
+ prompt, self.get_message(self.last_response)
2360
+ )
2361
+
2362
+ def for_non_stream():
2363
+ # let's make use of stream
2364
+ for _ in for_stream():
2365
+ pass
2366
+ return self.last_response
2367
+
2368
+ return for_stream() if stream else for_non_stream()
2369
+
2370
+ def chat(
2371
+ self,
2372
+ prompt: str,
2373
+ stream: bool = False,
2374
+ optimizer: str = None,
2375
+ conversationally: bool = False,
2376
+ ) -> str:
2377
+ """Generate response `str`
2378
+ Args:
2379
+ prompt (str): Prompt to be send.
2380
+ stream (bool, optional): Flag for streaming response. Defaults to False.
2381
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
2382
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
2383
+ Returns:
2384
+ str: Response generated
2385
+ """
2386
+
2387
+ def for_stream():
2388
+ for response in self.ask(
2389
+ prompt, True, optimizer=optimizer, conversationally=conversationally
2390
+ ):
2391
+ yield self.get_message(response)
2392
+
2393
+ def for_non_stream():
2394
+ return self.get_message(
2395
+ self.ask(
2396
+ prompt,
2397
+ False,
2398
+ optimizer=optimizer,
2399
+ conversationally=conversationally,
2400
+ )
2401
+ )
2402
+
2403
+ return for_stream() if stream else for_non_stream()
2404
+
2405
+ def get_message(self, response: dict) -> str:
2406
+ """Retrieves message only from response
2407
+
2408
+ Args:
2409
+ response (dict): Response generated by `self.ask`
2410
+
2411
+ Returns:
2412
+ str: Message extracted
2413
+ """
2414
+ assert isinstance(response, dict), "Response should be of dict data-type only"
2415
+ return response.get("token")
2416
+ class AsyncKOBOLDAI(AsyncProvider):
2417
+ def __init__(
2418
+ self,
2419
+ is_conversation: bool = True,
2420
+ max_tokens: int = 600,
2421
+ temperature: float = 1,
2422
+ top_p: float = 1,
2423
+ timeout: int = 30,
2424
+ intro: str = None,
2425
+ filepath: str = None,
2426
+ update_file: bool = True,
2427
+ proxies: dict = {},
2428
+ history_offset: int = 10250,
2429
+ act: str = None,
2430
+ ):
2431
+ """Instantiate TGPT
2432
+
2433
+ Args:
2434
+ is_conversation (str, optional): Flag for chatting conversationally. Defaults to True.
2435
+ max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
2436
+ temperature (float, optional): Charge of the generated text's randomness. Defaults to 0.2.
2437
+ top_p (float, optional): Sampling threshold during inference time. Defaults to 0.999.
2438
+ timeout (int, optional): Http requesting timeout. Defaults to 30
2439
+ intro (str, optional): Conversation introductory prompt. Defaults to `Conversation.intro`.
2440
+ filepath (str, optional): Path to file containing conversation history. Defaults to None.
2441
+ update_file (bool, optional): Add new prompts and responses to the file. Defaults to True.
2442
+ proxies (dict, optional) : Http reqiuest proxies (socks). Defaults to {}.
2443
+ history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
2444
+ act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
2445
+ """
2446
+ self.is_conversation = is_conversation
2447
+ self.max_tokens_to_sample = max_tokens
2448
+ self.temperature = temperature
2449
+ self.top_p = top_p
2450
+ self.chat_endpoint = (
2451
+ "https://koboldai-koboldcpp-tiefighter.hf.space/api/extra/generate/stream"
2452
+ )
2453
+ self.stream_chunk_size = 64
2454
+ self.timeout = timeout
2455
+ self.last_response = {}
2456
+ self.headers = {
2457
+ "Content-Type": "application/json",
2458
+ "Accept": "application/json",
2459
+ }
2460
+
2461
+ self.__available_optimizers = (
2462
+ method
2463
+ for method in dir(Optimizers)
2464
+ if callable(getattr(Optimizers, method)) and not method.startswith("__")
2465
+ )
2466
+ Conversation.intro = (
2467
+ AwesomePrompts().get_act(
2468
+ act, raise_not_found=True, default=None, case_insensitive=True
2469
+ )
2470
+ if act
2471
+ else intro or Conversation.intro
2472
+ )
2473
+ self.conversation = Conversation(
2474
+ is_conversation, self.max_tokens_to_sample, filepath, update_file
2475
+ )
2476
+ self.conversation.history_offset = history_offset
2477
+ self.session = httpx.AsyncClient(headers=self.headers, proxies=proxies)
2478
+
2479
+ async def ask(
2480
+ self,
2481
+ prompt: str,
2482
+ stream: bool = False,
2483
+ raw: bool = False,
2484
+ optimizer: str = None,
2485
+ conversationally: bool = False,
2486
+ ) -> dict | AsyncGenerator:
2487
+ """Chat with AI asynchronously.
2488
+
2489
+ Args:
2490
+ prompt (str): Prompt to be send.
2491
+ stream (bool, optional): Flag for streaming response. Defaults to False.
2492
+ raw (bool, optional): Stream back raw response as received. Defaults to False.
2493
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
2494
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
2495
+ Returns:
2496
+ dict|AsyncGenerator : ai content
2497
+ ```json
2498
+ {
2499
+ "token" : "How may I assist you today?"
2500
+ }
2501
+ ```
2502
+ """
2503
+ conversation_prompt = self.conversation.gen_complete_prompt(prompt)
2504
+ if optimizer:
2505
+ if optimizer in self.__available_optimizers:
2506
+ conversation_prompt = getattr(Optimizers, optimizer)(
2507
+ conversation_prompt if conversationally else prompt
2508
+ )
2509
+ else:
2510
+ raise Exception(
2511
+ f"Optimizer is not one of {self.__available_optimizers}"
2512
+ )
2513
+
2514
+ payload = {
2515
+ "prompt": conversation_prompt,
2516
+ "temperature": self.temperature,
2517
+ "top_p": self.top_p,
2518
+ }
2519
+
2520
+ async def for_stream():
2521
+ async with self.session.stream(
2522
+ "POST", self.chat_endpoint, json=payload, timeout=self.timeout
2523
+ ) as response:
2524
+ if not response.is_success:
2525
+ raise exceptions.FailedToGenerateResponseError(
2526
+ f"Failed to generate response - ({response.status_code}, {response.reason_phrase})"
2527
+ )
2528
+
2529
+ message_load = ""
2530
+ async for value in response.aiter_lines():
2531
+ try:
2532
+ resp = sanitize_stream(value)
2533
+ message_load += await self.get_message(resp)
2534
+ resp["token"] = message_load
2535
+ self.last_response.update(resp)
2536
+ yield value if raw else resp
2537
+ except json.decoder.JSONDecodeError:
2538
+ pass
2539
+
2540
+ self.conversation.update_chat_history(
2541
+ prompt, await self.get_message(self.last_response)
2542
+ )
2543
+
2544
+ async def for_non_stream():
2545
+ # let's make use of stream
2546
+ async for _ in for_stream():
2547
+ pass
2548
+ return self.last_response
2549
+
2550
+ return for_stream() if stream else await for_non_stream()
2551
+
2552
+ async def chat(
2553
+ self,
2554
+ prompt: str,
2555
+ stream: bool = False,
2556
+ optimizer: str = None,
2557
+ conversationally: bool = False,
2558
+ ) -> str | AsyncGenerator:
2559
+ """Generate response `str` asynchronously.
2560
+ Args:
2561
+ prompt (str): Prompt to be send.
2562
+ stream (bool, optional): Flag for streaming response. Defaults to False.
2563
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
2564
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
2565
+ Returns:
2566
+ str: Response generated
2567
+ """
2568
+
2569
+ async def for_stream():
2570
+ async_ask = await self.ask(
2571
+ prompt, True, optimizer=optimizer, conversationally=conversationally
2572
+ )
2573
+ async for response in async_ask:
2574
+ yield await self.get_message(response)
2575
+
2576
+ async def for_non_stream():
2577
+ return await self.get_message(
2578
+ await self.ask(
2579
+ prompt,
2580
+ False,
2581
+ optimizer=optimizer,
2582
+ conversationally=conversationally,
2583
+ )
2584
+ )
2585
+
2586
+ return for_stream() if stream else await for_non_stream()
2587
+
2588
+ async def get_message(self, response: dict) -> str:
2589
+ """Retrieves message only from response
2590
+
2591
+ Args:
2592
+ response (dict): Response generated by `self.ask`
2593
+
2594
+ Returns:
2595
+ str: Message extracted
2596
+ """
2597
+ assert isinstance(response, dict), "Response should be of dict data-type only"
2598
+ return response.get("token")
2599
+ #------------------------------------------------------OpenGPT-----------------------------------------------------------
2600
+ class OPENGPT:
2601
+ def __init__(
2602
+ self,
2603
+ is_conversation: bool = True,
2604
+ max_tokens: int = 600,
2605
+ timeout: int = 30,
2606
+ intro: str = None,
2607
+ filepath: str = None,
2608
+ update_file: bool = True,
2609
+ proxies: dict = {},
2610
+ history_offset: int = 10250,
2611
+ act: str = None,
2612
+ ):
2613
+ """Instantiates OPENGPT
2614
+
2615
+ Args:
2616
+ is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True
2617
+ max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
2618
+ timeout (int, optional): Http request timeout. Defaults to 30.
2619
+ intro (str, optional): Conversation introductory prompt. Defaults to None.
2620
+ filepath (str, optional): Path to file containing conversation history. Defaults to None.
2621
+ update_file (bool, optional): Add new prompts and responses to the file. Defaults to True.
2622
+ proxies (dict, optional): Http request proxies. Defaults to {}.
2623
+ history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
2624
+ act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
2625
+ """
2626
+ self.session = requests.Session()
2627
+ self.max_tokens_to_sample = max_tokens
2628
+ self.is_conversation = is_conversation
2629
+ self.chat_endpoint = (
2630
+ "https://opengpts-example-vz4y4ooboq-uc.a.run.app/runs/stream"
2631
+ )
2632
+ self.stream_chunk_size = 64
2633
+ self.timeout = timeout
2634
+ self.last_response = {}
2635
+ self.assistant_id = "bca37014-6f97-4f2b-8928-81ea8d478d88"
2636
+ self.authority = "opengpts-example-vz4y4ooboq-uc.a.run.app"
2637
+
2638
+ self.headers = {
2639
+ "authority": self.authority,
2640
+ "accept": "text/event-stream",
2641
+ "accept-language": "en-US,en;q=0.7",
2642
+ "cache-control": "no-cache",
2643
+ "content-type": "application/json",
2644
+ "origin": "https://opengpts-example-vz4y4ooboq-uc.a.run.app",
2645
+ "pragma": "no-cache",
2646
+ "referer": "https://opengpts-example-vz4y4ooboq-uc.a.run.app/",
2647
+ "sec-fetch-site": "same-origin",
2648
+ "sec-gpc": "1",
2649
+ "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
2650
+ }
2651
+
2652
+ self.__available_optimizers = (
2653
+ method
2654
+ for method in dir(Optimizers)
2655
+ if callable(getattr(Optimizers, method)) and not method.startswith("__")
2656
+ )
2657
+ self.session.headers.update(self.headers)
2658
+ Conversation.intro = (
2659
+ AwesomePrompts().get_act(
2660
+ act, raise_not_found=True, default=None, case_insensitive=True
2661
+ )
2662
+ if act
2663
+ else intro or Conversation.intro
2664
+ )
2665
+ self.conversation = Conversation(
2666
+ is_conversation, self.max_tokens_to_sample, filepath, update_file
2667
+ )
2668
+ self.conversation.history_offset = history_offset
2669
+ self.session.proxies = proxies
2670
+
2671
+ def ask(
2672
+ self,
2673
+ prompt: str,
2674
+ stream: bool = False,
2675
+ raw: bool = False,
2676
+ optimizer: str = None,
2677
+ conversationally: bool = False,
2678
+ ) -> dict:
2679
+ """Chat with AI
2680
+
2681
+ Args:
2682
+ prompt (str): Prompt to be send.
2683
+ stream (bool, optional): Flag for streaming response. Defaults to False.
2684
+ raw (bool, optional): Stream back raw response as received. Defaults to False.
2685
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
2686
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
2687
+ Returns:
2688
+ dict : {}
2689
+ ```json
2690
+ {
2691
+ "messages": [
2692
+ {
2693
+ "content": "Hello there",
2694
+ "additional_kwargs": {},
2695
+ "type": "human",
2696
+ "example": false
2697
+ },
2698
+ {
2699
+ "content": "Hello! How can I assist you today?",
2700
+ "additional_kwargs": {
2701
+ "agent": {
2702
+ "return_values": {
2703
+ "output": "Hello! How can I assist you today?"
2704
+ },
2705
+ "log": "Hello! How can I assist you today?",
2706
+ "type": "AgentFinish"
2707
+ }
2708
+ },
2709
+ "type": "ai",
2710
+ "example": false
2711
+ }]
2712
+ }
2713
+ ```
2714
+ """
2715
+ conversation_prompt = self.conversation.gen_complete_prompt(prompt)
2716
+ if optimizer:
2717
+ if optimizer in self.__available_optimizers:
2718
+ conversation_prompt = getattr(Optimizers, optimizer)(
2719
+ conversation_prompt if conversationally else prompt
2720
+ )
2721
+ else:
2722
+ raise Exception(
2723
+ f"Optimizer is not one of {self.__available_optimizers}"
2724
+ )
2725
+
1452
2726
  self.session.headers.update(self.headers)
1453
2727
  self.session.headers.update(
1454
2728
  dict(
@@ -1456,16 +2730,1062 @@ class OPENGPT:
1456
2730
  )
1457
2731
  )
1458
2732
  payload = {
1459
- "input": [
1460
- {
1461
- "content": conversation_prompt,
1462
- "additional_kwargs": {},
1463
- "type": "human",
1464
- "example": False,
1465
- },
2733
+ "input": [
2734
+ {
2735
+ "content": conversation_prompt,
2736
+ "additional_kwargs": {},
2737
+ "type": "human",
2738
+ "example": False,
2739
+ },
2740
+ ],
2741
+ "assistant_id": self.assistant_id,
2742
+ "thread_id": "",
2743
+ }
2744
+
2745
+ def for_stream():
2746
+ response = self.session.post(
2747
+ self.chat_endpoint, json=payload, stream=True, timeout=self.timeout
2748
+ )
2749
+ if (
2750
+ not response.ok
2751
+ or not response.headers.get("Content-Type")
2752
+ == "text/event-stream; charset=utf-8"
2753
+ ):
2754
+ raise Exception(
2755
+ f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
2756
+ )
2757
+
2758
+ for value in response.iter_lines(
2759
+ decode_unicode=True,
2760
+ chunk_size=self.stream_chunk_size,
2761
+ ):
2762
+ try:
2763
+ modified_value = re.sub("data:", "", value)
2764
+ resp = json.loads(modified_value)
2765
+ if len(resp) == 1:
2766
+ continue
2767
+ self.last_response.update(resp[1])
2768
+ yield value if raw else resp[1]
2769
+ except json.decoder.JSONDecodeError:
2770
+ pass
2771
+ self.conversation.update_chat_history(
2772
+ prompt, self.get_message(self.last_response)
2773
+ )
2774
+
2775
+ def for_non_stream():
2776
+ for _ in for_stream():
2777
+ pass
2778
+ return self.last_response
2779
+
2780
+ return for_stream() if stream else for_non_stream()
2781
+
2782
+ def chat(
2783
+ self,
2784
+ prompt: str,
2785
+ stream: bool = False,
2786
+ optimizer: str = None,
2787
+ conversationally: bool = False,
2788
+ ) -> str:
2789
+ """Generate response `str`
2790
+ Args:
2791
+ prompt (str): Prompt to be send.
2792
+ stream (bool, optional): Flag for streaming response. Defaults to False.
2793
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
2794
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
2795
+ Returns:
2796
+ str: Response generated
2797
+ """
2798
+
2799
+ def for_stream():
2800
+ for response in self.ask(
2801
+ prompt, True, optimizer=optimizer, conversationally=conversationally
2802
+ ):
2803
+ yield self.get_message(response)
2804
+
2805
+ def for_non_stream():
2806
+ return self.get_message(
2807
+ self.ask(
2808
+ prompt,
2809
+ False,
2810
+ optimizer=optimizer,
2811
+ conversationally=conversationally,
2812
+ )
2813
+ )
2814
+
2815
+ return for_stream() if stream else for_non_stream()
2816
+
2817
+ def get_message(self, response: dict) -> str:
2818
+ """Retrieves message only from response
2819
+
2820
+ Args:
2821
+ response (dict): Response generated by `self.ask`
2822
+
2823
+ Returns:
2824
+ str: Message extracted
2825
+ """
2826
+ assert isinstance(response, dict), "Response should be of dict data-type only"
2827
+ return response["content"]
2828
+ class AsyncOPENGPT(AsyncProvider):
2829
+ def __init__(
2830
+ self,
2831
+ is_conversation: bool = True,
2832
+ max_tokens: int = 600,
2833
+ timeout: int = 30,
2834
+ intro: str = None,
2835
+ filepath: str = None,
2836
+ update_file: bool = True,
2837
+ proxies: dict = {},
2838
+ history_offset: int = 10250,
2839
+ act: str = None,
2840
+ ):
2841
+ """Instantiates OPENGPT
2842
+
2843
+ Args:
2844
+ is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True
2845
+ max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
2846
+ timeout (int, optional): Http request timeout. Defaults to 30.
2847
+ intro (str, optional): Conversation introductory prompt. Defaults to None.
2848
+ filepath (str, optional): Path to file containing conversation history. Defaults to None.
2849
+ update_file (bool, optional): Add new prompts and responses to the file. Defaults to True.
2850
+ proxies (dict, optional): Http request proxies. Defaults to {}.
2851
+ history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
2852
+ act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
2853
+ """
2854
+ self.max_tokens_to_sample = max_tokens
2855
+ self.is_conversation = is_conversation
2856
+ self.chat_endpoint = (
2857
+ "https://opengpts-example-vz4y4ooboq-uc.a.run.app/runs/stream"
2858
+ )
2859
+ self.stream_chunk_size = 64
2860
+ self.timeout = timeout
2861
+ self.last_response = {}
2862
+ self.assistant_id = "bca37014-6f97-4f2b-8928-81ea8d478d88"
2863
+ self.authority = "opengpts-example-vz4y4ooboq-uc.a.run.app"
2864
+
2865
+ self.headers = {
2866
+ "authority": self.authority,
2867
+ "accept": "text/event-stream",
2868
+ "accept-language": "en-US,en;q=0.7",
2869
+ "cache-control": "no-cache",
2870
+ "content-type": "application/json",
2871
+ "origin": "https://opengpts-example-vz4y4ooboq-uc.a.run.app",
2872
+ "pragma": "no-cache",
2873
+ "referer": "https://opengpts-example-vz4y4ooboq-uc.a.run.app/",
2874
+ "sec-fetch-site": "same-origin",
2875
+ "sec-gpc": "1",
2876
+ "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
2877
+ }
2878
+
2879
+ self.__available_optimizers = (
2880
+ method
2881
+ for method in dir(Optimizers)
2882
+ if callable(getattr(Optimizers, method)) and not method.startswith("__")
2883
+ )
2884
+ Conversation.intro = (
2885
+ AwesomePrompts().get_act(
2886
+ act, raise_not_found=True, default=None, case_insensitive=True
2887
+ )
2888
+ if act
2889
+ else intro or Conversation.intro
2890
+ )
2891
+ self.conversation = Conversation(
2892
+ is_conversation, self.max_tokens_to_sample, filepath, update_file
2893
+ )
2894
+ self.conversation.history_offset = history_offset
2895
+ self.session = httpx.AsyncClient(headers=self.headers, proxies=proxies)
2896
+
2897
+ async def ask(
2898
+ self,
2899
+ prompt: str,
2900
+ stream: bool = False,
2901
+ raw: bool = False,
2902
+ optimizer: str = None,
2903
+ conversationally: bool = False,
2904
+ ) -> dict | AsyncGenerator:
2905
+ """Chat with AI asynchronously
2906
+
2907
+ Args:
2908
+ prompt (str): Prompt to be send.
2909
+ stream (bool, optional): Flag for streaming response. Defaults to False.
2910
+ raw (bool, optional): Stream back raw response as received. Defaults to False.
2911
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
2912
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
2913
+ Returns:
2914
+ dict|AsyncGenerator : ai content.
2915
+ ```json
2916
+ {
2917
+ "messages": [
2918
+ {
2919
+ "content": "Hello there",
2920
+ "additional_kwargs": {},
2921
+ "type": "human",
2922
+ "example": false
2923
+ },
2924
+ {
2925
+ "content": "Hello! How can I assist you today?",
2926
+ "additional_kwargs": {
2927
+ "agent": {
2928
+ "return_values": {
2929
+ "output": "Hello! How can I assist you today?"
2930
+ },
2931
+ "log": "Hello! How can I assist you today?",
2932
+ "type": "AgentFinish"
2933
+ }
2934
+ },
2935
+ "type": "ai",
2936
+ "example": false
2937
+ }]
2938
+ }
2939
+ ```
2940
+ """
2941
+ conversation_prompt = self.conversation.gen_complete_prompt(prompt)
2942
+ if optimizer:
2943
+ if optimizer in self.__available_optimizers:
2944
+ conversation_prompt = getattr(Optimizers, optimizer)(
2945
+ conversation_prompt if conversationally else prompt
2946
+ )
2947
+ else:
2948
+ raise Exception(
2949
+ f"Optimizer is not one of {self.__available_optimizers}"
2950
+ )
2951
+ self.headers.update(
2952
+ dict(
2953
+ cookie=f"opengpts_user_id={uuid4().__str__()}",
2954
+ )
2955
+ )
2956
+ payload = {
2957
+ "input": [
2958
+ {
2959
+ "content": conversation_prompt,
2960
+ "additional_kwargs": {},
2961
+ "type": "human",
2962
+ "example": False,
2963
+ },
2964
+ ],
2965
+ "assistant_id": self.assistant_id,
2966
+ "thread_id": "",
2967
+ }
2968
+
2969
+ async def for_stream():
2970
+ async with self.session.stream(
2971
+ "POST",
2972
+ self.chat_endpoint,
2973
+ json=payload,
2974
+ timeout=self.timeout,
2975
+ headers=self.headers,
2976
+ ) as response:
2977
+ if (
2978
+ not response.is_success
2979
+ or not response.headers.get("Content-Type")
2980
+ == "text/event-stream; charset=utf-8"
2981
+ ):
2982
+ raise exceptions.FailedToGenerateResponseError(
2983
+ f"Failed to generate response - ({response.status_code}, {response.reason_phrase}) - {response.text}"
2984
+ )
2985
+
2986
+ async for value in response.aiter_lines():
2987
+ try:
2988
+ modified_value = re.sub("data:", "", value)
2989
+ resp = json.loads(modified_value)
2990
+ if len(resp) == 1:
2991
+ continue
2992
+ self.last_response.update(resp[1])
2993
+ yield value if raw else resp[1]
2994
+ except json.decoder.JSONDecodeError:
2995
+ pass
2996
+
2997
+ self.conversation.update_chat_history(
2998
+ prompt, await self.get_message(self.last_response)
2999
+ )
3000
+
3001
+ async def for_non_stream():
3002
+ async for _ in for_stream():
3003
+ pass
3004
+ return self.last_response
3005
+
3006
+ return for_stream() if stream else await for_non_stream()
3007
+
3008
+ async def chat(
3009
+ self,
3010
+ prompt: str,
3011
+ stream: bool = False,
3012
+ optimizer: str = None,
3013
+ conversationally: bool = False,
3014
+ ) -> str | AsyncGenerator:
3015
+ """Generate response `str` asynchronously.
3016
+ Args:
3017
+ prompt (str): Prompt to be send.
3018
+ stream (bool, optional): Flag for streaming response. Defaults to False.
3019
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
3020
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
3021
+ Returns:
3022
+ str|AsyncGenerator: Response generated
3023
+ """
3024
+
3025
+ async def for_stream():
3026
+ async_ask = await self.ask(
3027
+ prompt, True, optimizer=optimizer, conversationally=conversationally
3028
+ )
3029
+ async for response in async_ask:
3030
+ yield await self.get_message(response)
3031
+
3032
+ async def for_non_stream():
3033
+ return await self.get_message(
3034
+ await self.ask(
3035
+ prompt,
3036
+ False,
3037
+ optimizer=optimizer,
3038
+ conversationally=conversationally,
3039
+ )
3040
+ )
3041
+
3042
+ return for_stream() if stream else await for_non_stream()
3043
+
3044
+ async def get_message(self, response: dict) -> str:
3045
+ """Retrieves message only from response
3046
+
3047
+ Args:
3048
+ response (dict): Response generated by `self.ask`
3049
+
3050
+ Returns:
3051
+ str: Message extracted
3052
+ """
3053
+ assert isinstance(response, dict), "Response should be of dict data-type only"
3054
+ return response["content"]
3055
+ #------------------------------------------------------PERPLEXITY--------------------------------------------------------
3056
+ class PERPLEXITY(Provider):
3057
+ def __init__(
3058
+ self,
3059
+ is_conversation: bool = True,
3060
+ max_tokens: int = 600,
3061
+ timeout: int = 30,
3062
+ intro: str = None,
3063
+ filepath: str = None,
3064
+ update_file: bool = True,
3065
+ proxies: dict = {},
3066
+ history_offset: int = 10250,
3067
+ act: str = None,
3068
+ quiet: bool = False,
3069
+ ):
3070
+ """Instantiates PERPLEXITY
3071
+
3072
+ Args:
3073
+ is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True
3074
+ max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
3075
+ timeout (int, optional): Http request timeout. Defaults to 30.
3076
+ intro (str, optional): Conversation introductory prompt. Defaults to None.
3077
+ filepath (str, optional): Path to file containing conversation history. Defaults to None.
3078
+ update_file (bool, optional): Add new prompts and responses to the file. Defaults to True.
3079
+ proxies (dict, optional): Http request proxies. Defaults to {}.
3080
+ history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
3081
+ act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
3082
+ quiet (bool, optional): Ignore web search-results and yield final response only. Defaults to False.
3083
+ """
3084
+ self.max_tokens_to_sample = max_tokens
3085
+ self.is_conversation = is_conversation
3086
+ self.last_response = {}
3087
+ self.web_results: dict = {}
3088
+ self.quiet = quiet
3089
+
3090
+ self.__available_optimizers = (
3091
+ method
3092
+ for method in dir(Optimizers)
3093
+ if callable(getattr(Optimizers, method)) and not method.startswith("__")
3094
+ )
3095
+ Conversation.intro = (
3096
+ AwesomePrompts().get_act(
3097
+ act, raise_not_found=True, default=None, case_insensitive=True
3098
+ )
3099
+ if act
3100
+ else intro or Conversation.intro
3101
+ )
3102
+ self.conversation = Conversation(
3103
+ is_conversation, self.max_tokens_to_sample, filepath, update_file
3104
+ )
3105
+ self.conversation.history_offset = history_offset
3106
+
3107
+ def ask(
3108
+ self,
3109
+ prompt: str,
3110
+ stream: bool = False,
3111
+ raw: bool = False,
3112
+ optimizer: str = None,
3113
+ conversationally: bool = False,
3114
+ ) -> dict:
3115
+ """Chat with AI
3116
+
3117
+ Args:
3118
+ prompt (str): Prompt to be send.
3119
+ stream (bool, optional): Flag for streaming response. Defaults to False.
3120
+ raw (bool, optional): Stream back raw response as received. Defaults to False.
3121
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
3122
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
3123
+ Returns:
3124
+ dict : {}
3125
+ ```json
3126
+ {
3127
+ "status": "pending",
3128
+ "uuid": "3604dfcc-611f-4b7d-989d-edca2a7233c7",
3129
+ "read_write_token": null,
3130
+ "frontend_context_uuid": "f6d43119-5231-481d-b692-f52e1f52d2c6",
3131
+ "final": false,
3132
+ "backend_uuid": "a6d6ec9e-da69-4841-af74-0de0409267a8",
3133
+ "media_items": [],
3134
+ "widget_data": [],
3135
+ "knowledge_cards": [],
3136
+ "expect_search_results": "false",
3137
+ "mode": "concise",
3138
+ "search_focus": "internet",
3139
+ "gpt4": false,
3140
+ "display_model": "turbo",
3141
+ "attachments": null,
3142
+ "answer": "",
3143
+ "web_results": [],
3144
+ "chunks": [],
3145
+ "extra_web_results": []
3146
+ }
3147
+ ```
3148
+ """
3149
+ conversation_prompt = self.conversation.gen_complete_prompt(prompt)
3150
+ if optimizer:
3151
+ if optimizer in self.__available_optimizers:
3152
+ conversation_prompt = getattr(Optimizers, optimizer)(
3153
+ conversation_prompt if conversationally else prompt
3154
+ )
3155
+ else:
3156
+ raise Exception(
3157
+ f"Optimizer is not one of {self.__available_optimizers}"
3158
+ )
3159
+
3160
+ def for_stream():
3161
+ for response in Perplexity().generate_answer(conversation_prompt):
3162
+ yield json.dumps(response) if raw else response
3163
+ self.last_response.update(response)
3164
+
3165
+ self.conversation.update_chat_history(
3166
+ prompt,
3167
+ self.get_message(self.last_response),
3168
+ )
3169
+
3170
+ def for_non_stream():
3171
+ for _ in for_stream():
3172
+ pass
3173
+ return self.last_response
3174
+
3175
+ return for_stream() if stream else for_non_stream()
3176
+
3177
+ def chat(
3178
+ self,
3179
+ prompt: str,
3180
+ stream: bool = False,
3181
+ optimizer: str = None,
3182
+ conversationally: bool = False,
3183
+ ) -> str:
3184
+ """Generate response `str`
3185
+ Args:
3186
+ prompt (str): Prompt to be send.
3187
+ stream (bool, optional): Flag for streaming response. Defaults to False.
3188
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
3189
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
3190
+ Returns:
3191
+ str: Response generated
3192
+ """
3193
+
3194
+ def for_stream():
3195
+ for response in self.ask(
3196
+ prompt, True, optimizer=optimizer, conversationally=conversationally
3197
+ ):
3198
+ yield self.get_message(response)
3199
+
3200
+ def for_non_stream():
3201
+ return self.get_message(
3202
+ self.ask(
3203
+ prompt,
3204
+ False,
3205
+ optimizer=optimizer,
3206
+ conversationally=conversationally,
3207
+ )
3208
+ )
3209
+
3210
+ return for_stream() if stream else for_non_stream()
3211
+
3212
+ def get_message(self, response: dict) -> str:
3213
+ """Retrieves message only from response
3214
+
3215
+ Args:
3216
+ response (dict): Response generated by `self.ask`
3217
+
3218
+ Returns:
3219
+ str: Message extracted
3220
+ """
3221
+ assert isinstance(response, dict), "Response should be of dict data-type only"
3222
+ text_str: str = response.get("answer", "")
3223
+
3224
+ def update_web_results(web_results: list) -> None:
3225
+ for index, results in enumerate(web_results, start=1):
3226
+ self.web_results[str(index) + ". " + results["name"]] = dict(
3227
+ url=results.get("url"), snippet=results.get("snippet")
3228
+ )
3229
+
3230
+ if response.get("text"):
3231
+ # last chunk
3232
+ target: dict[str, Any] = json.loads(response.get("text"))
3233
+ text_str = target.get("answer")
3234
+ web_results: list[dict] = target.get("web_results")
3235
+ self.web_results.clear()
3236
+ update_web_results(web_results)
3237
+
3238
+ return (
3239
+ text_str
3240
+ if self.quiet or not self.web_results
3241
+ else text_str + "\n\n# WEB-RESULTS\n\n" + yaml.dump(self.web_results)
3242
+ )
3243
+
3244
+ else:
3245
+ if str(response.get("expect_search_results")).lower() == "true":
3246
+ return (
3247
+ text_str
3248
+ if self.quiet
3249
+ else text_str
3250
+ + "\n\n# WEB-RESULTS\n\n"
3251
+ + yaml.dump(response.get("web_results"))
3252
+ )
3253
+ else:
3254
+ return text_str
3255
+ #------------------------------------------------------BLACKBOXAI--------------------------------------------------------
3256
+ class BLACKBOXAI:
3257
+ def __init__(
3258
+ self,
3259
+ is_conversation: bool = True,
3260
+ max_tokens: int = 8000,
3261
+ timeout: int = 30,
3262
+ intro: str = None,
3263
+ filepath: str = None,
3264
+ update_file: bool = True,
3265
+ proxies: dict = {},
3266
+ history_offset: int = 10250,
3267
+ act: str = None,
3268
+ model: str = None,
3269
+ ):
3270
+ """Instantiates BLACKBOXAI
3271
+
3272
+ Args:
3273
+ is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True
3274
+ max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
3275
+ timeout (int, optional): Http request timeout. Defaults to 30.
3276
+ intro (str, optional): Conversation introductory prompt. Defaults to None.
3277
+ filepath (str, optional): Path to file containing conversation history. Defaults to None.
3278
+ update_file (bool, optional): Add new prompts and responses to the file. Defaults to True.
3279
+ proxies (dict, optional): Http request proxies. Defaults to {}.
3280
+ history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
3281
+ act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
3282
+ model (str, optional): Model name. Defaults to "Phind Model".
3283
+ """
3284
+ self.session = requests.Session()
3285
+ self.max_tokens_to_sample = max_tokens
3286
+ self.is_conversation = is_conversation
3287
+ self.chat_endpoint = "https://www.blackbox.ai/api/chat"
3288
+ self.stream_chunk_size = 64
3289
+ self.timeout = timeout
3290
+ self.last_response = {}
3291
+ self.model = model
3292
+ self.previewToken: str = None
3293
+ self.userId: str = ""
3294
+ self.codeModelMode: bool = True
3295
+ self.id: str = ""
3296
+ self.agentMode: dict = {}
3297
+ self.trendingAgentMode: dict = {}
3298
+ self.isMicMode: bool = False
3299
+
3300
+ self.headers = {
3301
+ "Content-Type": "application/json",
3302
+ "User-Agent": "",
3303
+ "Accept": "*/*",
3304
+ "Accept-Encoding": "Identity",
3305
+ }
3306
+
3307
+ self.__available_optimizers = (
3308
+ method
3309
+ for method in dir(Optimizers)
3310
+ if callable(getattr(Optimizers, method)) and not method.startswith("__")
3311
+ )
3312
+ self.session.headers.update(self.headers)
3313
+ Conversation.intro = (
3314
+ AwesomePrompts().get_act(
3315
+ act, raise_not_found=True, default=None, case_insensitive=True
3316
+ )
3317
+ if act
3318
+ else intro or Conversation.intro
3319
+ )
3320
+ self.conversation = Conversation(
3321
+ is_conversation, self.max_tokens_to_sample, filepath, update_file
3322
+ )
3323
+ self.conversation.history_offset = history_offset
3324
+ self.session.proxies = proxies
3325
+
3326
+ def ask(
3327
+ self,
3328
+ prompt: str,
3329
+ stream: bool = False,
3330
+ raw: bool = False,
3331
+ optimizer: str = None,
3332
+ conversationally: bool = False,
3333
+ ) -> dict:
3334
+ """Chat with AI
3335
+
3336
+ Args:
3337
+ prompt (str): Prompt to be send.
3338
+ stream (bool, optional): Flag for streaming response. Defaults to False.
3339
+ raw (bool, optional): Stream back raw response as received. Defaults to False.
3340
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
3341
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
3342
+ Returns:
3343
+ dict : {}
3344
+ ```json
3345
+ {
3346
+ "text" : "print('How may I help you today?')"
3347
+ }
3348
+ ```
3349
+ """
3350
+ conversation_prompt = self.conversation.gen_complete_prompt(prompt)
3351
+ if optimizer:
3352
+ if optimizer in self.__available_optimizers:
3353
+ conversation_prompt = getattr(Optimizers, optimizer)(
3354
+ conversation_prompt if conversationally else prompt
3355
+ )
3356
+ else:
3357
+ raise Exception(
3358
+ f"Optimizer is not one of {self.__available_optimizers}"
3359
+ )
3360
+
3361
+ self.session.headers.update(self.headers)
3362
+ payload = {
3363
+ "messages": [
3364
+ # json.loads(prev_messages),
3365
+ {"content": conversation_prompt, "role": "user"}
3366
+ ],
3367
+ "id": self.id,
3368
+ "previewToken": self.previewToken,
3369
+ "userId": self.userId,
3370
+ "codeModelMode": self.codeModelMode,
3371
+ "agentMode": self.agentMode,
3372
+ "trendingAgentMode": self.trendingAgentMode,
3373
+ "isMicMode": self.isMicMode,
3374
+ }
3375
+
3376
+ def for_stream():
3377
+ response = self.session.post(
3378
+ self.chat_endpoint, json=payload, stream=True, timeout=self.timeout
3379
+ )
3380
+ if (
3381
+ not response.ok
3382
+ or not response.headers.get("Content-Type")
3383
+ == "text/plain; charset=utf-8"
3384
+ ):
3385
+ raise Exception(
3386
+ f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
3387
+ )
3388
+ streaming_text = ""
3389
+ for value in response.iter_lines(
3390
+ decode_unicode=True,
3391
+ chunk_size=self.stream_chunk_size,
3392
+ delimiter="\n",
3393
+ ):
3394
+ try:
3395
+ if bool(value):
3396
+ streaming_text += value + ("\n" if stream else "")
3397
+
3398
+ resp = dict(text=streaming_text)
3399
+ self.last_response.update(resp)
3400
+ yield value if raw else resp
3401
+ except json.decoder.JSONDecodeError:
3402
+ pass
3403
+ self.conversation.update_chat_history(
3404
+ prompt, self.get_message(self.last_response)
3405
+ )
3406
+
3407
+ def for_non_stream():
3408
+ for _ in for_stream():
3409
+ pass
3410
+ return self.last_response
3411
+
3412
+ return for_stream() if stream else for_non_stream()
3413
+
3414
+ def chat(
3415
+ self,
3416
+ prompt: str,
3417
+ stream: bool = False,
3418
+ optimizer: str = None,
3419
+ conversationally: bool = False,
3420
+ ) -> str:
3421
+ """Generate response `str`
3422
+ Args:
3423
+ prompt (str): Prompt to be send.
3424
+ stream (bool, optional): Flag for streaming response. Defaults to False.
3425
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
3426
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
3427
+ Returns:
3428
+ str: Response generated
3429
+ """
3430
+
3431
+ def for_stream():
3432
+ for response in self.ask(
3433
+ prompt, True, optimizer=optimizer, conversationally=conversationally
3434
+ ):
3435
+ yield self.get_message(response)
3436
+
3437
+ def for_non_stream():
3438
+ return self.get_message(
3439
+ self.ask(
3440
+ prompt,
3441
+ False,
3442
+ optimizer=optimizer,
3443
+ conversationally=conversationally,
3444
+ )
3445
+ )
3446
+
3447
+ return for_stream() if stream else for_non_stream()
3448
+
3449
+ def get_message(self, response: dict) -> str:
3450
+ """Retrieves message only from response
3451
+
3452
+ Args:
3453
+ response (dict): Response generated by `self.ask`
3454
+
3455
+ Returns:
3456
+ str: Message extracted
3457
+ """
3458
+ assert isinstance(response, dict), "Response should be of dict data-type only"
3459
+ return response["text"]
3460
+ @staticmethod
3461
+ def chat_cli(prompt):
3462
+ """Sends a request to the BLACKBOXAI API and processes the response."""
3463
+ blackbox_ai = BLACKBOXAI() # Initialize a BLACKBOXAI instance
3464
+ response = blackbox_ai.ask(prompt) # Perform a chat with the given prompt
3465
+ processed_response = blackbox_ai.get_message(response) # Process the response
3466
+ print(processed_response)
3467
+ class AsyncBLACKBOXAI(AsyncProvider):
3468
+ def __init__(
3469
+ self,
3470
+ is_conversation: bool = True,
3471
+ max_tokens: int = 600,
3472
+ timeout: int = 30,
3473
+ intro: str = None,
3474
+ filepath: str = None,
3475
+ update_file: bool = True,
3476
+ proxies: dict = {},
3477
+ history_offset: int = 10250,
3478
+ act: str = None,
3479
+ model: str = None,
3480
+ ):
3481
+ """Instantiates BLACKBOXAI
3482
+
3483
+ Args:
3484
+ is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True
3485
+ max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
3486
+ timeout (int, optional): Http request timeout. Defaults to 30.
3487
+ intro (str, optional): Conversation introductory prompt. Defaults to None.
3488
+ filepath (str, optional): Path to file containing conversation history. Defaults to None.
3489
+ update_file (bool, optional): Add new prompts and responses to the file. Defaults to True.
3490
+ proxies (dict, optional): Http request proxies. Defaults to {}.
3491
+ history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
3492
+ act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
3493
+ model (str, optional): Model name. Defaults to "Phind Model".
3494
+ """
3495
+ self.max_tokens_to_sample = max_tokens
3496
+ self.is_conversation = is_conversation
3497
+ self.chat_endpoint = "https://www.blackbox.ai/api/chat"
3498
+ self.stream_chunk_size = 64
3499
+ self.timeout = timeout
3500
+ self.last_response = {}
3501
+ self.model = model
3502
+ self.previewToken: str = None
3503
+ self.userId: str = ""
3504
+ self.codeModelMode: bool = True
3505
+ self.id: str = ""
3506
+ self.agentMode: dict = {}
3507
+ self.trendingAgentMode: dict = {}
3508
+ self.isMicMode: bool = False
3509
+
3510
+ self.headers = {
3511
+ "Content-Type": "application/json",
3512
+ "User-Agent": "",
3513
+ "Accept": "*/*",
3514
+ "Accept-Encoding": "Identity",
3515
+ }
3516
+
3517
+ self.__available_optimizers = (
3518
+ method
3519
+ for method in dir(Optimizers)
3520
+ if callable(getattr(Optimizers, method)) and not method.startswith("__")
3521
+ )
3522
+ Conversation.intro = (
3523
+ AwesomePrompts().get_act(
3524
+ act, raise_not_found=True, default=None, case_insensitive=True
3525
+ )
3526
+ if act
3527
+ else intro or Conversation.intro
3528
+ )
3529
+ self.conversation = Conversation(
3530
+ is_conversation, self.max_tokens_to_sample, filepath, update_file
3531
+ )
3532
+ self.conversation.history_offset = history_offset
3533
+ self.session = httpx.AsyncClient(headers=self.headers, proxies=proxies)
3534
+
3535
+ async def ask(
3536
+ self,
3537
+ prompt: str,
3538
+ stream: bool = False,
3539
+ raw: bool = False,
3540
+ optimizer: str = None,
3541
+ conversationally: bool = False,
3542
+ ) -> dict | AsyncGenerator:
3543
+ """Chat with AI asynchronously.
3544
+
3545
+ Args:
3546
+ prompt (str): Prompt to be send.
3547
+ stream (bool, optional): Flag for streaming response. Defaults to False.
3548
+ raw (bool, optional): Stream back raw response as received. Defaults to False.
3549
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
3550
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
3551
+ Returns:
3552
+ dict|AsyncGenerator : ai content
3553
+ ```json
3554
+ {
3555
+ "text" : "print('How may I help you today?')"
3556
+ }
3557
+ ```
3558
+ """
3559
+ conversation_prompt = self.conversation.gen_complete_prompt(prompt)
3560
+ if optimizer:
3561
+ if optimizer in self.__available_optimizers:
3562
+ conversation_prompt = getattr(Optimizers, optimizer)(
3563
+ conversation_prompt if conversationally else prompt
3564
+ )
3565
+ else:
3566
+ raise Exception(
3567
+ f"Optimizer is not one of {self.__available_optimizers}"
3568
+ )
3569
+
3570
+ payload = {
3571
+ "messages": [
3572
+ # json.loads(prev_messages),
3573
+ {"content": conversation_prompt, "role": "user"}
3574
+ ],
3575
+ "id": self.id,
3576
+ "previewToken": self.previewToken,
3577
+ "userId": self.userId,
3578
+ "codeModelMode": self.codeModelMode,
3579
+ "agentMode": self.agentMode,
3580
+ "trendingAgentMode": self.trendingAgentMode,
3581
+ "isMicMode": self.isMicMode,
3582
+ }
3583
+
3584
+ async def for_stream():
3585
+ async with self.session.stream(
3586
+ "POST", self.chat_endpoint, json=payload, timeout=self.timeout
3587
+ ) as response:
3588
+ if (
3589
+ not response.is_success
3590
+ or not response.headers.get("Content-Type")
3591
+ == "text/plain; charset=utf-8"
3592
+ ):
3593
+ raise exceptions.FailedToGenerateResponseError(
3594
+ f"Failed to generate response - ({response.status_code}, {response.reason_phrase})"
3595
+ )
3596
+ streaming_text = ""
3597
+ async for value in response.aiter_lines():
3598
+ try:
3599
+ if bool(value):
3600
+ streaming_text += value + ("\n" if stream else "")
3601
+ resp = dict(text=streaming_text)
3602
+ self.last_response.update(resp)
3603
+ yield value if raw else resp
3604
+ except json.decoder.JSONDecodeError:
3605
+ pass
3606
+ self.conversation.update_chat_history(
3607
+ prompt, await self.get_message(self.last_response)
3608
+ )
3609
+
3610
+ async def for_non_stream():
3611
+ async for _ in for_stream():
3612
+ pass
3613
+ return self.last_response
3614
+
3615
+ return for_stream() if stream else await for_non_stream()
3616
+
3617
+ async def chat(
3618
+ self,
3619
+ prompt: str,
3620
+ stream: bool = False,
3621
+ optimizer: str = None,
3622
+ conversationally: bool = False,
3623
+ ) -> str | AsyncGenerator:
3624
+ """Generate response `str` asynchronously.
3625
+ Args:
3626
+ prompt (str): Prompt to be send.
3627
+ stream (bool, optional): Flag for streaming response. Defaults to False.
3628
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
3629
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
3630
+ Returns:
3631
+ str|AsyncGenerator: Response generated
3632
+ """
3633
+
3634
+ async def for_stream():
3635
+ async_ask = await self.ask(
3636
+ prompt, True, optimizer=optimizer, conversationally=conversationally
3637
+ )
3638
+ async for response in async_ask:
3639
+ yield await self.get_message(response)
3640
+
3641
+ async def for_non_stream():
3642
+ return await self.get_message(
3643
+ await self.ask(
3644
+ prompt,
3645
+ False,
3646
+ optimizer=optimizer,
3647
+ conversationally=conversationally,
3648
+ )
3649
+ )
3650
+
3651
+ return for_stream() if stream else await for_non_stream()
3652
+
3653
+ async def get_message(self, response: dict) -> str:
3654
+ """Retrieves message only from response
3655
+
3656
+ Args:
3657
+ response (dict): Response generated by `self.ask`
3658
+
3659
+ Returns:
3660
+ str: Message extracted
3661
+ """
3662
+ assert isinstance(response, dict), "Response should be of dict data-type only"
3663
+ return response["text"]
3664
+ #------------------------------------------------------phind-------------------------------------------------------------
3665
+ class PhindSearch:
3666
+ # default_model = "Phind Model"
3667
+ def __init__(
3668
+ self,
3669
+ is_conversation: bool = True,
3670
+ max_tokens: int = 8000,
3671
+ timeout: int = 30,
3672
+ intro: str = None,
3673
+ filepath: str = None,
3674
+ update_file: bool = True,
3675
+ proxies: dict = {},
3676
+ history_offset: int = 10250,
3677
+ act: str = None,
3678
+ model: str = "Phind Model",
3679
+ quiet: bool = False,
3680
+ ):
3681
+ """Instantiates PHIND
3682
+
3683
+ Args:
3684
+ is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True
3685
+ max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
3686
+ timeout (int, optional): Http request timeout. Defaults to 30.
3687
+ intro (str, optional): Conversation introductory prompt. Defaults to None.
3688
+ filepath (str, optional): Path to file containing conversation history. Defaults to None.
3689
+ update_file (bool, optional): Add new prompts and responses to the file. Defaults to True.
3690
+ proxies (dict, optional): Http request proxies. Defaults to {}.
3691
+ history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
3692
+ act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
3693
+ model (str, optional): Model name. Defaults to "Phind Model".
3694
+ quiet (bool, optional): Ignore web search-results and yield final response only. Defaults to False.
3695
+ """
3696
+ self.session = requests.Session()
3697
+ self.max_tokens_to_sample = max_tokens
3698
+ self.is_conversation = is_conversation
3699
+ self.chat_endpoint = "https://https.extension.phind.com/agent/"
3700
+ self.stream_chunk_size = 64
3701
+ self.timeout = timeout
3702
+ self.last_response = {}
3703
+ self.model = model
3704
+ self.quiet = quiet
3705
+
3706
+ self.headers = {
3707
+ "Content-Type": "application/json",
3708
+ "User-Agent": "",
3709
+ "Accept": "*/*",
3710
+ "Accept-Encoding": "Identity",
3711
+ }
3712
+
3713
+ self.__available_optimizers = (
3714
+ method
3715
+ for method in dir(Optimizers)
3716
+ if callable(getattr(Optimizers, method)) and not method.startswith("__")
3717
+ )
3718
+ self.session.headers.update(self.headers)
3719
+ Conversation.intro = (
3720
+ AwesomePrompts().get_act(
3721
+ act, raise_not_found=True, default=None, case_insensitive=True
3722
+ )
3723
+ if act
3724
+ else intro or Conversation.intro
3725
+ )
3726
+ self.conversation = Conversation(
3727
+ is_conversation, self.max_tokens_to_sample, filepath, update_file
3728
+ )
3729
+ self.conversation.history_offset = history_offset
3730
+ self.session.proxies = proxies
3731
+
3732
+ def ask(
3733
+ self,
3734
+ prompt: str,
3735
+ stream: bool = False,
3736
+ raw: bool = False,
3737
+ optimizer: str = None,
3738
+ conversationally: bool = False,
3739
+ ) -> dict:
3740
+ """Chat with AI
3741
+
3742
+ Args:
3743
+ prompt (str): Prompt to be send.
3744
+ stream (bool, optional): Flag for streaming response. Defaults to False.
3745
+ raw (bool, optional): Stream back raw response as received. Defaults to False.
3746
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
3747
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
3748
+ Returns:
3749
+ dict : {}
3750
+ ```json
3751
+ {
3752
+ "id": "chatcmpl-r0wujizf2i2xb60mjiwt",
3753
+ "object": "chat.completion.chunk",
3754
+ "created": 1706775384,
3755
+ "model": "trt-llm-phind-model-serving",
3756
+ "choices": [
3757
+ {
3758
+ "index": 0,
3759
+ "delta": {
3760
+ "content": "Hello! How can I assist you with your programming today?"
3761
+ },
3762
+ "finish_reason": null
3763
+ }
3764
+ ]
3765
+ }
3766
+ ```
3767
+ """
3768
+ conversation_prompt = self.conversation.gen_complete_prompt(prompt)
3769
+ if optimizer:
3770
+ if optimizer in self.__available_optimizers:
3771
+ conversation_prompt = getattr(Optimizers, optimizer)(
3772
+ conversation_prompt if conversationally else prompt
3773
+ )
3774
+ else:
3775
+ raise Exception(
3776
+ f"Optimizer is not one of {self.__available_optimizers}"
3777
+ )
3778
+
3779
+ self.session.headers.update(self.headers)
3780
+ payload = {
3781
+ "additional_extension_context": "",
3782
+ "allow_magic_buttons": True,
3783
+ "is_vscode_extension": True,
3784
+ "message_history": [
3785
+ {"content": conversation_prompt, "metadata": {}, "role": "user"}
1466
3786
  ],
1467
- "assistant_id": self.assistant_id,
1468
- "thread_id": "",
3787
+ "requested_model": self.model,
3788
+ "user_input": prompt,
1469
3789
  }
1470
3790
 
1471
3791
  def for_stream():
@@ -1477,21 +3797,26 @@ class OPENGPT:
1477
3797
  or not response.headers.get("Content-Type")
1478
3798
  == "text/event-stream; charset=utf-8"
1479
3799
  ):
1480
- raise Exception(
3800
+ raise exceptions.FailedToGenerateResponseError(
1481
3801
  f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
1482
3802
  )
1483
-
3803
+ streaming_text = ""
1484
3804
  for value in response.iter_lines(
1485
3805
  decode_unicode=True,
1486
3806
  chunk_size=self.stream_chunk_size,
1487
3807
  ):
1488
3808
  try:
1489
3809
  modified_value = re.sub("data:", "", value)
1490
- resp = json.loads(modified_value)
1491
- if len(resp) == 1:
3810
+ json_modified_value = json.loads(modified_value)
3811
+ retrieved_text = self.get_message(json_modified_value)
3812
+ if not retrieved_text:
1492
3813
  continue
1493
- self.last_response.update(resp[1])
1494
- yield value if raw else resp[1]
3814
+ streaming_text += retrieved_text
3815
+ json_modified_value["choices"][0]["delta"][
3816
+ "content"
3817
+ ] = streaming_text
3818
+ self.last_response.update(json_modified_value)
3819
+ yield value if raw else json_modified_value
1495
3820
  except json.decoder.JSONDecodeError:
1496
3821
  pass
1497
3822
  self.conversation.update_chat_history(
@@ -1550,13 +3875,40 @@ class OPENGPT:
1550
3875
  str: Message extracted
1551
3876
  """
1552
3877
  assert isinstance(response, dict), "Response should be of dict data-type only"
1553
- return response["content"]
1554
- #------------------------------------------------------PERPLEXITY--------------------------------------------------------
1555
- class PERPLEXITY:
3878
+ if response.get("type", "") == "metadata":
3879
+ return
3880
+
3881
+ delta: dict = response["choices"][0]["delta"]
3882
+
3883
+ if not delta:
3884
+ return ""
3885
+
3886
+ elif delta.get("function_call"):
3887
+ if self.quiet:
3888
+ return ""
3889
+
3890
+ function_call: dict = delta["function_call"]
3891
+ if function_call.get("name"):
3892
+ return function_call["name"]
3893
+ elif function_call.get("arguments"):
3894
+ return function_call.get("arguments")
3895
+
3896
+ elif delta.get("metadata"):
3897
+ if self.quiet:
3898
+ return ""
3899
+ return yaml.dump(delta["metadata"])
3900
+
3901
+ else:
3902
+ return (
3903
+ response["choices"][0]["delta"].get("content")
3904
+ if response["choices"][0].get("finish_reason") is None
3905
+ else ""
3906
+ )
3907
+ class AsyncPhindSearch(AsyncProvider):
1556
3908
  def __init__(
1557
3909
  self,
1558
3910
  is_conversation: bool = True,
1559
- max_tokens: int = 8000,
3911
+ max_tokens: int = 600,
1560
3912
  timeout: int = 30,
1561
3913
  intro: str = None,
1562
3914
  filepath: str = None,
@@ -1564,9 +3916,10 @@ class PERPLEXITY:
1564
3916
  proxies: dict = {},
1565
3917
  history_offset: int = 10250,
1566
3918
  act: str = None,
3919
+ model: str = "Phind Model",
1567
3920
  quiet: bool = False,
1568
3921
  ):
1569
- """Instantiates PERPLEXITY
3922
+ """Instantiates PHIND
1570
3923
 
1571
3924
  Args:
1572
3925
  is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True
@@ -1578,16 +3931,25 @@ class PERPLEXITY:
1578
3931
  proxies (dict, optional): Http request proxies. Defaults to {}.
1579
3932
  history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
1580
3933
  act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
3934
+ model (str, optional): Model name. Defaults to "Phind Model".
1581
3935
  quiet (bool, optional): Ignore web search-results and yield final response only. Defaults to False.
1582
3936
  """
1583
- logging.getLogger("websocket").setLevel(logging.ERROR)
1584
- self.session = requests.Session()
1585
3937
  self.max_tokens_to_sample = max_tokens
1586
3938
  self.is_conversation = is_conversation
3939
+ self.chat_endpoint = "https://https.extension.phind.com/agent/"
3940
+ self.stream_chunk_size = 64
3941
+ self.timeout = timeout
1587
3942
  self.last_response = {}
1588
- self.web_results: dict = {}
3943
+ self.model = model
1589
3944
  self.quiet = quiet
1590
3945
 
3946
+ self.headers = {
3947
+ "Content-Type": "application/json",
3948
+ "User-Agent": "",
3949
+ "Accept": "*/*",
3950
+ "Accept-Encoding": "Identity",
3951
+ }
3952
+
1591
3953
  self.__available_optimizers = (
1592
3954
  method
1593
3955
  for method in dir(Optimizers)
@@ -1604,48 +3966,44 @@ class PERPLEXITY:
1604
3966
  is_conversation, self.max_tokens_to_sample, filepath, update_file
1605
3967
  )
1606
3968
  self.conversation.history_offset = history_offset
3969
+ self.session = httpx.AsyncClient(headers=self.headers, proxies=proxies)
1607
3970
 
1608
- def ask(
3971
+ async def ask(
1609
3972
  self,
1610
3973
  prompt: str,
1611
3974
  stream: bool = False,
1612
3975
  raw: bool = False,
1613
3976
  optimizer: str = None,
1614
3977
  conversationally: bool = False,
1615
- ) -> dict:
1616
- """Chat with AI
3978
+ synchronous_generator=False,
3979
+ ) -> dict | AsyncGenerator:
3980
+ """Asynchronously Chat with AI
1617
3981
 
1618
- Args:
1619
- prompt (str): Prompt to be send.
1620
- stream (bool, optional): Flag for streaming response. Defaults to False.
1621
- raw (bool, optional): Stream back raw response as received. Defaults to False.
1622
- optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
1623
- conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
1624
- Returns:
1625
- dict : {}
1626
- ```json
3982
+ Args:
3983
+ prompt (str): Prompt to be send.
3984
+ stream (bool, optional): Flag for streaming response. Defaults to False.
3985
+ raw (bool, optional): Stream back raw response as received. Defaults to False.
3986
+ optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
3987
+ conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
3988
+ Returns:
3989
+ dict|AsyncGenerator : ai content.
3990
+ ```json
1627
3991
  {
1628
- "status": "pending",
1629
- "uuid": "3604dfcc-611f-4b7d-989d-edca2a7233c7",
1630
- "read_write_token": null,
1631
- "frontend_context_uuid": "f6d43119-5231-481d-b692-f52e1f52d2c6",
1632
- "final": false,
1633
- "backend_uuid": "a6d6ec9e-da69-4841-af74-0de0409267a8",
1634
- "media_items": [],
1635
- "widget_data": [],
1636
- "knowledge_cards": [],
1637
- "expect_search_results": "false",
1638
- "mode": "concise",
1639
- "search_focus": "internet",
1640
- "gpt4": false,
1641
- "display_model": "turbo",
1642
- "attachments": null,
1643
- "answer": "",
1644
- "web_results": [],
1645
- "chunks": [],
1646
- "extra_web_results": []
3992
+ "id": "chatcmpl-r0wujizf2i2xb60mjiwt",
3993
+ "object": "chat.completion.chunk",
3994
+ "created": 1706775384,
3995
+ "model": "trt-llm-phind-model-serving",
3996
+ "choices": [
3997
+ {
3998
+ "index": 0,
3999
+ "delta": {
4000
+ "content": "Hello! How can I assist you with your programming today?"
4001
+ },
4002
+ "finish_reason": null
4003
+ }
4004
+ ]
1647
4005
  }
1648
- ```
4006
+ ```
1649
4007
  """
1650
4008
  conversation_prompt = self.conversation.gen_complete_prompt(prompt)
1651
4009
  if optimizer:
@@ -1658,30 +4016,70 @@ class PERPLEXITY:
1658
4016
  f"Optimizer is not one of {self.__available_optimizers}"
1659
4017
  )
1660
4018
 
1661
- def for_stream():
1662
- for response in Perplexity().generate_answer(conversation_prompt):
1663
- yield json.dumps(response) if raw else response
1664
- self.last_response.update(response)
4019
+ payload = {
4020
+ "additional_extension_context": "",
4021
+ "allow_magic_buttons": True,
4022
+ "is_vscode_extension": True,
4023
+ "message_history": [
4024
+ {"content": conversation_prompt, "metadata": {}, "role": "user"}
4025
+ ],
4026
+ "requested_model": self.model,
4027
+ "user_input": prompt,
4028
+ }
1665
4029
 
1666
- self.conversation.update_chat_history(
1667
- prompt,
1668
- self.get_message(self.last_response),
1669
- )
4030
+ async def for_stream():
4031
+ async with self.session.stream(
4032
+ "POST",
4033
+ self.chat_endpoint,
4034
+ json=payload,
4035
+ timeout=self.timeout,
4036
+ ) as response:
4037
+ if (
4038
+ not response.is_success
4039
+ or not response.headers.get("Content-Type")
4040
+ == "text/event-stream; charset=utf-8"
4041
+ ):
4042
+ raise exceptions.FailedToGenerateResponseError(
4043
+ f"Failed to generate response - ({response.status_code}, {response.reason_phrase})"
4044
+ )
4045
+ streaming_text = ""
4046
+ async for value in response.aiter_lines():
4047
+ try:
4048
+ modified_value = re.sub("data:", "", value)
4049
+ json_modified_value = json.loads(modified_value)
4050
+ retrieved_text = await self.get_message(json_modified_value)
4051
+ if not retrieved_text:
4052
+ continue
4053
+ streaming_text += retrieved_text
4054
+ json_modified_value["choices"][0]["delta"][
4055
+ "content"
4056
+ ] = streaming_text
4057
+ self.last_response.update(json_modified_value)
4058
+ yield value if raw else json_modified_value
4059
+ except json.decoder.JSONDecodeError:
4060
+ pass
4061
+ self.conversation.update_chat_history(
4062
+ prompt, await self.get_message(self.last_response)
4063
+ )
1670
4064
 
1671
- def for_non_stream():
1672
- for _ in for_stream():
4065
+ async def for_non_stream():
4066
+ async for _ in for_stream():
1673
4067
  pass
1674
4068
  return self.last_response
1675
4069
 
1676
- return for_stream() if stream else for_non_stream()
4070
+ return (
4071
+ for_stream()
4072
+ if stream and not synchronous_generator
4073
+ else await for_non_stream()
4074
+ )
1677
4075
 
1678
- def chat(
4076
+ async def chat(
1679
4077
  self,
1680
4078
  prompt: str,
1681
4079
  stream: bool = False,
1682
4080
  optimizer: str = None,
1683
4081
  conversationally: bool = False,
1684
- ) -> str:
4082
+ ) -> str | AsyncGenerator:
1685
4083
  """Generate response `str`
1686
4084
  Args:
1687
4085
  prompt (str): Prompt to be send.
@@ -1689,18 +4087,19 @@ class PERPLEXITY:
1689
4087
  optimizer (str, optional): Prompt optimizer name - `[code, shell_command]`. Defaults to None.
1690
4088
  conversationally (bool, optional): Chat conversationally when using optimizer. Defaults to False.
1691
4089
  Returns:
1692
- str: Response generated
4090
+ str|AsyncGenerator: Response generated
1693
4091
  """
1694
4092
 
1695
- def for_stream():
1696
- for response in self.ask(
4093
+ async def for_stream():
4094
+ ask_resp = await self.ask(
1697
4095
  prompt, True, optimizer=optimizer, conversationally=conversationally
1698
- ):
1699
- yield self.get_message(response)
4096
+ )
4097
+ async for response in ask_resp:
4098
+ yield await self.get_message(response)
1700
4099
 
1701
- def for_non_stream():
1702
- return self.get_message(
1703
- self.ask(
4100
+ async def for_non_stream():
4101
+ return await self.get_message(
4102
+ await self.ask(
1704
4103
  prompt,
1705
4104
  False,
1706
4105
  optimizer=optimizer,
@@ -1708,9 +4107,9 @@ class PERPLEXITY:
1708
4107
  )
1709
4108
  )
1710
4109
 
1711
- return for_stream() if stream else for_non_stream()
4110
+ return for_stream() if stream else await for_non_stream()
1712
4111
 
1713
- def get_message(self, response: dict) -> str:
4112
+ async def get_message(self, response: dict) -> str:
1714
4113
  """Retrieves message only from response
1715
4114
 
1716
4115
  Args:
@@ -1720,45 +4119,46 @@ class PERPLEXITY:
1720
4119
  str: Message extracted
1721
4120
  """
1722
4121
  assert isinstance(response, dict), "Response should be of dict data-type only"
1723
- text_str: str = response.get("answer", "")
4122
+ if response.get("type", "") == "metadata":
4123
+ return
1724
4124
 
1725
- def update_web_results(web_results: list) -> None:
1726
- for index, results in enumerate(web_results, start=1):
1727
- self.web_results[str(index) + ". " + results["name"]] = dict(
1728
- url=results.get("url"), snippet=results.get("snippet")
1729
- )
4125
+ delta: dict = response["choices"][0]["delta"]
1730
4126
 
1731
- if response.get("text"):
1732
- # last chunk
1733
- target: dict[str, Any] = json.loads(response.get("text"))
1734
- text_str = target.get("answer")
1735
- web_results: list[dict] = target.get("web_results")
1736
- self.web_results.clear()
1737
- update_web_results(web_results)
4127
+ if not delta:
4128
+ return ""
1738
4129
 
1739
- return (
1740
- text_str
1741
- if self.quiet or not self.web_results
1742
- else text_str + "\n\n# WEB-RESULTS\n\n" + yaml.dump(self.web_results)
1743
- )
4130
+ elif delta.get("function_call"):
4131
+ if self.quiet:
4132
+ return ""
4133
+
4134
+ function_call: dict = delta["function_call"]
4135
+ if function_call.get("name"):
4136
+ return function_call["name"]
4137
+ elif function_call.get("arguments"):
4138
+ return function_call.get("arguments")
4139
+
4140
+ elif delta.get("metadata"):
4141
+ if self.quiet:
4142
+ return ""
4143
+ return yaml.dump(delta["metadata"])
1744
4144
 
1745
4145
  else:
1746
- if str(response.get("expect_search_results")).lower() == "true":
1747
- return (
1748
- text_str
1749
- if self.quiet
1750
- else text_str
1751
- + "\n\n# WEB-RESULTS\n\n"
1752
- + yaml.dump(response.get("web_results"))
1753
- )
1754
- else:
1755
- return text_str
1756
- #------------------------------------------------------BLACKBOXAI--------------------------------------------------------
1757
- class BLACKBOXAI:
4146
+ return (
4147
+ response["choices"][0]["delta"].get("content")
4148
+ if response["choices"][0].get("finish_reason") is None
4149
+ else ""
4150
+ )
4151
+ #-------------------------------------------------------yep.com--------------------------------------------------------
4152
+ class YEPCHAT(Provider):
1758
4153
  def __init__(
1759
4154
  self,
1760
4155
  is_conversation: bool = True,
1761
- max_tokens: int = 8000,
4156
+ max_tokens: int = 600,
4157
+ temperature: float = 0.6,
4158
+ presence_penalty: int = 0,
4159
+ frequency_penalty: int = 0,
4160
+ top_p: float = 0.7,
4161
+ model: str ="Mixtral-8x7B-Instruct-v0.1",
1762
4162
  timeout: int = 30,
1763
4163
  intro: str = None,
1764
4164
  filepath: str = None,
@@ -1766,13 +4166,17 @@ class BLACKBOXAI:
1766
4166
  proxies: dict = {},
1767
4167
  history_offset: int = 10250,
1768
4168
  act: str = None,
1769
- model: str = None,
1770
4169
  ):
1771
- """Instantiates BLACKBOXAI
4170
+ """Instantiates YEPCHAT
1772
4171
 
1773
4172
  Args:
1774
- is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True
4173
+ is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True.
1775
4174
  max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
4175
+ temperature (float, optional): Charge of the generated text's randomness. Defaults to 0.6.
4176
+ presence_penalty (int, optional): Chances of topic being repeated. Defaults to 0.
4177
+ frequency_penalty (int, optional): Chances of word being repeated. Defaults to 0.
4178
+ top_p (float, optional): Sampling threshold during inference time. Defaults to 0.7.
4179
+ model (str, optional): LLM model name. Defaults to "gpt-3.5-turbo".
1776
4180
  timeout (int, optional): Http request timeout. Defaults to 30.
1777
4181
  intro (str, optional): Conversation introductory prompt. Defaults to None.
1778
4182
  filepath (str, optional): Path to file containing conversation history. Defaults to None.
@@ -1780,29 +4184,26 @@ class BLACKBOXAI:
1780
4184
  proxies (dict, optional): Http request proxies. Defaults to {}.
1781
4185
  history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
1782
4186
  act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
1783
- model (str, optional): Model name. Defaults to "Phind Model".
1784
4187
  """
1785
- self.session = requests.Session()
1786
- self.max_tokens_to_sample = max_tokens
1787
4188
  self.is_conversation = is_conversation
1788
- self.chat_endpoint = "https://www.blackbox.ai/api/chat"
4189
+ self.max_tokens_to_sample = max_tokens
4190
+ self.model = model
4191
+ self.temperature = temperature
4192
+ self.presence_penalty = presence_penalty
4193
+ self.frequency_penalty = frequency_penalty
4194
+ self.top_p = top_p
4195
+ self.chat_endpoint = "https://api.yep.com/v1/chat/completions"
1789
4196
  self.stream_chunk_size = 64
1790
4197
  self.timeout = timeout
1791
4198
  self.last_response = {}
1792
- self.model = model
1793
- self.previewToken: str = None
1794
- self.userId: str = ""
1795
- self.codeModelMode: bool = True
1796
- self.id: str = ""
1797
- self.agentMode: dict = {}
1798
- self.trendingAgentMode: dict = {}
1799
- self.isMicMode: bool = False
1800
-
1801
4199
  self.headers = {
1802
- "Content-Type": "application/json",
1803
- "User-Agent": "",
1804
4200
  "Accept": "*/*",
1805
- "Accept-Encoding": "Identity",
4201
+ "Accept-Encoding": "gzip, deflate",
4202
+ "Accept-Language": "en-US,en;q=0.9",
4203
+ "Content-Type": "application/json; charset=utf-8",
4204
+ "Origin": "https://yep.com",
4205
+ "Referer": "https://yep.com/",
4206
+ "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
1806
4207
  }
1807
4208
 
1808
4209
  self.__available_optimizers = (
@@ -1844,7 +4245,20 @@ class BLACKBOXAI:
1844
4245
  dict : {}
1845
4246
  ```json
1846
4247
  {
1847
- "text" : "print('How may I help you today?')"
4248
+ "id": "cmpl-c61c1c88de4e4ad3a79134775d17ea0c",
4249
+ "object": "chat.completion.chunk",
4250
+ "created": 1713876886,
4251
+ "model": "Mixtral-8x7B-Instruct-v0.1",
4252
+ "choices": [
4253
+ {
4254
+ "index": 0,
4255
+ "delta": {
4256
+ "role": null,
4257
+ "content": " Sure, I can help with that. Are you looking for information on how to start coding, or do you need help with a specific coding problem? We can discuss various programming languages like Python, JavaScript, Java, C++, or others. Please provide more details so I can assist you better."
4258
+ },
4259
+ "finish_reason": null
4260
+ }
4261
+ ]
1848
4262
  }
1849
4263
  ```
1850
4264
  """
@@ -1858,47 +4272,41 @@ class BLACKBOXAI:
1858
4272
  raise Exception(
1859
4273
  f"Optimizer is not one of {self.__available_optimizers}"
1860
4274
  )
1861
-
1862
4275
  self.session.headers.update(self.headers)
1863
4276
  payload = {
1864
- "messages": [
1865
- # json.loads(prev_messages),
1866
- {"content": conversation_prompt, "role": "user"}
1867
- ],
1868
- "id": self.id,
1869
- "previewToken": self.previewToken,
1870
- "userId": self.userId,
1871
- "codeModelMode": self.codeModelMode,
1872
- "agentMode": self.agentMode,
1873
- "trendingAgentMode": self.trendingAgentMode,
1874
- "isMicMode": self.isMicMode,
4277
+ "stream": True,
4278
+ "max_tokens": 1280,
4279
+ "top_p": self.top_p,
4280
+ "temperature": self.temperature,
4281
+ "messages": [{"content": conversation_prompt, "role": "user"}],
4282
+ "model": self.model,
1875
4283
  }
1876
4284
 
1877
4285
  def for_stream():
1878
4286
  response = self.session.post(
1879
4287
  self.chat_endpoint, json=payload, stream=True, timeout=self.timeout
1880
4288
  )
1881
- if (
1882
- not response.ok
1883
- or not response.headers.get("Content-Type")
1884
- == "text/plain; charset=utf-8"
1885
- ):
1886
- raise Exception(
4289
+ if not response.ok:
4290
+ raise exceptions.FailedToGenerateResponseError(
1887
4291
  f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
1888
4292
  )
1889
- streaming_text = ""
4293
+
4294
+ message_load = ""
1890
4295
  for value in response.iter_lines(
1891
4296
  decode_unicode=True,
4297
+ delimiter="" if raw else "data:",
1892
4298
  chunk_size=self.stream_chunk_size,
1893
- delimiter="\n",
1894
4299
  ):
1895
4300
  try:
1896
- if bool(value):
1897
- streaming_text += value + ("\n" if stream else "")
1898
-
1899
- resp = dict(text=streaming_text)
4301
+ resp = json.loads(value)
4302
+ incomplete_message = self.get_message(resp)
4303
+ if incomplete_message:
4304
+ message_load += incomplete_message
4305
+ resp["choices"][0]["delta"]["content"] = message_load
1900
4306
  self.last_response.update(resp)
1901
4307
  yield value if raw else resp
4308
+ elif raw:
4309
+ yield value
1902
4310
  except json.decoder.JSONDecodeError:
1903
4311
  pass
1904
4312
  self.conversation.update_chat_history(
@@ -1957,21 +4365,22 @@ class BLACKBOXAI:
1957
4365
  str: Message extracted
1958
4366
  """
1959
4367
  assert isinstance(response, dict), "Response should be of dict data-type only"
1960
- return response["text"]
1961
- @staticmethod
1962
- def chat_cli(prompt):
1963
- """Sends a request to the BLACKBOXAI API and processes the response."""
1964
- blackbox_ai = BLACKBOXAI() # Initialize a BLACKBOXAI instance
1965
- response = blackbox_ai.ask(prompt) # Perform a chat with the given prompt
1966
- processed_response = blackbox_ai.get_message(response) # Process the response
1967
- print(processed_response)
1968
- #------------------------------------------------------phind-------------------------------------------------------------
1969
- class PhindSearch:
1970
- # default_model = "Phind Model"
4368
+ try:
4369
+ if response["choices"][0].get("delta"):
4370
+ return response["choices"][0]["delta"]["content"]
4371
+ return response["choices"][0]["message"]["content"]
4372
+ except KeyError:
4373
+ return ""
4374
+ class AsyncYEPCHAT(AsyncProvider):
1971
4375
  def __init__(
1972
4376
  self,
1973
4377
  is_conversation: bool = True,
1974
- max_tokens: int = 8000,
4378
+ max_tokens: int = 600,
4379
+ temperature: float = 0.6,
4380
+ presence_penalty: int = 0,
4381
+ frequency_penalty: int = 0,
4382
+ top_p: float = 0.7,
4383
+ model: str = "Mixtral-8x7B-Instruct-v0.1",
1975
4384
  timeout: int = 30,
1976
4385
  intro: str = None,
1977
4386
  filepath: str = None,
@@ -1979,14 +4388,17 @@ class PhindSearch:
1979
4388
  proxies: dict = {},
1980
4389
  history_offset: int = 10250,
1981
4390
  act: str = None,
1982
- model: str = "Phind Model",
1983
- quiet: bool = False,
1984
4391
  ):
1985
- """Instantiates PHIND
4392
+ """Instantiates YEPCHAT
1986
4393
 
1987
4394
  Args:
1988
- is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True
4395
+ is_conversation (bool, optional): Flag for chatting conversationally. Defaults to True.
1989
4396
  max_tokens (int, optional): Maximum number of tokens to be generated upon completion. Defaults to 600.
4397
+ temperature (float, optional): Charge of the generated text's randomness. Defaults to 0.6.
4398
+ presence_penalty (int, optional): Chances of topic being repeated. Defaults to 0.
4399
+ frequency_penalty (int, optional): Chances of word being repeated. Defaults to 0.
4400
+ top_p (float, optional): Sampling threshold during inference time. Defaults to 0.7.
4401
+ model (str, optional): LLM model name. Defaults to "gpt-3.5-turbo".
1990
4402
  timeout (int, optional): Http request timeout. Defaults to 30.
1991
4403
  intro (str, optional): Conversation introductory prompt. Defaults to None.
1992
4404
  filepath (str, optional): Path to file containing conversation history. Defaults to None.
@@ -1994,24 +4406,26 @@ class PhindSearch:
1994
4406
  proxies (dict, optional): Http request proxies. Defaults to {}.
1995
4407
  history_offset (int, optional): Limit conversation history to this number of last texts. Defaults to 10250.
1996
4408
  act (str|int, optional): Awesome prompt key or index. (Used as intro). Defaults to None.
1997
- model (str, optional): Model name. Defaults to "Phind Model".
1998
- quiet (bool, optional): Ignore web search-results and yield final response only. Defaults to False.
1999
4409
  """
2000
- self.session = requests.Session()
2001
- self.max_tokens_to_sample = max_tokens
2002
4410
  self.is_conversation = is_conversation
2003
- self.chat_endpoint = "https://https.extension.phind.com/agent/"
4411
+ self.max_tokens_to_sample = max_tokens
4412
+ self.model = model
4413
+ self.temperature = temperature
4414
+ self.presence_penalty = presence_penalty
4415
+ self.frequency_penalty = frequency_penalty
4416
+ self.top_p = top_p
4417
+ self.chat_endpoint = "https://api.yep.com/v1/chat/completions"
2004
4418
  self.stream_chunk_size = 64
2005
4419
  self.timeout = timeout
2006
4420
  self.last_response = {}
2007
- self.model = model
2008
- self.quiet = quiet
2009
-
2010
4421
  self.headers = {
2011
- "Content-Type": "application/json",
2012
- "User-Agent": "",
2013
4422
  "Accept": "*/*",
2014
- "Accept-Encoding": "Identity",
4423
+ "Accept-Encoding": "gzip, deflate",
4424
+ "Accept-Language": "en-US,en;q=0.9",
4425
+ "Content-Type": "application/json; charset=utf-8",
4426
+ "Origin": "https://yep.com",
4427
+ "Referer": "https://yep.com/",
4428
+ "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
2015
4429
  }
2016
4430
 
2017
4431
  self.__available_optimizers = (
@@ -2019,7 +4433,6 @@ class PhindSearch:
2019
4433
  for method in dir(Optimizers)
2020
4434
  if callable(getattr(Optimizers, method)) and not method.startswith("__")
2021
4435
  )
2022
- self.session.headers.update(self.headers)
2023
4436
  Conversation.intro = (
2024
4437
  AwesomePrompts().get_act(
2025
4438
  act, raise_not_found=True, default=None, case_insensitive=True
@@ -2031,9 +4444,12 @@ class PhindSearch:
2031
4444
  is_conversation, self.max_tokens_to_sample, filepath, update_file
2032
4445
  )
2033
4446
  self.conversation.history_offset = history_offset
2034
- self.session.proxies = proxies
4447
+ self.session = httpx.AsyncClient(
4448
+ headers=self.headers,
4449
+ proxies=proxies,
4450
+ )
2035
4451
 
2036
- def ask(
4452
+ async def ask(
2037
4453
  self,
2038
4454
  prompt: str,
2039
4455
  stream: bool = False,
@@ -2041,7 +4457,7 @@ class PhindSearch:
2041
4457
  optimizer: str = None,
2042
4458
  conversationally: bool = False,
2043
4459
  ) -> dict:
2044
- """Chat with AI
4460
+ """Chat with AI asynchronously.
2045
4461
 
2046
4462
  Args:
2047
4463
  prompt (str): Prompt to be send.
@@ -2053,15 +4469,16 @@ class PhindSearch:
2053
4469
  dict : {}
2054
4470
  ```json
2055
4471
  {
2056
- "id": "chatcmpl-r0wujizf2i2xb60mjiwt",
4472
+ "id": "cmpl-c61c1c88de4e4ad3a79134775d17ea0c",
2057
4473
  "object": "chat.completion.chunk",
2058
- "created": 1706775384,
2059
- "model": "trt-llm-phind-model-serving",
4474
+ "created": 1713876886,
4475
+ "model": "Mixtral-8x7B-Instruct-v0.1",
2060
4476
  "choices": [
2061
4477
  {
2062
4478
  "index": 0,
2063
4479
  "delta": {
2064
- "content": "Hello! How can I assist you with your programming today?"
4480
+ "role": null,
4481
+ "content": " Sure, I can help with that. Are you looking for information on how to start coding, or do you need help with a specific coding problem? We can discuss various programming languages like Python, JavaScript, Java, C++, or others. Please provide more details so I can assist you better."
2065
4482
  },
2066
4483
  "finish_reason": null
2067
4484
  }
@@ -2079,69 +4496,58 @@ class PhindSearch:
2079
4496
  raise Exception(
2080
4497
  f"Optimizer is not one of {self.__available_optimizers}"
2081
4498
  )
2082
-
2083
- self.session.headers.update(self.headers)
2084
4499
  payload = {
2085
- "additional_extension_context": "",
2086
- "allow_magic_buttons": True,
2087
- "is_vscode_extension": True,
2088
- "message_history": [
2089
- {"content": conversation_prompt, "metadata": {}, "role": "user"}
2090
- ],
2091
- "requested_model": self.model,
2092
- "user_input": prompt,
4500
+ "stream": True,
4501
+ "max_tokens": 1280,
4502
+ "top_p": self.top_p,
4503
+ "temperature": self.temperature,
4504
+ "messages": [{"content": conversation_prompt, "role": "user"}],
4505
+ "model": self.model,
2093
4506
  }
2094
4507
 
2095
- def for_stream():
2096
- response = self.session.post(
2097
- self.chat_endpoint, json=payload, stream=True, timeout=self.timeout
2098
- )
2099
- if (
2100
- not response.ok
2101
- or not response.headers.get("Content-Type")
2102
- == "text/event-stream; charset=utf-8"
2103
- ):
2104
- raise Exception(
2105
- f"Failed to generate response - ({response.status_code}, {response.reason}) - {response.text}"
2106
- )
2107
- streaming_text = ""
2108
- for value in response.iter_lines(
2109
- decode_unicode=True,
2110
- chunk_size=self.stream_chunk_size,
2111
- ):
2112
- try:
2113
- modified_value = re.sub("data:", "", value)
2114
- json_modified_value = json.loads(modified_value)
2115
- retrieved_text = self.get_message(json_modified_value)
2116
- if not retrieved_text:
2117
- continue
2118
- streaming_text += retrieved_text
2119
- json_modified_value["choices"][0]["delta"][
2120
- "content"
2121
- ] = streaming_text
2122
- self.last_response.update(json_modified_value)
2123
- yield value if raw else json_modified_value
2124
- except json.decoder.JSONDecodeError:
2125
- pass
4508
+ async def for_stream():
4509
+ async with self.session.stream(
4510
+ "POST", self.chat_endpoint, json=payload, timeout=self.timeout
4511
+ ) as response:
4512
+ if not response.is_success:
4513
+ raise exceptions.FailedToGenerateResponseError(
4514
+ f"Failed to generate response - ({response.status_code}, {response.reason_phrase}) - {response.text}"
4515
+ )
4516
+
4517
+ message_load = ""
4518
+ async for value in response.aiter_lines():
4519
+ try:
4520
+ resp = sanitize_stream(value)
4521
+ incomplete_message = await self.get_message(resp)
4522
+ if incomplete_message:
4523
+ message_load += incomplete_message
4524
+ resp["choices"][0]["delta"]["content"] = message_load
4525
+ self.last_response.update(resp)
4526
+ yield value if raw else resp
4527
+ elif raw:
4528
+ yield value
4529
+ except json.decoder.JSONDecodeError:
4530
+ pass
4531
+
2126
4532
  self.conversation.update_chat_history(
2127
- prompt, self.get_message(self.last_response)
4533
+ prompt, await self.get_message(self.last_response)
2128
4534
  )
2129
4535
 
2130
- def for_non_stream():
2131
- for _ in for_stream():
4536
+ async def for_non_stream():
4537
+ async for _ in for_stream():
2132
4538
  pass
2133
4539
  return self.last_response
2134
4540
 
2135
- return for_stream() if stream else for_non_stream()
4541
+ return for_stream() if stream else await for_non_stream()
2136
4542
 
2137
- def chat(
4543
+ async def chat(
2138
4544
  self,
2139
4545
  prompt: str,
2140
4546
  stream: bool = False,
2141
4547
  optimizer: str = None,
2142
4548
  conversationally: bool = False,
2143
4549
  ) -> str:
2144
- """Generate response `str`
4550
+ """Generate response `str` asynchronously.
2145
4551
  Args:
2146
4552
  prompt (str): Prompt to be send.
2147
4553
  stream (bool, optional): Flag for streaming response. Defaults to False.
@@ -2151,15 +4557,17 @@ class PhindSearch:
2151
4557
  str: Response generated
2152
4558
  """
2153
4559
 
2154
- def for_stream():
2155
- for response in self.ask(
4560
+ async def for_stream():
4561
+ async_ask = await self.ask(
2156
4562
  prompt, True, optimizer=optimizer, conversationally=conversationally
2157
- ):
2158
- yield self.get_message(response)
4563
+ )
2159
4564
 
2160
- def for_non_stream():
2161
- return self.get_message(
2162
- self.ask(
4565
+ async for response in async_ask:
4566
+ yield await self.get_message(response)
4567
+
4568
+ async def for_non_stream():
4569
+ return await self.get_message(
4570
+ await self.ask(
2163
4571
  prompt,
2164
4572
  False,
2165
4573
  optimizer=optimizer,
@@ -2167,9 +4575,9 @@ class PhindSearch:
2167
4575
  )
2168
4576
  )
2169
4577
 
2170
- return for_stream() if stream else for_non_stream()
4578
+ return for_stream() if stream else await for_non_stream()
2171
4579
 
2172
- def get_message(self, response: dict) -> str:
4580
+ async def get_message(self, response: dict) -> str:
2173
4581
  """Retrieves message only from response
2174
4582
 
2175
4583
  Args:
@@ -2179,99 +4587,12 @@ class PhindSearch:
2179
4587
  str: Message extracted
2180
4588
  """
2181
4589
  assert isinstance(response, dict), "Response should be of dict data-type only"
2182
- if response.get("type", "") == "metadata":
2183
- return
2184
-
2185
- delta: dict = response["choices"][0]["delta"]
2186
-
2187
- if not delta:
4590
+ try:
4591
+ if response["choices"][0].get("delta"):
4592
+ return response["choices"][0]["delta"]["content"]
4593
+ return response["choices"][0]["message"]["content"]
4594
+ except KeyError:
2188
4595
  return ""
2189
-
2190
- elif delta.get("function_call"):
2191
- if self.quiet:
2192
- return ""
2193
-
2194
- function_call: dict = delta["function_call"]
2195
- if function_call.get("name"):
2196
- return function_call["name"]
2197
- elif function_call.get("arguments"):
2198
- return function_call.get("arguments")
2199
-
2200
- elif delta.get("metadata"):
2201
- if self.quiet:
2202
- return ""
2203
- return yaml.dump(delta["metadata"])
2204
-
2205
- else:
2206
- return (
2207
- response["choices"][0]["delta"].get("content")
2208
- if response["choices"][0].get("finish_reason") is None
2209
- else ""
2210
- )
2211
- @staticmethod
2212
- def chat_cli(prompt):
2213
- """Sends a request to the Phind API and processes the response."""
2214
- phind_search = PhindSearch() # Initialize a PhindSearch instance
2215
- response = phind_search.ask(prompt) # Perform a search with the given prompt
2216
- processed_response = phind_search.get_message(response) # Process the response
2217
- print(processed_response)
2218
- #-------------------------------------------------------yep.com--------------------------------------------------------
2219
- class YepChat:
2220
- def __init__(self, message="hello"):
2221
- self.url = "https://api.yep.com/v1/chat/completions"
2222
- self.headers = {
2223
- "Accept": "*/*",
2224
- "Accept-Encoding": "gzip, deflate, br, zstd",
2225
- "Accept-Language": "en-US,en;q=0.9",
2226
- "Cache-Control": "max-age=0",
2227
- "Content-Type": "application/json; charset=utf-8",
2228
- "Origin": "https://yep.com",
2229
- "Referer": "https://yep.com/",
2230
- "Sec-Ch-Ua": '"Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"',
2231
- "Sec-Ch-Ua-Mobile": "?0",
2232
- "Sec-Ch-Ua-Platform": '"Windows"',
2233
- "Sec-Fetch-Dest": "empty",
2234
- "Sec-Fetch-Mode": "cors",
2235
- "Sec-Fetch-Site": "same-site",
2236
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0.0.0 Safari/537.36"
2237
- }
2238
- self.payload = {
2239
- "stream": True,
2240
- "max_tokens": 1280,
2241
- "top_p": 0.7,
2242
- "temperature": 0.6,
2243
- "messages": [{
2244
- "content": message,
2245
- "role": "user"
2246
- }],
2247
- "model": "Mixtral-8x7B-Instruct-v0.1"
2248
- }
2249
-
2250
- def send_request(self):
2251
- response = requests.post(self.url, headers=self.headers, data=json.dumps(self.payload), stream=True)
2252
- print(response.status_code)
2253
- return response
2254
-
2255
- def process_response(self, response):
2256
- myset = ""
2257
- for line in response.iter_lines():
2258
- if line:
2259
- myline = line.decode('utf-8').removeprefix("data: ").replace(" null", "False")
2260
- try:
2261
- myval = eval(myline)
2262
- if "choices" in myval and "delta" in myval["choices"][0] and "content" in myval["choices"][0]["delta"]:
2263
- myset += myval["choices"][0]["delta"]["content"]
2264
- except:
2265
- continue
2266
- return myset
2267
-
2268
- @staticmethod
2269
- def chat_cli(message):
2270
- """Sends a request to the Yep API and processes the response."""
2271
- yep_chat = YepChat(message=message)
2272
- response = yep_chat.send_request()
2273
- processed_response = yep_chat.process_response(response)
2274
- print(processed_response)
2275
4596
  #-------------------------------------------------------youchat--------------------------------------------------------
2276
4597
  class youChat:
2277
4598
  """
@@ -2623,88 +4944,3 @@ class Pollinations:
2623
4944
  image.show()
2624
4945
  except Exception as e:
2625
4946
  print(f"An error occurred: {e}")
2626
-
2627
- @click.group()
2628
- def cli():
2629
- """Webscout AI command-line interface."""
2630
- pass
2631
-
2632
- @cli.command()
2633
- @click.option('--prompt', prompt='Enter your search prompt', help='The prompt to send.')
2634
- def phindsearch(prompt):
2635
- """Perform a search with the given prompt using PhindSearch."""
2636
- phind_search = PhindSearch() # Initialize a PhindSearch instance
2637
- response = phind_search.ask(prompt) # Perform a search with the given prompt
2638
- processed_response = phind_search.get_message(response) # Process the response
2639
- print(processed_response)
2640
-
2641
- @cli.command()
2642
- @click.option('--message', prompt='Enter your message', help='The message to send.')
2643
- def yepchat(message):
2644
- YepChat.chat_cli(message)
2645
-
2646
- @cli.command()
2647
- @click.option('--prompt', prompt='Enter your prompt', help='The prompt to generate a completion from.')
2648
- def youchat(prompt):
2649
- youChat.chat_cli(prompt)
2650
-
2651
-
2652
- @cli.command()
2653
- @click.option('--prompt', prompt='Enter your prompt', help='The prompt for generating the image.')
2654
- def prodia(prompt):
2655
- """Generate an image based on the provided prompt."""
2656
- Prodia.prodia_cli(prompt)
2657
-
2658
- @cli.command()
2659
- @click.option('--prompt', prompt='Enter your prompt', help='The prompt for generating the image.')
2660
- def pollinations(prompt):
2661
- """Generate an image based on the provided prompt."""
2662
- Pollinations.pollinations_cli(prompt)
2663
-
2664
- @cli.command()
2665
- @click.option('--prompt', prompt='Enter your prompt', help='The prompt to send.')
2666
- def blackboxai(prompt):
2667
- """Chat with BLACKBOXAI using the provided prompt."""
2668
- BLACKBOXAI.chat_cli(prompt)
2669
-
2670
- @cli.command()
2671
- @click.option('--prompt', prompt='Enter your prompt', help='The prompt to send.')
2672
- @click.option('--stream', is_flag=True, help='Flag for streaming response.')
2673
- @click.option('--raw', is_flag=True, help='Stream back raw response as received.')
2674
- @click.option('--optimizer', type=str, help='Prompt optimizer name.')
2675
- @click.option('--conversationally', is_flag=True, help='Chat conversationally when using optimizer.')
2676
- def perplexity(prompt, stream, raw, optimizer, conversationally):
2677
- """Chat with PERPLEXITY using the provided prompt."""
2678
- perplexity_instance = PERPLEXITY() # Initialize a PERPLEXITY instance
2679
- response = perplexity_instance.ask(prompt, stream, raw, optimizer, conversationally)
2680
- processed_response = perplexity_instance.get_message(response) # Process the response
2681
- print(processed_response)
2682
-
2683
- @cli.command()
2684
- @click.option('--prompt', prompt='Enter your search prompt', help='The prompt to send.')
2685
- @click.option('--stream', is_flag=True, help='Flag for streaming response.')
2686
- def opengpt(prompt, stream):
2687
- """Chat with OPENGPT using the provided prompt."""
2688
- opengpt = OPENGPT(is_conversation=True, max_tokens=8000, timeout=30)
2689
- if stream:
2690
- for response in opengpt.chat(prompt, stream=True):
2691
- print(response)
2692
- else:
2693
- response_str = opengpt.chat(prompt)
2694
- print(response_str)
2695
-
2696
- @cli.command()
2697
- @click.option('--prompt', prompt='Enter your prompt', help='The prompt to send.')
2698
- @click.option('--stream', is_flag=True, help='Flag for streaming response.')
2699
- @click.option('--raw', is_flag=True, help='Stream back raw response as received.')
2700
- @click.option('--optimizer', type=str, help='Prompt optimizer name.')
2701
- @click.option('--conversationally', is_flag=True, help='Chat conversationally when using optimizer.')
2702
- def koboldai_cli(prompt, stream, raw, optimizer, conversationally):
2703
- """Chat with KOBOLDAI using the provided prompt."""
2704
- koboldai_instance = KOBOLDAI() # Initialize a KOBOLDAI instance
2705
- response = koboldai_instance.ask(prompt, stream, raw, optimizer, conversationally)
2706
- processed_response = koboldai_instance.get_message(response) # Process the response
2707
- print(processed_response)
2708
-
2709
- if __name__ == '__main__':
2710
- cli()