ASUllmAPI 2.0.4__tar.gz → 2.0.6__tar.gz

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.
@@ -7,13 +7,14 @@ __author__ = ['swliu', 'vshourie']
7
7
  class ModelConfig:
8
8
 
9
9
  def __init__(self, access_token: str = None, action: str = None, api_url: str = "", enable_history: bool = False,
10
- enable_search: bool = True, history: List[Dict[str, str]] = None, model_max_tokens: int = None,
10
+ enable_search: bool = True, history: List[Dict[str, str]] = None, model_max_tokens: int = None,
11
11
  model_temperature: float = None, model_top_k: int = None, model_top_p: int = None, name: str = "",
12
12
  project_id: str = None, provider: str = "", response_format_type: str = "",
13
- search_collection: str = "asu", search_db_type: str = "milvus", search_output_fields: List[str] = None,
14
- search_retrieval_type: str = "chunk", search_source_name: List[str] = None, search_tags: list = None,
15
- search_top_k: int = 3, semantic_caching: bool = False, session_id: str = None,
16
- system_prompt: str = None):
13
+ search_collection: str = "asu", search_db_type: str = "opensearch",
14
+ search_output_fields: List[str] = None, search_retrieval_type: str = "chunk",
15
+ search_source_name: List[str] = None, search_tags: list = None, search_top_k: int = 3,
16
+ search_prompt_mode: str = "unrestricted", search_prompt: str = None, semantic_caching: bool = False,
17
+ session_id: str = None, system_prompt: str = None):
17
18
  self.access_token = access_token
18
19
  self.action = action
19
20
  self.api_url = api_url
@@ -35,6 +36,8 @@ class ModelConfig:
35
36
  self.search_tags = search_tags
36
37
  self.search_top_k = search_top_k
37
38
  self.search_retrieval_type = search_retrieval_type
39
+ self.search_prompt_mode = search_prompt_mode
40
+ self.search_prompt = search_prompt
38
41
  self.semantic_caching = semantic_caching
39
42
  self.session_id = session_id
40
43
  self.system_prompt = system_prompt
@@ -113,6 +116,10 @@ class ModelConfig:
113
116
  search_params["top_k"] = self.search_top_k
114
117
  search_params["retrieval_type"] = self.search_retrieval_type
115
118
 
119
+ if self.search_prompt_mode is not None:
120
+ search_params["prompt_mode"] = self.search_prompt_mode
121
+ if self.search_prompt is not None:
122
+ search_params["search_prompt"] = self.search_prompt
116
123
  if self.search_source_name is not None:
117
124
  search_params["source_name"] = self.search_source_name
118
125
  if self.search_tags is not None:
@@ -3,6 +3,7 @@ from concurrent.futures import ThreadPoolExecutor
3
3
  import time
4
4
  import json
5
5
  import asyncio
6
+ import sys
6
7
 
7
8
 
8
9
  def begin_task_execution(async_func):
@@ -13,17 +14,31 @@ def begin_task_execution(async_func):
13
14
  If an event loop doesn't exist, it reverts back to existing asyncio logic.
