camel-ai 0.1.6.2__tar.gz → 0.1.6.4__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.

Potentially problematic release.


This version of camel-ai might be problematic. Click here for more details.

Files changed (188) hide show
  1. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/PKG-INFO +9 -5
  2. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/README.md +1 -1
  3. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/__init__.py +1 -1
  4. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/configs/mistral_config.py +13 -9
  5. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/embeddings/mistral_embedding.py +5 -5
  6. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/interpreters/docker_interpreter.py +1 -1
  7. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/loaders/__init__.py +1 -2
  8. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/loaders/base_io.py +118 -52
  9. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/loaders/jina_url_reader.py +6 -6
  10. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/loaders/unstructured_io.py +24 -286
  11. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/models/__init__.py +2 -0
  12. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/models/mistral_model.py +120 -26
  13. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/models/model_factory.py +3 -3
  14. camel_ai-0.1.6.4/camel/models/openai_compatibility_model.py +105 -0
  15. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/retrievers/auto_retriever.py +25 -35
  16. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/retrievers/vector_retriever.py +20 -18
  17. camel_ai-0.1.6.4/camel/storages/object_storages/__init__.py +22 -0
  18. camel_ai-0.1.6.4/camel/storages/object_storages/amazon_s3.py +205 -0
  19. camel_ai-0.1.6.4/camel/storages/object_storages/azure_blob.py +166 -0
  20. camel_ai-0.1.6.4/camel/storages/object_storages/base.py +115 -0
  21. camel_ai-0.1.6.4/camel/storages/object_storages/google_cloud.py +152 -0
  22. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/retrieval_toolkit.py +5 -5
  23. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/search_toolkit.py +4 -4
  24. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/types/enums.py +7 -0
  25. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/utils/token_counting.py +7 -3
  26. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/pyproject.toml +22 -7
  27. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/agents/__init__.py +0 -0
  28. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/agents/base.py +0 -0
  29. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/agents/chat_agent.py +0 -0
  30. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/agents/critic_agent.py +0 -0
  31. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/agents/deductive_reasoner_agent.py +0 -0
  32. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/agents/embodied_agent.py +0 -0
  33. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/agents/knowledge_graph_agent.py +0 -0
  34. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/agents/role_assignment_agent.py +0 -0
  35. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/agents/search_agent.py +0 -0
  36. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/agents/task_agent.py +0 -0
  37. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/agents/tool_agents/__init__.py +0 -0
  38. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/agents/tool_agents/base.py +0 -0
  39. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/agents/tool_agents/hugging_face_tool_agent.py +0 -0
  40. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/configs/__init__.py +0 -0
  41. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/configs/anthropic_config.py +0 -0
  42. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/configs/base_config.py +0 -0
  43. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/configs/gemini_config.py +0 -0
  44. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/configs/groq_config.py +0 -0
  45. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/configs/litellm_config.py +0 -0
  46. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/configs/ollama_config.py +0 -0
  47. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/configs/openai_config.py +0 -0
  48. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/configs/vllm_config.py +0 -0
  49. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/configs/zhipuai_config.py +0 -0
  50. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/embeddings/__init__.py +0 -0
  51. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/embeddings/base.py +0 -0
  52. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/embeddings/openai_embedding.py +0 -0
  53. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/embeddings/sentence_transformers_embeddings.py +0 -0
  54. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/embeddings/vlm_embedding.py +0 -0
  55. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/generators.py +0 -0
  56. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/human.py +0 -0
  57. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/interpreters/__init__.py +0 -0
  58. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/interpreters/base.py +0 -0
  59. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/interpreters/internal_python_interpreter.py +0 -0
  60. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/interpreters/interpreter_error.py +0 -0
  61. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/interpreters/ipython_interpreter.py +0 -0
  62. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/interpreters/subprocess_interpreter.py +0 -0
  63. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/loaders/firecrawl_reader.py +0 -0
  64. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/memories/__init__.py +0 -0
  65. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/memories/agent_memories.py +0 -0
  66. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/memories/base.py +0 -0
  67. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/memories/blocks/__init__.py +0 -0
  68. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/memories/blocks/chat_history_block.py +0 -0
  69. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/memories/blocks/vectordb_block.py +0 -0
  70. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/memories/context_creators/__init__.py +0 -0
  71. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/memories/context_creators/score_based.py +0 -0
  72. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/memories/records.py +0 -0
  73. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/messages/__init__.py +0 -0
  74. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/messages/base.py +0 -0
  75. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/messages/func_message.py +0 -0
  76. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/models/anthropic_model.py +0 -0
  77. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/models/azure_openai_model.py +0 -0
  78. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/models/base_model.py +0 -0
  79. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/models/gemini_model.py +0 -0
  80. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/models/groq_model.py +0 -0
  81. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/models/litellm_model.py +0 -0
  82. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/models/nemotron_model.py +0 -0
  83. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/models/ollama_model.py +0 -0
  84. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/models/open_source_model.py +0 -0
  85. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/models/openai_audio_models.py +0 -0
  86. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/models/openai_model.py +0 -0
  87. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/models/stub_model.py +0 -0
  88. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/models/vllm_model.py +0 -0
  89. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/models/zhipuai_model.py +0 -0
  90. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/prompts/__init__.py +0 -0
  91. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/prompts/ai_society.py +0 -0
  92. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/prompts/base.py +0 -0
  93. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/prompts/code.py +0 -0
  94. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/prompts/evaluation.py +0 -0
  95. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/prompts/generate_text_embedding_data.py +0 -0
  96. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/prompts/image_craft.py +0 -0
  97. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/prompts/misalignment.py +0 -0
  98. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/prompts/multi_condition_image_craft.py +0 -0
  99. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/prompts/object_recognition.py +0 -0
  100. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/prompts/prompt_templates.py +0 -0
  101. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/prompts/role_description_prompt_template.py +0 -0
  102. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/prompts/solution_extraction.py +0 -0
  103. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/prompts/task_prompt_template.py +0 -0
  104. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/prompts/translation.py +0 -0
  105. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/prompts/video_description_prompt.py +0 -0
  106. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/responses/__init__.py +0 -0
  107. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/responses/agent_responses.py +0 -0
  108. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/retrievers/__init__.py +0 -0
  109. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/retrievers/base.py +0 -0
  110. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/retrievers/bm25_retriever.py +0 -0
  111. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/retrievers/cohere_rerank_retriever.py +0 -0
  112. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/societies/__init__.py +0 -0
  113. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/societies/babyagi_playing.py +0 -0
  114. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/societies/role_playing.py +0 -0
  115. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/storages/__init__.py +0 -0
  116. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/storages/graph_storages/__init__.py +0 -0
  117. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/storages/graph_storages/base.py +0 -0
  118. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/storages/graph_storages/graph_element.py +0 -0
  119. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/storages/graph_storages/neo4j_graph.py +0 -0
  120. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/storages/key_value_storages/__init__.py +0 -0
  121. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/storages/key_value_storages/base.py +0 -0
  122. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/storages/key_value_storages/in_memory.py +0 -0
  123. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/storages/key_value_storages/json.py +0 -0
  124. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/storages/key_value_storages/redis.py +0 -0
  125. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/storages/vectordb_storages/__init__.py +0 -0
  126. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/storages/vectordb_storages/base.py +0 -0
  127. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/storages/vectordb_storages/milvus.py +0 -0
  128. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/storages/vectordb_storages/qdrant.py +0 -0
  129. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/tasks/__init__.py +0 -0
  130. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/tasks/task.py +0 -0
  131. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/tasks/task_prompt.py +0 -0
  132. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/terminators/__init__.py +0 -0
  133. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/terminators/base.py +0 -0
  134. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/terminators/response_terminator.py +0 -0
  135. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/terminators/token_limit_terminator.py +0 -0
  136. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/__init__.py +0 -0
  137. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/base.py +0 -0
  138. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/code_execution.py +0 -0
  139. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/dalle_toolkit.py +0 -0
  140. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/github_toolkit.py +0 -0
  141. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/google_maps_toolkit.py +0 -0
  142. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/math_toolkit.py +0 -0
  143. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/biztoc/__init__.py +0 -0
  144. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/biztoc/ai-plugin.json +0 -0
  145. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/biztoc/openapi.yaml +0 -0
  146. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/coursera/__init__.py +0 -0
  147. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/coursera/openapi.yaml +0 -0
  148. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/create_qr_code/__init__.py +0 -0
  149. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/create_qr_code/openapi.yaml +0 -0
  150. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/klarna/__init__.py +0 -0
  151. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/klarna/openapi.yaml +0 -0
  152. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/nasa_apod/__init__.py +0 -0
  153. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/nasa_apod/openapi.yaml +0 -0
  154. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/outschool/__init__.py +0 -0
  155. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/outschool/ai-plugin.json +0 -0
  156. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/outschool/openapi.yaml +0 -0
  157. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/outschool/paths/__init__.py +0 -0
  158. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/outschool/paths/get_classes.py +0 -0
  159. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/outschool/paths/search_teachers.py +0 -0
  160. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/security_config.py +0 -0
  161. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/speak/__init__.py +0 -0
  162. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/speak/openapi.yaml +0 -0
  163. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/web_scraper/__init__.py +0 -0
  164. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/web_scraper/ai-plugin.json +0 -0
  165. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/web_scraper/openapi.yaml +0 -0
  166. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/web_scraper/paths/__init__.py +0 -0
  167. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_specs/web_scraper/paths/scraper.py +0 -0
  168. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/open_api_toolkit.py +0 -0
  169. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/openai_function.py +0 -0
  170. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/slack_toolkit.py +0 -0
  171. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/twitter_toolkit.py +0 -0
  172. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/toolkits/weather_toolkit.py +0 -0
  173. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/types/__init__.py +0 -0
  174. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/types/openai_types.py +0 -0
  175. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/utils/__init__.py +0 -0
  176. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/utils/async_func.py +0 -0
  177. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/utils/commons.py +0 -0
  178. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/utils/constants.py +0 -0
  179. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/workforce/__init__.py +0 -0
  180. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/workforce/base.py +0 -0
  181. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/workforce/manager_node.py +0 -0
  182. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/workforce/role_playing_node.py +0 -0
  183. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/workforce/single_agent_node.py +0 -0
  184. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/workforce/task_channel.py +0 -0
  185. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/workforce/utils.py +0 -0
  186. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/workforce/worker_node.py +0 -0
  187. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/workforce/workforce.py +0 -0
  188. {camel_ai-0.1.6.2 → camel_ai-0.1.6.4}/camel/workforce/workforce_prompt.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: camel-ai
