camel-ai 0.2.9__py3-none-any.whl → 0.2.11__py3-none-any.whl

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 (242) hide show
  1. camel/__init__.py +10 -5
  2. camel/agents/__init__.py +4 -4
  3. camel/agents/base.py +4 -4
  4. camel/agents/chat_agent.py +106 -42
  5. camel/agents/critic_agent.py +4 -4
  6. camel/agents/deductive_reasoner_agent.py +8 -5
  7. camel/agents/embodied_agent.py +4 -4
  8. camel/agents/knowledge_graph_agent.py +4 -4
  9. camel/agents/role_assignment_agent.py +4 -4
  10. camel/agents/search_agent.py +4 -4
  11. camel/agents/task_agent.py +4 -4
  12. camel/agents/tool_agents/__init__.py +4 -4
  13. camel/agents/tool_agents/base.py +4 -4
  14. camel/agents/tool_agents/hugging_face_tool_agent.py +4 -4
  15. camel/bots/__init__.py +4 -4
  16. camel/bots/discord_app.py +4 -4
  17. camel/bots/slack/__init__.py +4 -4
  18. camel/bots/slack/models.py +4 -4
  19. camel/bots/slack/slack_app.py +4 -4
  20. camel/bots/telegram_bot.py +4 -4
  21. camel/configs/__init__.py +13 -4
  22. camel/configs/anthropic_config.py +4 -4
  23. camel/configs/base_config.py +4 -4
  24. camel/configs/cohere_config.py +76 -0
  25. camel/configs/deepseek_config.py +134 -0
  26. camel/configs/gemini_config.py +85 -127
  27. camel/configs/groq_config.py +4 -4
  28. camel/configs/litellm_config.py +4 -4
  29. camel/configs/mistral_config.py +4 -7
  30. camel/configs/nvidia_config.py +70 -0
  31. camel/configs/ollama_config.py +4 -4
  32. camel/configs/openai_config.py +32 -7
  33. camel/configs/qwen_config.py +4 -4
  34. camel/configs/reka_config.py +4 -4
  35. camel/configs/samba_config.py +4 -4
  36. camel/configs/togetherai_config.py +4 -4
  37. camel/configs/vllm_config.py +14 -5
  38. camel/configs/yi_config.py +4 -4
  39. camel/configs/zhipuai_config.py +4 -4
  40. camel/embeddings/__init__.py +6 -4
  41. camel/embeddings/base.py +4 -4
  42. camel/embeddings/mistral_embedding.py +4 -4
  43. camel/embeddings/openai_compatible_embedding.py +91 -0
  44. camel/embeddings/openai_embedding.py +4 -4
  45. camel/embeddings/sentence_transformers_embeddings.py +4 -4
  46. camel/embeddings/vlm_embedding.py +8 -5
  47. camel/generators.py +4 -4
  48. camel/human.py +4 -4
  49. camel/interpreters/__init__.py +4 -4
  50. camel/interpreters/base.py +4 -4
  51. camel/interpreters/docker_interpreter.py +11 -6
  52. camel/interpreters/internal_python_interpreter.py +4 -4
  53. camel/interpreters/interpreter_error.py +4 -4
  54. camel/interpreters/ipython_interpreter.py +4 -4
  55. camel/interpreters/subprocess_interpreter.py +11 -6
  56. camel/loaders/__init__.py +4 -4
  57. camel/loaders/apify_reader.py +4 -4
  58. camel/loaders/base_io.py +4 -4
  59. camel/loaders/chunkr_reader.py +4 -4
  60. camel/loaders/firecrawl_reader.py +4 -7
  61. camel/loaders/jina_url_reader.py +4 -4
  62. camel/loaders/unstructured_io.py +4 -4
  63. camel/logger.py +112 -0
  64. camel/memories/__init__.py +4 -4
  65. camel/memories/agent_memories.py +4 -4
  66. camel/memories/base.py +4 -4
  67. camel/memories/blocks/__init__.py +4 -4
  68. camel/memories/blocks/chat_history_block.py +4 -4
  69. camel/memories/blocks/vectordb_block.py +4 -4
  70. camel/memories/context_creators/__init__.py +4 -4
  71. camel/memories/context_creators/score_based.py +4 -4
  72. camel/memories/records.py +4 -4
  73. camel/messages/__init__.py +20 -4
  74. camel/messages/base.py +118 -11
  75. camel/messages/conversion/__init__.py +31 -0
  76. camel/messages/conversion/alpaca.py +122 -0
  77. camel/messages/conversion/conversation_models.py +178 -0
  78. camel/messages/conversion/sharegpt/__init__.py +20 -0
  79. camel/messages/conversion/sharegpt/function_call_formatter.py +49 -0
  80. camel/messages/conversion/sharegpt/hermes/__init__.py +19 -0
  81. camel/messages/conversion/sharegpt/hermes/hermes_function_formatter.py +128 -0
  82. camel/messages/func_message.py +50 -4
  83. camel/models/__init__.py +13 -4
  84. camel/models/anthropic_model.py +4 -4
  85. camel/models/azure_openai_model.py +4 -4
  86. camel/models/base_model.py +4 -4
  87. camel/models/cohere_model.py +282 -0
  88. camel/models/deepseek_model.py +139 -0
  89. camel/models/gemini_model.py +61 -146
  90. camel/models/groq_model.py +4 -4
  91. camel/models/litellm_model.py +4 -4
  92. camel/models/mistral_model.py +4 -4
  93. camel/models/model_factory.py +13 -4
  94. camel/models/model_manager.py +212 -0
  95. camel/models/nemotron_model.py +4 -4
  96. camel/models/nvidia_model.py +141 -0
  97. camel/models/ollama_model.py +4 -4
  98. camel/models/openai_audio_models.py +4 -4
  99. camel/models/openai_compatible_model.py +4 -4
  100. camel/models/openai_model.py +43 -4
  101. camel/models/qwen_model.py +4 -4
  102. camel/models/reka_model.py +4 -4
  103. camel/models/samba_model.py +6 -5
  104. camel/models/stub_model.py +4 -4
  105. camel/models/togetherai_model.py +4 -4
  106. camel/models/vllm_model.py +4 -4
  107. camel/models/yi_model.py +4 -4
  108. camel/models/zhipuai_model.py +4 -4
  109. camel/personas/__init__.py +17 -0
  110. camel/personas/persona.py +103 -0
  111. camel/personas/persona_hub.py +293 -0
  112. camel/prompts/__init__.py +6 -4
  113. camel/prompts/ai_society.py +4 -4
  114. camel/prompts/base.py +4 -4
  115. camel/prompts/code.py +4 -4
  116. camel/prompts/evaluation.py +4 -4
  117. camel/prompts/generate_text_embedding_data.py +4 -4
  118. camel/prompts/image_craft.py +4 -4
  119. camel/prompts/misalignment.py +4 -4
  120. camel/prompts/multi_condition_image_craft.py +4 -4
  121. camel/prompts/object_recognition.py +4 -4
  122. camel/prompts/persona_hub.py +61 -0
  123. camel/prompts/prompt_templates.py +4 -4
  124. camel/prompts/role_description_prompt_template.py +4 -4
  125. camel/prompts/solution_extraction.py +4 -4
  126. camel/prompts/task_prompt_template.py +4 -4
  127. camel/prompts/translation.py +4 -4
  128. camel/prompts/video_description_prompt.py +4 -4
  129. camel/responses/__init__.py +4 -4
  130. camel/responses/agent_responses.py +4 -4
  131. camel/retrievers/__init__.py +4 -4
  132. camel/retrievers/auto_retriever.py +4 -4
  133. camel/retrievers/base.py +4 -4
  134. camel/retrievers/bm25_retriever.py +4 -4
  135. camel/retrievers/cohere_rerank_retriever.py +7 -9
  136. camel/retrievers/vector_retriever.py +26 -9
  137. camel/runtime/__init__.py +29 -0
  138. camel/runtime/api.py +93 -0
  139. camel/runtime/base.py +45 -0
  140. camel/runtime/configs.py +56 -0
  141. camel/runtime/docker_runtime.py +404 -0
  142. camel/runtime/llm_guard_runtime.py +199 -0
  143. camel/runtime/remote_http_runtime.py +204 -0
  144. camel/runtime/utils/__init__.py +20 -0
  145. camel/runtime/utils/function_risk_toolkit.py +58 -0
  146. camel/runtime/utils/ignore_risk_toolkit.py +72 -0
  147. camel/schemas/__init__.py +17 -0
  148. camel/schemas/base.py +45 -0
  149. camel/schemas/openai_converter.py +116 -0
  150. camel/societies/__init__.py +4 -4
  151. camel/societies/babyagi_playing.py +8 -5
  152. camel/societies/role_playing.py +4 -4
  153. camel/societies/workforce/__init__.py +4 -4
  154. camel/societies/workforce/base.py +4 -4
  155. camel/societies/workforce/prompts.py +4 -4
  156. camel/societies/workforce/role_playing_worker.py +4 -4
  157. camel/societies/workforce/single_agent_worker.py +4 -4
  158. camel/societies/workforce/task_channel.py +4 -4
  159. camel/societies/workforce/utils.py +4 -4
  160. camel/societies/workforce/worker.py +4 -4
  161. camel/societies/workforce/workforce.py +7 -7
  162. camel/storages/__init__.py +4 -4
  163. camel/storages/graph_storages/__init__.py +4 -4
  164. camel/storages/graph_storages/base.py +4 -4
  165. camel/storages/graph_storages/graph_element.py +4 -4
  166. camel/storages/graph_storages/nebula_graph.py +4 -4
  167. camel/storages/graph_storages/neo4j_graph.py +4 -4
  168. camel/storages/key_value_storages/__init__.py +4 -4
  169. camel/storages/key_value_storages/base.py +4 -4
  170. camel/storages/key_value_storages/in_memory.py +4 -4
  171. camel/storages/key_value_storages/json.py +4 -4
  172. camel/storages/key_value_storages/redis.py +4 -4
  173. camel/storages/object_storages/__init__.py +4 -4
  174. camel/storages/object_storages/amazon_s3.py +4 -4
  175. camel/storages/object_storages/azure_blob.py +4 -4
  176. camel/storages/object_storages/base.py +4 -4
  177. camel/storages/object_storages/google_cloud.py +4 -4
  178. camel/storages/vectordb_storages/__init__.py +4 -4
  179. camel/storages/vectordb_storages/base.py +4 -4
  180. camel/storages/vectordb_storages/milvus.py +4 -4
  181. camel/storages/vectordb_storages/qdrant.py +4 -4
  182. camel/tasks/__init__.py +4 -4
  183. camel/tasks/task.py +4 -4
  184. camel/tasks/task_prompt.py +4 -4
  185. camel/terminators/__init__.py +4 -4
  186. camel/terminators/base.py +4 -4
  187. camel/terminators/response_terminator.py +4 -4
  188. camel/terminators/token_limit_terminator.py +4 -4
  189. camel/toolkits/__init__.py +16 -17
  190. camel/toolkits/arxiv_toolkit.py +4 -4
  191. camel/toolkits/ask_news_toolkit.py +7 -18
  192. camel/toolkits/base.py +4 -4
  193. camel/toolkits/code_execution.py +57 -10
  194. camel/toolkits/dalle_toolkit.py +4 -7
  195. camel/toolkits/data_commons_toolkit.py +4 -4
  196. camel/toolkits/function_tool.py +220 -69
  197. camel/toolkits/github_toolkit.py +4 -4
  198. camel/toolkits/google_maps_toolkit.py +4 -4
  199. camel/toolkits/google_scholar_toolkit.py +4 -4
  200. camel/toolkits/human_toolkit.py +53 -0
  201. camel/toolkits/linkedin_toolkit.py +4 -4
  202. camel/toolkits/math_toolkit.py +4 -7
  203. camel/toolkits/meshy_toolkit.py +185 -0
  204. camel/toolkits/notion_toolkit.py +4 -4
  205. camel/toolkits/open_api_specs/biztoc/__init__.py +4 -4
  206. camel/toolkits/open_api_specs/coursera/__init__.py +4 -4
  207. camel/toolkits/open_api_specs/create_qr_code/__init__.py +4 -4
  208. camel/toolkits/open_api_specs/klarna/__init__.py +4 -4
  209. camel/toolkits/open_api_specs/nasa_apod/__init__.py +4 -4
  210. camel/toolkits/open_api_specs/outschool/__init__.py +4 -4
  211. camel/toolkits/open_api_specs/outschool/paths/__init__.py +4 -4
  212. camel/toolkits/open_api_specs/outschool/paths/get_classes.py +4 -4
  213. camel/toolkits/open_api_specs/outschool/paths/search_teachers.py +4 -4
  214. camel/toolkits/open_api_specs/security_config.py +4 -4
  215. camel/toolkits/open_api_specs/speak/__init__.py +4 -4
  216. camel/toolkits/open_api_specs/web_scraper/__init__.py +4 -4
  217. camel/toolkits/open_api_specs/web_scraper/paths/__init__.py +4 -4
  218. camel/toolkits/open_api_specs/web_scraper/paths/scraper.py +4 -4
  219. camel/toolkits/open_api_toolkit.py +4 -4
  220. camel/toolkits/reddit_toolkit.py +4 -4
  221. camel/toolkits/retrieval_toolkit.py +4 -4
  222. camel/toolkits/search_toolkit.py +49 -29
  223. camel/toolkits/slack_toolkit.py +4 -4
  224. camel/toolkits/twitter_toolkit.py +13 -13
  225. camel/toolkits/video_toolkit.py +211 -0
  226. camel/toolkits/weather_toolkit.py +4 -7
  227. camel/toolkits/whatsapp_toolkit.py +6 -6
  228. camel/types/__init__.py +6 -4
  229. camel/types/enums.py +118 -15
  230. camel/types/openai_types.py +6 -4
  231. camel/types/unified_model_type.py +9 -4
  232. camel/utils/__init__.py +35 -33
  233. camel/utils/async_func.py +4 -4
  234. camel/utils/commons.py +26 -9
  235. camel/utils/constants.py +4 -4
  236. camel/utils/response_format.py +63 -0
  237. camel/utils/token_counting.py +8 -5
  238. {camel_ai-0.2.9.dist-info → camel_ai-0.2.11.dist-info}/METADATA +108 -56
  239. camel_ai-0.2.11.dist-info/RECORD +252 -0
  240. camel_ai-0.2.9.dist-info/RECORD +0 -215
  241. {camel_ai-0.2.9.dist-info → camel_ai-0.2.11.dist-info}/LICENSE +0 -0
  242. {camel_ai-0.2.9.dist-info → camel_ai-0.2.11.dist-info}/WHEEL +0 -0
