sunholo 0.108.0__tar.gz → 0.109.3__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 (168) hide show
  1. {sunholo-0.108.0 → sunholo-0.109.3}/PKG-INFO +6 -5
  2. {sunholo-0.108.0 → sunholo-0.109.3}/setup.py +5 -4
  3. sunholo-0.109.3/sunholo/genai/__init__.py +4 -0
  4. sunholo-0.109.3/sunholo/genai/file_handling.py +221 -0
  5. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/senses/stream_voice.py +2 -0
  6. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo.egg-info/PKG-INFO +6 -5
  7. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo.egg-info/SOURCES.txt +1 -0
  8. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo.egg-info/requires.txt +4 -3
  9. sunholo-0.108.0/sunholo/genai/__init__.py +0 -3
  10. {sunholo-0.108.0 → sunholo-0.109.3}/LICENSE.txt +0 -0
  11. {sunholo-0.108.0 → sunholo-0.109.3}/MANIFEST.in +0 -0
  12. {sunholo-0.108.0 → sunholo-0.109.3}/README.md +0 -0
  13. {sunholo-0.108.0 → sunholo-0.109.3}/setup.cfg +0 -0
  14. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/__init__.py +0 -0
  15. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/agents/__init__.py +0 -0
  16. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/agents/chat_history.py +0 -0
  17. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/agents/dispatch_to_qa.py +0 -0
  18. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/agents/fastapi/__init__.py +0 -0
  19. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/agents/fastapi/base.py +0 -0
  20. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/agents/fastapi/qna_routes.py +0 -0
  21. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/agents/flask/__init__.py +0 -0
  22. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/agents/flask/base.py +0 -0
  23. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/agents/flask/qna_routes.py +0 -0
  24. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/agents/flask/vac_routes.py +0 -0
  25. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/agents/langserve.py +0 -0
  26. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/agents/pubsub.py +0 -0
  27. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/agents/route.py +0 -0
  28. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/agents/special_commands.py +0 -0
  29. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/agents/swagger.py +0 -0
  30. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/archive/__init__.py +0 -0
  31. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/archive/archive.py +0 -0
  32. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/auth/__init__.py +0 -0
  33. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/auth/gcloud.py +0 -0
  34. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/auth/refresh.py +0 -0
  35. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/auth/run.py +0 -0
  36. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/azure/__init__.py +0 -0
  37. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/azure/auth.py +0 -0
  38. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/azure/blobs.py +0 -0
  39. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/azure/event_grid.py +0 -0
  40. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/bots/__init__.py +0 -0
  41. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/bots/discord.py +0 -0
  42. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/bots/github_webhook.py +0 -0
  43. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/bots/webapp.py +0 -0
  44. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/chunker/__init__.py +0 -0
  45. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/chunker/azure.py +0 -0
  46. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/chunker/doc_handling.py +0 -0
  47. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/chunker/encode_metadata.py +0 -0
  48. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/chunker/images.py +0 -0
  49. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/chunker/loaders.py +0 -0
  50. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/chunker/message_data.py +0 -0
  51. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/chunker/pdfs.py +0 -0
  52. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/chunker/process_chunker_data.py +0 -0
  53. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/chunker/publish.py +0 -0
  54. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/chunker/pubsub.py +0 -0
  55. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/chunker/splitter.py +0 -0
  56. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/cli/__init__.py +0 -0
  57. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/cli/chat_vac.py +0 -0
  58. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/cli/cli.py +0 -0
  59. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/cli/cli_init.py +0 -0
  60. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/cli/configs.py +0 -0
  61. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/cli/deploy.py +0 -0
  62. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/cli/embedder.py +0 -0
  63. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/cli/merge_texts.py +0 -0
  64. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/cli/run_proxy.py +0 -0
  65. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/cli/sun_rich.py +0 -0
  66. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/cli/swagger.py +0 -0
  67. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/cli/vertex.py +0 -0
  68. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/components/__init__.py +0 -0
  69. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/components/llm.py +0 -0
  70. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/components/retriever.py +0 -0
  71. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/components/vectorstore.py +0 -0
  72. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/custom_logging.py +0 -0
  73. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/database/__init__.py +0 -0
  74. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/database/alloydb.py +0 -0
  75. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/database/alloydb_client.py +0 -0
  76. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/database/database.py +0 -0
  77. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/database/lancedb.py +0 -0
  78. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/database/sql/sb/create_function.sql +0 -0
  79. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/database/sql/sb/create_function_time.sql +0 -0
  80. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/database/sql/sb/create_table.sql +0 -0
  81. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/database/sql/sb/delete_source_row.sql +0 -0
  82. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/database/sql/sb/return_sources.sql +0 -0
  83. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/database/sql/sb/setup.sql +0 -0
  84. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/database/static_dbs.py +0 -0
  85. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/database/uuid.py +0 -0
  86. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/discovery_engine/__init__.py +0 -0
  87. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/discovery_engine/chunker_handler.py +0 -0
  88. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/discovery_engine/create_new.py +0 -0
  89. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/discovery_engine/discovery_engine_client.py +0 -0
  90. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/discovery_engine/get_ai_search_chunks.py +0 -0
  91. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/embedder/__init__.py +0 -0
  92. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/embedder/embed_chunk.py +0 -0
  93. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/excel/__init__.py +0 -0
  94. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/excel/plugin.py +0 -0
  95. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/gcs/__init__.py +0 -0
  96. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/gcs/add_file.py +0 -0
  97. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/gcs/download_folder.py +0 -0
  98. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/gcs/download_url.py +0 -0
  99. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/gcs/extract_and_sign.py +0 -0
  100. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/gcs/metadata.py +0 -0
  101. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/genai/images.py +0 -0
  102. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/genai/init.py +0 -0
  103. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/genai/process_funcs_cls.py +0 -0
  104. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/genai/safety.py +0 -0
  105. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/invoke/__init__.py +0 -0
  106. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/invoke/async_class.py +0 -0
  107. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/invoke/direct_vac_func.py +0 -0
  108. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/invoke/invoke_vac_utils.py +0 -0
  109. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/langfuse/__init__.py +0 -0
  110. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/langfuse/callback.py +0 -0
  111. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/langfuse/evals.py +0 -0
  112. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/langfuse/prompts.py +0 -0
  113. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/llamaindex/__init__.py +0 -0
  114. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/llamaindex/get_files.py +0 -0
  115. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/llamaindex/import_files.py +0 -0
  116. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/llamaindex/llamaindex_class.py +0 -0
  117. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/llamaindex/user_history.py +0 -0
  118. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/lookup/__init__.py +0 -0
  119. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/lookup/model_lookup.yaml +0 -0
  120. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/patches/__init__.py +0 -0
  121. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/patches/langchain/__init__.py +0 -0
  122. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/patches/langchain/lancedb.py +0 -0
  123. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/patches/langchain/vertexai.py +0 -0
  124. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/pubsub/__init__.py +0 -0
  125. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/pubsub/process_pubsub.py +0 -0
  126. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/pubsub/pubsub_manager.py +0 -0
  127. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/qna/__init__.py +0 -0
  128. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/qna/parsers.py +0 -0
  129. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/qna/retry.py +0 -0
  130. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/senses/__init__.py +0 -0
  131. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/streaming/__init__.py +0 -0
  132. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/streaming/content_buffer.py +0 -0
  133. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/streaming/langserve.py +0 -0
  134. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/streaming/stream_lookup.py +0 -0
  135. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/streaming/streaming.py +0 -0
  136. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/summarise/__init__.py +0 -0
  137. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/summarise/summarise.py +0 -0
  138. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/terraform/__init__.py +0 -0
  139. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/terraform/tfvars_editor.py +0 -0
  140. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/tools/__init__.py +0 -0
  141. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/tools/web_browser.py +0 -0
  142. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/utils/__init__.py +0 -0
  143. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/utils/api_key.py +0 -0
  144. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/utils/big_context.py +0 -0
  145. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/utils/config.py +0 -0
  146. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/utils/config_class.py +0 -0
  147. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/utils/config_schema.py +0 -0
  148. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/utils/gcp.py +0 -0
  149. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/utils/gcp_project.py +0 -0
  150. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/utils/mime.py +0 -0
  151. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/utils/parsers.py +0 -0
  152. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/utils/timedelta.py +0 -0
  153. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/utils/user_ids.py +0 -0
  154. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/utils/version.py +0 -0
  155. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/vertex/__init__.py +0 -0
  156. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/vertex/extensions_call.py +0 -0
  157. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/vertex/extensions_class.py +0 -0
  158. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/vertex/genai_functions.py +0 -0
  159. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/vertex/init.py +0 -0
  160. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/vertex/memory_tools.py +0 -0
  161. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/vertex/safety.py +0 -0
  162. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo/vertex/type_dict_to_json.py +0 -0
  163. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo.egg-info/dependency_links.txt +0 -0
  164. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo.egg-info/entry_points.txt +0 -0
  165. {sunholo-0.108.0 → sunholo-0.109.3}/sunholo.egg-info/top_level.txt +0 -0
  166. {sunholo-0.108.0 → sunholo-0.109.3}/tests/test_async.py +0 -0
  167. {sunholo-0.108.0 → sunholo-0.109.3}/tests/test_chat_history.py +0 -0
  168. {sunholo-0.108.0 → sunholo-0.109.3}/tests/test_config.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.108.0