3
- Version: 0.1.6.2
3
+ Version: 0.1.6.4
4
4
  Summary: Communicative Agents for AI Society Study
5
5
  Home-page: https://www.camel-ai.org/
6
6
  License: Apache-2.0
@@ -18,6 +18,7 @@ Provides-Extra: graph-storages
18
18
  Provides-Extra: huggingface-agent
19
19
  Provides-Extra: kv-stroages
20
20
  Provides-Extra: model-platforms
21
+ Provides-Extra: object-storages
21
22
  Provides-Extra: retrievers
22
23
  Provides-Extra: test
23
24
  Provides-Extra: tools
@@ -26,7 +27,9 @@ Requires-Dist: PyMuPDF (>=1.22.5,<2.0.0) ; extra == "tools" or extra == "all"
26
27
  Requires-Dist: accelerate (>=0,<1) ; extra == "huggingface-agent" or extra == "all"
27
28
  Requires-Dist: agentops (>=0.3.6,<0.4.0) ; extra == "tools" or extra == "all"
28
29
  Requires-Dist: anthropic (>=0.29.0,<0.30.0)
30
+ Requires-Dist: azure-storage-blob (>=12.21.0,<13.0.0) ; extra == "object-storages" or extra == "all"
29
31
  Requires-Dist: beautifulsoup4 (>=4,<5) ; extra == "tools" or extra == "all"
