sunholo 0.82.2__py3-none-any.whl → 0.83.1__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.
@@ -23,6 +23,7 @@ from ...streaming import start_streaming_chat
23
23
  from ...archive import archive_qa
24
24
  from ...custom_logging import log
25
25
  from ...utils.config import load_config
26
+ from ...utils import ConfigManager
26
27
  from ...utils.version import sunholo_version
27
28
  import os
28
29
  from ...gcs.add_file import add_file_to_gcs, handle_base64_image
@@ -183,6 +184,15 @@ def register_qna_routes(app, stream_interpreter, vac_interpreter):
183
184
  generation.end(output=response)
184
185
  span.end(output=response)
185
186
  trace.update(output=response)
187
+
188
+ #if 'user_id' in all_input["kwargs"]:
189
+ # kwargs = all_input["kwargs"]
190
+ # config = ConfigManager(vector_name)
191
+ # add_user_history_rag(kwargs.pop('user_id'),
192
+ # config,
193
+ # question=all_input.pop("user_input"),
194
+ # answer=response.get('answer'),
195
+ # metadata=all_input)
186
196
 
187
197
  return response
188
198
 
sunholo/cli/chat_vac.py CHANGED
@@ -411,7 +411,7 @@ def resolve_service_url(args, no_config=False):
411
411
 
412
412
  def vac_command(args):
413
413
 
414
- config = ConfigManager(args.vac_name)
414
+
415
415
 
416
416
  if args.action == 'list':
417
417
 
@@ -426,6 +426,7 @@ def vac_command(args):
426
426
  return
427
427
 
428
428
  elif args.action == 'chat':
429
+ config = ConfigManager(args.vac_name)
429
430
  service_url = resolve_service_url(args)
430
431
  agent_name = config.vacConfig("agent")
431
432
 
@@ -466,7 +467,6 @@ def vac_command(args):
466
467
 
467
468
  invoke_vac(service_url, args.data, is_file=args.is_file)
468
469
 
469
-
470
470
  def list_cloud_run_services(project, region):
471
471
  """
472
472
  Lists all Cloud Run services the user has access to in a specific project and region.
@@ -583,4 +583,5 @@ def setup_vac_subparser(subparsers):
583
583
  invoke_parser.add_argument('data', help='Data to send to the VAC service (as JSON string).')
584
584
  invoke_parser.add_argument('--is-file', action='store_true', help='Indicate if the data argument is a file path')
585
585
 
586
- vac_parser.set_defaults(func=vac_command)
586
+ # If no subcommand is provided, print the help message
587
+ vac_parser.set_defaults(func=lambda args: vac_parser.print_help() if args.action is None else vac_command(args))
sunholo/cli/cli.py CHANGED
@@ -13,6 +13,7 @@ from .vertex import setup_vertex_subparser
13
13
  from ..llamaindex import setup_llamaindex_subparser
14
14
 
15
15
  from ..utils import ConfigManager
16
+ from ..utils.version import sunholo_version
16
17
 
17
18
  from ..custom_logging import log
18
19
 
@@ -63,7 +64,8 @@ def main(args=None):
63
64
  parser.add_argument('--debug', action='store_true', help='Enable debug output')
64
65
  parser.add_argument('--project', default=default_project, help='GCP project to list Cloud Run services from.')
65
66
  parser.add_argument('--region', default=default_region, help='Region to list Cloud Run services from.')
66
-
67
+ parser.add_argument('--version', action='store_true', help='Show the version and exit')
68
+
67
69
  subparsers = parser.add_subparsers(title='commands',
68
70
  description='Valid commands',
69
71
  help='Commands',
@@ -102,6 +104,10 @@ def main(args=None):
102
104
  log.setLevel(logging.WARNING)
103
105
  logging.getLogger().setLevel(logging.WARNING)
104
106
 
107
+ if args.version:
108
+ sunholo_version()
109
+ return
110
+
105
111
  if hasattr(args, 'func'):
106
112
  args.func(args)
107
113
  else:
@@ -3,7 +3,7 @@ try:
3
3
  import pg8000
4
4
  import sqlalchemy
5
5
  from sqlalchemy.exc import DatabaseError, ProgrammingError
6
- from google.cloud.alloydb.connector import Connector
6
+ from langchain_google_alloydb_pg import AlloyDBEngine
7
7
  except ImportError:
8
8
  AlloyDBEngine = None
9
9
  pass
@@ -42,16 +42,14 @@ class AlloyDBClient:
42
42
  region: str=None,
43
43
  cluster_name:str=None,
44
44
  instance_name:str=None,
45
- user:str=None,
46
- password=None,
45
+ user:str=None,
47
46
  db="postgres"):
48
47
  """Initializes the AlloyDB client.