3
+ Version: 0.109.3
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.108.0.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.109.3.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -21,8 +21,9 @@ License-File: LICENSE.txt
21
21
  Requires-Dist: google-auth
22
22
  Requires-Dist: ruamel.yaml
23
23
  Requires-Dist: langchain==0.2.16
24
- Requires-Dist: langchain_experimental>=0.0.61
25
- Requires-Dist: langchain-community>=0.2.11
24
+ Requires-Dist: langchain_experimental==0.0.65
25
+ Requires-Dist: langchain-community==0.2.17
26
+ Requires-Dist: langsmith==0.1.140
26
27
  Provides-Extra: all
27
28
  Requires-Dist: anthropic[vertex]; extra == "all"
28
29
  Requires-Dist: asyncpg; extra == "all"
@@ -50,7 +51,7 @@ Requires-Dist: httpcore; extra == "all"
50
51
  Requires-Dist: httpx; extra == "all"
51
52
  Requires-Dist: jsonschema; extra == "all"
52
53
  Requires-Dist: lancedb; extra == "all"
53
- Requires-Dist: langchain>=0.2.12; extra == "all"
54
+ Requires-Dist: langchain>=0.2.16; extra == "all"
54
55
  Requires-Dist: langchain-experimental>=0.0.61; extra == "all"