14
15
  """
15
16
  def wrap(*args, **kwargs):
16
- try:
17
- asyncio.get_running_loop() # Triggers RuntimeError if no running event loop
18
- # Create a separate thread so we can block before returning
17
+ # It is safer to use a if/else statement than try/except since
18
+ # the underlying code we wrap our function around can also raise RuntimeErrors.
19
+ # When this happens, multiple asyncio.run() executions occur, which is dangerous.
20
+ if is_jupyter():
19
21
  with ThreadPoolExecutor(1) as pool:
20
22
  result = pool.submit(lambda: asyncio.run(async_func(*args, **kwargs))).result()
21
- except RuntimeError:
23
+ else:
22
24
  result = asyncio.run(async_func(*args, **kwargs))
23
25
  return result
24
26
  return wrap
25
27
 
26
28
 
29
+ def is_jupyter():
30
+ try:
31
+ # Check if 'IPython' is in sys.modules
32
+ if 'IPython' in sys.modules:
33
+ from IPython import get_ipython
34
+ # Check if we're in an IPython environment
35
+ if get_ipython() is not None:
36
+ return True
37
+ except ImportError:
38
+ pass
39
+ return False
40
+
41
+
27
42
  def load_json_buffer(string):
28
43
  try:
29
44
  return json.loads(string)
@@ -98,29 +98,37 @@ async def interact_with_websocket(uri: str, queue: asyncio.Queue,
98
98
  queue.task_done()
99
99
  # END - QUERY QUEUE LOOP
100
100
  except (asyncio.TimeoutError, websockets.ConnectionClosed, Exception) as exc:
101
- time.sleep(reconnect_timeout_secs)
102
- # If the query is already complete, we don't want to increment the error count
103
- if response_payloads[qid]["success"] == 0:
104
- error_ct += 1
105
- # Reset buffer stream so that you don't get messed by pre-existing data.
106
- response_payloads[qid]["response"] = ""
107
- else:
108
- logging.info(f"Query ID {qid} completed...")
109
- queue.task_done()
110
101
  if isinstance(exc, asyncio.TimeoutError):
111
- logging.error(f"Error {error_ct} on {qid} stream timeout: resetting connection...")
102
+ logging.error(f"Error {error_ct} on Question ID {qid} stream timeout: resetting connection...")
112
103
  elif isinstance(exc, ResponseDataError):
113
- logging.error(f"Error {error_ct} on {qid}: invalid response from endpoint.\n"
104
+ logging.error(f"Error {error_ct} on Question ID {qid}: invalid response from endpoint.\n"
114
105
  f"{response_payloads[qid]}")
115
106
  elif isinstance(exc, websockets.ConnectionClosed):
116
- logging.error(f"Error {error_ct} on {qid}: WebSocket connection closed on "
107
+ logging.error(f"Error {error_ct} on Question ID {qid}: WebSocket connection closed on "
117
108
  f"query ID {qid}. Reopening...")
109
+ elif isinstance(exc, websockets.exceptions.InvalidStatusCode):
110
+ logging.error(f"Error {error_ct} on Question ID {qid}: Server rejected the connection. "
111
+ f"Check URI again.")
118
112
  else:
119
- logging.error(f"Error {error_ct} on {qid}: {traceback.format_exc()}")
120
-
121
- # prevent any further retries if at error limit.
122
- if error_ct == error_threshold:
123
- error_ct = 0
113
+ logging.error(f"Error {error_ct} on Question ID {qid}: {traceback.format_exc()}")
114
+
115
+ try:
116
+ # If the query is already complete, we don't want to increment the error count
117
+ if response_payloads[qid]["success"] == 0:
118
+ error_ct += 1
119
+ # Reset buffer stream so that you don't get messed by pre-existing data.
120
+ response_payloads[qid]["response"] = ""
121
+ else:
122
+ logging.info(f"Query ID {qid} completed...")
123
+ queue.task_done()
124
+ except KeyError:
125
+ logging.error(f"Question ID {qid} does not exist in the queue. Exiting...")
126
+ return
127
+ finally:
128
+ # prevent any further retries if at error limit.
129
+ if error_ct == error_threshold:
130
+ error_ct = 0
131
+ time.sleep(reconnect_timeout_secs)
124
132
  # END - WEBSOCKET LOOP
125
133
  logging.info("WebSocket connection closed. Queue appears to be empty...")
126
134
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ASUllmAPI
3
- Version: 2.0.4
3
+ Version: 2.0.6
4
4
  Summary: A simple python package to facilitate connection to ASU LLM API
5
5
  Author-email: Stella Wenxing Liu <stellawenxingliu@gmail.com>, Varun Shourie <svarun195@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/ASU/aiml-ssmdv-student-support-ml-data-visualization
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ASUllmAPI
3
- Version: 2.0.4
3
+ Version: 2.0.6
4
4
  Summary: A simple python package to facilitate connection to ASU LLM API
5
5
  Author-email: Stella Wenxing Liu <stellawenxingliu@gmail.com>, Varun Shourie <svarun195@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/ASU/aiml-ssmdv-student-support-ml-data-visualization
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ASUllmAPI"
3
- version = "2.0.4"
3
+ version = "2.0.6"
4
4
  authors = [
5
5
  { name="Stella Wenxing Liu", email="stellawenxingliu@gmail.com" },
6
6
  { name="Varun Shourie", email="svarun195@gmail.com" }
File without changes
File without changes
File without changes
File without changes