32
+ Requires-Dist: boto3 (>=1.34.149,<2.0.0) ; extra == "object-storages" or extra == "all"
30
33
  Requires-Dist: cohere (>=4.56,<5.0) ; extra == "retrievers" or extra == "all"
31
34
  Requires-Dist: colorama (>=0,<1)
32
35
  Requires-Dist: curl_cffi (==0.6.2)
@@ -39,6 +42,7 @@ Requires-Dist: docx2txt (>=0.8,<0.9) ; extra == "tools" or extra == "all"
39
42
  Requires-Dist: duckduckgo-search (>=6.1.0,<7.0.0) ; extra == "tools" or extra == "all"
40
43
  Requires-Dist: eval-type-backport (==0.2.0)
41
44
  Requires-Dist: firecrawl-py (>=0.0.20,<0.0.21) ; extra == "tools" or extra == "all"
45
+ Requires-Dist: google-cloud-storage (>=2.18.0,<3.0.0) ; extra == "object-storages" or extra == "all"
42
46
  Requires-Dist: google-generativeai (>=0.6.0,<0.7.0) ; extra == "model-platforms" or extra == "all"
43
47
  Requires-Dist: googlemaps (>=4.10.0,<5.0.0) ; extra == "tools" or extra == "all"
44
48
  Requires-Dist: groq (>=0.5.0,<0.6.0)
