sunholo 0.114.2__tar.gz → 0.115.1__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.114.2 → sunholo-0.115.1}/PKG-INFO +16 -12
- {sunholo-0.114.2 → sunholo-0.115.1}/setup.py +17 -13
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/__init__.py +0 -2
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/chunker/message_data.py +1 -4
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/chunker/pdfs.py +1 -1
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/chunker/publish.py +1 -5
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/chunker/splitter.py +6 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/cli/cli_init.py +3 -1
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/components/llm.py +1 -1
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/components/vectorstore.py +1 -1
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/embedder/embed_chunk.py +3 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/senses/stream_voice.py +22 -7
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/streaming/content_buffer.py +6 -13
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/summarise/summarise.py +5 -5
- sunholo-0.115.1/sunholo/types.py +52 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/utils/config.py +4 -3
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/utils/config_class.py +20 -20
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/utils/gcp.py +0 -3
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/vertex/extensions_class.py +4 -4
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo.egg-info/PKG-INFO +16 -12
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo.egg-info/SOURCES.txt +1 -4
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo.egg-info/requires.txt +14 -10
- sunholo-0.114.2/sunholo/patches/__init__.py +0 -0
- sunholo-0.114.2/sunholo/patches/langchain/__init__.py +0 -0
- sunholo-0.114.2/sunholo/patches/langchain/lancedb.py +0 -219
- sunholo-0.114.2/sunholo/patches/langchain/vertexai.py +0 -506
- {sunholo-0.114.2 → sunholo-0.115.1}/LICENSE.txt +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/MANIFEST.in +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/README.md +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/setup.cfg +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/agents/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/agents/chat_history.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/agents/dispatch_to_qa.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/agents/fastapi/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/agents/fastapi/base.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/agents/fastapi/qna_routes.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/agents/flask/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/agents/flask/base.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/agents/flask/qna_routes.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/agents/flask/vac_routes.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/agents/langserve.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/agents/pubsub.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/agents/route.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/agents/special_commands.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/agents/swagger.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/archive/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/archive/archive.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/auth/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/auth/gcloud.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/auth/refresh.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/auth/run.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/azure/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/azure/auth.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/azure/blobs.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/azure/event_grid.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/bots/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/bots/discord.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/bots/github_webhook.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/bots/webapp.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/chunker/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/chunker/azure.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/chunker/doc_handling.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/chunker/encode_metadata.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/chunker/images.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/chunker/loaders.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/chunker/process_chunker_data.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/chunker/pubsub.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/cli/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/cli/chat_vac.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/cli/cli.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/cli/configs.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/cli/deploy.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/cli/embedder.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/cli/merge_texts.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/cli/run_proxy.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/cli/sun_rich.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/cli/swagger.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/cli/vertex.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/components/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/components/retriever.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/custom_logging.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/database/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/database/alloydb.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/database/alloydb_client.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/database/database.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/database/lancedb.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/database/sql/sb/create_function.sql +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/database/sql/sb/create_function_time.sql +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/database/sql/sb/create_table.sql +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/database/sql/sb/delete_source_row.sql +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/database/sql/sb/return_sources.sql +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/database/sql/sb/setup.sql +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/database/static_dbs.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/database/uuid.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/discovery_engine/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/discovery_engine/chunker_handler.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/discovery_engine/create_new.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/discovery_engine/discovery_engine_client.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/discovery_engine/get_ai_search_chunks.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/embedder/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/excel/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/excel/plugin.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/gcs/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/gcs/add_file.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/gcs/download_folder.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/gcs/download_url.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/gcs/extract_and_sign.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/gcs/metadata.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/genai/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/genai/file_handling.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/genai/images.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/genai/init.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/genai/process_funcs_cls.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/genai/safety.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/invoke/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/invoke/async_class.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/invoke/direct_vac_func.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/invoke/invoke_vac_utils.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/langfuse/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/langfuse/callback.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/langfuse/evals.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/langfuse/prompts.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/llamaindex/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/llamaindex/get_files.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/llamaindex/import_files.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/llamaindex/llamaindex_class.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/llamaindex/user_history.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/lookup/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/lookup/model_lookup.yaml +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/pubsub/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/pubsub/process_pubsub.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/pubsub/pubsub_manager.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/qna/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/qna/parsers.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/qna/retry.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/senses/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/streaming/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/streaming/langserve.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/streaming/stream_lookup.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/streaming/streaming.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/summarise/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/terraform/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/terraform/tfvars_editor.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/tools/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/tools/web_browser.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/utils/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/utils/api_key.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/utils/big_context.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/utils/config_schema.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/utils/gcp_project.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/utils/mime.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/utils/parsers.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/utils/timedelta.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/utils/user_ids.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/utils/version.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/vertex/__init__.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/vertex/extensions_call.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/vertex/genai_functions.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/vertex/init.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/vertex/memory_tools.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/vertex/safety.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo/vertex/type_dict_to_json.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo.egg-info/dependency_links.txt +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo.egg-info/entry_points.txt +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/sunholo.egg-info/top_level.txt +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/tests/test_async.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/tests/test_chat_history.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/tests/test_config.py +0 -0
- {sunholo-0.114.2 → sunholo-0.115.1}/tests/test_unstructured.py +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sunholo
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.115.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.
|
|
6
|
+
Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.115.1.tar.gz
|
|
7
7
|
Author: Holosun ApS
|
|
8
8
|
Author-email: multivac@sunholo.com
|
|
9
9
|
License: Apache License, Version 2.0
|
|
@@ -18,13 +18,14 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
19
|
Description-Content-Type: text/markdown
|
|
20
20
|
License-File: LICENSE.txt
|
|
21
|
+
Requires-Dist: aiohttp
|
|
21
22
|
Requires-Dist: google-auth
|
|
23
|
+
Requires-Dist: pydantic
|
|
24
|
+
Requires-Dist: requests
|
|
22
25
|
Requires-Dist: ruamel.yaml
|
|
23
|
-
Requires-Dist:
|
|
24
|
-
Requires-Dist: langchain_experimental==0.0.65
|
|
25
|
-
Requires-Dist: langchain-community==0.2.17
|
|
26
|
-
Requires-Dist: langsmith==0.1.143
|
|
26
|
+
Requires-Dist: tenacity
|
|
27
27
|
Provides-Extra: all
|
|
28
|
+
Requires-Dist: aiohttp; extra == "all"
|
|
28
29
|
Requires-Dist: anthropic[vertex]; extra == "all"
|
|
29
30
|
Requires-Dist: asyncpg; extra == "all"
|
|
30
31
|
Requires-Dist: azure-identity; extra == "all"
|
|
@@ -68,10 +69,12 @@ Requires-Dist: pillow; extra == "all"
|
|
|
68
69
|
Requires-Dist: playwright; extra == "all"
|
|
69
70
|
Requires-Dist: psutil; extra == "all"
|
|
70
71
|
Requires-Dist: psycopg2-binary; extra == "all"
|
|
72
|
+
Requires-Dist: pydantic; extra == "all"
|
|
71
73
|
Requires-Dist: pypdf; extra == "all"
|
|
72
74
|
Requires-Dist: python-hcl2; extra == "all"
|
|
73
75
|
Requires-Dist: python-socketio; extra == "all"
|
|
74
76
|
Requires-Dist: pytesseract; extra == "all"
|
|
77
|
+
Requires-Dist: requests; extra == "all"
|
|
75
78
|
Requires-Dist: rich; extra == "all"
|
|
76
79
|
Requires-Dist: sounddevice; extra == "all"
|
|
77
80
|
Requires-Dist: supabase; extra == "all"
|
|
@@ -82,10 +85,10 @@ Requires-Dist: tiktoken; extra == "all"
|
|
|
82
85
|
Requires-Dist: unstructured[all-docs,local-inference]; extra == "all"
|
|
83
86
|
Requires-Dist: xlwings; extra == "all"
|
|
84
87
|
Provides-Extra: langchain
|
|
85
|
-
Requires-Dist: langchain
|
|
86
|
-
Requires-Dist: langchain_experimental
|
|
87
|
-
Requires-Dist: langchain-community
|
|
88
|
-
Requires-Dist: langsmith
|
|
88
|
+
Requires-Dist: langchain; extra == "langchain"
|
|
89
|
+
Requires-Dist: langchain_experimental; extra == "langchain"
|
|
90
|
+
Requires-Dist: langchain-community; extra == "langchain"
|
|
91
|
+
Requires-Dist: langsmith; extra == "langchain"
|
|
89
92
|
Provides-Extra: azure
|
|
90
93
|
Requires-Dist: azure-identity; extra == "azure"
|
|
91
94
|
Requires-Dist: azure-storage-blob; extra == "azure"
|
|
@@ -104,6 +107,7 @@ Requires-Dist: tantivy; extra == "database"
|
|
|
104
107
|
Provides-Extra: pipeline
|
|
105
108
|
Requires-Dist: GitPython; extra == "pipeline"
|
|
106
109
|
Requires-Dist: lark; extra == "pipeline"
|
|
110
|
+
Requires-Dist: langchain>=0.2.16; extra == "pipeline"
|
|
107
111
|
Requires-Dist: langchain-unstructured; extra == "pipeline"
|
|
108
112
|
Requires-Dist: psutil; extra == "pipeline"
|
|
109
113
|
Requires-Dist: pypdf; extra == "pipeline"
|
|
@@ -125,8 +129,8 @@ Requires-Dist: google-cloud-logging; extra == "gcp"
|
|
|
125
129
|
Requires-Dist: google-cloud-pubsub; extra == "gcp"
|
|
126
130
|
Requires-Dist: google-cloud-discoveryengine; extra == "gcp"
|
|
127
131
|
Requires-Dist: google-cloud-texttospeech; extra == "gcp"
|
|
128
|
-
Requires-Dist: google-generativeai>=0.
|
|
129
|
-
Requires-Dist: langchain-google-genai
|
|
132
|
+
Requires-Dist: google-generativeai>=0.8.3; extra == "gcp"
|
|
133
|
+
Requires-Dist: langchain-google-genai>=2.0.0; extra == "gcp"
|
|
130
134
|
Requires-Dist: langchain_google_alloydb_pg>=0.2.2; extra == "gcp"
|
|
131
135
|
Requires-Dist: langchain-google-vertexai; extra == "gcp"
|
|
132
136
|
Requires-Dist: pillow; extra == "gcp"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from setuptools import setup, find_packages
|
|
2
2
|
|
|
3
|
-
version = '0.
|
|
3
|
+
version = '0.115.1'
|
|
4
4
|
|
|
5
5
|
setup(
|
|
6
6
|
name='sunholo',
|
|
@@ -27,16 +27,17 @@ setup(
|
|
|
27
27
|
},
|
|
28
28
|
install_requires=[
|
|
29
29
|
# Base dependencies
|
|
30
|
+
"aiohttp",
|
|
30
31
|
"google-auth", # to check if on gcp
|
|
32
|
+
"pydantic",
|
|
33
|
+
"requests",
|
|
31
34
|
"ruamel.yaml",
|
|
32
|
-
"
|
|
33
|
-
"langchain_experimental==0.0.65",
|
|
34
|
-
"langchain-community==0.2.17",
|
|
35
|
-
"langsmith==0.1.143",
|
|
35
|
+
"tenacity"
|
|
36
36
|
],
|
|
37
37
|
extras_require={
|
|
38
38
|
# Define optional dependencies with feature names
|
|
39
39
|
'all': [
|
|
40
|
+
"aiohttp",
|
|
40
41
|
"anthropic[vertex]",
|
|
41
42
|
"asyncpg",
|
|
42
43
|
"azure-identity",
|
|
@@ -80,10 +81,12 @@ setup(
|
|
|
80
81
|
"playwright",
|
|
81
82
|
"psutil",
|
|
82
83
|
"psycopg2-binary",
|
|
84
|
+
"pydantic",
|
|
83
85
|
"pypdf",
|
|
84
86
|
"python-hcl2",
|
|
85
87
|
"python-socketio",
|
|
86
88
|
"pytesseract",
|
|
89
|
+
"requests",
|
|
87
90
|
"rich",
|
|
88
91
|
"sounddevice",
|
|
89
92
|
"supabase",
|
|
@@ -95,10 +98,10 @@ setup(
|
|
|
95
98
|
"xlwings"
|
|
96
99
|
],
|
|
97
100
|
'langchain': [
|
|
98
|
-
"langchain
|
|
99
|
-
"langchain_experimental
|
|
100
|
-
"langchain-community
|
|
101
|
-
"langsmith
|
|
101
|
+
"langchain",
|
|
102
|
+
"langchain_experimental",
|
|
103
|
+
"langchain-community",
|
|
104
|
+
"langsmith",
|
|
102
105
|
],
|
|
103
106
|
'azure': [
|
|
104
107
|
"azure-identity",
|
|
@@ -121,6 +124,7 @@ setup(
|
|
|
121
124
|
'pipeline': [
|
|
122
125
|
"GitPython",
|
|
123
126
|
"lark",
|
|
127
|
+
"langchain>=0.2.16",
|
|
124
128
|
"langchain-unstructured",
|
|
125
129
|
"psutil",
|
|
126
130
|
"pypdf",
|
|
@@ -143,8 +147,8 @@ setup(
|
|
|
143
147
|
"google-cloud-pubsub",
|
|
144
148
|
"google-cloud-discoveryengine",
|
|
145
149
|
"google-cloud-texttospeech",
|
|
146
|
-
"google-generativeai>=0.
|
|
147
|
-
"langchain-google-genai
|
|
150
|
+
"google-generativeai>=0.8.3",
|
|
151
|
+
"langchain-google-genai>=2.0.0",
|
|
148
152
|
"langchain_google_alloydb_pg>=0.2.2",
|
|
149
153
|
"langchain-google-vertexai",
|
|
150
154
|
"pillow",
|
|
@@ -189,10 +193,10 @@ setup(
|
|
|
189
193
|
},
|
|
190
194
|
classifiers=[
|
|
191
195
|
'Development Status :: 3 - Alpha', # Chose either "3 - Alpha", "4 - Beta" or "5 - Production/Stable" as the current state of your package
|
|
192
|
-
'Intended Audience :: Developers',
|
|
196
|
+
'Intended Audience :: Developers',
|
|
193
197
|
'Topic :: Software Development :: Build Tools',
|
|
194
198
|
'License :: OSI Approved :: Apache Software License',
|
|
195
|
-
'Programming Language :: Python :: 3',
|
|
199
|
+
'Programming Language :: Python :: 3',
|
|
196
200
|
'Programming Language :: Python :: 3.10',
|
|
197
201
|
'Programming Language :: Python :: 3.11',
|
|
198
202
|
'Programming Language :: Python :: 3.12'
|
|
@@ -15,7 +15,6 @@ from . import invoke
|
|
|
15
15
|
from . import langfuse
|
|
16
16
|
from . import llamaindex
|
|
17
17
|
from . import lookup
|
|
18
|
-
from . import patches
|
|
19
18
|
from . import pubsub
|
|
20
19
|
from . import qna
|
|
21
20
|
from . import senses
|
|
@@ -44,7 +43,6 @@ __all__ = ['agents',
|
|
|
44
43
|
'langfuse',
|
|
45
44
|
'llamaindex',
|
|
46
45
|
'lookup',
|
|
47
|
-
'patches',
|
|
48
46
|
'pubsub',
|
|
49
47
|
'qna',
|
|
50
48
|
'senses',
|
|
@@ -29,10 +29,7 @@ try:
|
|
|
29
29
|
except ImportError:
|
|
30
30
|
BlobServiceClient = None
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
from langchain.schema import Document
|
|
34
|
-
except ImportError:
|
|
35
|
-
Document = None
|
|
32
|
+
from ..types import Document
|
|
36
33
|
|
|
37
34
|
from .splitter import chunk_doc_to_docs
|
|
38
35
|
from .pdfs import split_pdf_to_pages
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import os
|
|
15
15
|
import pathlib
|
|
16
16
|
from ..custom_logging import log
|
|
17
|
+
from ..types import Document
|
|
17
18
|
|
|
18
19
|
def split_pdf_to_pages(pdf_path, temp_dir):
|
|
19
20
|
|
|
@@ -51,7 +52,6 @@ def split_pdf_to_pages(pdf_path, temp_dir):
|
|
|
51
52
|
return page_files
|
|
52
53
|
|
|
53
54
|
def read_pdf_file(pdf_path, metadata):
|
|
54
|
-
from langchain.schema import Document
|
|
55
55
|
from pypdf import PdfReader
|
|
56
56
|
log.info(f"Trying local PDF parsing. Reading PDF {pdf_path}...")
|
|
57
57
|
|
|
@@ -2,11 +2,7 @@ from ..custom_logging import log
|
|
|
2
2
|
from ..pubsub import PubSubManager
|
|
3
3
|
from ..utils.parsers import contains_url, extract_urls
|
|
4
4
|
from ..utils.gcp_project import get_gcp_project
|
|
5
|
-
|
|
6
|
-
try:
|
|
7
|
-
from langchain.schema import Document
|
|
8
|
-
except ImportError:
|
|
9
|
-
Document=None
|
|
5
|
+
from ..types import Document
|
|
10
6
|
|
|
11
7
|
def publish_if_urls(the_content, vector_name):
|
|
12
8
|
"""
|
|
@@ -28,6 +28,9 @@ except ImportError:
|
|
|
28
28
|
def chunk_doc_to_docs(documents: list, extension: str = ".md", min_size: int = 800, vector_name=None, **kwargs):
|
|
29
29
|
"""Turns a Document object into a list of many Document chunks.
|
|
30
30
|
If a document or chunk is smaller than min_size, it will be merged with adjacent documents or chunks."""
|
|
31
|
+
|
|
32
|
+
if Document is None:
|
|
33
|
+
raise ImportError("Document chunker needs langchain installed via sunholo[pipeline]")
|
|
31
34
|
|
|
32
35
|
if len(documents)==0:
|
|
33
36
|
log.warning("No documents found to chunk in chunk_doc_to_docs")
|
|
@@ -137,6 +140,9 @@ def choose_splitter(extension: str, chunk_size: int=1024, chunk_overlap:int=200,
|
|
|
137
140
|
|
|
138
141
|
return semantic_splitter
|
|
139
142
|
|
|
143
|
+
if not text_splitter:
|
|
144
|
+
raise ImportError("text_splitter needs langchain installed via sunholo[pipeline]")
|
|
145
|
+
|
|
140
146
|
|
|
141
147
|
if extension == ".py":
|
|
142
148
|
return text_splitter.PythonCodeTextSplitter()
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import os
|
|
2
|
-
import
|
|
2
|
+
from ruamel.yaml import YAML
|
|
3
3
|
import shutil
|
|
4
4
|
from ..utils.config import get_module_filepath
|
|
5
5
|
from ..utils.parsers import sanitize_cloudrun_name
|
|
6
6
|
|
|
7
|
+
yaml = YAML(typ='safe')
|
|
8
|
+
|
|
7
9
|
def init_project(args):
|
|
8
10
|
"""
|
|
9
11
|
Initializes a new sunholo project with a basic configuration file and directory structure.
|
|
@@ -110,7 +110,7 @@ def llm_str_to_llm(llm_str, model=None, vector_name=None, config=None):
|
|
|
110
110
|
return VertexAI(model_name = model, temperature=0, max_output_tokens=1024)
|
|
111
111
|
|
|
112
112
|
elif llm_str == 'model_garden':
|
|
113
|
-
from
|
|
113
|
+
from langchain_google_vertexai import VertexAIModelGarden
|
|
114
114
|
model_garden_config = config.vacConfig("gcp_config")
|
|
115
115
|
if model_garden_config is None:
|
|
116
116
|
raise ValueError("llm='model_garden' requires a gcp_config entry in config yaml file")
|
|
@@ -102,7 +102,7 @@ def pick_vectorstore(vs_str: str, vector_name: str=None, embeddings=None, config
|
|
|
102
102
|
return vectorstore
|
|
103
103
|
|
|
104
104
|
elif vs_str == "lancedb":
|
|
105
|
-
from
|
|
105
|
+
from langchain_community.vectorstores import LanceDB
|
|
106
106
|
import lancedb
|
|
107
107
|
|
|
108
108
|
LANCEDB_BUCKET = os.environ.get("LANCEDB_BUCKET")
|
|
@@ -34,6 +34,9 @@ def embed_pubsub_chunk(data: dict):
|
|
|
34
34
|
data JSON
|
|
35
35
|
"""
|
|
36
36
|
|
|
37
|
+
if Document is None:
|
|
38
|
+
raise ImportError("Embeddin requires langchain installed via sunholo[pipeline]")
|
|
39
|
+
|
|
37
40
|
message_data = base64.b64decode(data['message']['data']).decode('utf-8')
|
|
38
41
|
messageId = data['message'].get('messageId')
|
|
39
42
|
publishTime = data['message'].get('publishTime')
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
from typing import Optional, TYPE_CHECKING, Union, Any
|
|
2
|
+
|
|
3
|
+
if TYPE_CHECKING:
|
|
4
|
+
import numpy as np
|
|
5
|
+
from numpy.typing import NDArray
|
|
6
|
+
ArrayType = NDArray[np.int16]
|
|
7
|
+
else:
|
|
8
|
+
ArrayType = Any # Fallback type when numpy isn't available
|
|
9
|
+
|
|
1
10
|
try:
|
|
2
11
|
from google.cloud import texttospeech
|
|
3
12
|
except ImportError:
|
|
@@ -29,9 +38,6 @@ import io
|
|
|
29
38
|
import wave
|
|
30
39
|
|
|
31
40
|
import argparse
|
|
32
|
-
import json
|
|
33
|
-
from typing import Optional
|
|
34
|
-
from pathlib import Path
|
|
35
41
|
import sys
|
|
36
42
|
|
|
37
43
|
class StreamingTTS:
|
|
@@ -195,8 +201,11 @@ class StreamingTTS:
|
|
|
195
201
|
log.error(f"Error initializing audio device: {e}")
|
|
196
202
|
raise
|
|
197
203
|
|
|
198
|
-
def _make_fade(self, length: int, fade_type: str='l') ->
|
|
204
|
+
def _make_fade(self, length: int, fade_type: str='l') -> ArrayType:
|
|
199
205
|
"""Generate a fade curve of specified length and type."""
|
|
206
|
+
if np is None: # Runtime check
|
|
207
|
+
raise ImportError("numpy is required. Install with pip install sunholo[tts]")
|
|
208
|
+
|
|
200
209
|
fade = np.arange(length, dtype=np.float32) / length
|
|
201
210
|
|
|
202
211
|
if fade_type == 't': # triangle
|
|
@@ -214,8 +223,11 @@ class StreamingTTS:
|
|
|
214
223
|
|
|
215
224
|
return fade
|
|
216
225
|
|
|
217
|
-
def _apply_fade(self, audio:
|
|
226
|
+
def _apply_fade(self, audio: ArrayType, fade_duration: float, fade_in: bool = True, fade_out: bool = True) -> ArrayType:
|
|
218
227
|
"""Apply fade in/out to audio with specified duration."""
|
|
228
|
+
if np is None: # Runtime check
|
|
229
|
+
raise ImportError("numpy is required. Install with pip install sunholo[tts]")
|
|
230
|
+
|
|
219
231
|
if audio.ndim != 1:
|
|
220
232
|
raise ValueError("Audio must be 1-dimensional")
|
|
221
233
|
|
|
@@ -233,8 +245,11 @@ class StreamingTTS:
|
|
|
233
245
|
return audio.astype(np.int16)
|
|
234
246
|
|
|
235
247
|
|
|
236
|
-
def _play_audio_chunk(self, audio_chunk:
|
|
248
|
+
def _play_audio_chunk(self, audio_chunk: ArrayType, is_final_chunk: bool = False):
|
|
237
249
|
"""Play a single audio chunk with proper device handling."""
|
|
250
|
+
if np is None: # Runtime check
|
|
251
|
+
raise ImportError("numpy is required. Install with pip install sunholo[tts]")
|
|
252
|
+
|
|
238
253
|
try:
|
|
239
254
|
# Add longer padding for the final chunk
|
|
240
255
|
padding_duration = 0.1 if is_final_chunk else 0.02
|
|
@@ -415,7 +430,7 @@ def tts_command(args):
|
|
|
415
430
|
Panel((
|
|
416
431
|
f"Saying: {args.text}"
|
|
417
432
|
),
|
|
418
|
-
title=
|
|
433
|
+
title="Text to Speech",
|
|
419
434
|
subtitle=f"{tts.voice_name} is talking"),
|
|
420
435
|
)
|
|
421
436
|
tts.process_text_stream(
|
|
@@ -13,13 +13,6 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
from typing import Any, Dict, List, Union
|
|
15
15
|
|
|
16
|
-
try:
|
|
17
|
-
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
|
|
18
|
-
from langchain.schema import LLMResult
|
|
19
|
-
except ImportError:
|
|
20
|
-
StreamingStdOutCallbackHandler = None
|
|
21
|
-
LLMResult = None
|
|
22
|
-
|
|
23
16
|
import threading
|
|
24
17
|
import asyncio
|
|
25
18
|
import re
|
|
@@ -114,7 +107,7 @@ class ContentBuffer:
|
|
|
114
107
|
self.content_available.clear()
|
|
115
108
|
|
|
116
109
|
|
|
117
|
-
class BufferStreamingStdOutCallbackHandler
|
|
110
|
+
class BufferStreamingStdOutCallbackHandler:
|
|
118
111
|
"""
|
|
119
112
|
A callback handler for streaming LLM output to a content buffer.
|
|
120
113
|
|
|
@@ -212,12 +205,12 @@ class BufferStreamingStdOutCallbackHandler(StreamingStdOutCallbackHandler):
|
|
|
212
205
|
self.content_buffer.write(self.buffer)
|
|
213
206
|
self.buffer = ""
|
|
214
207
|
|
|
215
|
-
def on_llm_end(self, response
|
|
208
|
+
def on_llm_end(self, response, **kwargs: Any) -> None:
|
|
216
209
|
"""
|
|
217
210
|
Handles the end of LLM streaming.
|
|
218
211
|
|
|
219
212
|
Args:
|
|
220
|
-
response
|
|
213
|
+
response: The result returned by the LLM.
|
|
221
214
|
**kwargs: Additional keyword arguments.
|
|
222
215
|
|
|
223
216
|
Writes any remaining buffer content to the content buffer, and sets a signal indicating
|
|
@@ -233,7 +226,7 @@ class BufferStreamingStdOutCallbackHandler(StreamingStdOutCallbackHandler):
|
|
|
233
226
|
|
|
234
227
|
|
|
235
228
|
|
|
236
|
-
class BufferStreamingStdOutCallbackHandlerAsync
|
|
229
|
+
class BufferStreamingStdOutCallbackHandlerAsync:
|
|
237
230
|
"""
|
|
238
231
|
An async callback handler for streaming LLM output to a content buffer.
|
|
239
232
|
|
|
@@ -315,12 +308,12 @@ class BufferStreamingStdOutCallbackHandlerAsync(StreamingStdOutCallbackHandler):
|
|
|
315
308
|
await self.content_buffer.async_write(self.buffer)
|
|
316
309
|
self.buffer = ""
|
|
317
310
|
|
|
318
|
-
async def async_on_llm_end(self, response
|
|
311
|
+
async def async_on_llm_end(self, response, **kwargs: Any) -> None:
|
|
319
312
|
"""
|
|
320
313
|
Asynchronously handles the end of LLM streaming.
|
|
321
314
|
|
|
322
315
|
Args:
|
|
323
|
-
response
|
|
316
|
+
response: The result returned by the LLM.
|
|
324
317
|
**kwargs: Additional keyword arguments.
|
|
325
318
|
"""
|
|
326
319
|
if self.buffer:
|
|
@@ -13,8 +13,6 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
from ..custom_logging import log
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
16
|
from ..components import get_llm
|
|
19
17
|
from ..chunker.splitter import chunk_doc_to_docs
|
|
20
18
|
|
|
@@ -36,6 +34,8 @@ except ImportError:
|
|
|
36
34
|
VertexAI=None
|
|
37
35
|
load_summarize_chain=None
|
|
38
36
|
Document=None
|
|
37
|
+
import time
|
|
38
|
+
import random
|
|
39
39
|
|
|
40
40
|
prompt_template = """Write a summary for below, including key concepts, people and distinct information but do not add anything that is not in the original text:
|
|
41
41
|
|
|
@@ -45,10 +45,10 @@ SUMMARY:"""
|
|
|
45
45
|
MAP_PROMPT = PromptTemplate(template=prompt_template, input_variables=["text"])
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
import time
|
|
49
|
-
import random
|
|
50
|
-
|
|
51
48
|
def summarise_docs(docs, vector_name, skip_if_less=10000):
|
|
49
|
+
if Document is None:
|
|
50
|
+
raise ImportError("summarise_docs requires langchain installed via sunholo[pipeline]")
|
|
51
|
+
|
|
52
52
|
llm = get_llm(vector_name)
|
|
53
53
|
|
|
54
54
|
if isinstance(llm, ChatOpenAI) or isinstance(llm, OpenAI):
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from typing import Any, Dict, Optional, TYPE_CHECKING, Union
|
|
2
|
+
from dataclasses import dataclass, asdict
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from langchain.schema import Document as LangchainDocument
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class Document:
|
|
11
|
+
"""A simple document class with content and metadata.
|
|
12
|
+
|
|
13
|
+
Used for storing text content and associated metadata when not using LangChain.
|
|
14
|
+
Maintains the same basic interface (page_content and metadata) for compatibility.
|
|
15
|
+
|
|
16
|
+
Using @dataclass makes it automatically serializable and provides nice defaults.
|
|
17
|
+
"""
|
|
18
|
+
page_content: str
|
|
19
|
+
metadata: Dict[str, Any] = None
|
|
20
|
+
|
|
21
|
+
def __post_init__(self) -> None:
|
|
22
|
+
"""Initialize metadata if None."""
|
|
23
|
+
if self.metadata is None:
|
|
24
|
+
self.metadata = {}
|
|
25
|
+
|
|
26
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
27
|
+
"""Convert to dictionary."""
|
|
28
|
+
return asdict(self)
|
|
29
|
+
|
|
30
|
+
@classmethod
|
|
31
|
+
def from_dict(cls, data: Dict[str, Any]) -> "Document":
|
|
32
|
+
"""Create from dictionary."""
|
|
33
|
+
return cls(**data)
|
|
34
|
+
|
|
35
|
+
def json(self) -> str:
|
|
36
|
+
"""Convert to JSON string - for compatibility with LangChain's Document."""
|
|
37
|
+
return json.dumps(self.to_dict())
|
|
38
|
+
|
|
39
|
+
def convert_to_langchain_doc(doc: Document) -> Union[Any, "LangchainDocument"]:
|
|
40
|
+
"""Convert our Document to a LangChain Document.
|
|
41
|
+
|
|
42
|
+
Returns Any when LangChain isn't available to avoid type errors.
|
|
43
|
+
Only imports LangChain when the function is actually called.
|
|
44
|
+
"""
|
|
45
|
+
try:
|
|
46
|
+
from langchain.schema import Document as LangchainDocument
|
|
47
|
+
return LangchainDocument(
|
|
48
|
+
page_content=doc.page_content,
|
|
49
|
+
metadata=doc.metadata
|
|
50
|
+
)
|
|
51
|
+
except ImportError:
|
|
52
|
+
raise ImportError("LangChain is required for this conversion. Please install langchain.")
|
|
@@ -14,11 +14,12 @@
|
|
|
14
14
|
|
|
15
15
|
import os
|
|
16
16
|
import json
|
|
17
|
-
import yaml
|
|
18
17
|
from datetime import datetime, timedelta
|
|
19
18
|
from collections import defaultdict
|
|
20
19
|
from .timedelta import format_timedelta
|
|
21
20
|
|
|
21
|
+
from ruamel.yaml import YAML
|
|
22
|
+
yaml = YAML(typ='safe')
|
|
22
23
|
|
|
23
24
|
def get_module_filepath(filepath: str):
|
|
24
25
|
"""
|
|
@@ -107,7 +108,7 @@ def reload_config_file(config_file, filename):
|
|
|
107
108
|
if filename.endswith('.json'):
|
|
108
109
|
config = json.load(file)
|
|
109
110
|
else:
|
|
110
|
-
config = yaml.
|
|
111
|
+
config = yaml.load(file)
|
|
111
112
|
|
|
112
113
|
config_cache[filename] = (config, datetime.now())
|
|
113
114
|
log.debug(f"Loaded and cached {config_file}")
|
|
@@ -166,7 +167,7 @@ def load_config(filename: str=None) -> tuple[dict, str]:
|
|
|
166
167
|
if filename.endswith(".json"):
|
|
167
168
|
config = json.load(f)
|
|
168
169
|
elif filename.endswith(".yaml") or filename.endswith(".yml"):
|
|
169
|
-
config = yaml.
|
|
170
|
+
config = yaml.load(f)
|
|
170
171
|
else:
|
|
171
172
|
raise ValueError(f"Unsupported config file format: {config_file}. The supported formats are JSON and YAML.")
|
|
172
173
|
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import json
|
|
3
|
-
import yaml
|
|
4
3
|
from datetime import datetime, timedelta
|
|
5
4
|
from collections import defaultdict
|
|
6
|
-
from yaml.constructor import SafeConstructor, ConstructorError
|
|
7
5
|
|
|
8
6
|
from .timedelta import format_timedelta
|
|
9
7
|
|
|
@@ -122,30 +120,32 @@ class ConfigManager:
|
|
|
122
120
|
Returns:
|
|
123
121
|
dict: The loaded configuration.
|
|
124
122
|
"""
|
|
125
|
-
|
|
123
|
+
def _reload_config_file(self, config_file, filename, is_local=False):
|
|
124
|
+
"""
|
|
125
|
+
Helper function to load a config file and update the cache.
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
NoDuplicateKeyLoader = yaml.Loader
|
|
139
|
-
NoDuplicateKeyLoader.add_constructor(
|
|
140
|
-
yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
|
|
141
|
-
NoDuplicateKeyConstructor.construct_mapping
|
|
142
|
-
)
|
|
127
|
+
Args:
|
|
128
|
+
config_file (str): The path to the configuration file.
|
|
129
|
+
filename (str): The name of the configuration file.
|
|
130
|
+
is_local (bool): Indicates if the config file is from the local folder.
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
dict: The loaded configuration.
|
|
134
|
+
"""
|
|
135
|
+
from ..custom_logging import log
|
|
136
|
+
from ruamel.yaml import YAML, DuplicateKeyError
|
|
143
137
|
|
|
144
138
|
with open(config_file, 'r') as file:
|
|
145
139
|
if filename.endswith('.json'):
|
|
146
140
|
config = json.load(file)
|
|
147
141
|
else:
|
|
148
|
-
|
|
142
|
+
# Create YAML parser that forbids duplicates
|
|
143
|
+
yaml = YAML(typ='safe')
|
|
144
|
+
yaml.allow_duplicate_keys = False
|
|
145
|
+
try:
|
|
146
|
+
config = yaml.load(file)
|
|
147
|
+
except DuplicateKeyError as e:
|
|
148
|
+
raise ValueError(f"Duplicate key found in {filename}: {str(e)}")
|
|
149
149
|
|
|
150
150
|
self.config_cache[filename] = (config, datetime.now())
|
|
151
151
|
if is_local:
|
|
@@ -13,6 +13,8 @@ import json
|
|
|
13
13
|
from io import StringIO
|
|
14
14
|
import os
|
|
15
15
|
import re
|
|
16
|
+
from ruamel.yaml import YAML
|
|
17
|
+
yaml = YAML(typ='safe')
|
|
16
18
|
|
|
17
19
|
class VertexAIExtensions:
|
|
18
20
|
"""
|
|
@@ -115,13 +117,12 @@ class VertexAIExtensions:
|
|
|
115
117
|
def upload_openapi_file(self, filename: str, extension_name:str, vac:str=None):
|
|
116
118
|
if vac:
|
|
117
119
|
from ..agents.route import route_vac
|
|
118
|
-
import yaml
|
|
119
120
|
|
|
120
121
|
new_url = route_vac(vac)
|
|
121
122
|
|
|
122
123
|
log.info(f'Overwriting extension URL with VAC url for {vac=} - {new_url=}')
|
|
123
124
|
|
|
124
|
-
openapi = yaml.
|
|
125
|
+
openapi = yaml.load(filename)
|
|
125
126
|
|
|
126
127
|
openapi['servers'][0]['url'] = new_url
|
|
127
128
|
with open(filename, 'w') as file:
|
|
@@ -145,10 +146,9 @@ class VertexAIExtensions:
|
|
|
145
146
|
return self.current_extension.api_spec()
|
|
146
147
|
|
|
147
148
|
def load_tool_use_examples(self, filename: str):
|
|
148
|
-
import yaml
|
|
149
149
|
|
|
150
150
|
with open(filename, 'r') as file:
|
|
151
|
-
self.tool_use_examples = yaml.
|
|
151
|
+
self.tool_use_examples = yaml.load(file)
|
|
152
152
|
|
|
153
153
|
# google.cloud.aiplatform_v1beta1.types.ToolUseExample
|
|
154
154
|
return self.tool_use_examples
|