sunholo 0.120.0__tar.gz → 0.120.2__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 (186) hide show
  1. {sunholo-0.120.0/src/sunholo.egg-info → sunholo-0.120.2}/PKG-INFO +1 -1
  2. {sunholo-0.120.0 → sunholo-0.120.2}/pyproject.toml +1 -1
  3. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/genai/file_handling.py +51 -20
  4. {sunholo-0.120.0 → sunholo-0.120.2/src/sunholo.egg-info}/PKG-INFO +1 -1
  5. {sunholo-0.120.0 → sunholo-0.120.2}/LICENSE.txt +0 -0
  6. {sunholo-0.120.0 → sunholo-0.120.2}/MANIFEST.in +0 -0
  7. {sunholo-0.120.0 → sunholo-0.120.2}/README.md +0 -0
  8. {sunholo-0.120.0 → sunholo-0.120.2}/setup.cfg +0 -0
  9. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/__init__.py +0 -0
  10. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/agents/__init__.py +0 -0
  11. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/agents/chat_history.py +0 -0
  12. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/agents/dispatch_to_qa.py +0 -0
  13. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/agents/fastapi/__init__.py +0 -0
  14. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/agents/fastapi/base.py +0 -0
  15. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/agents/fastapi/qna_routes.py +0 -0
  16. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/agents/flask/__init__.py +0 -0
  17. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/agents/flask/base.py +0 -0
  18. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/agents/flask/qna_routes.py +0 -0
  19. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/agents/flask/vac_routes.py +0 -0
  20. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/agents/langserve.py +0 -0
  21. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/agents/pubsub.py +0 -0
  22. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/agents/route.py +0 -0
  23. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/agents/special_commands.py +0 -0
  24. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/agents/swagger.py +0 -0
  25. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/archive/__init__.py +0 -0
  26. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/archive/archive.py +0 -0
  27. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/auth/__init__.py +0 -0
  28. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/auth/gcloud.py +0 -0
  29. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/auth/refresh.py +0 -0
  30. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/auth/run.py +0 -0
  31. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/azure/__init__.py +0 -0
  32. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/azure/auth.py +0 -0
  33. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/azure/blobs.py +0 -0
  34. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/azure/event_grid.py +0 -0
  35. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/bots/__init__.py +0 -0
  36. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/bots/discord.py +0 -0
  37. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/bots/github_webhook.py +0 -0
  38. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/bots/webapp.py +0 -0
  39. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/chunker/__init__.py +0 -0
  40. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/chunker/azure.py +0 -0
  41. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/chunker/doc_handling.py +0 -0
  42. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/chunker/encode_metadata.py +0 -0
  43. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/chunker/images.py +0 -0
  44. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/chunker/loaders.py +0 -0
  45. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/chunker/message_data.py +0 -0
  46. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/chunker/pdfs.py +0 -0
  47. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/chunker/process_chunker_data.py +0 -0
  48. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/chunker/publish.py +0 -0
  49. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/chunker/pubsub.py +0 -0
  50. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/chunker/splitter.py +0 -0
  51. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/cli/__init__.py +0 -0
  52. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/cli/chat_vac.py +0 -0
  53. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/cli/cli.py +0 -0
  54. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/cli/cli_init.py +0 -0
  55. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/cli/configs.py +0 -0
  56. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/cli/deploy.py +0 -0
  57. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/cli/embedder.py +0 -0
  58. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/cli/merge_texts.py +0 -0
  59. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/cli/run_proxy.py +0 -0
  60. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/cli/sun_rich.py +0 -0
  61. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/cli/swagger.py +0 -0
  62. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/cli/vertex.py +0 -0
  63. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/components/__init__.py +0 -0
  64. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/components/llm.py +0 -0
  65. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/components/retriever.py +0 -0
  66. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/components/vectorstore.py +0 -0
  67. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/custom_logging.py +0 -0
  68. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/database/__init__.py +0 -0
  69. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/database/alloydb.py +0 -0
  70. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/database/alloydb_client.py +0 -0
  71. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/database/database.py +0 -0
  72. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/database/lancedb.py +0 -0
  73. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/database/sql/sb/create_function.sql +0 -0
  74. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/database/sql/sb/create_function_time.sql +0 -0
  75. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/database/sql/sb/create_table.sql +0 -0
  76. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/database/sql/sb/delete_source_row.sql +0 -0
  77. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/database/sql/sb/return_sources.sql +0 -0
  78. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/database/sql/sb/setup.sql +0 -0
  79. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/database/static_dbs.py +0 -0
  80. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/database/uuid.py +0 -0
  81. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/discovery_engine/__init__.py +0 -0
  82. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/discovery_engine/chunker_handler.py +0 -0
  83. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/discovery_engine/cli.py +0 -0
  84. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/discovery_engine/create_new.py +0 -0
  85. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/discovery_engine/discovery_engine_client.py +0 -0
  86. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/discovery_engine/get_ai_search_chunks.py +0 -0
  87. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/embedder/__init__.py +0 -0
  88. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/embedder/embed_chunk.py +0 -0
  89. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/embedder/embed_metadata.py +0 -0
  90. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/excel/__init__.py +0 -0
  91. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/excel/plugin.py +0 -0
  92. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/gcs/__init__.py +0 -0
  93. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/gcs/add_file.py +0 -0
  94. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/gcs/download_folder.py +0 -0
  95. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/gcs/download_url.py +0 -0
  96. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/gcs/extract_and_sign.py +0 -0
  97. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/gcs/metadata.py +0 -0
  98. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/genai/__init__.py +0 -0
  99. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/genai/genaiv2.py +0 -0
  100. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/genai/images.py +0 -0
  101. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/genai/init.py +0 -0
  102. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/genai/process_funcs_cls.py +0 -0
  103. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/genai/safety.py +0 -0
  104. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/invoke/__init__.py +0 -0
  105. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/invoke/async_class.py +0 -0
  106. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/invoke/direct_vac_func.py +0 -0
  107. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/invoke/invoke_vac_utils.py +0 -0
  108. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/langchain_types.py +0 -0
  109. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/langfuse/__init__.py +0 -0
  110. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/langfuse/callback.py +0 -0
  111. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/langfuse/evals.py +0 -0
  112. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/langfuse/prompts.py +0 -0
  113. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/llamaindex/__init__.py +0 -0
  114. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/llamaindex/get_files.py +0 -0
  115. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/llamaindex/import_files.py +0 -0
  116. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/llamaindex/llamaindex_class.py +0 -0
  117. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/llamaindex/user_history.py +0 -0
  118. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/lookup/__init__.py +0 -0
  119. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/lookup/model_lookup.yaml +0 -0
  120. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/mcp/__init__.py +0 -0
  121. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/mcp/cli.py +0 -0
  122. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/pubsub/__init__.py +0 -0
  123. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/pubsub/process_pubsub.py +0 -0
  124. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/pubsub/pubsub_manager.py +0 -0
  125. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/qna/__init__.py +0 -0
  126. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/qna/parsers.py +0 -0
  127. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/qna/retry.py +0 -0
  128. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/senses/__init__.py +0 -0
  129. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/senses/stream_voice.py +0 -0
  130. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/streaming/__init__.py +0 -0
  131. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/streaming/content_buffer.py +0 -0
  132. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/streaming/langserve.py +0 -0
  133. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/streaming/stream_lookup.py +0 -0
  134. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/streaming/streaming.py +0 -0
  135. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/summarise/__init__.py +0 -0
  136. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/summarise/summarise.py +0 -0
  137. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/templates/agent/__init__.py +0 -0
  138. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/templates/agent/agent_service.py +0 -0
  139. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/templates/agent/app.py +0 -0
  140. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/templates/agent/my_log.py +0 -0
  141. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/templates/agent/tools/__init__.py +0 -0
  142. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/templates/agent/tools/your_agent.py +0 -0
  143. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/templates/agent/vac_service.py +0 -0
  144. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/templates/project/__init__.py +0 -0
  145. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/templates/project/app.py +0 -0
  146. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/templates/project/my_log.py +0 -0
  147. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/templates/project/vac_service.py +0 -0
  148. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/templates/system_services/__init__.py +0 -0
  149. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/templates/system_services/app.py +0 -0
  150. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/templates/system_services/my_log.py +0 -0
  151. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/terraform/__init__.py +0 -0
  152. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/terraform/tfvars_editor.py +0 -0
  153. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/tools/__init__.py +0 -0
  154. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/tools/web_browser.py +0 -0
  155. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/utils/__init__.py +0 -0
  156. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/utils/api_key.py +0 -0
  157. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/utils/big_context.py +0 -0
  158. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/utils/config.py +0 -0
  159. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/utils/config_class.py +0 -0
  160. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/utils/config_schema.py +0 -0
  161. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/utils/gcp.py +0 -0
  162. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/utils/gcp_project.py +0 -0
  163. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/utils/mime.py +0 -0
  164. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/utils/parsers.py +0 -0
  165. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/utils/timedelta.py +0 -0
  166. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/utils/user_ids.py +0 -0
  167. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/utils/version.py +0 -0
  168. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/vertex/__init__.py +0 -0
  169. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/vertex/extensions_call.py +0 -0
  170. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/vertex/extensions_class.py +0 -0
  171. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/vertex/genai_functions.py +0 -0
  172. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/vertex/init.py +0 -0
  173. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/vertex/memory_tools.py +0 -0
  174. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/vertex/safety.py +0 -0
  175. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo/vertex/type_dict_to_json.py +0 -0
  176. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo.egg-info/SOURCES.txt +0 -0
  177. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo.egg-info/dependency_links.txt +0 -0
  178. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo.egg-info/entry_points.txt +0 -0
  179. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo.egg-info/requires.txt +0 -0
  180. {sunholo-0.120.0 → sunholo-0.120.2}/src/sunholo.egg-info/top_level.txt +0 -0
  181. {sunholo-0.120.0 → sunholo-0.120.2}/tests/test_async.py +0 -0
  182. {sunholo-0.120.0 → sunholo-0.120.2}/tests/test_async_genai2.py +0 -0
  183. {sunholo-0.120.0 → sunholo-0.120.2}/tests/test_chat_history.py +0 -0
  184. {sunholo-0.120.0 → sunholo-0.120.2}/tests/test_config.py +0 -0
  185. {sunholo-0.120.0 → sunholo-0.120.2}/tests/test_genai2.py +0 -0
  186. {sunholo-0.120.0 → sunholo-0.120.2}/tests/test_unstructured.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: sunholo
3
- Version: 0.120.0
3
+ Version: 0.120.2
4
4
  Summary: Large Language Model DevOps - a package to help deploy LLMs to the Cloud.
5
5
  Author-email: Holosun ApS <multivac@sunholo.com>
6
6
  License: Apache License, Version 2.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "sunholo"
7
- version = "0.120.0"
7
+ version = "0.120.2"
8
8
  description = "Large Language Model DevOps - a package to help deploy LLMs to the Cloud."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -79,24 +79,40 @@ ALLOWED_MIME_TYPES = set(AUDIO_MIMES + VIDEO_MIMES + IMAGE_MIMES + DOCUMENT_MIME
79
79
  # ]
80
80
 
81
81
  def sanitize_file(filename):
82
+ """
83
+ Sanitize filename to conform to Gemini API requirements:
84
+ - Only lowercase alphanumeric characters and dashes
85
+ - Cannot begin or end with a dash
86
+ """
82
87
  # Split the filename into name and extension
83
88
  name, extension = os.path.splitext(filename)
84
89
 
85
- # Sanitize the name by removing invalid characters and converting to lowercase
86
- sanitized_name = re.sub(r'[^a-z0-9-]', '', name.lower())
87
- sanitized_name = re.sub(r'^-+|-+$', '', sanitized_name) # Remove leading or trailing dashes
90
+ # Convert to lowercase
91
+ name = name.lower()
92
+
93
+ # Replace any non-alphanumeric characters (including underscores) with dashes
94
+ sanitized_name = re.sub(r'[^a-z0-9]', '-', name)
95
+
96
+ # Remove consecutive dashes
97
+ sanitized_name = re.sub(r'-+', '-', sanitized_name)
88
98
 
89
- # Reattach the original extension
99
+ # Remove leading or trailing dashes
100
+ sanitized_name = sanitized_name.strip('-')
101
+
102
+ # If the name is empty after sanitization, use a default
103
+ if not sanitized_name:
104
+ sanitized_name = 'file'
105
+
106
+ # Limit the length
90
107
  return sanitized_name[:40]
91
108
 
92
- async def construct_file_content(gs_list, bucket:str, genai_lib=False):
109
+ async def construct_file_content(gs_list, bucket:str, genai_lib=False, timeout=60):
93
110
  """
94
- Thread-safe implementation for processing multiple files concurrently.
95
-
96
111
  Args:
97
112
  - gs_list: a list of dicts representing files in a bucket
98
113
  - bucket: The bucket the files are in
99
114
  - genai_lib: whether its using the genai SDK
115
+ - timeout: timeout in seconds for the gather operation
100
116
  """
101
117
 
102
118
  file_list = []
@@ -112,7 +128,7 @@ async def construct_file_content(gs_list, bucket:str, genai_lib=False):
112
128
  log.warning(f'{the_mime_type} is not in allowed MIME types for {element.get("name")}')
113
129
 
114
130
  if not file_list:
115
- return {"role": "user", "parts": [{"text": "No eligible contentTypes were found"}]}
131
+ return [{"role": "user", "parts": [{"text": "No eligible contentTypes were found"}]}]
116
132
 
117
133
  content = []
118
134
 
@@ -122,9 +138,10 @@ async def construct_file_content(gs_list, bucket:str, genai_lib=False):
122
138
  img_url = f"gs://{bucket}/{file_info['storagePath']}"
123
139
  display_url = file_info.get('url')
124
140
  mime_type = file_info['contentType']
125
- # Generate a unique name for each file to avoid conflicts
141
+ # Generate a unique name for each file
126
142
  original_name = sanitize_file(file_info['name'])
127
- unique_name = f"{original_name}_{str(uuid.uuid4())[:8]}"
143
+ unique_name = sanitize_file(f"{original_name}")
144
+
128
145
  display_name = file_info['name']
129
146
  log.info(f"Processing {unique_name=} {display_name=}")
130
147
 
@@ -148,16 +165,30 @@ async def construct_file_content(gs_list, bucket:str, genai_lib=False):
148
165
  genai_lib=genai_lib)
149
166
  )
150
167
 
151
- # Process files in batches to avoid overwhelming the system
152
- content_results = []
153
- batch_size = 3 # Process 3 files at a time
154
-
155
- for i in range(0, len(tasks), batch_size):
156
- batch = tasks[i:i+batch_size]
157
- batch_results = await asyncio.gather(*batch)
158
- content_results.extend(batch_results)
168
+ # Process files with timeout
169
+ if tasks:
170
+ try:
171
+ # Add timeout to prevent hanging
172
+ task_results = await asyncio.wait_for(asyncio.gather(*tasks, return_exceptions=True), timeout=timeout)
173
+
174
+ # Process results, handle any exceptions
175
+ for result in task_results:
176
+ if isinstance(result, Exception):
177
+ log.error(f"Task failed with error: {str(result)}")
178
+ # Add error message to content
179
+ content.append({"role": "user", "parts": [{"text": f"Error processing file: {str(result)}"}]})
180
+ else:
181
+ # Normalize the result structure based on genai_lib
182
+ if genai_lib and isinstance(result, list):
183
+ content.append(result[0]) # The file object
184
+ content.append({"role": "user", "parts": [{"text": result[1]}]}) # The message
185
+ else:
186
+ content.append(result)
187
+ except asyncio.TimeoutError:
188
+ log.error(f"Timeout occurred after {timeout} seconds while processing files")
189
+ content.append({"role": "user", "parts": [{"text": f"Some files could not be processed within the time limit ({timeout} seconds)"}]})
159
190
 
160
- content.extend(content_results)
191
+ log.info(f"construct_file_content completed with {len(content)} items")
161
192
  return content
162
193
 
163
194
  # Helper function to handle each file download with error handling
@@ -218,7 +249,7 @@ async def download_gcs_upload_genai(img_url,
218
249
 
219
250
  # Create a file with unique path
220
251
  file_path = os.path.join(temp_dir, f"file_{unique_id}{extension}")
221
-
252
+ file_path = sanitize_file(file_path)
222
253
  log.info(f"Writing file {file_path}")
223
254
  async with aiofiles.open(file_path, 'wb') as f:
224
255
  await f.write(file_bytes)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: sunholo
3
- Version: 0.120.0
3
+ Version: 0.120.2
4
4
  Summary: Large Language Model DevOps - a package to help deploy LLMs to the Cloud.
5
5
  Author-email: Holosun ApS <multivac@sunholo.com>
6
6
  License: Apache License, Version 2.0
File without changes
File without changes
File without changes
File without changes
File without changes