@@ -0,0 +1,31 @@
1
+ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
+
15
+ from .alpaca import AlpacaItem
16
+ from .conversation_models import (
17
+ ShareGPTConversation,
18
+ ShareGPTMessage,
19
+ ToolCall,
20
+ ToolResponse,
21
+ )
22
+ from .sharegpt import HermesFunctionFormatter
23
+
24
+ __all__ = [
25
+ 'ShareGPTMessage',
26
+ 'ShareGPTConversation',
27
+ 'HermesFunctionFormatter',
28
+ 'AlpacaItem',
29
+ 'ToolCall',
30
+ 'ToolResponse',
31
+ ]
@@ -0,0 +1,122 @@
1
+ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
+
15
+ import re
16
+
17
+ from pydantic import BaseModel, Field, field_validator
18
+
19
+
20
+ class AlpacaItem(BaseModel):
21
+ r"""Represents an instruction-response item in the Alpaca format.
22
+
23
+ Appropripate for both cases where input field is empty, or populated.
24
+ Provides parsing from string format using the class method from_string().
25
+
26
+ Args:
27
+ instruction (str): The instruction/question/prompt
28
+ input (str): Input context or examples (put empty string if none)
29
+ output (str): The response/answer to the instruction
30
+ """
31
+
32
+ instruction: str = Field(description="The instruction/question/prompt")
33
+ input: str = Field(
34
+ description="Optional context or input for the task."
35
+ " For example, when the instruction is \"Summarize the "
36
+ "following article\", the input is the article."
37
+ )
38
+ output: str = Field(description="The response/answer to the instruction")
39
+
40
+ @field_validator('instruction', 'output')
41
+ def no_section_markers(cls, value: str) -> str:
42
+ r"""Ensures fields don't contain section markers like '###
43
+ Response:'
44
+ """
45
+ if (
46
+ '### Response' in value
47
+ or '### Instruction' in value
48
+ or '### Input' in value
49
+ ):
50
+ raise ValueError("Field cannot contain section markers")
51
+ return value.strip()
52
+
53
+ @classmethod
54
+ def from_string(cls, text: str) -> "AlpacaItem":
55
+ r"""Creates an AlpacaItem from a formatted string.
56
+
57
+ Args:
58
+ text: String in either of these formats:
59
+ With input:
60
+ ### Instruction:
61
+ {instruction}
62
+ ### Input:
63
+ {input}
64
+ ### Response:
65
+ {response}
66
+
67
+ Without input:
68
+ ### Instruction:
69
+ {instruction}
70
+ ### Response:
71
+ {response}
72
+
73
+ Returns:
74
+ AlpacaItem: Parsed instance
75
+
76
+ Raises:
77
+ ValueError: text doesn't match expected format or sections missing
78
+ """
79
+ # Strip and standardize newlines
80
+ text = text.strip().replace('\r\n', '\n')
81
+
82
+ # Try to extract sections using regex
83
+ instruction_match = re.search(
84
+ r'###\s*Instruction:\s*\n(.+?)(?=\n###|\Z)', text, re.DOTALL
85
+ )
86
+ input_match = re.search(
87
+ r'###\s*Input:\s*\n(.+?)(?=\n###|\Z)', text, re.DOTALL
88
+ )
89
+ response_match = re.search(
90
+ r'###\s*Response:\s*\n(.+?)(?=\n###|\Z)', text, re.DOTALL
91
+ )
92
+
93
+ if not instruction_match or not response_match:
94
+ raise ValueError(
95
+ "Text must contain '### Instruction:'"
96
+ " and '### Response:' sections"
97
+ )
98
+
99
+ return cls(
100
+ instruction=instruction_match.group(1).strip(),
101
+ input=input_match.group(1).strip() if input_match else "",
102
+ output=response_match.group(1).strip(),
103
+ )
104
+
105
+ def to_string(self) -> str:
106
+ r"""Converts the AlpacaItem to its string representation.
107
+
108
+ Returns:
109
+ str: Formatted string representation with sections markers
110
+ """
111
+ return "\n".join(
112
+ [
113
+ "### Instruction:",
114
+ self.instruction,
115
+ "",
116
+ "### Input:",
117
+ self.input,
118
+ "",
119
+ "### Response:",
120
+ self.output,
121
+ ]
122
+ )
@@ -0,0 +1,178 @@
1
+ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
+
15
+ import json
16
+ from typing import Any, Dict, List, Literal
17
+
18
+ from pydantic import (
19
+ BaseModel,
20
+ Field,
21
+ RootModel,
22
+ field_validator,
23
+ model_validator,
24
+ )
25
+
26
+
27
+ class ShareGPTMessage(BaseModel):
28
+ r"""A single message in ShareGPT format with enhanced validation"""
29
+
30
+ from_: Literal["human", "gpt", "system", "tool"] = Field(
31
+ alias="from", description="The role of the message sender"
32
+ )
33
+ value: str = Field(
34
+ min_length=0,
35
+ max_length=100000,
36
+ description="The content of the message",
37
+ )
38
+
39
+ model_config = {
40
+ "populate_by_name": True,
41
+ "extra": "forbid",
42
+ "json_schema_extra": {
43
+ "examples": [
44
+ {"from": "human", "value": "What's the weather like today?"}
45
+ ]
46
+ },
47
+ }
48
+
49
+
50
+ class ShareGPTConversation(RootModel):
51
+ r"""A full conversation in ShareGPT format with validation"""
52
+
53
+ root: List[ShareGPTMessage]
54
+
55
+ @model_validator(mode='after')
56
+ def validate_conversation_flow(self) -> 'ShareGPTConversation':
57
+ r"""Validate the conversation follows logical message order"""
58
+ messages = self.root
59
+
60
+ if not messages:
61
+ raise ValueError("Conversation cannot be empty")
62
+
63
+ if messages[0].from_ not in ("system", "human"):
64
+ raise ValueError(
65
+ "Conversation must start with either system or human message"
66
+ )
67
+
68
+ # Validate message sequence
69
+ for i in range(1, len(messages)):
70
+ curr, prev = messages[i], messages[i - 1]
71
+
72
+ if curr.from_ == "tool":
73
+ if prev.from_ != "gpt" or "<tool_call>" not in prev.value:
74
+ raise ValueError(
75
+ f"Tool response at position {i} "
76
+ f"must follow an gpt message with a tool call"
77
+ )
78
+
79
+ if curr.from_ == "gpt" and prev.from_ not in (
80
+ "human",
81
+ "tool",
82
+ ):
83
+ raise ValueError(
84
+ f"Assistant message at position {i} "
85
+ f"must follow a human or tool message"
86
+ )
87
+
88
+ return self
89
+
90
+ def model_dump(self, **kwargs):
91
+ return self.root
92
+
93
+ def __iter__(self):
94
+ return iter(self.root)
95
+
96
+
97
+ class ToolCall(BaseModel):
98
+ r"""Represents a single tool/function call with validation"""
99
+
100
+ name: str = Field(
101
+ min_length=1,
102
+ max_length=256,
103
+ description="The name of the tool to call",
104
+ )
105
+ arguments: Dict[str, Any] = Field(
106
+ description="The arguments to pass to the tool"
107
+ )
108
+
109
+ @field_validator('arguments')
110
+ @classmethod
111
+ def validate_arguments(cls, v: Dict[str, Any]) -> Dict[str, Any]:
112
+ r"""Validate argument structure and content"""
113
+
114
+ # Try to serialize arguments to ensure they're JSON-compatible
115
+ try:
116
+ json.dumps(v)
117
+ except (TypeError, ValueError):
118
+ raise ValueError("Arguments must be JSON-serializable")
119
+
120
+ return v
121
+
122
+ model_config = {
123
+ "extra": "forbid",
124
+ "json_schema_extra": {
125
+ "examples": [
126
+ {
127
+ "name": "get_weather",
128
+ "arguments": {"city": "London", "units": "celsius"},
129
+ }
130
+ ]
131
+ },
132
+ }
133
+
134
+
135
+ class ToolResponse(BaseModel):
136
+ r"""Represents a tool/function response with validation. This is a
137
+ base class and default implementation for tool responses, for the purpose
138
+ of converting between different formats.
139
+ """
140
+
141
+ name: str = Field(
142
+ min_length=1,
143
+ max_length=256,
144
+ description="The name of the tool that was called",
145
+ )
146
+ content: Any = Field(
147
+ description="The response content from the tool."
148
+ " Must be JSON serializable literal or object"
149
+ )
150
+
151
+ @field_validator('content')
152
+ @classmethod
153
+ def validate_content(cls, v: Dict[str, Any]) -> Dict[str, Any]:
154
+ r"""Validate response content structure"""
155
+
156
+ # Ensure content is JSON-serializable
157
+ try:
158
+ json.dumps(v)
159
+ except (TypeError, ValueError):
160
+ raise ValueError("Response content must be JSON-serializable")
161
+
162
+ return v
163
+
164
+ model_config = {
165
+ "extra": "forbid",
166
+ "json_schema_extra": {
167
+ "examples": [
168
+ {
169
+ "name": "get_weather",
170
+ "content": {
171
+ "temperature": 20,
172
+ "conditions": "sunny",
173
+ "humidity": 65,
174
+ },
175
+ }
176
+ ]
177
+ },
178
+ }
@@ -0,0 +1,20 @@
1
+ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
+
15
+
16
+ from .hermes import HermesFunctionFormatter
17
+
18
+ __all__ = [
19
+ 'HermesFunctionFormatter',
20
+ ]
@@ -0,0 +1,49 @@
1
+ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
+ from abc import ABC, abstractmethod
15
+ from typing import Any, Dict, Generic, List, Optional, TypeVar
16
+
17
+ from camel.messages.conversion import (
18
+ ToolCall,
19
+ ToolResponse,
20
+ )
21
+
22
+ CallT = TypeVar('CallT', bound=ToolCall, covariant=True)
23
+ ResponseT = TypeVar('ResponseT', bound=ToolResponse, covariant=True)
24
+
25
+
26
+ class FunctionCallFormatter(ABC, Generic[CallT, ResponseT]):
27
+ r"""Abstract base class for function calling formats"""
28
+
29
+ @abstractmethod
30
+ def extract_tool_calls(self, message: str) -> List[CallT]:
31
+ r"""Extract function call info from a message string"""
32
+ pass
33
+
34
+ @abstractmethod
35
+ def extract_tool_response(self, message: str) -> Optional[ResponseT]:
36
+ r"""Extract function response info from a message string"""
37
+ pass
38
+
39
+ @abstractmethod
40
+ def format_tool_call(
41
+ self, content: str, func_name: str, args: Dict[str, Any]
42
+ ) -> str:
43
+ r"""Format a function call into a message string"""
44
+ pass
45
+
46
+ @abstractmethod
47
+ def format_tool_response(self, func_name: str, result: Any) -> str:
48
+ r"""Format a function response into a message string"""
49
+ pass
@@ -0,0 +1,19 @@
1
+ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
+
15
+ from .hermes_function_formatter import HermesFunctionFormatter
16
+
17
+ __all__ = [
18
+ 'HermesFunctionFormatter',
19
+ ]
@@ -0,0 +1,128 @@
1
+ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
+ import json
15
+ import re
16
+ from typing import Any, Dict, List, Optional
17
+
18
+ from camel.messages.conversion import (
19
+ ToolCall,
20
+ ToolResponse,
21
+ )
22
+ from camel.messages.conversion.sharegpt.function_call_formatter import (
23
+ FunctionCallFormatter,
24
+ )
25
+
26
+
27
+ class HermesToolResponse(ToolResponse):
28
+ r"""Represents a single tool/function call with validation"""
29
+
30
+ pass
31
+
32
+
33
+ class HermesToolCall(ToolCall):
34
+ r"""Represents a single tool/function call with validation"""
35
+
36
+ pass
37
+
38
+
39
+ class HermesFunctionFormatter(
40
+ FunctionCallFormatter[HermesToolCall, HermesToolResponse]
41
+ ):
42
+ r"""Hermes-style function calling format implementation with validation"""
43
+
44
+ def extract_tool_calls(self, message: str) -> List[HermesToolCall]:
45
+ r"""Extracts all tool calls from the provided message string.
46
+
47
+ Args:
48
+ message (str): The input message string containing potential tool
49
+ calls.
50
+
51
+ Returns:
52
+ List[HermesToolCall]: A list of parsed HermesToolCall objects.
53
+ """
54
+ tool_calls = []
55
+ pattern = r"<tool_call>\s*({.*?})\s*</tool_call>"
56
+ matches = re.finditer(pattern, message, re.DOTALL)
57
+
58
+ for match in matches:
59
+ try:
60
+ call_dict = json.loads(match.group(1).replace("'", '"'))
61
+ tool_calls.append(HermesToolCall.model_validate(call_dict))
62
+ except Exception as e:
63
+ print(f"Warning: Failed to parse tool call: {e}")
64
+ continue
65
+
66
+ return tool_calls
67
+
68
+ def extract_tool_response(
69
+ self, message: str
70
+ ) -> Optional[HermesToolResponse]:
71
+ r"""Extracts a single tool response from the provided message string.
72
+
73
+ Args:
74
+ message (str): The input message string containing a potential
75
+ tool response.
76
+
77
+ Returns:
78
+ Optional[HermesToolResponse]: A parsed HermesToolResponse object,
79
+ or None if no valid response is found.
80
+ """
81
+ pattern = r"<tool_response>\s*({.*?})\s*</tool_response>"
82
+ match = re.search(pattern, message, re.DOTALL)
83
+
84
+ if match:
85
+ try:
86
+ response_json = match.group(1)
87
+ response_dict = json.loads(response_json.replace("'", '"'))
88
+ return HermesToolResponse.model_validate(response_dict)
89
+ except Exception as e:
90
+ print(f"Warning: Failed to parse tool response: {e}")
91
+ return None
92
+ return None
93
+
94
+ def format_tool_call(
95
+ self, content: str, func_name: str, args: Dict[str, Any]
96
+ ) -> str:
97
+ r"""Formats a tool call message with the given content, function name,
98
+ and arguments.
99
+
100
+ Args:
101
+ content (str): The content or message to be included in the tool
102
+ call.
103
+ func_name (str): The name of the function being called.
104
+ args (Dict[str, Any]): A dictionary of arguments to be passed to
105
+ the function.
106
+
107
+ Returns:
108
+ str: A formatted string representing the tool call in Hermes
109
+ format.
110
+ """
111
+ tool_call_dict = {"name": func_name, "arguments": args}
112
+ return f"{content}\n<tool_call>\n{tool_call_dict}\n</tool_call>"
113
+
114
+ def format_tool_response(self, func_name: str, result: Any) -> str:
115
+ r"""Formats a tool response message with the given function name and
116
+ result.
117
+
118
+ Args:
119
+ func_name (str): The name of the function whose result is being
120
+ returned.
121
+ result (Any): The result to be included in the tool response.
122
+
123
+ Returns:
124
+ str: A formatted string representing the tool response in Hermes
125
+ format.
126
+ """
127
+ response_dict = {"name": func_name, "content": result}
128
+ return f"<tool_response>\n{response_dict}\n</tool_response>"
@@ -1,25 +1,34 @@
1
- # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
2
- # Licensed under the Apache License, Version 2.0 (the License);
1
+ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
3
  # you may not use this file except in compliance with the License.