49
48
  - project_id (str): GCP project ID where the AlloyDB instance resides.
50
49
  - region (str): The region where the AlloyDB instance is located.
51
50
  - cluster_name (str): The name of the AlloyDB cluster.
52
51
  - instance_name (str): The name of the AlloyDB instance.
53
- - user (str): The database user name.
54
- - password (str): The database user's password.
52
+ - user (str): If user is None will use the default service email
55
53
  - db_name (str): The name of the database.
56
54
  """
57
55
  if config is None:
@@ -61,6 +59,7 @@ class AlloyDBClient:
61
59
  alloydb_config = config.vacConfig("alloydb_config")
62
60
  if not alloydb_config:
63
61
  raise ValueError("Must specify vac.alloydb_config")
62
+ self.config = alloydb_config
64
63
  project_id = alloydb_config["project_id"]
65
64
  region = alloydb_config["region"]
66
65
  cluster_name = alloydb_config["cluster"]
@@ -70,33 +69,34 @@ class AlloyDBClient:
70
69
  if ALLOYDB_DB is None and alloydb_config.get("database") is None:
71
70
  log.warning("Could not locate ALLOYDB_DB environment variable or 'alloydb_config.database'")
72
71
 
73
- self.database = alloydb_config.get("database") or ALLOYDB_DB,
74
- self.connector = Connector()
75
- self.inst_uri = self._build_instance_uri(project_id, region, cluster_name, instance_name)
76
- self.engine = self._create_engine(self.inst_uri, user, password, db)
77
-
78
- def _build_instance_uri(self, project_id, region, cluster_name, instance_name):
79
- return f"projects/{project_id}/locations/{region}/clusters/{cluster_name}/instances/{instance_name}"
80
-
81
- def _create_engine(self, inst_uri, user, password, db):
82
- def getconn() -> pg8000.dbapi.Connection:
83
- conn = self.connector.connect(
84
- inst_uri,
85
- "pg8000",
86
- user=user,
87
- password=password,
88
- db=db,
89
- enable_iam_auth=True,
90
- )
91
- return conn
92
-
93
- engine = sqlalchemy.create_engine(
94
- "postgresql+pg8000://",
95
- isolation_level="AUTOCOMMIT",
96
- creator=getconn
72
+ self.database = alloydb_config.get("database") or ALLOYDB_DB
73
+
74
+ if user and not user.endswith(".iam"):
75
+ raise ValueError("If you supply an IAM user it must end with .iam e.g. 'sa-cloudbuild@multivac-deploy.iam'")
76
+
77
+ self.user = user
78
+ self.engine = self._create_engine()
79
+
80
+ def _create_engine(self):
81
+ if not AlloyDBEngine:
82
+ log.error("Can't create AlloyDBEngine - install via `pip install sunholo[gcp,database]`")
83
+ raise ValueError("Can't import AlloyDBEngine")
84
+
85
+ log.info("Inititaing AlloyDB Langchain engine for database: {self.database}")
86
+
87
+ from google.cloud.alloydb.connector import IPTypes
88
+ engine = AlloyDBEngine.from_instance(
89
+ project_id=self.config["project_id"],
90
+ region=self.config["region"],
91
+ cluster=self.config["cluster"],
92
+ instance=self.config["instance"],
93
+ user=self.user,
94
+ database=self.database,
95
+ ip_type=self.config.get("ip_type") or IPTypes.PRIVATE
97
96
  )
98
- engine.dialect.description_encoding = None
99
- log.info(f"Created AlloyDB engine for {inst_uri} and user: {user}")
97
+
98
+ log.info(f"Created AlloyDB engine for {engine}")
99
+
100
100
  return engine
101
101
 
102
102
  def execute_sql(self, sql_statement):
@@ -152,6 +152,20 @@ class AlloyDBClient:
152
152
  documents = await self.execute_sql_async(query)
153
153
  return documents
154
154
 
155
+ def get_sources_from_docstore(self, sources, vector_name, search_type="OR", just_source_name=False):
156
+ """Fetches sources from the docstore."""
157
+ if just_source_name:
158
+ query = self._list_sources_from_docstore(sources, vector_name=vector_name, search_type=search_type)
159
+ else:
160
+ query = self._get_sources_from_docstore(sources, vector_name=vector_name, search_type=search_type)
161
+
162
+ if not query:
163
+ return []
164
+
165
+ documents = self.execute_sql(query)
166
+
167
+ return documents
168
+
155
169
  def _get_sources_from_docstore(self, sources, vector_name, search_type="OR"):
156
170
  """Helper function to build the SQL query for fetching sources."""
157
171
  if not sources:
@@ -22,7 +22,7 @@ from .content_buffer import ContentBuffer, BufferStreamingStdOutCallbackHandler
22
22
  from ..qna.parsers import parse_output
23
23
 
24
24
  from ..custom_logging import log
25
- from ..utils import load_config_key
25
+ from ..utils import load_config_key, ConfigManager
26
26
  from ..utils.parsers import check_kwargs_support
27
27
 
28
28
  from .langserve import parse_langserve_token, parse_langserve_token_async
@@ -248,8 +248,9 @@ def generate_proxy_stream(stream_to_f, user_input, vector_name, chat_history, ge
248
248
  ):
249
249
  print(output) # Process each streaming output chunk
250
250
  """
