sunholo 0.84.3__tar.gz → 0.84.7__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.84.3 → sunholo-0.84.7}/PKG-INFO +2 -2
- {sunholo-0.84.3 → sunholo-0.84.7}/setup.py +1 -1
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/__init__.py +2 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/database/alloydb_client.py +4 -2
- sunholo-0.84.7/sunholo/genai/__init__.py +2 -0
- sunholo-0.84.7/sunholo/genai/process_funcs_cls.py +210 -0
- sunholo-0.84.7/sunholo/genai/safety.py +32 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/utils/parsers.py +8 -3
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo.egg-info/PKG-INFO +2 -2
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo.egg-info/SOURCES.txt +3 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/LICENSE.txt +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/MANIFEST.in +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/README.md +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/setup.cfg +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/agents/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/agents/chat_history.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/agents/dispatch_to_qa.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/agents/fastapi/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/agents/fastapi/base.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/agents/fastapi/qna_routes.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/agents/flask/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/agents/flask/base.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/agents/flask/qna_routes.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/agents/flask/vac_routes.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/agents/langserve.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/agents/pubsub.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/agents/route.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/agents/special_commands.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/agents/swagger.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/archive/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/archive/archive.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/auth/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/auth/gcloud.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/auth/refresh.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/auth/run.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/azure/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/azure/auth.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/azure/blobs.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/azure/event_grid.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/bots/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/bots/discord.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/bots/github_webhook.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/bots/webapp.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/chunker/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/chunker/azure.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/chunker/doc_handling.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/chunker/encode_metadata.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/chunker/images.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/chunker/loaders.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/chunker/message_data.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/chunker/pdfs.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/chunker/process_chunker_data.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/chunker/publish.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/chunker/pubsub.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/chunker/splitter.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/cli/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/cli/chat_vac.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/cli/cli.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/cli/cli_init.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/cli/configs.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/cli/deploy.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/cli/embedder.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/cli/merge_texts.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/cli/run_proxy.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/cli/sun_rich.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/cli/swagger.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/cli/vertex.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/components/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/components/llm.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/components/retriever.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/components/vectorstore.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/custom_logging.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/database/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/database/alloydb.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/database/database.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/database/lancedb.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/database/sql/sb/create_function.sql +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/database/sql/sb/create_function_time.sql +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/database/sql/sb/create_table.sql +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/database/sql/sb/delete_source_row.sql +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/database/sql/sb/return_sources.sql +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/database/sql/sb/setup.sql +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/database/static_dbs.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/database/uuid.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/discovery_engine/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/discovery_engine/chunker_handler.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/discovery_engine/create_new.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/discovery_engine/discovery_engine_client.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/discovery_engine/get_ai_search_chunks.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/embedder/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/embedder/embed_chunk.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/gcs/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/gcs/add_file.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/gcs/download_folder.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/gcs/download_url.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/gcs/metadata.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/invoke/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/invoke/async_class.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/invoke/direct_vac_func.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/invoke/invoke_vac_utils.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/langfuse/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/langfuse/callback.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/langfuse/prompts.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/llamaindex/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/llamaindex/get_files.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/llamaindex/import_files.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/llamaindex/llamaindex_class.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/llamaindex/user_history.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/lookup/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/lookup/model_lookup.yaml +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/patches/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/patches/langchain/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/patches/langchain/lancedb.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/patches/langchain/vertexai.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/pubsub/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/pubsub/process_pubsub.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/pubsub/pubsub_manager.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/qna/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/qna/parsers.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/qna/retry.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/streaming/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/streaming/content_buffer.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/streaming/langserve.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/streaming/stream_lookup.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/streaming/streaming.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/summarise/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/summarise/summarise.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/tools/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/tools/web_browser.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/utils/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/utils/api_key.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/utils/big_context.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/utils/config.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/utils/config_class.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/utils/config_schema.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/utils/gcp.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/utils/gcp_project.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/utils/timedelta.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/utils/user_ids.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/utils/version.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/vertex/__init__.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/vertex/extensions_call.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/vertex/extensions_class.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/vertex/genai_functions.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/vertex/init.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/vertex/memory_tools.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/vertex/safety.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo/vertex/type_dict_to_json.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo.egg-info/dependency_links.txt +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo.egg-info/entry_points.txt +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo.egg-info/requires.txt +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/sunholo.egg-info/top_level.txt +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/tests/test_chat_history.py +0 -0
- {sunholo-0.84.3 → sunholo-0.84.7}/tests/test_config.py +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sunholo
|
|
3
|
-
Version: 0.84.
|
|
3
|
+
Version: 0.84.7
|
|
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.84.
|
|
6
|
+
Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.84.7.tar.gz
|
|
7
7
|
Author: Holosun ApS
|
|
8
8
|
Author-email: multivac@sunholo.com
|
|
9
9
|
License: Apache License, Version 2.0
|
|
@@ -9,6 +9,7 @@ from . import database
|
|
|
9
9
|
from . import discovery_engine
|
|
10
10
|
from . import embedder
|
|
11
11
|
from . import gcs
|
|
12
|
+
from . import genai
|
|
12
13
|
from . import invoke
|
|
13
14
|
from . import langfuse
|
|
14
15
|
from . import llamaindex
|
|
@@ -34,6 +35,7 @@ __all__ = ['agents',
|
|
|
34
35
|
'discovery_engine',
|
|
35
36
|
'embedder',
|
|
36
37
|
'gcs',
|
|
38
|
+
'genai',
|
|
37
39
|
'invoke',
|
|
38
40
|
'langfuse',
|
|
39
41
|
'llamaindex',
|
|
@@ -71,7 +71,9 @@ class AlloyDBClient:
|
|
|
71
71
|
if ALLOYDB_DB is None and alloydb_config.get("database") is None:
|
|
72
72
|
log.warning("Could not locate ALLOYDB_DB environment variable or 'alloydb_config.database'")
|
|
73
73
|
|
|
74
|
-
self.database =
|
|
74
|
+
self.database = alloydb_config.get("database") or ALLOYDB_DB or db
|
|
75
|
+
if not self.database:
|
|
76
|
+
raise ValueError("Could not derive a database to query")
|
|
75
77
|
|
|
76
78
|
self.user = user
|
|
77
79
|
self.password = password
|
|
@@ -213,7 +215,7 @@ class AlloyDBClient:
|
|
|
213
215
|
|
|
214
216
|
query = f"""
|
|
215
217
|
SELECT page_content, source, langchain_metadata, images_gsurls, doc_id::text as doc_id
|
|
216
|
-
FROM {table_name}
|
|
218
|
+
FROM "{table_name}"
|
|
217
219
|
WHERE doc_id = '{doc_id}'
|
|
218
220
|
LIMIT 1;
|
|
219
221
|
"""
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import traceback
|
|
2
|
+
|
|
3
|
+
from ..custom_logging import log
|
|
4
|
+
from ..utils import ConfigManager
|
|
5
|
+
from .safety import genai_safety
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
8
|
+
|
|
9
|
+
try:
|
|
10
|
+
import google.generativeai as genai
|
|
11
|
+
except ImportError:
|
|
12
|
+
genai = None
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from google.generativeai.protos import Part
|
|
16
|
+
|
|
17
|
+
class GenAIFunctionProcessor:
|
|
18
|
+
"""
|
|
19
|
+
A generic class for processing function calls from google.generativeai function calling models.
|
|
20
|
+
|
|
21
|
+
This class provides a framework for handling multiple function calls in responses
|
|
22
|
+
from generative AI systems. Users of this class should subclass it and provide
|
|
23
|
+
their own implementation of the `construct_tools` method, which returns a dictionary
|
|
24
|
+
of function names mapped to their implementations.
|
|
25
|
+
|
|
26
|
+
Attributes:
|
|
27
|
+
config (ConfigManager): Configuration manager instance.
|
|
28
|
+
funcs (dict): A dictionary of function names mapped to their implementations.
|
|
29
|
+
|
|
30
|
+
Example usage:
|
|
31
|
+
```python
|
|
32
|
+
class AlloyDBFunctionProcessor(GenAIFunctionProcessor):
|
|
33
|
+
def construct_tools(self) -> dict:
|
|
34
|
+
...
|
|
35
|
+
|
|
36
|
+
config = ConfigManager()
|
|
37
|
+
alloydb_processor = AlloyDBFunctionProcessor(config)
|
|
38
|
+
|
|
39
|
+
results = alloydb_processor.process_funcs(full_response)
|
|
40
|
+
|
|
41
|
+
alloydb_model = alloydb_processor.get_model(
|
|
42
|
+
model_name="gemini-1.5-pro",
|
|
43
|
+
system_instruction="You are a helpful AlloyDB agent that helps users search and extract documents from the database."
|
|
44
|
+
)
|
|
45
|
+
```
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
def __init__(self, config: ConfigManager):
|
|
49
|
+
"""
|
|
50
|
+
Initializes the GenAIFunctionProcessor with the given configuration.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
config (ConfigManager): The configuration manager instance.
|
|
54
|
+
"""
|
|
55
|
+
if not genai:
|
|
56
|
+
raise ImportError("import google.generativeai as genai is required, import via `pip install sunholo[gcp]`")
|
|
57
|
+
|
|
58
|
+
self.config = config
|
|
59
|
+
self.funcs = self.construct_tools()
|
|
60
|
+
self.model_name = config.vacConfig("model") or "gemini-1.5-flash"
|
|
61
|
+
self._validate_functions()
|
|
62
|
+
|
|
63
|
+
def construct_tools(self) -> dict:
|
|
64
|
+
"""
|
|
65
|
+
Constructs a dictionary of tools (functions) specific to the application.
|
|
66
|
+
|
|
67
|
+
This method should be overridden in subclasses to provide the specific
|
|
68
|
+
function implementations required for the application.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
dict: A dictionary where keys are function names and values are function objects. e.g. {"my_func": my_func}
|
|
72
|
+
|
|
73
|
+
Raises:
|
|
74
|
+
NotImplementedError: If the method is not overridden in a subclass.
|
|
75
|
+
"""
|
|
76
|
+
raise NotImplementedError("Subclasses must implement this method to return a dictionary of functions.")
|
|
77
|
+
|
|
78
|
+
def _validate_functions(self):
|
|
79
|
+
"""
|
|
80
|
+
Validates that all functions in the `funcs` dictionary have docstrings.
|
|
81
|
+
|
|
82
|
+
This method checks each function in the `funcs` dictionary to ensure it has
|
|
83
|
+
a docstring. If a function is missing a docstring, an error is logged, and
|
|
84
|
+
a `ValueError` is raised.
|
|
85
|
+
|
|
86
|
+
Raises:
|
|
87
|
+
ValueError: If any function is missing a docstring.
|
|
88
|
+
"""
|
|
89
|
+
for func_name, func in self.funcs.items():
|
|
90
|
+
if not func.__doc__:
|
|
91
|
+
log.error(f"Function {func_name} is missing a docstring.")
|
|
92
|
+
raise ValueError(f"Function {func_name} must have a docstring to be used as a genai tool.")
|
|
93
|
+
|
|
94
|
+
def process_funcs(self, full_response, output_parts=True) -> list['Part'] | str:
|
|
95
|
+
"""
|
|
96
|
+
Processes the functions based on the full_response from the generative model.
|
|
97
|
+
|
|
98
|
+
This method iterates through each part of the response, extracts function
|
|
99
|
+
calls and their parameters, and executes the corresponding functions defined
|
|
100
|
+
in the `funcs` dictionary.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
full_response: The response object containing function calls.
|
|
104
|
+
output_parts (bool): Indicates whether to return structured parts or plain strings.
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
list[Part] | str: A list of Part objects or a formatted string with the results.
|
|
108
|
+
|
|
109
|
+
Example usage:
|
|
110
|
+
```python
|
|
111
|
+
results = alloydb_processor.process_funcs(full_response)
|
|
112
|
+
```
|
|
113
|
+
"""
|
|
114
|
+
api_requests_and_responses = []
|
|
115
|
+
|
|
116
|
+
# Loop through each part in the response to handle multiple function calls
|
|
117
|
+
#TODO: async
|
|
118
|
+
for part in full_response.candidates[0].content.parts:
|
|
119
|
+
if fn := part.function_call:
|
|
120
|
+
# Extract parameters for the function call
|
|
121
|
+
function_name = fn.name
|
|
122
|
+
params = {key: val for key, val in fn.args.items()}
|
|
123
|
+
log.info(f"Executing {function_name} with params {params}")
|
|
124
|
+
|
|
125
|
+
# Check if the function is in our dictionary of available functions
|
|
126
|
+
if function_name in self.funcs:
|
|
127
|
+
try:
|
|
128
|
+
# Execute the function with the provided parameters
|
|
129
|
+
result = self.funcs[function_name](**params)
|
|
130
|
+
log.info(f"Got result from {function_name}: {result}")
|
|
131
|
+
except Exception as err:
|
|
132
|
+
error_message = f"Error in {function_name}: {str(err)}"
|
|
133
|
+
traceback_details = traceback.format_exc()
|
|
134
|
+
log.warning(f"{error_message}\nTraceback: {traceback_details}")
|
|
135
|
+
result = [f"{error_message}\n{traceback_details}"]
|
|
136
|
+
|
|
137
|
+
api_requests_and_responses.append(
|
|
138
|
+
[function_name, params, result]
|
|
139
|
+
)
|
|
140
|
+
else:
|
|
141
|
+
log.error(f"Function {function_name} is not recognized")
|
|
142
|
+
|
|
143
|
+
log.info(f"{api_requests_and_responses=}")
|
|
144
|
+
|
|
145
|
+
if output_parts:
|
|
146
|
+
parts = []
|
|
147
|
+
for part in api_requests_and_responses:
|
|
148
|
+
parts.append(
|
|
149
|
+
Part(
|
|
150
|
+
function_response=genai.protos.FunctionResponse(
|
|
151
|
+
name=part[0],
|
|
152
|
+
response={"result": part[2]}
|
|
153
|
+
)
|
|
154
|
+
)
|
|
155
|
+
)
|
|
156
|
+
return parts
|
|
157
|
+
|
|
158
|
+
strings = []
|
|
159
|
+
for part in api_requests_and_responses:
|
|
160
|
+
strings.append(
|
|
161
|
+
f"function tool {part[0]} was called with arguments: {part[1]} and got this result:\n"
|
|
162
|
+
f"<{part[0]}_result>{part[2]}</{part[0]}_result>"
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
return strings
|
|
166
|
+
|
|
167
|
+
def get_model(self, system_instruction: str, generation_config=None, model_name: str=None):
|
|
168
|
+
"""
|
|
169
|
+
Constructs and returns the generative AI model configured with the tools.
|
|
170
|
+
|
|
171
|
+
This method creates a generative AI model using the tools defined in the
|
|
172
|
+
`funcs` dictionary and the provided configuration options.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
model_name (str): The name of the model to use.
|
|
176
|
+
system_instruction (str): Instructions for the AI system.
|
|
177
|
+
generation_config (dict, optional): Configuration for generation, such as temperature.
|
|
178
|
+
|
|
179
|
+
Returns:
|
|
180
|
+
GenerativeModel: An instance of the GenerativeModel configured with the provided tools.
|
|
181
|
+
|
|
182
|
+
Example usage:
|
|
183
|
+
```python
|
|
184
|
+
alloydb_model = alloydb_processor.get_model(
|
|
185
|
+
model_name="gemini-1.5-pro",
|
|
186
|
+
system_instruction="You are a helpful AlloyDB agent that helps users search and extract documents from the database."
|
|
187
|
+
)
|
|
188
|
+
```
|
|
189
|
+
"""
|
|
190
|
+
if generation_config is None:
|
|
191
|
+
generation_config = {
|
|
192
|
+
"temperature": 0.1,
|
|
193
|
+
"max_output_tokens": 4000,
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
# Extract the functions from the dictionary to pass into the model
|
|
197
|
+
tools = list(self.funcs.values())
|
|
198
|
+
|
|
199
|
+
try:
|
|
200
|
+
model = genai.GenerativeModel(
|
|
201
|
+
model_name=model_name or self.model_name,
|
|
202
|
+
tools=tools,
|
|
203
|
+
generation_config=generation_config,
|
|
204
|
+
safety_settings=genai_safety(),
|
|
205
|
+
system_instruction=system_instruction,
|
|
206
|
+
)
|
|
207
|
+
return model
|
|
208
|
+
except Exception as err:
|
|
209
|
+
log.error(f"Error initializing model: {str(err)}")
|
|
210
|
+
return None
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
|
|
2
|
+
def genai_safety(threshold: str = "BLOCK_ONLY_HIGH"):
|
|
3
|
+
"""
|
|
4
|
+
BLOCK_ONLY_HIGH - block when high probability of unsafe content is detected
|
|
5
|
+
BLOCK_MEDIUM_AND_ABOVE - block when medium or high probability of content is detected
|
|
6
|
+
BLOCK_LOW_AND_ABOVE - block when low, medium, or high probability of unsafe content is detected
|
|
7
|
+
BLOCK_NONE - no block, but need to be on an allow list to use
|
|
8
|
+
"""
|
|
9
|
+
from google.generativeai.types import (
|
|
10
|
+
HarmCategory,
|
|
11
|
+
HarmBlockThreshold
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
if threshold == 'BLOCK_ONLY_HIGH':
|
|
15
|
+
thresh = HarmBlockThreshold.BLOCK_ONLY_HIGH
|
|
16
|
+
elif threshold == 'BLOCK_MEDIUM_AND_ABOVE':
|
|
17
|
+
thresh = HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE
|
|
18
|
+
elif threshold == 'BLOCK_LOW_AND_ABOVE':
|
|
19
|
+
thresh = HarmBlockThreshold.BLOCK_LOW_AND_ABOVE
|
|
20
|
+
elif threshold == 'BLOCK_NONE':
|
|
21
|
+
thresh = HarmBlockThreshold.BLOCK_NONE
|
|
22
|
+
else:
|
|
23
|
+
raise ValueError("Invalid threshold")
|
|
24
|
+
|
|
25
|
+
safety_settings = {
|
|
26
|
+
HarmCategory.HARM_CATEGORY_HARASSMENT: thresh,
|
|
27
|
+
HarmCategory.HARM_CATEGORY_HATE_SPEECH: thresh,
|
|
28
|
+
HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: thresh,
|
|
29
|
+
HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: thresh,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return safety_settings
|
|
@@ -181,9 +181,14 @@ def escape_braces(text):
|
|
|
181
181
|
Returns:
|
|
182
182
|
str: The modified string with single braces converted to double braces.
|
|
183
183
|
"""
|
|
184
|
-
#
|
|
185
|
-
|
|
186
|
-
text = re.sub(r'(?<!
|
|
184
|
+
# First, handle cases where there might be a mix of braces
|
|
185
|
+
# Replace all `{` that are not followed by another `{` with `{{`
|
|
186
|
+
text = re.sub(r'(?<!{){(?!{)', '{{', text)
|
|
187
|
+
|
|
188
|
+
# Replace all `}` that are not preceded by another `}` with `}}`
|
|
189
|
+
text = re.sub(r'(?<!})}(?!})', '}}', text)
|
|
190
|
+
|
|
191
|
+
# After escaping single braces, return the modified text
|
|
187
192
|
return text
|
|
188
193
|
|
|
189
194
|
def get_clean_website_name(url: str):
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sunholo
|
|
3
|
-
Version: 0.84.
|
|
3
|
+
Version: 0.84.7
|
|
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.84.
|
|
6
|
+
Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.84.7.tar.gz
|
|
7
7
|
Author: Holosun ApS
|
|
8
8
|
Author-email: multivac@sunholo.com
|
|
9
9
|
License: Apache License, Version 2.0
|
|
@@ -93,6 +93,9 @@ sunholo/gcs/add_file.py
|
|
|
93
93
|
sunholo/gcs/download_folder.py
|
|
94
94
|
sunholo/gcs/download_url.py
|
|
95
95
|
sunholo/gcs/metadata.py
|
|
96
|
+
sunholo/genai/__init__.py
|
|
97
|
+
sunholo/genai/process_funcs_cls.py
|
|
98
|
+
sunholo/genai/safety.py
|
|
96
99
|
sunholo/invoke/__init__.py
|
|
97
100
|
sunholo/invoke/async_class.py
|
|
98
101
|
sunholo/invoke/direct_vac_func.py
|
|
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
|
|
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
|