4
4
  # You may obtain a copy of the License at
5
5
  #
6
6
  # http://www.apache.org/licenses/LICENSE-2.0
7
7
  #
8
8
  # Unless required by applicable law or agreed to in writing, software
9
- # distributed under the License is distributed on an AS IS BASIS,
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
10
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
11
  # See the License for the specific language governing permissions and
12
12
  # limitations under the License.
13
- # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
13
+ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
  from dataclasses import dataclass
15
15
  from typing import Any, Dict, Optional
16
16
 
17
17
  from camel.messages import (
18
18
  BaseMessage,
19
+ HermesFunctionFormatter,
19
20
  OpenAIAssistantMessage,
20
21
  OpenAIFunctionMessage,
21
22
  OpenAIMessage,
22
23
  )
24
+ from camel.messages.conversion import (
25
+ ShareGPTMessage,
26
+ ToolCall,
27
+ ToolResponse,
28
+ )
29
+ from camel.messages.conversion.sharegpt.function_call_formatter import (
30
+ FunctionCallFormatter,
31
+ )
23
32
  from camel.types import OpenAIBackendRole
24
33
 
25
34
 
@@ -61,6 +70,43 @@ class FunctionCallingMessage(BaseMessage):
61
70
  else:
62
71
  raise ValueError(f"Unsupported role: {role_at_backend}.")