@@ -47,11 +51,11 @@ Requires-Dist: ipykernel (>=6.0.0,<7.0.0)
47
51
  Requires-Dist: jsonschema (>=4,<5)
48
52
  Requires-Dist: jupyter_client (>=8.6.2,<9.0.0) ; extra == "tools" or extra == "all"
49
53
  Requires-Dist: litellm (>=1.38.1,<2.0.0) ; extra == "model-platforms" or extra == "all"
50
- Requires-Dist: mistral-common (>=1.3.3,<2.0.0) ; extra == "model-platforms" or extra == "all"
51
- Requires-Dist: mistralai (>=0.4.2,<0.5.0) ; extra == "model-platforms" or extra == "all"
54
+ Requires-Dist: mistralai (>=1.0.0,<2.0.0) ; extra == "model-platforms" or extra == "all"
52
55
  Requires-Dist: mock (>=5,<6) ; extra == "test"
53
56
  Requires-Dist: neo4j (>=5.18.0,<6.0.0) ; extra == "graph-storages" or extra == "all"
54
57
  Requires-Dist: newspaper3k (>=0.2.8,<0.3.0) ; extra == "tools" or extra == "all"
58
+ Requires-Dist: nltk (==3.8.1) ; extra == "tools" or extra == "all"
55
59
  Requires-Dist: numpy (>=1,<2)
56
60
  Requires-Dist: openai (>=1.2.3,<2.0.0)
57
61
  Requires-Dist: openapi-spec-validator (>=0.7.1,<0.8.0) ; extra == "tools" or extra == "all"
@@ -79,7 +83,7 @@ Requires-Dist: soundfile (>=0,<1) ; extra == "huggingface-agent" or extra == "al
79
83
  Requires-Dist: tiktoken (>=0.7.0,<0.8.0)
80
84
  Requires-Dist: torch (>=2,<3) ; extra == "huggingface-agent" or extra == "all"
81
85
  Requires-Dist: transformers (>=4,<5) ; extra == "huggingface-agent" or extra == "all"
82
- Requires-Dist: unstructured[all-docs] (>=0.10.30,<0.11.0) ; extra == "tools" or extra == "all"
86
+ Requires-Dist: unstructured[all-docs] (>=0.10,<0.11) ; extra == "tools" or extra == "all"
83
87
  Requires-Dist: wikipedia (>=1,<2) ; extra == "tools" or extra == "all"
84
88
  Requires-Dist: wolframalpha (>=5.0.0,<6.0.0) ; extra == "tools" or extra == "all"
85
89
  Project-URL: Documentation, https://docs.camel-ai.org
@@ -198,7 +202,7 @@ conda create --name camel python=3.9
198
202
  conda activate camel
199
203
 
200
204
  # Clone github repo
201
- git clone -b v0.1.6.2 https://github.com/camel-ai/camel.git
205
+ git clone -b v0.1.6.4 https://github.com/camel-ai/camel.git
202
206
 
203
207
  # Change directory into project directory
204
208
  cd camel
@@ -110,7 +110,7 @@ conda create --name camel python=3.9
110
110
  conda activate camel
111
111
 
112
112
  # Clone github repo
113
- git clone -b v0.1.6.2 https://github.com/camel-ai/camel.git
113
+ git clone -b v0.1.6.4 https://github.com/camel-ai/camel.git
114
114
 
115
115
  # Change directory into project directory
116
116
  cd camel
@@ -12,7 +12,7 @@
12
12
  # limitations under the License.
13
13
  # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
14
14
 
15
- __version__ = '0.1.6.2'
15
+ __version__ = '0.1.6.4'
16
16
 
