sunholo 0.76.6__tar.gz → 0.76.8__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.
Files changed (141) hide show
  1. {sunholo-0.76.6 → sunholo-0.76.8}/PKG-INFO +2 -2
  2. {sunholo-0.76.6 → sunholo-0.76.8}/setup.py +1 -1
  3. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/auth/run.py +1 -1
  4. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/azure/event_grid.py +6 -4
  5. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/vertex/__init__.py +2 -0
  6. sunholo-0.76.8/sunholo/vertex/extensions_call.py +284 -0
  7. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/vertex/extensions_class.py +17 -14
  8. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo.egg-info/PKG-INFO +2 -2
  9. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo.egg-info/SOURCES.txt +1 -0
  10. {sunholo-0.76.6 → sunholo-0.76.8}/LICENSE.txt +0 -0
  11. {sunholo-0.76.6 → sunholo-0.76.8}/MANIFEST.in +0 -0
  12. {sunholo-0.76.6 → sunholo-0.76.8}/README.md +0 -0
  13. {sunholo-0.76.6 → sunholo-0.76.8}/setup.cfg +0 -0
  14. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/__init__.py +0 -0
  15. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/agents/__init__.py +0 -0
  16. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/agents/chat_history.py +0 -0
  17. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/agents/dispatch_to_qa.py +0 -0
  18. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/agents/fastapi/__init__.py +0 -0
  19. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/agents/fastapi/base.py +0 -0
  20. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/agents/fastapi/qna_routes.py +0 -0
  21. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/agents/flask/__init__.py +0 -0
  22. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/agents/flask/base.py +0 -0
  23. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/agents/flask/qna_routes.py +0 -0
  24. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/agents/flask/vac_routes.py +0 -0
  25. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/agents/langserve.py +0 -0
  26. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/agents/pubsub.py +0 -0
  27. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/agents/route.py +0 -0
  28. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/agents/special_commands.py +0 -0
  29. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/agents/swagger.py +0 -0
  30. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/archive/__init__.py +0 -0
  31. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/archive/archive.py +0 -0
  32. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/auth/__init__.py +0 -0
  33. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/auth/gcloud.py +0 -0
  34. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/auth/refresh.py +0 -0
  35. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/azure/__init__.py +0 -0
  36. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/bots/__init__.py +0 -0
  37. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/bots/discord.py +0 -0
  38. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/bots/github_webhook.py +0 -0
  39. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/bots/webapp.py +0 -0
  40. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/chunker/__init__.py +0 -0
  41. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/chunker/azure.py +0 -0
  42. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/chunker/doc_handling.py +0 -0
  43. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/chunker/images.py +0 -0
  44. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/chunker/loaders.py +0 -0
  45. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/chunker/message_data.py +0 -0
  46. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/chunker/pdfs.py +0 -0
  47. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/chunker/process_chunker_data.py +0 -0
  48. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/chunker/publish.py +0 -0
  49. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/chunker/pubsub.py +0 -0
  50. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/chunker/splitter.py +0 -0
  51. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/cli/__init__.py +0 -0
  52. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/cli/chat_vac.py +0 -0
  53. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/cli/cli.py +0 -0
  54. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/cli/cli_init.py +0 -0
  55. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/cli/configs.py +0 -0
  56. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/cli/deploy.py +0 -0
  57. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/cli/embedder.py +0 -0
  58. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/cli/merge_texts.py +0 -0
  59. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/cli/run_proxy.py +0 -0
  60. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/cli/sun_rich.py +0 -0
  61. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/cli/swagger.py +0 -0
  62. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/cli/vertex.py +0 -0
  63. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/components/__init__.py +0 -0
  64. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/components/llm.py +0 -0
  65. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/components/retriever.py +0 -0
  66. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/components/vectorstore.py +0 -0
  67. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/database/__init__.py +0 -0
  68. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/database/alloydb.py +0 -0
  69. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/database/alloydb_client.py +0 -0
  70. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/database/database.py +0 -0
  71. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/database/lancedb.py +0 -0
  72. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/database/sql/sb/create_function.sql +0 -0
  73. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/database/sql/sb/create_function_time.sql +0 -0
  74. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/database/sql/sb/create_table.sql +0 -0
  75. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/database/sql/sb/delete_source_row.sql +0 -0
  76. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/database/sql/sb/return_sources.sql +0 -0
  77. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/database/sql/sb/setup.sql +0 -0
  78. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/database/static_dbs.py +0 -0
  79. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/database/uuid.py +0 -0
  80. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/discovery_engine/__init__.py +0 -0
  81. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/discovery_engine/chunker_handler.py +0 -0
  82. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/discovery_engine/create_new.py +0 -0
  83. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/discovery_engine/discovery_engine_client.py +0 -0
  84. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/embedder/__init__.py +0 -0
  85. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/embedder/embed_chunk.py +0 -0
  86. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/gcs/__init__.py +0 -0
  87. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/gcs/add_file.py +0 -0
  88. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/gcs/download_url.py +0 -0
  89. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/gcs/metadata.py +0 -0
  90. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/invoke/__init__.py +0 -0
  91. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/invoke/invoke_vac_utils.py +0 -0
  92. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/langfuse/__init__.py +0 -0
  93. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/langfuse/callback.py +0 -0
  94. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/langfuse/prompts.py +0 -0
  95. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/llamaindex/__init__.py +0 -0
  96. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/llamaindex/generate.py +0 -0
  97. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/llamaindex/get_files.py +0 -0
  98. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/llamaindex/import_files.py +0 -0
  99. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/logging.py +0 -0
  100. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/lookup/__init__.py +0 -0
  101. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/lookup/model_lookup.yaml +0 -0
  102. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/patches/__init__.py +0 -0
  103. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/patches/langchain/__init__.py +0 -0
  104. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/patches/langchain/lancedb.py +0 -0
  105. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/patches/langchain/vertexai.py +0 -0
  106. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/pubsub/__init__.py +0 -0
  107. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/pubsub/process_pubsub.py +0 -0
  108. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/pubsub/pubsub_manager.py +0 -0
  109. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/qna/__init__.py +0 -0
  110. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/qna/parsers.py +0 -0
  111. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/qna/retry.py +0 -0
  112. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/streaming/__init__.py +0 -0
  113. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/streaming/content_buffer.py +0 -0
  114. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/streaming/langserve.py +0 -0
  115. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/streaming/stream_lookup.py +0 -0
  116. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/streaming/streaming.py +0 -0
  117. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/summarise/__init__.py +0 -0
  118. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/summarise/summarise.py +0 -0
  119. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/tools/__init__.py +0 -0
  120. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/tools/web_browser.py +0 -0
  121. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/utils/__init__.py +0 -0
  122. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/utils/api_key.py +0 -0
  123. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/utils/big_context.py +0 -0
  124. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/utils/config.py +0 -0
  125. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/utils/config_class.py +0 -0
  126. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/utils/config_schema.py +0 -0
  127. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/utils/gcp.py +0 -0
  128. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/utils/gcp_project.py +0 -0
  129. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/utils/parsers.py +0 -0
  130. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/utils/timedelta.py +0 -0
  131. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/utils/user_ids.py +0 -0
  132. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/utils/version.py +0 -0
  133. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/vertex/init.py +0 -0
  134. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/vertex/memory_tools.py +0 -0
  135. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo/vertex/safety.py +0 -0
  136. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo.egg-info/dependency_links.txt +0 -0
  137. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo.egg-info/entry_points.txt +0 -0
  138. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo.egg-info/requires.txt +0 -0
  139. {sunholo-0.76.6 → sunholo-0.76.8}/sunholo.egg-info/top_level.txt +0 -0
  140. {sunholo-0.76.6 → sunholo-0.76.8}/tests/test_chat_history.py +0 -0
  141. {sunholo-0.76.6 → sunholo-0.76.8}/tests/test_config.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.76.6