251
- agent = load_config_key("agent", vector_name=vector_name, kind="vacConfig")
252
- agent_type = load_config_key("agent_type", vector_name=vector_name, kind="vacConfig")
251
+ config = ConfigManager(vector_name)
252
+ agent = config.vacConfig("agent")
253
+ agent_type = config.vacConfig("agent_type")
253
254
 
254
255
  def generate():
255
256
  json_buffer = ""
@@ -306,9 +307,10 @@ async def generate_proxy_stream_async(stream_to_f, user_input, vector_name, chat
306
307
  ):
307
308
  print(output) # Process each streaming output chunk
308
309
  """
309
- agent = load_config_key("agent", vector_name=vector_name, kind="vacConfig")
310
- agent_type = load_config_key("agent_type", vector_name=vector_name, kind="vacConfig")
311
-
310
+ config = ConfigManager(vector_name)
311
+ agent = config.vacConfig("agent")
312
+ agent_type = config.vacConfig("agent_type")
313
+
312
314
  async def generate():
313
315
  json_buffer = ""
314
316
  inside_json = False
@@ -133,8 +133,8 @@ def get_google_search_grounding(vector_name:str=None, config:ConfigManager=None)
133
133
  config = ConfigManager(vector_name)
134
134
 
135
135
  # can't have this and llamaindex memories?
136
- ground = config.vacConfig("grounding")
137
- if ground and ground.get("google_search"):
136
+ tools = config.vacConfig("tools")
137
+ if tools and tools.get("google_search"):
138
138
  gs_tool = Tool.from_google_search_retrieval(grounding.GoogleSearchRetrieval())
139
139
  log.info(f"Got Search Tool: {gs_tool}")
140
140
  return gs_tool
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.82.2
3
+ Version: 0.83.1
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.82.2.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.83.1.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -13,7 +13,7 @@ sunholo/agents/fastapi/base.py,sha256=W-cyF8ZDUH40rc-c-Apw3-_8IIi2e4Y9qRtnoVnsc1
13
13
  sunholo/agents/fastapi/qna_routes.py,sha256=lKHkXPmwltu9EH3RMwmD153-J6pE7kWQ4BhBlV3to-s,3864
14
14
  sunholo/agents/flask/__init__.py,sha256=uqfHNw2Ru3EJ4dJEcbp86h_lkquBQPMxZbjhV_xe3rs,72
15
15
  sunholo/agents/flask/base.py,sha256=FgSaCODyoTtlstJtsqlLPScdgRUtv9_plxftdzHdVFo,809
16
- sunholo/agents/flask/qna_routes.py,sha256=pSXAipANqoE4wgDv4YD2_Sd7GvpGmFcj4Quslf4FKTM,22057
16
+ sunholo/agents/flask/qna_routes.py,sha256=uwUD1yrzOPH27m2AXpiQrPk_2VfJOQOM6dAynOWQtoQ,22532
17
17
  sunholo/agents/flask/vac_routes.py,sha256=JHBrz9URmRzxoNAiqEeI-5qWyKfVSZ1Ix__1t19p6HI,19527
18
18
  sunholo/archive/__init__.py,sha256=qNHWm5rGPVOlxZBZCpA1wTYPbalizRT7f8X4rs2t290,31
19
19
  sunholo/archive/archive.py,sha256=PxVfDtO2_2ZEEbnhXSCbXLdeoHoQVImo4y3Jr2XkCFY,1204
@@ -42,8 +42,8 @@ sunholo/chunker/publish.py,sha256=AX5u-fcyDytED67IfizMzvOMcYPXEo6XBJvyk_7maK8,29
42
42
  sunholo/chunker/pubsub.py,sha256=48bhuAcszN7LGe3-ksPSLHHhq0uKxiXOrizck5qpcP0,1012
43
43
  sunholo/chunker/splitter.py,sha256=QLAEsJOpEYFZr9-UGZUuAlNVyjfCWb8jvzCHg0rVShE,6751
44
44
  sunholo/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
- sunholo/cli/chat_vac.py,sha256=UNLzZYAejjEvMR0EjpxIHXyvUpBDoqThohzzFL_m3Yg,23026
46
- sunholo/cli/cli.py,sha256=yuY7SLFiYDUKqJDOXy7jL1l6P0UVPMuAZK9bXXTG8ck,3939
45
+ sunholo/cli/chat_vac.py,sha256=jTmCt62U4uqJjeGp_XfIbxnafAAOhQAJMi8TxSkeKlM,23164
46
+ sunholo/cli/cli.py,sha256=tnavBrQruyB-G56hGIQ86YkQbpCQQ4K3zvnoP8GrgCU,4135
47
47
  sunholo/cli/cli_init.py,sha256=JMZ9AX2cPDZ-_mv3adiv2ToFVNyRPtjk9Biszl1kiR0,2358
48
48
  sunholo/cli/configs.py,sha256=QUM9DvKOdZmEQRM5uI3Nh887T0YDiSMr7O240zTLqws,4546
49
49
  sunholo/cli/deploy.py,sha256=zxdwUsRTRMC8U5vyRv0JiKBLFn84Ug_Tc88-_h9hJSs,1609
@@ -59,7 +59,7 @@ sunholo/components/retriever.py,sha256=bKIVT7_18Ut3OJd0E0jyiISPnD9qkHWVjcQPT4i1_
59
59
  sunholo/components/vectorstore.py,sha256=xKk7micTRwZckaI7U6PxvFz_ZSjCH48xPTDYiDcv2tc,5913
60
60
  sunholo/database/__init__.py,sha256=bpB5Nk21kwqYj-qdVnvNgXjLsbflnH4g-San7OHMqR4,283
61
61
  sunholo/database/alloydb.py,sha256=YH8wNPS8gN-TDZEXQcVHxwd1NScHRfAxma3gK4R6KCk,11740
62
- sunholo/database/alloydb_client.py,sha256=vZu7m3n1TrGFqQ_F4kGgDEC-v_tnlJfByDGuI_4rrfw,11051
62
+ sunholo/database/alloydb_client.py,sha256=3Jdye7vTfAVQhAmEd5FjxBQ0a_iENFmvzoOIP-pNz6I,11554
63
63
  sunholo/database/database.py,sha256=VqhZdkXUNdvWn8sUcUV3YNby1JDVf7IykPVXWBtxo9U,7361
64
64
  sunholo/database/lancedb.py,sha256=DyfZntiFKBlVPaFooNN1Z6Pl-LAs4nxWKKuq8GBqN58,715
65
65
  sunholo/database/static_dbs.py,sha256=8cvcMwUK6c32AS2e_WguKXWMkFf5iN3g9WHzsh0C07Q,442
@@ -109,7 +109,7 @@ sunholo/streaming/__init__.py,sha256=MpbydI2UYo_adttPQFkxNM33b-QRyNEbrKJx0C2AGPc
109
109
  sunholo/streaming/content_buffer.py,sha256=A9rVhlmLZxaFPvGYjVqCs5GfIsA1EMl_tyk-0VCDvo4,6462
110
110
  sunholo/streaming/langserve.py,sha256=hi7q8WY8DPKrALl9m_dOMxWOdE-iEuk7YW05SVDFIX8,6514
111
111
  sunholo/streaming/stream_lookup.py,sha256=hYg1DbdSE_QNJ8ZB-ynXJlWgvFjrGvwoUsGJu_E0pRQ,360
112
- sunholo/streaming/streaming.py,sha256=9YpU8FchLz1rx-wQWFxeEueguKo9VatzJxTCGL4tWbw,16412
112
+ sunholo/streaming/streaming.py,sha256=5dRXo1wHYE0E91gll-939RShYTYxQMeVwAVCqFR13h0,16343
113
113
  sunholo/summarise/__init__.py,sha256=MZk3dblUMODcPb1crq4v-Z508NrFIpkSWNf9FIO8BcU,38
114
114
  sunholo/summarise/summarise.py,sha256=95A-6PXFGanjona8DvZPnnIHLbzZ2ip5hO0wOAJQhfw,3791
115
115
  sunholo/tools/__init__.py,sha256=5NuYpwwTX81qGUWvgwfItoSLXteNnp7KjgD7IPZUFjI,53
@@ -131,12 +131,12 @@ sunholo/vertex/extensions_call.py,sha256=QeQbL3aAHlc4_-SynOzooZ_3xkQWAlcgNmFBSwL
131
131
  sunholo/vertex/extensions_class.py,sha256=2QGW28lNjoMEnaoVb3QcqEDwphclIsZthnpLUi5_Ivo,21033
132
132
  sunholo/vertex/genai_functions.py,sha256=2z6grM9H0Z79Yzx88l8mE1wXck3bRa0TWvnqZZ9ifDc,2051
133
133
  sunholo/vertex/init.py,sha256=1OQwcPBKZYBTDPdyU7IM4X4OmiXLdsNV30C-fee2scQ,2875
134
- sunholo/vertex/memory_tools.py,sha256=pgSahVDh7GPEulu3nl-w0jb5lTClb4TCnVxPnMokNZY,7533
134
+ sunholo/vertex/memory_tools.py,sha256=q_phxgGX2TG2j2MXNULF2xGzQnQPENwjPN9nZ_A9Gh0,7526
135
135
  sunholo/vertex/safety.py,sha256=S9PgQT1O_BQAkcqauWncRJaydiP8Q_Jzmu9gxYfy1VA,2482
136
136
  sunholo/vertex/type_dict_to_json.py,sha256=uTzL4o9tJRao4u-gJOFcACgWGkBOtqACmb6ihvCErL8,4694
137
- sunholo-0.82.2.dist-info/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
138
- sunholo-0.82.2.dist-info/METADATA,sha256=VLKO28E-90cflxHCVUXlVpNoPZPHcTNOgzuCg7XNZdQ,7413
139
- sunholo-0.82.2.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
140
- sunholo-0.82.2.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
141
- sunholo-0.82.2.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
142
- sunholo-0.82.2.dist-info/RECORD,,
137
+ sunholo-0.83.1.dist-info/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
138
+ sunholo-0.83.1.dist-info/METADATA,sha256=yihJkACY1C9pmb-C1dCKwI714WHSYVr_DkcCrPU_gCs,7413
139
+ sunholo-0.83.1.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
140
+ sunholo-0.83.1.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
141
+ sunholo-0.83.1.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
142
+ sunholo-0.83.1.dist-info/RECORD,,