sunholo 0.71.28__tar.gz → 0.72.0__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.
- {sunholo-0.71.28 → sunholo-0.72.0}/PKG-INFO +6 -4
- {sunholo-0.71.28 → sunholo-0.72.0}/setup.py +6 -3
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/gcs/__init__.py +1 -1
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/gcs/download_url.py +15 -0
- sunholo-0.72.0/sunholo/utils/__init__.py +2 -0
- sunholo-0.72.0/sunholo/utils/config_class.py +207 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo.egg-info/PKG-INFO +6 -4
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo.egg-info/SOURCES.txt +1 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo.egg-info/requires.txt +4 -2
- sunholo-0.71.28/sunholo/utils/__init__.py +0 -1
- {sunholo-0.71.28 → sunholo-0.72.0}/LICENSE.txt +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/MANIFEST.in +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/README.md +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/setup.cfg +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/agents/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/agents/chat_history.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/agents/dispatch_to_qa.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/agents/fastapi/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/agents/fastapi/base.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/agents/fastapi/qna_routes.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/agents/flask/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/agents/flask/base.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/agents/flask/qna_routes.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/agents/flask/vac_routes.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/agents/langserve.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/agents/pubsub.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/agents/route.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/agents/special_commands.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/agents/swagger.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/archive/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/archive/archive.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/auth/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/auth/run.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/bots/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/bots/discord.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/bots/github_webhook.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/bots/webapp.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/chunker/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/chunker/data_to_embed_pubsub.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/chunker/doc_handling.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/chunker/images.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/chunker/loaders.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/chunker/message_data.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/chunker/pdfs.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/chunker/publish.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/chunker/splitter.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/cli/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/cli/chat_vac.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/cli/cli.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/cli/cli_init.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/cli/configs.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/cli/deploy.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/cli/embedder.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/cli/merge_texts.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/cli/run_proxy.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/cli/sun_rich.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/cli/swagger.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/components/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/components/llm.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/components/retriever.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/components/vectorstore.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/database/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/database/alloydb.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/database/alloydb_client.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/database/database.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/database/lancedb.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/database/sql/sb/create_function.sql +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/database/sql/sb/create_function_time.sql +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/database/sql/sb/create_table.sql +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/database/sql/sb/delete_source_row.sql +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/database/sql/sb/return_sources.sql +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/database/sql/sb/setup.sql +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/database/static_dbs.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/database/uuid.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/discovery_engine/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/discovery_engine/chunker_handler.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/discovery_engine/create_new.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/discovery_engine/discovery_engine_client.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/embedder/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/embedder/embed_chunk.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/gcs/add_file.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/gcs/metadata.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/langfuse/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/langfuse/callback.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/langfuse/prompts.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/llamaindex/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/llamaindex/generate.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/llamaindex/get_files.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/llamaindex/import_files.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/logging.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/lookup/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/lookup/model_lookup.yaml +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/patches/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/patches/langchain/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/patches/langchain/lancedb.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/patches/langchain/vertexai.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/pubsub/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/pubsub/process_pubsub.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/pubsub/pubsub_manager.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/qna/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/qna/parsers.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/qna/retry.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/streaming/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/streaming/content_buffer.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/streaming/langserve.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/streaming/stream_lookup.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/streaming/streaming.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/summarise/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/summarise/summarise.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/tools/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/tools/web_browser.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/utils/api_key.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/utils/big_context.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/utils/config.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/utils/config_schema.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/utils/gcp.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/utils/gcp_project.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/utils/parsers.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/utils/timedelta.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/utils/user_ids.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/utils/version.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/vertex/__init__.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/vertex/extensions.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/vertex/extensions_class.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/vertex/init.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/vertex/memory_tools.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo/vertex/safety.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo.egg-info/dependency_links.txt +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo.egg-info/entry_points.txt +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/sunholo.egg-info/top_level.txt +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/tests/test_chat_history.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/tests/test_chunker.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/tests/test_config.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/tests/test_dispatch_to_qa.py +0 -0
- {sunholo-0.71.28 → sunholo-0.72.0}/tests/test_swagger.py +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sunholo
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.72.0
|
|
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.
|
|
6
|
+
Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.72.0.tar.gz
|
|
7
7
|
Author: Holosun ApS
|
|
8
8
|
Author-email: multivac@sunholo.com
|
|
9
9
|
License: Apache License, Version 2.0
|
|
@@ -56,6 +56,7 @@ Requires-Dist: langchain-anthropic>=0.1.13; extra == "all"
|
|
|
56
56
|
Requires-Dist: langfuse; extra == "all"
|
|
57
57
|
Requires-Dist: pg8000; extra == "all"
|
|
58
58
|
Requires-Dist: pgvector; extra == "all"
|
|
59
|
+
Requires-Dist: pillow; extra == "all"
|
|
59
60
|
Requires-Dist: playwright; extra == "all"
|
|
60
61
|
Requires-Dist: psycopg2-binary; extra == "all"
|
|
61
62
|
Requires-Dist: pypdf; extra == "all"
|
|
@@ -87,6 +88,8 @@ Requires-Dist: pytesseract; extra == "pipeline"
|
|
|
87
88
|
Requires-Dist: tabulate; extra == "pipeline"
|
|
88
89
|
Requires-Dist: unstructured[local-inference]; extra == "pipeline"
|
|
89
90
|
Provides-Extra: gcp
|
|
91
|
+
Requires-Dist: google-api-python-client; extra == "gcp"
|
|
92
|
+
Requires-Dist: google-cloud-alloydb-connector[pg8000]; extra == "gcp"
|
|
90
93
|
Requires-Dist: google-auth-httplib2; extra == "gcp"
|
|
91
94
|
Requires-Dist: google-auth-oauthlib; extra == "gcp"
|
|
92
95
|
Requires-Dist: google-cloud-aiplatform; extra == "gcp"
|
|
@@ -100,8 +103,7 @@ Requires-Dist: google-cloud-discoveryengine; extra == "gcp"
|
|
|
100
103
|
Requires-Dist: google-generativeai>=0.7.1; extra == "gcp"
|
|
101
104
|
Requires-Dist: langchain-google-genai>=1.0.5; extra == "gcp"
|
|
102
105
|
Requires-Dist: langchain_google_alloydb_pg>=0.2.2; extra == "gcp"
|
|
103
|
-
Requires-Dist:
|
|
104
|
-
Requires-Dist: google-cloud-alloydb-connector[pg8000]; extra == "gcp"
|
|
106
|
+
Requires-Dist: pillow; extra == "gcp"
|
|
105
107
|
Provides-Extra: openai
|
|
106
108
|
Requires-Dist: langchain-openai; extra == "openai"
|
|
107
109
|
Requires-Dist: tiktoken; extra == "openai"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from setuptools import setup, find_packages
|
|
2
2
|
|
|
3
3
|
# Define your base version
|
|
4
|
-
version = '0.
|
|
4
|
+
version = '0.72.0'
|
|
5
5
|
|
|
6
6
|
setup(
|
|
7
7
|
name='sunholo',
|
|
@@ -71,6 +71,7 @@ setup(
|
|
|
71
71
|
"langfuse",
|
|
72
72
|
"pg8000",
|
|
73
73
|
"pgvector",
|
|
74
|
+
"pillow",
|
|
74
75
|
"playwright",
|
|
75
76
|
"psycopg2-binary",
|
|
76
77
|
"pypdf",
|
|
@@ -107,6 +108,8 @@ setup(
|
|
|
107
108
|
"unstructured[local-inference]",
|
|
108
109
|
],
|
|
109
110
|
'gcp': [
|
|
111
|
+
"google-api-python-client",
|
|
112
|
+
"google-cloud-alloydb-connector[pg8000]",
|
|
110
113
|
"google-auth-httplib2",
|
|
111
114
|
"google-auth-oauthlib",
|
|
112
115
|
"google-cloud-aiplatform",
|
|
@@ -120,8 +123,8 @@ setup(
|
|
|
120
123
|
"google-generativeai>=0.7.1",
|
|
121
124
|
"langchain-google-genai>=1.0.5",
|
|
122
125
|
"langchain_google_alloydb_pg>=0.2.2",
|
|
123
|
-
"
|
|
124
|
-
|
|
126
|
+
"pillow",
|
|
127
|
+
|
|
125
128
|
],
|
|
126
129
|
'openai': [
|
|
127
130
|
"langchain-openai",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
from .download_url import construct_download_link, get_bytes_from_gcs
|
|
1
|
+
from .download_url import construct_download_link, get_bytes_from_gcs, get_image_from_gcs
|
|
@@ -14,12 +14,27 @@ except ImportError:
|
|
|
14
14
|
|
|
15
15
|
from ..logging import log
|
|
16
16
|
from ..utils.gcp import is_running_on_gcp
|
|
17
|
+
from io import BytesIO
|
|
18
|
+
try:
|
|
19
|
+
from PIL import Image
|
|
20
|
+
except ImportError:
|
|
21
|
+
Image = None
|
|
17
22
|
|
|
18
23
|
gcs_credentials = None
|
|
19
24
|
project_id = None
|
|
20
25
|
gcs_client = None
|
|
21
26
|
gcs_bucket_cache = {}
|
|
22
27
|
|
|
28
|
+
def get_image_from_gcs(gs_uri: str):
|
|
29
|
+
"""Converts image bytes from GCS to a PIL Image object."""
|
|
30
|
+
image_bytes = get_bytes_from_gcs(gs_uri)
|
|
31
|
+
if not Image:
|
|
32
|
+
raise ImportError('Could not import PIL (pillow) - install via `pip install sunholo[gcp]`')
|
|
33
|
+
try:
|
|
34
|
+
img = Image.open(BytesIO(image_bytes))
|
|
35
|
+
return img
|
|
36
|
+
except IOError as e:
|
|
37
|
+
raise ValueError("Unable to open image from bytes:", e)
|
|
23
38
|
|
|
24
39
|
def get_bytes_from_gcs(gs_uri):
|
|
25
40
|
"""
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import json
|
|
3
|
+
import yaml
|
|
4
|
+
from datetime import datetime, timedelta
|
|
5
|
+
from collections import defaultdict
|
|
6
|
+
from .timedelta import format_timedelta
|
|
7
|
+
|
|
8
|
+
class ConfigManager:
|
|
9
|
+
def __init__(self, vector_name: str):
|
|
10
|
+
"""
|
|
11
|
+
Initialize the ConfigManager with a vector name.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
vector_name (str): The name of the vector in the configuration files.
|
|
15
|
+
|
|
16
|
+
Example:
|
|
17
|
+
```python
|
|
18
|
+
# Usage example:
|
|
19
|
+
config = ConfigManager("myVector")
|
|
20
|
+
agent = config.vacConfig("agent")
|
|
21
|
+
```
|
|
22
|
+
"""
|
|
23
|
+
self.vector_name = vector_name
|
|
24
|
+
self.config_cache = {}
|
|
25
|
+
self.config_folder = os.getenv("VAC_CONFIG_FOLDER", os.getcwd())
|
|
26
|
+
self.local_config_folder = os.path.join(os.getcwd(), "config")
|
|
27
|
+
self.configs_by_kind = self.load_all_configs()
|
|
28
|
+
|
|
29
|
+
def load_all_configs(self):
|
|
30
|
+
"""
|
|
31
|
+
Load all configuration files from the specified directories into a dictionary.
|
|
32
|
+
Caching is used to avoid reloading files within a 5-minute window.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
dict: A dictionary of configurations grouped by their 'kind' key.
|
|
36
|
+
"""
|
|
37
|
+
from ..logging import log
|
|
38
|
+
|
|
39
|
+
log.debug(f"Loading all configs from folder: {self.config_folder} and local folder: {self.local_config_folder}")
|
|
40
|
+
global_configs_by_kind = self._load_configs_from_folder(self.config_folder)
|
|
41
|
+
local_configs_by_kind = self._load_configs_from_folder(self.local_config_folder)
|
|
42
|
+
|
|
43
|
+
# Merge local configs into global configs
|
|
44
|
+
for kind, local_config in local_configs_by_kind.items():
|
|
45
|
+
if kind in global_configs_by_kind:
|
|
46
|
+
global_configs_by_kind[kind] = self._merge_dicts(global_configs_by_kind[kind], local_config)
|
|
47
|
+
else:
|
|
48
|
+
global_configs_by_kind[kind] = local_config
|
|
49
|
+
|
|
50
|
+
return global_configs_by_kind
|
|
51
|
+
|
|
52
|
+
def _load_configs_from_folder(self, folder):
|
|
53
|
+
"""
|
|
54
|
+
Load all configuration files from a specific folder into a dictionary.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
folder (str): The path of the folder to load configurations from.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
dict: A dictionary of configurations grouped by their 'kind' key.
|
|
61
|
+
"""
|
|
62
|
+
from ..logging import log
|
|
63
|
+
|
|
64
|
+
configs_by_kind = defaultdict(dict)
|
|
65
|
+
current_time = datetime.now()
|
|
66
|
+
|
|
67
|
+
for filename in os.listdir(folder):
|
|
68
|
+
if filename in ["cloudbuild.yaml", "cloud_run_urls.json"]:
|
|
69
|
+
continue
|
|
70
|
+
if filename.endswith(('.yaml', '.yml', '.json')):
|
|
71
|
+
config_file = os.path.join(folder, filename)
|
|
72
|
+
if filename in self.config_cache:
|
|
73
|
+
cached_config, cache_time = self.config_cache[filename]
|
|
74
|
+
time_to_recache = (current_time - cache_time)
|
|
75
|
+
if time_to_recache < timedelta(minutes=5):
|
|
76
|
+
config = cached_config
|
|
77
|
+
else:
|
|
78
|
+
config = self._reload_config_file(config_file, filename, folder == self.local_config_folder)
|
|
79
|
+
else:
|
|
80
|
+
config = self._reload_config_file(config_file, filename, folder == self.local_config_folder)
|
|
81
|
+
kind = config.get('kind')
|
|
82
|
+
if kind:
|
|
83
|
+
configs_by_kind[kind] = config
|
|
84
|
+
else:
|
|
85
|
+
log.warning(f"No 'kind' found in {filename}")
|
|
86
|
+
return configs_by_kind
|
|
87
|
+
|
|
88
|
+
def _reload_config_file(self, config_file, filename, is_local=False):
|
|
89
|
+
"""
|
|
90
|
+
Helper function to load a config file and update the cache.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
config_file (str): The path to the configuration file.
|
|
94
|
+
filename (str): The name of the configuration file.
|
|
95
|
+
is_local (bool): Indicates if the config file is from the local folder.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
dict: The loaded configuration.
|
|
99
|
+
"""
|
|
100
|
+
from ..logging import log
|
|
101
|
+
with open(config_file, 'r') as file:
|
|
102
|
+
if filename.endswith('.json'):
|
|
103
|
+
config = json.load(file)
|
|
104
|
+
else:
|
|
105
|
+
config = yaml.safe_load(file)
|
|
106
|
+
self.config_cache[filename] = (config, datetime.now())
|
|
107
|
+
log.debug(f"Loaded and cached {config_file}")
|
|
108
|
+
if is_local:
|
|
109
|
+
log.warning(f"Local configuration override for {filename}")
|
|
110
|
+
return config
|
|
111
|
+
|
|
112
|
+
def _check_and_reload_configs(self):
|
|
113
|
+
"""
|
|
114
|
+
Check if configurations are older than 5 minutes and reload if necessary.
|
|
115
|
+
"""
|
|
116
|
+
current_time = datetime.now()
|
|
117
|
+
for filename, (config, cache_time) in list(self.config_cache.items()):
|
|
118
|
+
if (current_time - cache_time) >= timedelta(minutes=5):
|
|
119
|
+
config_file_main = os.path.join(self.config_folder, filename)
|
|
120
|
+
config_file_local = os.path.join(self.local_config_folder, filename)
|
|
121
|
+
if os.path.exists(config_file_local):
|
|
122
|
+
self._reload_config_file(config_file_local, filename, is_local=True)
|
|
123
|
+
if os.path.exists(config_file_main):
|
|
124
|
+
self._reload_config_file(config_file_main, filename, is_local=False)
|
|
125
|
+
self.configs_by_kind = self.load_all_configs()
|
|
126
|
+
|
|
127
|
+
def _merge_dicts(self, dict1, dict2):
|
|
128
|
+
"""
|
|
129
|
+
Recursively merge two dictionaries. Local values in dict2 will overwrite global values in dict1.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
dict1 (dict): The global dictionary.
|
|
133
|
+
dict2 (dict): The local dictionary.
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
dict: The merged dictionary.
|
|
137
|
+
"""
|
|
138
|
+
for key, value in dict2.items():
|
|
139
|
+
if isinstance(value, dict) and key in dict1 and isinstance(dict1[key], dict):
|
|
140
|
+
dict1[key] = self._merge_dicts(dict1[key], value)
|
|
141
|
+
else:
|
|
142
|
+
dict1[key] = value
|
|
143
|
+
return dict1
|
|
144
|
+
|
|
145
|
+
def vacConfig(self, key: str):
|
|
146
|
+
"""
|
|
147
|
+
Fetch a key from 'vacConfig' kind configuration.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
key (str): The key to fetch from the configuration.
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
str: The value associated with the specified key.
|
|
154
|
+
"""
|
|
155
|
+
self._check_and_reload_configs()
|
|
156
|
+
config = self.configs_by_kind.get('vacConfig')
|
|
157
|
+
if not config:
|
|
158
|
+
return None
|
|
159
|
+
if self.vector_name == 'global':
|
|
160
|
+
return config.get(key)
|
|
161
|
+
vac = config['vac']
|
|
162
|
+
|
|
163
|
+
vac_config = vac.get(self.vector_name)
|
|
164
|
+
if not vac_config:
|
|
165
|
+
return None
|
|
166
|
+
return vac_config.get(key)
|
|
167
|
+
|
|
168
|
+
def promptConfig(self, key: str):
|
|
169
|
+
"""
|
|
170
|
+
Fetch a key from 'promptConfig' kind configuration.
|
|
171
|
+
|
|
172
|
+
Args:
|
|
173
|
+
key (str): The key to fetch from the configuration.
|
|
174
|
+
|
|
175
|
+
Returns:
|
|
176
|
+
str: The value associated with the specified key.
|
|
177
|
+
"""
|
|
178
|
+
self._check_and_reload_configs()
|
|
179
|
+
config = self.configs_by_kind.get('promptConfig')
|
|
180
|
+
if not config:
|
|
181
|
+
return None
|
|
182
|
+
prompts = config['prompts']
|
|
183
|
+
prompt_for_vector_name = prompts.get(self.vector_name)
|
|
184
|
+
if not prompt_for_vector_name:
|
|
185
|
+
return None
|
|
186
|
+
return prompt_for_vector_name.get(key)
|
|
187
|
+
|
|
188
|
+
def agentConfig(self, key: str):
|
|
189
|
+
"""
|
|
190
|
+
Fetch a key from 'agentConfig' kind configuration.
|
|
191
|
+
|
|
192
|
+
Args:
|
|
193
|
+
key (str): The key to fetch from the configuration.
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
str: The value associated with the specified key.
|
|
197
|
+
"""
|
|
198
|
+
self._check_and_reload_configs()
|
|
199
|
+
config = self.configs_by_kind.get('agentConfig')
|
|
200
|
+
if not config:
|
|
201
|
+
return None
|
|
202
|
+
agents = config.get('agents')
|
|
203
|
+
if key in agents:
|
|
204
|
+
return agents[key]
|
|
205
|
+
else:
|
|
206
|
+
return agents.get("default")
|
|
207
|
+
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sunholo
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.72.0
|
|
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.
|
|
6
|
+
Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.72.0.tar.gz
|
|
7
7
|
Author: Holosun ApS
|
|
8
8
|
Author-email: multivac@sunholo.com
|
|
9
9
|
License: Apache License, Version 2.0
|
|
@@ -56,6 +56,7 @@ Requires-Dist: langchain-anthropic>=0.1.13; extra == "all"
|
|
|
56
56
|
Requires-Dist: langfuse; extra == "all"
|
|
57
57
|
Requires-Dist: pg8000; extra == "all"
|
|
58
58
|
Requires-Dist: pgvector; extra == "all"
|
|
59
|
+
Requires-Dist: pillow; extra == "all"
|
|
59
60
|
Requires-Dist: playwright; extra == "all"
|
|
60
61
|
Requires-Dist: psycopg2-binary; extra == "all"
|
|
61
62
|
Requires-Dist: pypdf; extra == "all"
|
|
@@ -87,6 +88,8 @@ Requires-Dist: pytesseract; extra == "pipeline"
|
|
|
87
88
|
Requires-Dist: tabulate; extra == "pipeline"
|
|
88
89
|
Requires-Dist: unstructured[local-inference]; extra == "pipeline"
|
|
89
90
|
Provides-Extra: gcp
|
|
91
|
+
Requires-Dist: google-api-python-client; extra == "gcp"
|
|
92
|
+
Requires-Dist: google-cloud-alloydb-connector[pg8000]; extra == "gcp"
|
|
90
93
|
Requires-Dist: google-auth-httplib2; extra == "gcp"
|
|
91
94
|
Requires-Dist: google-auth-oauthlib; extra == "gcp"
|
|
92
95
|
Requires-Dist: google-cloud-aiplatform; extra == "gcp"
|
|
@@ -100,8 +103,7 @@ Requires-Dist: google-cloud-discoveryengine; extra == "gcp"
|
|
|
100
103
|
Requires-Dist: google-generativeai>=0.7.1; extra == "gcp"
|
|
101
104
|
Requires-Dist: langchain-google-genai>=1.0.5; extra == "gcp"
|
|
102
105
|
Requires-Dist: langchain_google_alloydb_pg>=0.2.2; extra == "gcp"
|
|
103
|
-
Requires-Dist:
|
|
104
|
-
Requires-Dist: google-cloud-alloydb-connector[pg8000]; extra == "gcp"
|
|
106
|
+
Requires-Dist: pillow; extra == "gcp"
|
|
105
107
|
Provides-Extra: openai
|
|
106
108
|
Requires-Dist: langchain-openai; extra == "openai"
|
|
107
109
|
Requires-Dist: tiktoken; extra == "openai"
|
|
@@ -37,6 +37,7 @@ langchain-anthropic>=0.1.13
|
|
|
37
37
|
langfuse
|
|
38
38
|
pg8000
|
|
39
39
|
pgvector
|
|
40
|
+
pillow
|
|
40
41
|
playwright
|
|
41
42
|
psycopg2-binary
|
|
42
43
|
pypdf
|
|
@@ -67,6 +68,8 @@ lancedb
|
|
|
67
68
|
tantivy
|
|
68
69
|
|
|
69
70
|
[gcp]
|
|
71
|
+
google-api-python-client
|
|
72
|
+
google-cloud-alloydb-connector[pg8000]
|
|
70
73
|
google-auth-httplib2
|
|
71
74
|
google-auth-oauthlib
|
|
72
75
|
google-cloud-aiplatform
|
|
@@ -80,8 +83,7 @@ google-cloud-discoveryengine
|
|
|
80
83
|
google-generativeai>=0.7.1
|
|
81
84
|
langchain-google-genai>=1.0.5
|
|
82
85
|
langchain_google_alloydb_pg>=0.2.2
|
|
83
|
-
|
|
84
|
-
google-cloud-alloydb-connector[pg8000]
|
|
86
|
+
pillow
|
|
85
87
|
|
|
86
88
|
[http]
|
|
87
89
|
fastapi
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from .config import load_config_key, load_config
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|