3
+ Version: 0.76.8
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.76.6.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.76.8.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -1,7 +1,7 @@
1
1
  from setuptools import setup, find_packages
2
2
 
3
3
  # Define your base version
4
- version = '0.76.6'
4
+ version = '0.76.8'
5
5
 
6
6
  setup(
7
7
  name='sunholo',
@@ -66,7 +66,7 @@ def get_cloud_run_token(vector_name):
66
66
  }
67
67
  log.info(f"Authenticating for run_url {run_url} from {caller_frame.f_code.co_name}")
68
68
  id_token = get_id_token(run_url)
69
- log.info(f"id_token {id_token}")
69
+ #log.info(f"id_token {id_token}")
70
70
  return id_token
71
71
 
72
72
  def get_header(vector_name) -> Optional[dict]:
@@ -12,9 +12,10 @@ def process_azure_blob_event(events: list) -> tuple:
12
12
  tuple: A tuple containing the blob URL, attributes as metadata, and the vector name.
13
13
 
14
14
  Example of Event Grid schema:
15
+ ```
15
16
  {
16
- "topic": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.Storage/storageAccounts/{storage-account}",
17
- "subject": "/blobServices/default/containers/{container}/blobs/{blob}",
17
+ "topic": "/subscriptions/subscription-id/resourceGroups/resource-group/providers/Microsoft.Storage/storageAccounts/storage-account",
18
+ "subject": "/blobServices/default/containers/container/blobs/blob",
18
19
  "eventType": "Microsoft.Storage.BlobCreated",
19
20
  "eventTime": "2021-01-01T12:34:56.789Z",
20
21
  "id": "event-id",
@@ -26,8 +27,8 @@ def process_azure_blob_event(events: list) -> tuple:
26
27
  "contentType": "application/octet-stream",
27
28
  "contentLength": 524288,
28
29
  "blobType": "BlockBlob",
29
- "url": "https://{storage-account}.blob.core.windows.net/{container}/{blob}",
30
- "sequencer": "0000000000000000000000000000000000000000000000000000000000000000",
30
+ "url": "https://storage-account.blob.core.windows.net/container/blob",
31
+ "sequencer": "0000000000000000000000000",
31
32
  "storageDiagnostics": {
32
33
  "batchId": "batch-id"
33
34
  }
@@ -35,6 +36,7 @@ def process_azure_blob_event(events: list) -> tuple:
35
36
  "dataVersion": "",
36
37
  "metadataVersion": "1"
37
38
  }
39
+ ```
38
40
  """
39
41
  storage_blob_created_event = "Microsoft.Storage.BlobCreated"
40
42
 
@@ -2,3 +2,5 @@ from .init import init_vertex, init_genai
2
2
  from .memory_tools import get_vertex_memories, print_grounding_response, get_google_search_grounding
3
3
  from .safety import vertex_safety, genai_safety
4
4
  from .extensions_class import VertexAIExtensions
5
+ from .extensions_call import get_extension_content
6
+
@@ -0,0 +1,284 @@
1
+ from .extensions_class import VertexAIExtensions
2
+ from ..utils import ConfigManager
3
+ from ..logging import log
4
+ import collections.abc
5
+
6
+ def get_extension_content(question: str, config: ConfigManager, project_id:str=None, **kwargs):
7
+ """
8
+ Fetches content from extensions based on the provided question and configuration.
9
+
10
+ Args:
11
+ question (str): The question to be processed by the extensions.
12
+ config (ConfigManager): The configuration manager instance.
13
+ **kwargs: Additional parameters to be passed to the extension.
14
+
15
+ Returns:
16
+ list: A list of responses from the extensions.
17
+
18
+ Example:
19
+ Assuming a YAML configuration file as follows:
20
+
21
+ ```yaml
22
+ kind: vacConfig
23
+ vac:
24
+ my_vac:
25
+ extensions:
26
+ - extension_id: 8524997435263549440
27
+ operation_id: post_our_new_energy_invoke_one_generic
28
+ vac: our_generic
29
+ operation_params:
30
+ input:
31
+ question: ""
32
+ chat_history: []
33
+ source_filters: []
34
+ source_filters_and_or: false
35
+ search_kwargs:
36
+ k: 0
37
+ filter: ""
38
+ fetch_k: 0
39
+ private_docs: []
40
+ whole_document: false
41
+ ```
42
+
43
+ The function can be called as:
44
+
45
+ ```python
46
+ config = ConfigManager()
47
+ question = "What is the capital of France?"
48
+
49
+ responses = get_extension_content(
50
+ question=question,
51
+ config=config,
52
+ input={
53
+ "chat_history": [{"role": "user", "content": "Hello"}],
54
+ "source_filters": ["PPA/"],
55
+ "search_kwargs": {"k": 50, "filter": "source ILIKE '%GermanPolicyforPPA/%'", "fetch_k": 100}
56
+ }
57
+ )
58
+ ```
59
+
60
+ In this example, `operation_params` will be updated to:
61
+
62
+ ```python
63
+ {
64
+ "input": {
65
+ "question": "What is the capital of France?",
66
+ "chat_history": [{"role": "user", "content": "Hello"}],
67
+ "source_filters": ["PPA/"],
68
+ "source_filters_and_or": false,
69
+ "search_kwargs": {
70
+ "k": 50,
71
+ "filter": "source ILIKE '%GermanPolicyforPPA/%'",
72
+ "fetch_k": 100
73
+ },
74
+ "private_docs": [],
75
+ "whole_document": false
76
+ }
77
+ }
78
+ ```
79
+ """
80
+ extensions = config.vacConfig('extensions')
81
+ responses = []
82
+ for tool in extensions:
83
+ try:
84
+ ve = VertexAIExtensions(project_id)
85
+
86
+ # Merge operation_params from tool config and **kwargs
87
+ operation_params = tool.get('operation_params', {})
88
+ log.info(f'{operation_params=}')
89
+ operation_params_input = update_nested_params(operation_params, kwargs)
90
+
91
+ # Update the question in operation_params if it exists
92
+ operation_params_input = inject_question(question, operation_params)
93
+
94
+ response = ve.execute_extension(
95
+ operation_id=tool['operation_id'],
96
+ operation_params=operation_params_input,
97
+ extension_id=tool.get('extension_id'),
98
+ extension_display_name=tool.get('extension_display_name'),
99
+ vac=tool.get('vac')
100
+ )
101
+
102
+ # Dynamically get keys for answer and metadata from YAML configuration
103
+ output_config = operation_params.get('output', {})
104
+ answer_key = output_config.get('answer', 'answer')
105
+ metadata_key = output_config.get('metadata', 'metadata')
106
+
107
+ # Extract answer and metadata based on the specified keys
108
+ log.info(f'{answer_key} {metadata_key}')
109
+
110
+ answer = extract_nested_value(response, answer_key)
111
+ metadata = extract_nested_value(response, metadata_key)
112
+
113
+ log.info(f'{answer=} {metadata=}')
114
+
115
+ if answer and metadata:
116
+ responses.append(f"{answer}\nMetadata: {metadata}")
117
+ elif answer:
118
+ responses.append(answer)
119
+
120
+ except Exception as err:
121
+ log.error(f'Could not find vertex-extension response: {str(err)}')
122
+ answer = None
123
+
124
+ log.info(f'Vertex extension responses: {responses=}')
125
+
126
+ answers = "\n\n".join([resp for resp in responses if resp is not None])
127
+
128
+ return answers
129
+
130
+ def update_nested_params(original, updates):
131
+ """
132
+ Recursively update nested dictionaries with new values.
133
+
134
+ Args:
135
+ original (dict): The original dictionary to be updated.
136
+ updates (dict): The new values to be merged into the original dictionary.
137
+
138
+ Returns:
139
+ dict: The updated dictionary.
140
+
141
+ Example:
142
+ ```python
143
+ original = {
144
+ "param1": "value1",
145
+ "nested_param": {
146
+ "sub_param1": "sub_value1"
147
+ }
148
+ }
149
+
150
+ updates = {
151
+ "param1": "new_value1",
152
+ "nested_param": {
153
+ "sub_param1": "new_sub_value1"
154
+ }
155
+ }
156
+
157
+ updated_params = update_nested_params(original, updates)
158
+
159
+ # updated_params will be:
160
+ # {
161
+ # "param1": "new_value1",
162
+ # "nested_param": {
163
+ # "sub_param1": "new_sub_value1"
164
+ # }
165
+ # }
166
+ ```
167
+ """
168
+ for key, value in updates.items():
169
+ if isinstance(value, collections.abc.Mapping):
170
+ original[key] = update_nested_params(original.get(key, {}), value)
171
+ else:
172
+ original[key] = value
173
+ return original
174
+
175
+ def inject_question(question, params):
176
+ """
177
+ Recursively injects the question into nested dictionaries where the key is 'question' and the value is empty.
178
+
179
+ Args:
180
+ question (str): The question to be injected.
181
+ params (dict): The dictionary where the question should be injected.
182
+
183
+ Returns:
184
+ dict: The dictionary with the question injected.
185
+
186
+ Example:
187
+ ```python
188
+ params = {
189
+ "input": {
190
+ "question": "",
191
+ "chat_history": [],
192
+ "source_filters": [],
193
+ "search_kwargs": {
194
+ "k": 0,
195
+ "filter": "",
196
+ "fetch_k": 0
197
+ },
198
+ "private_docs": [],
199
+ "whole_document": false
200
+ }
201
+ }
202
+
203
+ question = "What is the capital of France?"
204
+
205
+ updated_params = inject_question(question, params)
206
+
207
+ # updated_params will be:
208
+ # {
209
+ # "input": {
210
+ # "question": "What is the capital of France?",
211
+ # "chat_history": [],
212
+ # "source_filters": [],
213
+ # "search_kwargs": {
214
+ # "k": 0,
215
+ # "filter": "",
216
+ # "fetch_k": 0
217
+ # },
218
+ # "private_docs": [],
219
+ # "whole_document": false
220
+ # }
221
+ # }
222
+ ```
223
+ """
224
+ if isinstance(params, collections.abc.Mapping):
225
+ for key, value in params.items():
226
+ if isinstance(value, collections.abc.Mapping):
227
+ params[key] = inject_question(question, value)
228
+ elif key == 'question' and not value:
229
+ params[key] = question
230
+ return params
231
+
232
+ def extract_nested_value(data, key):
233
+ """
234
+ Recursively extract a value from nested dictionaries based on the specified key or a dot-separated key path.
235
+ If the key is not dot-separated, it will find the first occurrence of that key in the nested dictionaries.
236
+
237
+ Args:
238
+ data (dict): The dictionary to extract the value from.
239
+ key (str): The key or dot-separated key path to extract the value.
240
+
241
+ Returns:
242
+ Any: The extracted value, or None if the key or key path is not found.
243
+
244
+ Example:
245
+ ```python
246
+ data = {
247
+ "output": {
248
+ "content": "Some content",
249
+ "metadata": {"key1": "value1"}
250
+ }
251
+ }
252
+
253
+ value = extract_nested_value(data, "content")
254
+ # value will be "Some content"
255
+
256
+ value = extract_nested_value(data, "output.metadata")
257
+ # value will be {"key1": "value1"}
258
+ ```
259
+ """
260
+ def search_key(data, key):
261
+ if isinstance(data, dict):
262
+ if key in data:
263
+ return data[key]
264
+ for k, v in data.items():
265
+ if isinstance(v, dict):
266
+ result = search_key(v, key)
267
+ if result is not None:
268
+ return result
269
+ return None
270
+
271
+ if '.' in key:
272
+ keys = key.split('.')
273
+ for k in keys:
274
+ if isinstance(data, dict) and k in data:
275
+ data = data[k]
276
+ else:
277
+ return None
278
+ return data
279
+ else:
280
+ return search_key(data, key)
281
+
282
+ if __name__ == "__main__":
283
+ config = ConfigManager("one_ai")
284
+ get_extension_content("What are PPAs in france like?", config=config)
@@ -7,6 +7,7 @@ from .init import init_vertex
7
7
  from ..logging import log
8
8
  from ..utils.gcp_project import get_gcp_project
9
9
  from ..utils.parsers import validate_extension_id
10
+ from ..utils.gcp import is_running_on_cloudrun
10
11
  from ..auth import get_local_gcloud_token, get_cloud_run_token
11
12
  import base64
12
13
  import json
@@ -271,27 +272,31 @@ class VertexAIExtensions:
271
272
  operation_id: str,
272
273
  operation_params: dict,
273
274
  extension_id: str=None,
275
+ extension_display_name: str=None,
274
276
  vac: str=None):
275
277
 
276
- if not extension_id:
277
- extension_name = self.created_extension.resource_name
278
- if extension_name is None:
279
- raise ValueError("Must specify extension_id or init one with class")
280
- else:
278
+ if extension_display_name:
279
+ extensions = self.list_extensions()
280
+ for extension in extensions:
281
+ if extension.get('display_name') == extension_display_name:
282
+ log.info(f"Found extension_id for '{extension_display_name}'")
283
+ extension_id = extension['resource_name']
284
+ break
285
+
286
+ if extension_id:
281
287
  extension_id = str(extension_id)
282
288
  if not extension_id.startswith("projects/"):
283
289
  extension_name = f"projects/{self.project_id}/locations/{self.location}/extensions/{extension_id}"
284
290
  else:
285
291
  extension_name = extension_id
292
+ else:
293
+ extension_name = self.created_extension.resource_name
294
+ if not extension_name:
295
+ raise ValueError("Must specify extension_id or extension_name - both were None")
286
296
 
287
297
  extension = extensions.Extension(extension_name)
288
298
 
289
- log.info(f"Executing extension {extension_name=} with {operation_id=} and {operation_params=}")
290
-
291
- # local testing auth
292
- from ..utils.gcp import is_running_on_cloudrun
293
- auth_config=None # on cloud run it sorts itself out via default creds(?)
294
-
299
+ auth_config=None
295
300
  if not is_running_on_cloudrun():
296
301
 
297
302
  log.warning("Using local authentication via gcloud")
@@ -308,10 +313,8 @@ class VertexAIExtensions:
308
313
  }
309
314
  else:
310
315
  log.warning("No vac configuration and not running locally so no authentication being set for this extension API call")
311
-
312
- if auth_config:
313
- log.info(f"{auth_config=}")
314
316
 
317
+ log.info(f"Executing extension {extension_name=} with {operation_id=} and {operation_params=}")
315
318
  response = extension.execute(
316
319
  operation_id=operation_id,
317
320
  operation_params=operation_params,
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.76.6
3
+ Version: 0.76.8
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.76.6.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.76.8.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -131,6 +131,7 @@ sunholo/utils/timedelta.py
131
131
  sunholo/utils/user_ids.py
132
132
  sunholo/utils/version.py
133
133
  sunholo/vertex/__init__.py
134
+ sunholo/vertex/extensions_call.py
134
135
  sunholo/vertex/extensions_class.py
135
136
  sunholo/vertex/init.py
136
137
  sunholo/vertex/memory_tools.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