17
17
  __all__ = [
18
18
  '__version__',
@@ -26,23 +26,26 @@ class MistralConfig(BaseConfig):
26
26
 
27
27
  reference: https://github.com/mistralai/client-python/blob/9d238f88c41689821d7b08570f13b43426f97fd6/src/mistralai/client.py#L195
28
28
 
29
+ #TODO: Support stream mode
30
+
29
31
  Args:
30
32
  temperature (Optional[float], optional): temperature the temperature
31
33
  to use for sampling, e.g. 0.5.
32
- max_tokens (Optional[int], optional): the maximum number of tokens to
33
- generate, e.g. 100. Defaults to None.
34
34
  top_p (Optional[float], optional): the cumulative probability of
35
35
  tokens to generate, e.g. 0.9. Defaults to None.
36
+ max_tokens (Optional[int], optional): the maximum number of tokens to
37
+ generate, e.g. 100. Defaults to None.
38
+ min_tokens (Optional[int], optional): the minimum number of tokens to
39
+ generate, e.g. 100. Defaults to None.
40
+ stop (Optional[Union[str,list[str]]]): Stop generation if this token
41
+ is detected. Or if one of these tokens is detected when providing
42
+ a string list.
36
43
  random_seed (Optional[int], optional): the random seed to use for
37
44
  sampling, e.g. 42. Defaults to None.
38
- safe_mode (bool, optional): deprecated, use safe_prompt instead.
39
- Defaults to False.
40
45
  safe_prompt (bool, optional): whether to use safe prompt, e.g. true.
41
46
  Defaults to False.
42
47
  response_format (Union[Dict[str, str], ResponseFormat): format of the
43
48
  response.
44
- tools (Optional[list[OpenAIFunction]], optional): a list of tools to
45
- use.
46
49
  tool_choice (str, optional): Controls which (if
47
50
  any) tool is called by the model. :obj:`"none"` means the model
48
51
  will not call any tool and instead generates a message.
@@ -53,10 +56,11 @@ class MistralConfig(BaseConfig):
53
56
  """
54
57
 
55
58
  temperature: Optional[float] = None
56
- max_tokens: Optional[int] = None
57
59
  top_p: Optional[float] = None
60
+ max_tokens: Optional[int] = None
61
+ min_tokens: Optional[int] = None
62
+ stop: Optional[Union[str, list[str]]] = None
58
63
  random_seed: Optional[int] = None
59
- safe_mode: bool = False
60
64
  safe_prompt: bool = False
61
65
  response_format: Optional[Union[Dict[str, str], Any]] = None
62
66
  tool_choice: Optional[str] = "auto"
@@ -65,7 +69,7 @@ class MistralConfig(BaseConfig):
65
69
  @classmethod
66
70
  def fields_type_checking(cls, response_format):
67
71
  if response_format and not isinstance(response_format, dict):
68
- from mistralai.models.chat_completion import ResponseFormat
72
+ from mistralai.models import ResponseFormat
69
73
 
70
74
  if not isinstance(response_format, ResponseFormat):
71
75
  raise ValueError(
@@ -43,7 +43,7 @@ class MistralEmbedding(BaseEmbedding[str]):
43
43
  api_key: str | None = None,
44
44
  dimensions: int | None = None,
45
45
  ) -> None:
46
- from mistralai.client import MistralClient
46
+ from mistralai import Mistral
47
47
 
48
48
  if not model_type.is_mistral:
49
49
  raise ValueError("Invalid Mistral embedding model type.")
@@ -54,7 +54,7 @@ class MistralEmbedding(BaseEmbedding[str]):
54
54
  assert isinstance(dimensions, int)
55
55
  self.output_dim = dimensions
56
56
  self._api_key = api_key or os.environ.get("MISTRAL_API_KEY")
57
- self._client = MistralClient(api_key=self._api_key)
57
+ self._client = Mistral(api_key=self._api_key)
58
58
 
59
59
  @api_keys_required("MISTRAL_API_KEY")
60
60
  def embed_list(
@@ -73,12 +73,12 @@ class MistralEmbedding(BaseEmbedding[str]):
73
73
  as a list of floating-point numbers.
74
74
  """
75
75
  # TODO: count tokens
76
- response = self._client.embeddings(
77
- input=objs,
76
+ response = self._client.embeddings.create(
77
+ inputs=objs,
78
78
  model=self.model_type.value,
79
79
  **kwargs,
80
80
  )
81
- return [data.embedding for data in response.data]
81
+ return [data.embedding for data in response.data] # type: ignore[misc,union-attr]
82
82
 
83
83
  def get_output_dim(self) -> int:
84
84
  r"""Returns the output dimension of the embeddings.
@@ -130,7 +130,7 @@ class DockerInterpreter(BaseInterpreter):
130
130
  code_type = self._check_code_type(code_type)
131
131
  commands = shlex.split(
132
132
  self._CODE_EXECUTE_CMD_MAPPING[code_type].format(
133
- file_name=str(file)
133
+ file_name=file.as_posix()
134
134
  )
135
135
  )
136
136
  if self._container is None:
@@ -12,14 +12,13 @@
12
12
  # limitations under the License.
13
13
  # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
14
14
 
15
- from .base_io import File, read_file
15
+ from .base_io import File
16
16
  from .firecrawl_reader import Firecrawl
17
17
  from .jina_url_reader import JinaURLReader
18
18
  from .unstructured_io import UnstructuredIO
19
19
 
20
20
  __all__ = [
21
21
  'File',
22
- 'read_file',
23
22
  'UnstructuredIO',
24
23
  'JinaURLReader',
25
24
  'Firecrawl',
@@ -23,52 +23,113 @@ from camel.utils import dependencies_required
23
23
 
24
24
 
25
25
  class File(ABC):
26
- r"""Represents an uploaded file comprised of Documents"""
26
+ r"""Represents an uploaded file comprised of Documents.
27
+
28
+ Args:
29
+ name (str): The name of the file.
30
+ file_id (str): The unique identifier of the file.
31
+ metadata (Dict[str, Any], optional): Additional metadata
32
+ associated with the file. Defaults to None.
33
+ docs (List[Dict[str, Any]], optional): A list of documents
34
+ contained within the file. Defaults to None.
35
+ raw_bytes (bytes, optional): The raw bytes content of the file.
36
+ Defaults to b"".
37
+ """
27
38
 
28
39
  def __init__(
29
40
  self,
30
41
  name: str,
31
- id: str,
42
+ file_id: str,
32
43
  metadata: Optional[Dict[str, Any]] = None,
33
44
  docs: Optional[List[Dict[str, Any]]] = None,
45
+ raw_bytes: bytes = b"",
34
46
  ):
35
- r"""
36
-
37
- Args:
38
- name (str): The name of the file.
39
- id (str): The unique identifier of the file.
40
- metadata (Dict[str, Any], optional): Additional metadata
41
- associated with the file. Defaults to None.
42
- docs (List[Dict[str, Any]], optional): A list of documents
43
- contained within the file. Defaults to None.
44
- """
45
47
  self.name = name
46
- self.id = id
48
+ self.file_id = file_id
47
49
  self.metadata = metadata or {}
48
50
  self.docs = docs or []
51
+ self.raw_bytes = raw_bytes
49
52
 
50
53
  @classmethod
51
54
  @abstractmethod
52
- def from_bytes(cls, file: BytesIO) -> "File":
55
+ def from_bytes(cls, file: BytesIO, filename: str) -> "File":
53
56
  r"""Creates a File object from a BytesIO object.
54
57
 
55
58
  Args:
56
59
  file (BytesIO): A BytesIO object representing the contents of the
57
60
  file.
61
+ filename (str): The name of the file.
62
+
63
+ Returns:
64
+ File: A File object.
65
+ """
66
+ pass
67
+
68
+ @classmethod
69
+ def from_raw_bytes(cls, raw_bytes: bytes, filename: str) -> "File":
70
+ r"""Creates a File object from raw bytes.
71
+
72
+ Args:
73
+ raw_bytes (bytes): The raw bytes content of the file.
74
+ filename (str): The name of the file.
58
75
 
59
76
  Returns:
60
77
  File: A File object.
61
78
  """
79
+ file = BytesIO(raw_bytes)
80
+ return cls.from_bytes(file, filename)
81
+
82
+ @staticmethod
83
+ def create_file(file: BytesIO, filename: str) -> "File":
84
+ r"""Reads an uploaded file and returns a File object.
85
+
86
+ Args:
87
+ file (BytesIO): A BytesIO object representing the contents of the
88
+ file.
89
+ filename (str): The name of the file.
90
+
91
+ Returns:
92
+ File: A File object.
93
+ """
94
+ ext_to_cls = {
95
+ "docx": DocxFile,
96
+ "pdf": PdfFile,
97
+ "txt": TxtFile,
98
+ "json": JsonFile,
99
+ "html": HtmlFile,
100
+ }
101
+
102
+ ext = filename.split(".")[-1].lower()
103
+ if ext not in ext_to_cls:
104
+ raise NotImplementedError(f"File type {ext} not supported")
105
+
106
+ out_file = ext_to_cls[ext].from_bytes(file, filename)
107
+ return out_file
108
+
109
+ @staticmethod
110
+ def create_file_from_raw_bytes(raw_bytes: bytes, filename: str) -> "File":
111
+ r"""Reads raw bytes and returns a File object.
112
+
113
+ Args:
114
+ raw_bytes (bytes): The raw bytes content of the file.
115
+ filename (str): The name of the file.
116
+
117
+ Returns:
118
+ File: A File object.
119
+ """
120
+ file = BytesIO(raw_bytes)
121
+ return File.create_file(file, filename)
62
122
 
63
123
  def __repr__(self) -> str:
64
124
  return (
65
- f"File(name={self.name}, id={self.id}, "
125
+ f"File(name={self.name}, id={self.file_id}, "
66
126
  f"metadata={self.metadata}, docs={self.docs})"
67
127
  )
68
128
 
69
129
  def __str__(self) -> str:
70
130
  return (
71
- f"File(name={self.name}, id={self.id}, metadata={self.metadata})"
131
+ f"File(name={self.name}, id={self.file_id}, metadata="
132
+ f"{self.metadata})"
72
133
  )
73
134
 
74
135
  def copy(self) -> "File":
@@ -76,9 +137,10 @@ class File(ABC):
76
137
 
77
138
  return self.__class__(
78
139
  name=self.name,
79
- id=self.id,
140
+ file_id=self.file_id,
80
141
  metadata=deepcopy(self.metadata),
81
142
  docs=deepcopy(self.docs),
143
+ raw_bytes=self.raw_bytes,
82
144
  )
83
145
 
84
146
 
@@ -97,12 +159,13 @@ def strip_consecutive_newlines(text: str) -> str:
97
159
  class DocxFile(File):
98
160
  @classmethod
99
161
  @dependencies_required('docx2txt')
100
- def from_bytes(cls, file: BytesIO) -> "DocxFile":
162
+ def from_bytes(cls, file: BytesIO, filename: str) -> "DocxFile":
101
163
  r"""Creates a DocxFile object from a BytesIO object.
102
164
 
103
165
  Args:
104
166
  file (BytesIO): A BytesIO object representing the contents of the
105
167
  docx file.
168
+ filename (str): The name of the file.
106
169
 
107
170
  Returns:
108
171
  DocxFile: A DocxFile object.
@@ -117,17 +180,23 @@ class DocxFile(File):
117
180
  file_id = md5(file.getvalue()).hexdigest()
118
181
  # Reset the file pointer to the beginning
119
182
  file.seek(0)
120
- return cls(name=file.name, id=file_id, docs=[doc])
183
+ return cls(
184
+ name=filename,
185
+ file_id=file_id,
186
+ docs=[doc],
187
+ raw_bytes=file.getvalue(),
188
+ )
121
189
 
122
190
 
123
191
  class PdfFile(File):
124
192
  @classmethod
125
- def from_bytes(cls, file: BytesIO) -> "PdfFile":
193
+ def from_bytes(cls, file: BytesIO, filename: str) -> "PdfFile":
126
194
  r"""Creates a PdfFile object from a BytesIO object.
127
195
 
128
196
  Args:
129
197
  file (BytesIO): A BytesIO object representing the contents of the
130
198
  pdf file.
199
+ filename (str): The name of the file.
131
200
 
132
201
  Returns:
133
202
  PdfFile: A PdfFile object.
@@ -153,17 +222,23 @@ class PdfFile(File):
153
222
  file_id = md5(file.getvalue()).hexdigest()
154
223
  # Reset the file pointer to the beginning
155
224
  file.seek(0)
156
- return cls(name=file.name, id=file_id, docs=docs)
225
+ return cls(
226
+ name=filename,
227
+ file_id=file_id,
228
+ docs=docs,
229
+ raw_bytes=file.getvalue(),
230
+ )
157
231
 
158
232
 
159
233
  class TxtFile(File):
160
234
  @classmethod
161
- def from_bytes(cls, file: BytesIO) -> "TxtFile":
235
+ def from_bytes(cls, file: BytesIO, filename: str) -> "TxtFile":
162
236
  r"""Creates a TxtFile object from a BytesIO object.
163
237
 
164
238
  Args:
165
239
  file (BytesIO): A BytesIO object representing the contents of the
166
240
  txt file.
241
+ filename (str): The name of the file.
167
242
 
168
243
  Returns:
169
244
  TxtFile: A TxtFile object.
@@ -177,17 +252,23 @@ class TxtFile(File):
177
252
  file_id = md5(file.getvalue()).hexdigest()
178
253
  # Reset the file pointer to the beginning
179
254
  file.seek(0)
180
- return cls(name=file.name, id=file_id, docs=[doc])
255
+ return cls(
256
+ name=filename,
257
+ file_id=file_id,
258
+ docs=[doc],
259
+ raw_bytes=file.getvalue(),
260
+ )
181
261
 
182
262
 
183
263
  class JsonFile(File):
184
264
  @classmethod
185
- def from_bytes(cls, file: BytesIO) -> "JsonFile":
265
+ def from_bytes(cls, file: BytesIO, filename: str) -> "JsonFile":
186
266
  r"""Creates a JsonFile object from a BytesIO object.
187
267
 
188
268
  Args:
189
269
  file (BytesIO): A BytesIO object representing the contents of the
190
270
  json file.
271
+ filename (str): The name of the file.
191
272
 
192
273
  Returns:
193
274
  JsonFile: A JsonFile object.
@@ -200,17 +281,23 @@ class JsonFile(File):
200
281
  file_id = md5(file.getvalue()).hexdigest()
201
282
  # Reset the file pointer to the beginning
202
283
  file.seek(0)
203
- return cls(name=file.name, id=file_id, docs=[doc])
284
+ return cls(
285
+ name=filename,
286
+ file_id=file_id,
287
+ docs=[doc],
288
+ raw_bytes=file.getvalue(),
289
+ )
204
290
 
205
291
 
206
292
  class HtmlFile(File):
207
293
  @classmethod
208
- def from_bytes(cls, file: BytesIO) -> "HtmlFile":
294
+ def from_bytes(cls, file: BytesIO, filename: str) -> "HtmlFile":
209
295
  r"""Creates a HtmlFile object from a BytesIO object.
210
296
 
211
297
  Args:
212
298
  file (BytesIO): A BytesIO object representing the contents of the
213
299
  html file.
300
+ filename (str): The name of the file.
214
301
 
215
302
  Returns:
216
303
  HtmlFile: A HtmlFile object.
@@ -233,30 +320,9 @@ class HtmlFile(File):
233
320
  file_id = md5(file.getvalue()).hexdigest()
234
321
  # Reset the file pointer to the beginning
235
322
  file.seek(0)
236
- return cls(name=file.name, id=file_id, docs=[doc])
237
-
238
-
239
- def read_file(file: BytesIO) -> File:
240
- r"""Reads an uploaded file and returns a File object.
241
-
242
- Args:
243
- file (BytesIO): A BytesIO object representing the contents of the file.
244
-
245
- Returns:
246
- File: A File object.
247
- """
248
- # Determine the file type based on the file extension
249
- if file.name.lower().endswith(".docx"):
250
- return DocxFile.from_bytes(file)
251
- elif file.name.lower().endswith(".pdf"):
252
- return PdfFile.from_bytes(file)
253
- elif file.name.lower().endswith(".txt"):
254
- return TxtFile.from_bytes(file)
255
- elif file.name.lower().endswith(".json"):
256
- return JsonFile.from_bytes(file)
257
- elif file.name.lower().endswith(".html"):
258
- return HtmlFile.from_bytes(file)
259
- else:
260
- raise NotImplementedError(
261
- f"File type {file.name.split('.')[-1]} not supported"
323
+ return cls(
324
+ name=filename,
325
+ file_id=file_id,
326
+ docs=[doc],
327
+ raw_bytes=file.getvalue(),
262
328
  )
@@ -14,6 +14,7 @@
14
14
 
15
15
  import os
16
16
  from typing import Any, Optional
17
+ from warnings import warn
17
18
 
18
19
  from camel.types.enums import JinaReturnFormat
19
20
 
@@ -54,11 +55,10 @@ class JinaURLReader:
54
55
  **kwargs: Any,
55
56
  ) -> None:
56
57
  api_key = api_key or os.getenv('JINA_API_KEY')
57
- if api_key is None:
58
- print(
59
- "[JinaURLReader] JINA_API_KEY not set. This will result in a "
60
- "low rate limit of Jina URL Reader. Get API key here: "
61
- "https://jina.ai/reader."
58
+ if not api_key:
59
+ warn(
60
+ "JINA_API_KEY not set. This will result in a low rate limit "
61
+ "of Jina URL Reader. Get API key here: https://jina.ai/reader."
62
62
  )
63
63
 
64
64
  # if the following field not provided, it will be None
@@ -94,6 +94,6 @@ class JinaURLReader:
94
94
  resp = requests.get(full_url, headers=self._headers)
95
95
  resp.raise_for_status()
96
96
  except Exception as e:
97
- raise Exception(f"Failed to read content from {url}: {e}") from e
97
+ raise ValueError(f"Failed to read content from {url}: {e}") from e
98
98
 
99
99
  return resp.text