55
56
  Requires-Dist: langchain-community>=0.2.11; extra == "all"
56
57
  Requires-Dist: langchain-openai==0.1.25; extra == "all"
@@ -1,6 +1,6 @@
1
1
  from setuptools import setup, find_packages
2
2
 
3
- version = '0.108.0'
3
+ version = '0.109.3'
4
4
 
5
5
  setup(
6
6
  name='sunholo',
@@ -30,8 +30,9 @@ setup(
30
30
  "google-auth", # to check if on gcp
31
31
  "ruamel.yaml",
32
32
  "langchain==0.2.16",
33
- "langchain_experimental>=0.0.61",
34
- "langchain-community>=0.2.11",
33
+ "langchain_experimental==0.0.65",
34
+ "langchain-community==0.2.17",
35
+ "langsmith==0.1.140",
35
36
  ],
36
37
  extras_require={
37
38
  # Define optional dependencies with feature names
@@ -62,7 +63,7 @@ setup(
62
63
  "httpx",
63
64
  "jsonschema",
64
65
  "lancedb",
65
- "langchain>=0.2.12",
66
+ "langchain>=0.2.16",
66
67
  "langchain-experimental>=0.0.61",
67
68
  "langchain-community>=0.2.11",
68
69
  "langchain-openai==0.1.25",
@@ -0,0 +1,4 @@
1
+ from .process_funcs_cls import GenAIFunctionProcessor
2
+ from .safety import genai_safety
3
+ from .init import init_genai
4
+ from .file_handling import download_gcs_upload_genai, construct_file_content
@@ -0,0 +1,221 @@
1
+ from ..custom_logging import log
2
+ from ..gcs import get_bytes_from_gcs
3
+
4
+ from functools import partial
5
+ import mimetypes
6
+ import asyncio
7
+ import tempfile
8
+ import re
9
+ import os
10
+ import traceback
11
+ try:
12
+ import google.generativeai as genai
13
+ except ImportError:
14
+ genai = None
15
+
16
+ DOCUMENT_MIMES = [
17
+ 'application/pdf',
18
+ 'application/x-javascript',
19
+ 'text/javascript',
20
+ 'application/x-python',
21
+ 'text/x-python',
22
+ 'text/plain',
23
+ 'text/html',
24
+ 'text/css',
25
+ 'text/md',
26
+ 'text/csv',
27
+ 'text/xml',
28
+ 'text/rtf'
29
+ ]
30
+
31
+ IMAGE_MIMES = [
32
+ 'image/png',
33
+ 'image/jpeg',
34
+ 'image/webp',
35
+ 'image/heic',
36
+ 'image/heif',
37
+ ]
38
+
39
+ VIDEO_MIMES = [
40
+ 'video/mp4',
41
+ 'video/mpeg',
42
+ 'video/mov',
43
+ 'video/avi',
44
+ 'video/x-flv',
45
+ 'video/mpg',
46
+ 'video/webm',
47
+ 'video/wmv',
48
+ 'video/3gpp'
49
+ ]
50
+
51
+ AUDIO_MIMES = [
52
+ 'audio/wav',
53
+ 'audio/mp3',
54
+ 'audio/aiff',
55
+ 'audio/aac',
56
+ 'audio/ogg',
57
+ 'audio/flac',
58
+ ]
59
+
60
+ ALLOWED_MIME_TYPES = set(AUDIO_MIMES + VIDEO_MIMES + IMAGE_MIMES + DOCUMENT_MIMES)
61
+
62
+ # 'documents':
63
+ # [
64
+ # {'storagePath': 'users/UQcKi4u7s...dsd.png',
65
+ # 'url': 'https://firebasestorage.googleapis.com/v0/b/multi...',
66
+ # 'contentType': 'image/png',
67
+ # 'type': 'image',
68
+ # 'name': 'multivac-data-architecture.png'},
69
+ # {'storagePath': 'users/UQc...3dc59e1.jpg',
70
+ # 'type': 'image',
71
+ # 'name': 'holosun-circle.jpg',
72
+ # 'url': 'https://firebasestorage.googleapis.com/v0/b/multiv...',
73
+ # 'contentType': 'image/jpeg'}
74
+ # ]
75
+
76
+ def sanitize_file(filename):
77
+ # Split the filename into name and extension
78
+ name, extension = os.path.splitext(filename)
79
+
80
+ # Sanitize the name by removing invalid characters and converting to lowercase
81
+ sanitized_name = re.sub(r'[^a-z0-9-]', '', name.lower())
82
+ sanitized_name = re.sub(r'^-+|-+$', '', sanitized_name) # Remove leading or trailing dashes
83
+
84
+ # Reattach the original extension
85
+ return f"{sanitized_name}"
86
+
87
+ async def construct_file_content(gs_list, bucket:str):
88
+ """
89
+ Args:
90
+ - gs_list: a list of dicts representing files in a bucket
91
+ - contentType: The content type of the file on GCS
92
+ - storagePath: The path in the bucket
93
+ - name: The name of the file
94
+ - bucket: The bucket the files are in
95
+
96
+ """
97
+
98
+ file_list = []
99
+ for element in gs_list:
100
+
101
+ the_mime_type = element.get('contentType')
102
+ if the_mime_type is None:
103
+ continue
104
+ if element.get('storagePath') is None:
105
+ continue
106
+ if the_mime_type in ALLOWED_MIME_TYPES:
107
+ file_list.append(element)
108
+
109
+ if not file_list:
110
+ return {"role": "user", "parts": [{"text": "No eligible contentTypes were found"}]}
111
+
112
+ content = []
113
+
114
+ # Loop through the valid files and process them
115
+ tasks = []
116
+ for file_info in file_list:
117
+ img_url = f"gs://{bucket}/{file_info['storagePath']}"
118
+ mime_type = file_info['contentType']
119
+ name = sanitize_file(file_info['name'])
120
+ log.info(f"Processing {name=}")
121
+ try:
122
+ myfile = genai.get_file(name)
123
+ content.append(
124
+ {"role": "user", "parts": [
125
+ {"file_data": myfile},
126
+ {"text": f"You have been given the ability to work with file '{name}' with {mime_type=}."}
127
+ ]
128
+ })
129
+ log.info(f"Found existing genai.get_file {name=}")
130
+
131
+ except Exception as e:
132
+ log.info(f"Not found checking genai.get_file: '{name}' {str(e)}")
133
+ tasks.append(download_gcs_upload_genai(img_url, mime_type, name=name))
134
+
135
+ # Run all tasks in parallel
136
+ if tasks:
137
+ task_content = await asyncio.gather(*tasks)
138
+ content.extend(task_content)
139
+
140
+ return content
141
+
142
+ # Helper function to handle each file download with error handling
143
+ async def download_file_with_error_handling(img_url, mime_type, name):
144
+ try:
145
+ return await download_gcs_upload_genai(img_url, mime_type, name)
146
+ except Exception as err:
147
+ msg= f"Error processing file from {img_url}: {str(err)}"
148
+ log.error(msg)
149
+ return {"role": "user", "parts": [{"text": msg}]}
150
+
151
+ async def download_gcs_upload_genai(img_url, mime_type, name=None, retries=3, delay=2):
152
+ import aiofiles
153
+ from google.generativeai.types import file_types
154
+ """
155
+ Downloads and uploads a file with retries in case of failure.
156
+
157
+ Args:
158
+ - img_url: str The URL of the file to download.
159
+ - mime_type: str The MIME type of the file.
160
+ - name: str Optional name, else a random one will be created
161
+ - retries: int Number of retry attempts before failing.
162
+ - delay: int Initial delay between retries, exponentially increasing.
163
+
164
+ Returns:
165
+ - downloaded_content: The result of the file upload if successful.
166
+ """
167
+ for attempt in range(retries):
168
+ try:
169
+ log.info(f"Upload {attempt} for {img_url=}")
170
+ # Download the file bytes asynchronously
171
+ file_bytes = await asyncio.to_thread(get_bytes_from_gcs, img_url)
172
+ if not file_bytes:
173
+ msg = f"Failed to download file from {img_url}: got None"
174
+ log.warning(msg)
175
+ return {"role": "user", "parts": [{"text": msg}]}
176
+
177
+ # Log the size of the file bytes
178
+ file_size = len(file_bytes)
179
+ log.info(f"Downloaded file size for {img_url}: {file_size} bytes")
180
+
181
+ if file_size > 19434343:
182
+ log.warning(f"File size for {img_url}: {file_size} is too big.")
183
+ msg = f"The file for {img_url} is too large ({file_size} bytes) to be used directly. Use RAG instead."
184
+ return {"role": "user", "parts": [{"text": msg}]}
185
+
186
+ extension = mimetypes.guess_extension(mime_type)
187
+
188
+ # Use aiofiles for asynchronous file operations
189
+ temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=extension)
190
+ downloaded_file = temp_file.name
191
+
192
+ sanitized_file = sanitize_file(downloaded_file)
193
+
194
+ log.info(f"Writing file {sanitized_file}")
195
+ async with aiofiles.open(sanitized_file, 'wb') as f:
196
+ await f.write(file_bytes)
197
+
198
+ # Upload the file and get its content reference
199
+ try:
200
+ downloaded_content: file_types.File = await asyncio.to_thread(
201
+ partial(genai.upload_file, name=name, mime_type=mime_type),
202
+ sanitized_file
203
+ )
204
+ return {"role": "user", "parts": [{"file_data": downloaded_content},
205
+ {"text": f"You have been given the ability to read and work with filename '{name}' with {mime_type=}."}
206
+ ]}
207
+ except Exception as err:
208
+ msg = f"Could not upload {sanitized_file} to genai.upload_file: {str(err)} {traceback.format_exc()}"
209
+ log.error(msg)
210
+ return {"role": "user", "parts": [{"text": msg}]}
211
+
212
+ except Exception as err:
213
+ log.error(f"Error processing file {img_url} on attempt {attempt + 1}/{retries}: {str(err)}")
214
+
215
+ if attempt < retries - 1:
216
+ log.info(f"Retrying in {delay} seconds...")
217
+ await asyncio.sleep(delay)
218
+ delay *= 2 # Exponential backoff
219
+ else:
220
+ raise err # Raise the error after max retries
221
+
@@ -6,6 +6,8 @@ try:
6
6
  import sounddevice as sd
7
7
  except ImportError:
8
8
  sd = None
9
+ except OSError:
10
+ sd = None
9
11
 
10
12
  try:
11
13
  import numpy as np
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.108.0
3
+ Version: 0.109.3
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.108.0.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.109.3.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -21,8 +21,9 @@ License-File: LICENSE.txt
21
21
  Requires-Dist: google-auth
22
22
  Requires-Dist: ruamel.yaml
23
23
  Requires-Dist: langchain==0.2.16
24
- Requires-Dist: langchain_experimental>=0.0.61
25
- Requires-Dist: langchain-community>=0.2.11
24
+ Requires-Dist: langchain_experimental==0.0.65
25
+ Requires-Dist: langchain-community==0.2.17
26
+ Requires-Dist: langsmith==0.1.140
26
27
  Provides-Extra: all
27
28
  Requires-Dist: anthropic[vertex]; extra == "all"
28
29
  Requires-Dist: asyncpg; extra == "all"
@@ -50,7 +51,7 @@ Requires-Dist: httpcore; extra == "all"
50
51
  Requires-Dist: httpx; extra == "all"
51
52
  Requires-Dist: jsonschema; extra == "all"
52
53
  Requires-Dist: lancedb; extra == "all"
53
- Requires-Dist: langchain>=0.2.12; extra == "all"
54
+ Requires-Dist: langchain>=0.2.16; extra == "all"
54
55
  Requires-Dist: langchain-experimental>=0.0.61; extra == "all"
55
56
  Requires-Dist: langchain-community>=0.2.11; extra == "all"
56
57
  Requires-Dist: langchain-openai==0.1.25; extra == "all"
@@ -97,6 +97,7 @@ sunholo/gcs/download_url.py
97
97
  sunholo/gcs/extract_and_sign.py
98
98
  sunholo/gcs/metadata.py
99
99
  sunholo/genai/__init__.py
100
+ sunholo/genai/file_handling.py
100
101
  sunholo/genai/images.py
101
102
  sunholo/genai/init.py
102
103
  sunholo/genai/process_funcs_cls.py
@@ -1,8 +1,9 @@
1
1
  google-auth
2
2
  ruamel.yaml
3
3
  langchain==0.2.16
4
- langchain_experimental>=0.0.61
5
- langchain-community>=0.2.11
4
+ langchain_experimental==0.0.65
5
+ langchain-community==0.2.17
6
+ langsmith==0.1.140
6
7
 
7
8
  [all]
8
9
  anthropic[vertex]
@@ -31,7 +32,7 @@ httpcore
31
32
  httpx
32
33
  jsonschema
33
34
  lancedb
34
- langchain>=0.2.12
35
+ langchain>=0.2.16
35
36
  langchain-experimental>=0.0.61
36
37
  langchain-community>=0.2.11
37
38
  langchain-openai==0.1.25
@@ -1,3 +0,0 @@
1
- from .process_funcs_cls import GenAIFunctionProcessor
2
- from .safety import genai_safety
3
- from .init import init_genai
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes