sunholo 0.120.0__tar.gz → 0.120.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.
Files changed (186) hide show
  1. {sunholo-0.120.0/src/sunholo.egg-info → sunholo-0.120.1}/PKG-INFO +1 -1
  2. {sunholo-0.120.0 → sunholo-0.120.1}/pyproject.toml +1 -1
  3. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/genai/file_handling.py +52 -19
  4. {sunholo-0.120.0 → sunholo-0.120.1/src/sunholo.egg-info}/PKG-INFO +1 -1
  5. {sunholo-0.120.0 → sunholo-0.120.1}/LICENSE.txt +0 -0
  6. {sunholo-0.120.0 → sunholo-0.120.1}/MANIFEST.in +0 -0
  7. {sunholo-0.120.0 → sunholo-0.120.1}/README.md +0 -0
  8. {sunholo-0.120.0 → sunholo-0.120.1}/setup.cfg +0 -0
  9. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/__init__.py +0 -0
  10. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/agents/__init__.py +0 -0
  11. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/agents/chat_history.py +0 -0
  12. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/agents/dispatch_to_qa.py +0 -0
  13. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/agents/fastapi/__init__.py +0 -0
  14. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/agents/fastapi/base.py +0 -0
  15. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/agents/fastapi/qna_routes.py +0 -0
  16. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/agents/flask/__init__.py +0 -0
  17. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/agents/flask/base.py +0 -0
  18. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/agents/flask/qna_routes.py +0 -0
  19. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/agents/flask/vac_routes.py +0 -0
  20. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/agents/langserve.py +0 -0
  21. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/agents/pubsub.py +0 -0
  22. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/agents/route.py +0 -0
  23. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/agents/special_commands.py +0 -0
  24. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/agents/swagger.py +0 -0
  25. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/archive/__init__.py +0 -0
  26. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/archive/archive.py +0 -0
  27. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/auth/__init__.py +0 -0
  28. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/auth/gcloud.py +0 -0
  29. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/auth/refresh.py +0 -0
  30. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/auth/run.py +0 -0
  31. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/azure/__init__.py +0 -0
  32. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/azure/auth.py +0 -0
  33. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/azure/blobs.py +0 -0
  34. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/azure/event_grid.py +0 -0
  35. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/bots/__init__.py +0 -0
  36. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/bots/discord.py +0 -0
  37. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/bots/github_webhook.py +0 -0
  38. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/bots/webapp.py +0 -0
  39. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/chunker/__init__.py +0 -0
  40. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/chunker/azure.py +0 -0
  41. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/chunker/doc_handling.py +0 -0
  42. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/chunker/encode_metadata.py +0 -0
  43. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/chunker/images.py +0 -0
  44. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/chunker/loaders.py +0 -0
  45. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/chunker/message_data.py +0 -0
  46. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/chunker/pdfs.py +0 -0
  47. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/chunker/process_chunker_data.py +0 -0
  48. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/chunker/publish.py +0 -0
  49. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/chunker/pubsub.py +0 -0
  50. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/chunker/splitter.py +0 -0
  51. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/cli/__init__.py +0 -0
  52. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/cli/chat_vac.py +0 -0
  53. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/cli/cli.py +0 -0
  54. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/cli/cli_init.py +0 -0
  55. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/cli/configs.py +0 -0
  56. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/cli/deploy.py +0 -0
  57. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/cli/embedder.py +0 -0
  58. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/cli/merge_texts.py +0 -0
  59. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/cli/run_proxy.py +0 -0
  60. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/cli/sun_rich.py +0 -0
  61. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/cli/swagger.py +0 -0
  62. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/cli/vertex.py +0 -0
  63. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/components/__init__.py +0 -0
  64. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/components/llm.py +0 -0
  65. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/components/retriever.py +0 -0
  66. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/components/vectorstore.py +0 -0
  67. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/custom_logging.py +0 -0
  68. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/database/__init__.py +0 -0
  69. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/database/alloydb.py +0 -0
  70. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/database/alloydb_client.py +0 -0
  71. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/database/database.py +0 -0
  72. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/database/lancedb.py +0 -0
  73. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/database/sql/sb/create_function.sql +0 -0
  74. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/database/sql/sb/create_function_time.sql +0 -0
  75. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/database/sql/sb/create_table.sql +0 -0
  76. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/database/sql/sb/delete_source_row.sql +0 -0
  77. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/database/sql/sb/return_sources.sql +0 -0
  78. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/database/sql/sb/setup.sql +0 -0
  79. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/database/static_dbs.py +0 -0
  80. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/database/uuid.py +0 -0
  81. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/discovery_engine/__init__.py +0 -0
  82. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/discovery_engine/chunker_handler.py +0 -0
  83. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/discovery_engine/cli.py +0 -0
  84. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/discovery_engine/create_new.py +0 -0
  85. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/discovery_engine/discovery_engine_client.py +0 -0
  86. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/discovery_engine/get_ai_search_chunks.py +0 -0
  87. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/embedder/__init__.py +0 -0
  88. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/embedder/embed_chunk.py +0 -0
  89. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/embedder/embed_metadata.py +0 -0
  90. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/excel/__init__.py +0 -0
  91. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/excel/plugin.py +0 -0
  92. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/gcs/__init__.py +0 -0
  93. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/gcs/add_file.py +0 -0
  94. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/gcs/download_folder.py +0 -0
  95. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/gcs/download_url.py +0 -0
  96. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/gcs/extract_and_sign.py +0 -0
  97. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/gcs/metadata.py +0 -0
  98. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/genai/__init__.py +0 -0
  99. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/genai/genaiv2.py +0 -0
  100. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/genai/images.py +0 -0
  101. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/genai/init.py +0 -0
  102. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/genai/process_funcs_cls.py +0 -0
  103. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/genai/safety.py +0 -0
  104. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/invoke/__init__.py +0 -0
  105. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/invoke/async_class.py +0 -0
  106. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/invoke/direct_vac_func.py +0 -0
  107. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/invoke/invoke_vac_utils.py +0 -0
  108. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/langchain_types.py +0 -0
  109. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/langfuse/__init__.py +0 -0
  110. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/langfuse/callback.py +0 -0
  111. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/langfuse/evals.py +0 -0
  112. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/langfuse/prompts.py +0 -0
  113. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/llamaindex/__init__.py +0 -0
  114. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/llamaindex/get_files.py +0 -0
  115. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/llamaindex/import_files.py +0 -0
  116. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/llamaindex/llamaindex_class.py +0 -0
  117. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/llamaindex/user_history.py +0 -0
  118. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/lookup/__init__.py +0 -0
  119. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/lookup/model_lookup.yaml +0 -0
  120. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/mcp/__init__.py +0 -0
  121. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/mcp/cli.py +0 -0
  122. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/pubsub/__init__.py +0 -0
  123. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/pubsub/process_pubsub.py +0 -0
  124. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/pubsub/pubsub_manager.py +0 -0
  125. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/qna/__init__.py +0 -0
  126. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/qna/parsers.py +0 -0
  127. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/qna/retry.py +0 -0
  128. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/senses/__init__.py +0 -0
  129. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/senses/stream_voice.py +0 -0
  130. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/streaming/__init__.py +0 -0
  131. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/streaming/content_buffer.py +0 -0
  132. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/streaming/langserve.py +0 -0
  133. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/streaming/stream_lookup.py +0 -0
  134. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/streaming/streaming.py +0 -0
  135. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/summarise/__init__.py +0 -0
  136. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/summarise/summarise.py +0 -0
  137. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/templates/agent/__init__.py +0 -0
  138. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/templates/agent/agent_service.py +0 -0
  139. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/templates/agent/app.py +0 -0
  140. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/templates/agent/my_log.py +0 -0
  141. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/templates/agent/tools/__init__.py +0 -0
  142. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/templates/agent/tools/your_agent.py +0 -0
  143. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/templates/agent/vac_service.py +0 -0
  144. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/templates/project/__init__.py +0 -0
  145. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/templates/project/app.py +0 -0
  146. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/templates/project/my_log.py +0 -0
  147. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/templates/project/vac_service.py +0 -0
  148. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/templates/system_services/__init__.py +0 -0
  149. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/templates/system_services/app.py +0 -0
  150. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/templates/system_services/my_log.py +0 -0
  151. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/terraform/__init__.py +0 -0
  152. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/terraform/tfvars_editor.py +0 -0
  153. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/tools/__init__.py +0 -0
  154. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/tools/web_browser.py +0 -0
  155. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/utils/__init__.py +0 -0
  156. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/utils/api_key.py +0 -0
  157. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/utils/big_context.py +0 -0
  158. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/utils/config.py +0 -0
  159. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/utils/config_class.py +0 -0
  160. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/utils/config_schema.py +0 -0
  161. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/utils/gcp.py +0 -0
  162. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/utils/gcp_project.py +0 -0
  163. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/utils/mime.py +0 -0
  164. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/utils/parsers.py +0 -0
  165. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/utils/timedelta.py +0 -0
  166. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/utils/user_ids.py +0 -0
  167. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/utils/version.py +0 -0
  168. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/vertex/__init__.py +0 -0
  169. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/vertex/extensions_call.py +0 -0
  170. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/vertex/extensions_class.py +0 -0
  171. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/vertex/genai_functions.py +0 -0
  172. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/vertex/init.py +0 -0
  173. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/vertex/memory_tools.py +0 -0
  174. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/vertex/safety.py +0 -0
  175. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo/vertex/type_dict_to_json.py +0 -0
  176. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo.egg-info/SOURCES.txt +0 -0
  177. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo.egg-info/dependency_links.txt +0 -0
  178. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo.egg-info/entry_points.txt +0 -0
  179. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo.egg-info/requires.txt +0 -0
  180. {sunholo-0.120.0 → sunholo-0.120.1}/src/sunholo.egg-info/top_level.txt +0 -0
  181. {sunholo-0.120.0 → sunholo-0.120.1}/tests/test_async.py +0 -0
  182. {sunholo-0.120.0 → sunholo-0.120.1}/tests/test_async_genai2.py +0 -0
  183. {sunholo-0.120.0 → sunholo-0.120.1}/tests/test_chat_history.py +0 -0
  184. {sunholo-0.120.0 → sunholo-0.120.1}/tests/test_config.py +0 -0
  185. {sunholo-0.120.0 → sunholo-0.120.1}/tests/test_genai2.py +0 -0
  186. {sunholo-0.120.0 → sunholo-0.120.1}/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.1
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.1"
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)
98
+
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'
88
105
 
89
- # Reattach the original extension
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,12 @@ 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
142
+ import uuid
126
143
  original_name = sanitize_file(file_info['name'])
127
- unique_name = f"{original_name}_{str(uuid.uuid4())[:8]}"
144
+ unique_id = str(uuid.uuid4())[:8]
145
+ unique_name = sanitize_file(f"{original_name}-{unique_id}")
146
+
128
147
  display_name = file_info['name']
129
148
  log.info(f"Processing {unique_name=} {display_name=}")
130
149
 
@@ -148,16 +167,30 @@ async def construct_file_content(gs_list, bucket:str, genai_lib=False):
148
167
  genai_lib=genai_lib)
149
168
  )
150
169
 
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)
170
+ # Process files with timeout
171
+ if tasks:
172
+ try:
173
+ # Add timeout to prevent hanging
174
+ task_results = await asyncio.wait_for(asyncio.gather(*tasks, return_exceptions=True), timeout=timeout)
175
+
176
+ # Process results, handle any exceptions
177
+ for result in task_results:
178
+ if isinstance(result, Exception):
179
+ log.error(f"Task failed with error: {str(result)}")
180
+ # Add error message to content
181
+ content.append({"role": "user", "parts": [{"text": f"Error processing file: {str(result)}"}]})
182
+ else:
183
+ # Normalize the result structure based on genai_lib
184
+ if genai_lib and isinstance(result, list):
185
+ content.append(result[0]) # The file object
186
+ content.append({"role": "user", "parts": [{"text": result[1]}]}) # The message
187
+ else:
188
+ content.append(result)
189
+ except asyncio.TimeoutError:
190
+ log.error(f"Timeout occurred after {timeout} seconds while processing files")
191
+ content.append({"role": "user", "parts": [{"text": f"Some files could not be processed within the time limit ({timeout} seconds)"}]})
159
192
 
160
- content.extend(content_results)
193
+ log.info(f"construct_file_content completed with {len(content)} items")
161
194
  return content
162
195
 
163
196
  # Helper function to handle each file download with error handling
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: sunholo
3
- Version: 0.120.0
3
+ Version: 0.120.1
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