sunholo 0.60.9__py3-none-any.whl → 0.61.4__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.
@@ -74,7 +74,7 @@ def embeds_to_json(message: dict):
74
74
  # Output: '[{"type": "image", "url": "https://example.com/image.png"}]'
75
75
  ```
76
76
  """
77
- if len(message['embeds'] > 0):
77
+ if 'embeds' in message and len(message['embeds']) > 0:
78
78
  return json.dumps(message.get("embeds"))
79
79
  else:
80
80
  return ""
@@ -45,7 +45,7 @@ def pick_vectorstore(vs_str, vector_name, embeddings, read_only=None):
45
45
  return vectorstore
46
46
 
47
47
  elif vs_str == 'cloudsql' or vs_str == 'postgres':
48
- from langchain.vectorstores.pgvector import PGVector
48
+ from langchain_community.vectorstores import PGVector
49
49
 
50
50
  log.debug("Inititaing CloudSQL/Postgres pgvector")
51
51
  #setup_cloudsql(vector_name)
sunholo/utils/config.py CHANGED
@@ -75,7 +75,7 @@ def load_all_configs():
75
75
  if filename in config_cache:
76
76
  cached_config, cache_time = config_cache[filename]
77
77
  if (current_time - cache_time) < timedelta(minutes=5):
78
- log.info(f"Returning cached config for {filename}")
78
+ log.debug(f"Returning cached config for {filename}")
79
79
  config = cached_config
80
80
  else:
81
81
  config = reload_config_file(config_file, filename)
@@ -167,7 +167,7 @@ def load_config(filename: str=None) -> tuple[dict, str]:
167
167
 
168
168
  return config, filename
169
169
 
170
- def load_config_key(key: str, vector_name: str, kind: str=None):
170
+ def load_config_key(key: str, vector_name: str, kind: str):
171
171
  """
172
172
  Load a specific key from a configuration file.
173
173
 
@@ -192,27 +192,16 @@ def load_config_key(key: str, vector_name: str, kind: str=None):
192
192
 
193
193
  configs_by_kind = load_all_configs()
194
194
 
195
- if kind:
196
- log.debug(f"Got kind: {kind} - applying to configs")
195
+ log.debug(f"Got kind: {kind} - applying to configs")
197
196
 
198
197
  if not configs_by_kind:
199
198
  log.warning("Did not load configs via folder")
200
199
 
201
- if kind and configs_by_kind.get(kind):
202
- config = configs_by_kind[kind]
203
- filename = kind
204
- else:
205
- config, filename = load_config(filename)
200
+ config = configs_by_kind[kind]
206
201
 
207
- log.debug(f"Fetching '{key}' for '{vector_name}'")
208
202
  apiVersion = config.get('apiVersion')
209
- kind = config.get('kind')
210
- vac = config.get('vac')
211
203
 
212
- if not apiVersion or not kind:
213
- raise ValueError("Deprecated config file, move to config with `apiVersion` and `kind` set")
214
-
215
- log.debug(f"Loaded config file {kind}/{apiVersion}")
204
+ log.debug(f"Fetching '{key}' for '{vector_name}' from '{kind}/{apiVersion}'")
216
205
 
217
206
  if kind == 'vacConfig':
218
207
  if vector_name == 'global':
@@ -226,7 +215,7 @@ def load_config_key(key: str, vector_name: str, kind: str=None):
226
215
  raise ValueError("Deprecated config file, move to config with `vac:` at top level for `vector_name`")
227
216
  vac_config = vac.get(vector_name)
228
217
  if not vac_config:
229
- raise ValueError(f"No config array was found for {vector_name} in {filename}")
218
+ raise ValueError(f"No config array was found for {vector_name} in {kind}")
230
219
 
231
220
  log.debug(f'vac_config: {vac_config} for {vector_name} - fetching "{key}"')
232
221
  key_value = vac_config.get(key)
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.60.9
3
+ Version: 0.61.4
4
4
  Summary: Large Language Model DevOps - a package to help deploy LLMs to the Cloud.
5
5
  Home-page: https://github.com/sunholo-data/sunholo-py
6
- Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.60.9.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.61.4.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -1,13 +1,12 @@
1
1
  sunholo/__init__.py,sha256=0CdpufyRKWyZe7J7UKigL6j_qOorM-p0OjHIAuf9M38,864
2
2
  sunholo/logging.py,sha256=1jzfy4q9h5DNG4MjwtbTiM8keZxymlrZ0gDQEtGLMHY,11400
3
3
  sunholo/agents/__init__.py,sha256=CnlbVohPt-Doth9PyROSlN3P8xMV9j9yS19YE-wCS90,341
4
- sunholo/agents/chat_history.py,sha256=PbwYmw1TwzI8H-cwQIGgHZ6UIr2Qb-JWow0RG3ayLM8,5195
4
+ sunholo/agents/chat_history.py,sha256=bkII7PNEbGCaobu2Rnr2rM9dim3BCK0kM-tiWhoI1tw,5219
5
5
  sunholo/agents/dispatch_to_qa.py,sha256=h5qbcPqJ5JGa21T8Z5is7jbn4eG3P4xULLj_X25q3WM,8208
6
6
  sunholo/agents/langserve.py,sha256=FdhQjorAY2bMn2rpuabNT6bU3uqSKWrl8DjpH3L_V7k,4375
7
7
  sunholo/agents/pubsub.py,sha256=5hbbhbBGyVWRpt2sAGC5FEheYH1mCCwVUhZEB1S7vGg,1337
8
8
  sunholo/agents/route.py,sha256=0klBifx-QtMGsjq8HB04s9Bytm0nFXPYaWKeyt-S9S4,2356
9
9
  sunholo/agents/special_commands.py,sha256=PI4ADgFQvPDCeCpOeWIrD4bD432NYFeVcBBnkqTBWi8,6457
10
- sunholo/agents/test_chat_history.py,sha256=vPbPu0xREEs4J4X_zJKBY1f19Vy5yV05_CKfUUQqfFg,3923
11
10
  sunholo/agents/fastapi/__init__.py,sha256=S_pj4_bTUmDGoq_exaREHlOKThi0zTuGT0VZY0YfODQ,88
12
11
  sunholo/agents/fastapi/base.py,sha256=clk76cHbUAvU0OYJrRfCWX_5f0ACbhDsIzYBhI3wyoE,2514
13
12
  sunholo/agents/fastapi/qna_routes.py,sha256=DgK4Btu5XriOC1JaRQ4G_nWEjJfnQ0J5pyLanF6eF1g,3857
@@ -44,7 +43,7 @@ sunholo/components/__init__.py,sha256=RJGNEihwvRIiDScKis04RHJv4yZGI1UpXlOmuCptNZ
44
43
  sunholo/components/llm.py,sha256=T4we3tGmqUj4tPwxQr9M6AXv_BALqZV_dRSvINan-oU,10374
45
44
  sunholo/components/prompt.py,sha256=eZSghXkIlRzXiSrzgkG7e5ytUYq6R6LV-qjHU8jStig,6353
46
45
  sunholo/components/retriever.py,sha256=_Lyt9RIgb2PD-rhV6oKAadiUs3ukT5uAYGW197tEskw,3755
47
- sunholo/components/vectorstore.py,sha256=dzspqOBtuxSjCFxem5_50sqwUUjbZ4oBYERtCwxZR6E,5619
46
+ sunholo/components/vectorstore.py,sha256=lB8vx_N6eBA44orNeVo1WRn0Q8GCIjvPPT9AfiPWBWE,5620
48
47
  sunholo/database/__init__.py,sha256=Zz0Shcq-CtStf9rJGIYB_Ybzb8rY_Q9mfSj-nviM490,241
49
48
  sunholo/database/alloydb.py,sha256=0zRLyeC9nACzj3v36ET9NqLeuzdwBJ2bE09CzgVTTFM,17098
50
49
  sunholo/database/database.py,sha256=doY05kG8BZBLL-arh4hq5ef1ouWOtGHqdsDc6M2YHgk,7345
@@ -89,16 +88,16 @@ sunholo/summarise/__init__.py,sha256=MZk3dblUMODcPb1crq4v-Z508NrFIpkSWNf9FIO8BcU
89
88
  sunholo/summarise/summarise.py,sha256=C3HhjepTjUhUC8FLk4jMQIBvq1BcORniwuTFHjPVhVo,3784
90
89
  sunholo/utils/__init__.py,sha256=G11nN_6ATjxpuMfG_BvcUr9UU8onPIgkpTK6CjOcbr8,48
91
90
  sunholo/utils/big_context.py,sha256=gJIP7_ZL-YSLhOMq8jmFTMqH1wq8eB1NK7oKPeZAq2s,5578
92
- sunholo/utils/config.py,sha256=3GSDFGbHugB3qlkHadKi3Z1CEr6EZhCOQ3TiNt03nNU,8594
91
+ sunholo/utils/config.py,sha256=M755G2VGVsfRvGBv2hM18KzFiSf5lJ6wj3ncDBCvWtg,8215
93
92
  sunholo/utils/config_schema.py,sha256=Wv-ncitzljOhgbDaq9qnFqH5LCuxNv59dTGDWgd1qdk,4189
94
93
  sunholo/utils/gcp.py,sha256=B2G1YKjeD7X9dqO86Jrp2vPuFwZ223Xl5Tg09Ndw-oc,5760
95
94
  sunholo/utils/parsers.py,sha256=OrHmASqIbI45atVOhiGodgLvnfrzkvVzyHnSvAXD89I,3841
96
95
  sunholo/utils/user_ids.py,sha256=SQd5_H7FE7vcTZp9AQuQDWBXd4FEEd7TeVMQe1H4Ny8,292
97
96
  sunholo/vertex/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
98
97
  sunholo/vertex/init_vertex.py,sha256=JDMUaBRdednzbKF-5p33qqLit2LMsvgvWW-NRz0AqO0,1801
99
- sunholo-0.60.9.dist-info/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
100
- sunholo-0.60.9.dist-info/METADATA,sha256=HRCIwV9y1sAi8Ft3p73fUff0wkaxHQ7V9CSN-1jwSzE,8057
101
- sunholo-0.60.9.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
102
- sunholo-0.60.9.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
103
- sunholo-0.60.9.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
104
- sunholo-0.60.9.dist-info/RECORD,,
98
+ sunholo-0.61.4.dist-info/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
99
+ sunholo-0.61.4.dist-info/METADATA,sha256=fNJFynKc9QQ-n26UaiizHapEY9hWrt-imjk3WBxlJqs,8057
100
+ sunholo-0.61.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
101
+ sunholo-0.61.4.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
102
+ sunholo-0.61.4.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
103
+ sunholo-0.61.4.dist-info/RECORD,,
@@ -1,119 +0,0 @@
1
- import pytest
2
- from .chat_history import *
3
-
4
-
5
- def test_extract_chat_history_null_input():
6
- assert extract_chat_history(None) == [], 'Expected empty list for null input'
7
-
8
-
9
- def test_extract_chat_history_no_chat():
10
- assert extract_chat_history([]) == [], 'Expected empty list for no chat history'
11
-
12
-
13
- def test_extract_chat_history_with_chat():
14
- chat_history = [('User', 'Hello'), ('Bot', 'Hi'), ('User', 'How are you?'), ('Bot', 'I am fine.')]
15
- expected_output = [('User', 'Hello'), ('Bot', 'Hi'), ('User', 'How are you?'), ('Bot', 'I am fine.')]
16
- assert extract_chat_history(chat_history) == expected_output, 'Expected list of paired messages for chat history'
17
-
18
-
19
- # Test cases for embeds_to_json function
20
-
21
- def test_embeds_to_json_no_embeds():
22
- message = 'Hello, world!'
23
- assert embeds_to_json(message) == '', 'Expected empty string for message with no embeds'
24
-
25
-
26
- def test_embeds_to_json_one_embed():
27
- message = 'Hello, world! [embed]'
28
- expected_output = '{"embeds": ["embed"]}'
29
- assert embeds_to_json(message) == expected_output, 'Expected JSON string with one embed for message with one embed'
30
-
31
-
32
- def test_embeds_to_json_multiple_embeds():
33
- message = 'Hello, world! [embed1] [embed2]'
34
- expected_output = '{"embeds": ["embed1", "embed2"]}'
35
- assert embeds_to_json(message) == expected_output, 'Expected JSON string with multiple embeds for message with multiple embeds'
36
-
37
-
38
- # Test cases for create_message_element function
39
-
40
- def test_create_message_element_text():
41
- message = {'text': 'Hello, world!'}
42
- assert create_message_element(message) == 'Hello, world!', 'Expected text element for message with text'
43
-
44
-
45
- def test_create_message_element_content():
46
- message = {'content': 'Hello, world!'}
47
- assert create_message_element(message) == 'Hello, world!', 'Expected content element for message with content'
48
-
49
-
50
- def test_create_message_element_no_text_or_content():
51
- message = {}
52
- with pytest.raises(KeyError):
53
- create_message_element(message)
54
-
55
-
56
- # Test cases for is_human function
57
-
58
- def test_is_human_name_human():
59
- message = {'name': 'Human'}
60
- assert is_human(message) == True, 'Expected True for message with name Human'
61
-
62
-
63
- def test_is_human_sender_type_human():
64
- message = {'sender': {'type': 'HUMAN'}}
65
- assert is_human(message) == True, 'Expected True for message with sender type HUMAN'
66
-
67
-
68
- def test_is_human_user_no_bot_id():
69
- message = {'user': 'User1', 'bot_id': None}
70
- assert is_human(message) == True, 'Expected True for message with user field and no bot_id field'
71
-
72
-
73
- def test_is_human_not_human():
74
- message = {'name': 'Bot'}
75
- assert is_human(message) == False, 'Expected False for message not from a human'
76
-
77
-
78
- # Test cases for is_bot function
79
-
80
- def test_is_bot_name_bot():
81
- message = {'name': 'Bot'}
82
- assert is_bot(message) == True, 'Expected True for message with name Bot'
83
-
84
-
85
- def test_is_bot_sender_type_bot():
86
- message = {'sender': {'type': 'BOT'}}
87
- assert is_bot(message) == True, 'Expected True for message with sender type BOT'
88
-
89
-
90
- def test_is_bot_with_bot_id():
91
- message = {'bot_id': 'bot1'}
92
- assert is_bot(message) == True, 'Expected True for message with bot_id field'
93
-
94
-
95
- def test_is_bot_not_bot():
96
- message = {'name': 'Human'}
97
- assert is_bot(message) == False, 'Expected False for message not from a bot'
98
-
99
-
100
- # Test cases for is_ai function
101
-
102
- def test_is_ai_name_ai():
103
- message = {'name': 'AI'}
104
- assert is_ai(message) == True, 'Expected True for message with name AI'
105
-
106
-
107
- def test_is_ai_sender_type_bot():
108
- message = {'sender': {'type': 'BOT'}}
109
- assert is_ai(message) == True, 'Expected True for message with sender type BOT'
110
-
111
-
112
- def test_is_ai_with_bot_id():
113
- message = {'bot_id': 'bot1'}
114
- assert is_ai(message) == True, 'Expected True for message with bot_id field'
115
-
116
-
117
- def test_is_ai_not_ai():
118
- message = {'name': 'Human'}
119
- assert is_ai(message) == False, 'Expected False for message not from an AI'