63
72
 
73
+ def to_sharegpt(
74
+ self,
75
+ function_format: Optional[
76
+ FunctionCallFormatter[ToolCall, ToolResponse]
77
+ ] = None,
78
+ ) -> ShareGPTMessage:
79
+ r"""Convert FunctionCallingMessage to ShareGPT message.
80
+
81
+ Args:
82
+ function_format (FunctionCallFormatter[ToolCall, ToolResponse],
83
+ optional): The function formatter to use. Defaults to None.
84
+ """
85
+
86
+ if function_format is None:
87
+ function_format = HermesFunctionFormatter()
88
+ # The role of the message is an unreliable indicator of whether
89
+ # it is a function call or response, so use result
90
+ if self.result is None:
91
+ # This is a function call
92
+ # TODO: split the incoming types to be more specific
93
+ # and remove the type ignores
94
+ content = function_format.format_tool_call(
95
+ self.content or "", # type: ignore[arg-type]
96
+ self.func_name, # type: ignore[arg-type]
97
+ self.args, # type: ignore[arg-type]
98
+ )
99
+ return ShareGPTMessage(from_="gpt", value=content) # type: ignore[call-arg]
100
+ else:
101
+ # This is a function response
102
+ # TODO: Allow for more flexible setting of tool role,
103
+ # optionally to be the same as assistant messages
104
+ content = function_format.format_tool_response(
105
+ self.func_name, # type: ignore[arg-type]
106
+ self.result, # type: ignore[arg-type]
107
+ )
108
+ return ShareGPTMessage(from_="tool", value=content) # type: ignore[call-arg]
109
+
64
110
  def to_openai_assistant_message(self) -> OpenAIAssistantMessage:
65
111
  r"""Converts the message to an :obj:`OpenAIAssistantMessage` object.
66
112
 
camel/models/__init__.py CHANGED
@@ -1,25 +1,29 @@
1
- # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
2
- # Licensed under the Apache License, Version 2.0 (the License);
1
+ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
3
  # you may not use this file except in compliance with the License.
4
4
  # You may obtain a copy of the License at
5
5
  #
6
6
  # http://www.apache.org/licenses/LICENSE-2.0
7
7
  #
8
8
  # Unless required by applicable law or agreed to in writing, software
9
- # distributed under the License is distributed on an AS IS BASIS,
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
10
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
11
  # See the License for the specific language governing permissions and
12
12
  # limitations under the License.
13
- # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
13
+ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
  from .anthropic_model import AnthropicModel
15
15
  from .azure_openai_model import AzureOpenAIModel
16
16
  from .base_model import BaseModelBackend
17
+ from .cohere_model import CohereModel
18
+ from .deepseek_model import DeepSeekModel
17
19
  from .gemini_model import GeminiModel
18
20
  from .groq_model import GroqModel
19
21
  from .litellm_model import LiteLLMModel
20
22
  from .mistral_model import MistralModel
21
23
  from .model_factory import ModelFactory
24
+ from .model_manager import ModelManager, ModelProcessingError
22
25
  from .nemotron_model import NemotronModel
26
+ from .nvidia_model import NvidiaModel
23
27
  from .ollama_model import OllamaModel
24
28
  from .openai_audio_models import OpenAIAudioModels
25
29
  from .openai_compatible_model import OpenAICompatibleModel
@@ -42,10 +46,13 @@ __all__ = [
42
46
  'GroqModel',
43
47
  'StubModel',
44
48
  'ZhipuAIModel',
49
+ 'CohereModel',
45
50
  'ModelFactory',
51
+ 'ModelManager',
46
52
  'LiteLLMModel',
47
53
  'OpenAIAudioModels',
48
54
  'NemotronModel',
55
+ 'NvidiaModel',
49
56
  'OllamaModel',
50
57
  'VLLMModel',
51
58
  'GeminiModel',
@@ -55,4 +62,6 @@ __all__ = [
55
62
  'TogetherAIModel',
56
63
  'YiModel',
57
64
  'QwenModel',
65
+ 'ModelProcessingError',
66
+ 'DeepSeekModel',
58
67
  ]