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
@@ -1,30 +1,32 @@
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
+ import ast
15
+ import inspect
14
16
  import logging
15
17
  import warnings
16
18
  from inspect import Parameter, getsource, signature
17
- from typing import Any, Callable, Dict, Mapping, Optional, Tuple
19
+ from typing import Any, Callable, Dict, Mapping, Optional, Tuple, Type
18
20
 
19
21
  from docstring_parser import parse
20
22
  from jsonschema.exceptions import SchemaError
21
23
  from jsonschema.validators import Draft202012Validator as JSONValidator
22
- from pydantic import create_model
24
+ from pydantic import BaseModel, create_model
23
25
  from pydantic.fields import FieldInfo
24
26
 
25
27
  from camel.agents import ChatAgent
26
- from camel.models import BaseModelBackend
27
- from camel.types import ModelType
28
+ from camel.models import BaseModelBackend, ModelFactory
29
+ from camel.types import ModelPlatformType, ModelType
28
30
  from camel.utils import get_pydantic_object_schema, to_pascal
29
31
 
30
32
  logger = logging.getLogger(__name__)
@@ -40,6 +42,31 @@ def _remove_a_key(d: Dict, remove_key: Any) -> None:
40
42
  _remove_a_key(d[key], remove_key)
41
43
 
42
44
 
45
+ def _remove_title_recursively(data, parent_key=None):
46
+ r"""Recursively removes the 'title' key from all levels of a nested
47
+ dictionary, except when 'title' is an argument name in the schema.
48
+ """
49
+ if isinstance(data, dict):
50
+ # Only remove 'title' if it's not an argument name
51
+ if parent_key not in [
52
+ "properties",
53
+ "$defs",
54
+ "items",
55
+ "allOf",
56
+ "oneOf",
57
+ "anyOf",
58
+ ]:
59
+ data.pop("title", None)
60
+
61
+ # Recursively process each key-value pair
62
+ for key, value in data.items():
63
+ _remove_title_recursively(value, parent_key=key)
64
+ elif isinstance(data, list):
65
+ # Recursively process each element in the list
66
+ for item in data:
67
+ _remove_title_recursively(item, parent_key=parent_key)
68
+
69
+
43
70
  def get_openai_function_schema(func: Callable) -> Dict[str, Any]:
44
71
  r"""Generates a schema dict for an OpenAI function based on its signature.
45
72
 
@@ -118,9 +145,11 @@ def get_openai_tool_schema(func: Callable) -> Dict[str, Any]:
118
145
 
119
146
  model = _create_mol(to_pascal(func.__name__), fields)
120
147
  parameters_dict = get_pydantic_object_schema(model)
148
+
121
149
  # The `"title"` is generated by `model.model_json_schema()`
122
- # but is useless for openai json schema
123
- _remove_a_key(parameters_dict, "title")
150
+ # but is useless for openai json schema, remove generated 'title' from
151
+ # parameters_dict
152
+ _remove_title_recursively(parameters_dict)
124
153
 
125
154
  docstring = parse(func.__doc__ or "")
126
155
  for param in docstring.params:
@@ -227,47 +256,105 @@ class FunctionTool:
227
256
  openai_tool_schema (Optional[Dict[str, Any]], optional): A
228
257
  user-defined OpenAI tool schema to override the default result.
229
258
  (default: :obj:`None`)
230
- use_schema_assistant (Optional[bool], optional): Whether to enable the
231
- use of a schema assistant model to automatically generate the
259
+ synthesize_schema (Optional[bool], optional): Whether to enable the
260
+ use of a schema assistant model to automatically synthesize the
232
261
  schema if validation fails or no valid schema is provided.
233
262
  (default: :obj:`False`)
234
- schema_assistant_model (Optional[BaseModelBackend], optional): An
235
- assistant model (e.g., an LLM model) used to generate the schema
236
- if `use_schema_assistant` is enabled and no valid schema is
263
+ synthesize_schema_model (Optional[BaseModelBackend], optional): An
264
+ assistant model (e.g., an LLM model) used to synthesize the schema
265
+ if `synthesize_schema` is enabled and no valid schema is
237
266
  provided. (default: :obj:`None`)
238
- schema_generation_max_retries (int, optional): The maximum
239
- number of attempts to retry schema generation using the schema
267
+ synthesize_schema_max_retries (int, optional): The maximum
268
+ number of attempts to retry schema synthesis using the schema
240
269
  assistant model if the previous attempts fail. (default: 2)
270
+ synthesize_output (Optional[bool], optional): Flag for enabling
271
+ synthesis output mode, where output is synthesized based on the
272
+ function's execution. (default: :obj:`False`)
273
+ synthesize_output_model (Optional[BaseModelBackend], optional):
274
+ Model used for output synthesis in synthesis mode.
275
+ (default: :obj:`None`)
276
+ synthesize_output_format (Optional[Type[BaseModel]], optional): Format
277
+ for the response when synthesizing output. (default: :obj:`None`)
241
278
  """
242
279
 
243
280
  def __init__(
244
281
  self,
245
282
  func: Callable,
246
283
  openai_tool_schema: Optional[Dict[str, Any]] = None,
247
- use_schema_assistant: Optional[bool] = False,
248
- schema_assistant_model: Optional[BaseModelBackend] = None,
249
- schema_generation_max_retries: int = 2,
284
+ synthesize_schema: Optional[bool] = False,
285
+ synthesize_schema_model: Optional[BaseModelBackend] = None,
286
+ synthesize_schema_max_retries: int = 2,
287
+ synthesize_output: Optional[bool] = False,
288
+ synthesize_output_model: Optional[BaseModelBackend] = None,
289
+ synthesize_output_format: Optional[Type[BaseModel]] = None,
250
290
  ) -> None:
251
291
  self.func = func
252
292
  self.openai_tool_schema = openai_tool_schema or get_openai_tool_schema(
253
293
  func
254
294
  )
295
+ self.synthesize_output = synthesize_output
296
+ self.synthesize_output_model = synthesize_output_model
297
+ if synthesize_output and synthesize_output_model is None:
298
+ self.synthesize_output_model = ModelFactory.create(
299
+ model_platform=ModelPlatformType.DEFAULT,
300
+ model_type=ModelType.DEFAULT,
301
+ )
302
+ logger.warning(
303
+ "Warning: No synthesize_output_model provided. "
304
+ f"Use `{self.synthesize_output_model.model_type}` to "
305
+ "synthesize the output."
306
+ )
307
+ self.synthesize_output_format: Optional[type[BaseModel]] = None
308
+ return_annotation = inspect.signature(self.func).return_annotation
309
+ if synthesize_output_format is not None:
310
+ self.synthesize_output_format = synthesize_output_format
311
+ elif isinstance(return_annotation, type) and issubclass(
312
+ return_annotation, BaseModel
313
+ ):
314
+ self.synthesize_output_format = return_annotation
255
315
 
256
- if use_schema_assistant:
316
+ self.synthesize_schema_model = synthesize_schema_model
317
+ if synthesize_schema:
257
318
  if openai_tool_schema:
258
319
  logger.warning("""The user-defined OpenAI tool schema will be
259
320
  overridden by the schema assistant model.""")
260
- schema = self.generate_openai_tool_schema(
261
- schema_generation_max_retries, schema_assistant_model
321
+ if self.synthesize_schema_model is None:
322
+ self.synthesize_schema_model = ModelFactory.create(
323
+ model_platform=ModelPlatformType.DEFAULT,
324
+ model_type=ModelType.DEFAULT,
325
+ )
326
+ logger.warning(
327
+ "Warning: No synthesize_schema_model provided. "
328
+ f"Use `{self.synthesize_schema_model.model_type}` to "
329
+ "synthesize the schema."
330
+ )
331
+ schema = self.synthesize_openai_tool_schema(
332
+ synthesize_schema_max_retries
262
333
  )
263
334
  if schema:
264
335
  self.openai_tool_schema = schema
265
336
  else:
266
337
  raise ValueError(
267
- f"Failed to generate valid schema for "
338
+ f"Failed to synthesize a valid schema for "
268
339
  f"{self.func.__name__}."
269
340
  )
270
341
 
342
+ def __call__(self, *args: Any, **kwargs: Any) -> Any:
343
+ if self.synthesize_output:
344
+ result = self.synthesize_execution_output(args, kwargs)
345
+ return result
346
+ else:
347
+ # Pass the extracted arguments to the indicated function
348
+ try:
349
+ result = self.func(*args, **kwargs)
350
+ return result
351
+ except Exception as e:
352
+ raise ValueError(
353
+ f"Execution of function {self.func.__name__} failed with "
354
+ f"arguments {args} and {kwargs}. "
355
+ f"Error: {e}"
356
+ )
357
+
271
358
  @staticmethod
272
359
  def validate_openai_tool_schema(
273
360
  openai_tool_schema: Dict[str, Any],
@@ -464,52 +551,42 @@ class FunctionTool:
464
551
  param_name
465
552
  ] = value
466
553
 
467
- def generate_openai_tool_schema(
554
+ def synthesize_openai_tool_schema(
468
555
  self,
469
556
  max_retries: Optional[int] = None,
470
- schema_assistant_model: Optional[BaseModelBackend] = None,
471
557
  ) -> Dict[str, Any]:
472
- r"""Generates an OpenAI tool schema for the specified function.
558
+ r"""Synthesizes an OpenAI tool schema for the specified function.
473
559
 
474
- This method uses a language model (LLM) to generate the OpenAI tool
560
+ This method uses a language model (LLM) to synthesize the OpenAI tool
475
561
  schema for the specified function by first generating a docstring and
476
- then creating a schema based on the function's source code. If no LLM
477
- is provided, it defaults to initializing a gpt-4o-mini model. The
478
- schema generation and validation process is retried up to
562
+ then creating a schema based on the function's source code. The
563
+ schema synthesis and validation process is retried up to
479
564
  `max_retries` times in case of failure.
480
565
 
481
-
482
566
  Args:
483
567
  max_retries (Optional[int], optional): The maximum number of
484
- retries for schema generation and validation if the process
568
+ retries for schema synthesis and validation if the process
485
569
  fails. (default: :obj:`None`)
486
- schema_assistant_model (Optional[BaseModelBackend], optional): An
487
- optional LLM backend model used for generating the docstring
488
- and schema. If not provided, a gpt-4o-mini model
489
- will be created. (default: :obj:`None`)
490
570
 
491
571
  Returns:
492
- Dict[str, Any]: The generated OpenAI tool schema for the function.
572
+ Dict[str, Any]: The synthesis OpenAI tool schema for the function.
493
573
 
494
574
  Raises:
495
- ValueError: If schema generation or validation fails after the
575
+ ValueError: If schema synthesis or validation fails after the
496
576
  maximum number of retries, a ValueError is raised, prompting
497
577
  manual schema setting.
498
578
  """
499
- if not schema_assistant_model:
500
- logger.warning(
501
- "Warning: No model provided. "
502
- f"Use `{ModelType.GPT_4O_MINI.value}` to generate the schema."
503
- )
504
579
  code = getsource(self.func)
505
580
  retries = 0
506
581
  if max_retries is None:
507
582
  max_retries = 0
508
- # Retry loop to handle schema generation and validation
583
+ # Retry loop to handle schema synthesis and validation
509
584
  while retries <= max_retries:
510
585
  try:
511
586
  # Generate the docstring and the schema
512
- docstring = generate_docstring(code, schema_assistant_model)
587
+ docstring = generate_docstring(
588
+ code, self.synthesize_schema_model
589
+ )
513
590
  self.func.__doc__ = docstring
514
591
  schema = get_openai_tool_schema(self.func)
515
592
  # Validate the schema
@@ -520,7 +597,7 @@ class FunctionTool:
520
597
  retries += 1
521
598
  if retries == max_retries:
522
599
  raise ValueError(
523
- f"Failed to generate the OpenAI tool Schema after "
600
+ f"Failed to synthesize the OpenAI tool Schema after "
524
601
  f"{max_retries} retries. "
525
602
  f"Please set the OpenAI tool schema for "
526
603
  f"function {self.func.__name__} manually."
@@ -529,6 +606,102 @@ class FunctionTool:
529
606
 
530
607
  return {}
531
608
 
609
+ def synthesize_execution_output(
610
+ self,
611
+ args: Optional[tuple[Any, ...]] = None,
612
+ kwargs: Optional[Dict[str, Any]] = None,
613
+ ) -> Any:
614
+ r"""Synthesizes the output of the function based on the provided
615
+ positional arguments and keyword arguments.
616
+
617
+ Args:
618
+ args (Optional[tuple]): Positional arguments to pass to the
619
+ function during synthesis. (default: :obj:`None`)
620
+ kwargs (Optional[Dict[str, Any]]): Keyword arguments to pass to the
621
+ function during synthesis. (default: :obj:`None`)
622
+
623
+ Returns:
624
+ Any: Synthesized output from the function execution. If no
625
+ synthesis model is provided, a warning is logged.
626
+ """
627
+ import textwrap
628
+
629
+ # Retrieve the function source code
630
+ function_string = inspect.getsource(self.func)
631
+
632
+ # Check and update docstring if necessary
633
+ if self.func.__doc__ is not None:
634
+ function_string = textwrap.dedent(function_string)
635
+ tree = ast.parse(function_string)
636
+ func_node = (
637
+ tree.body[0]
638
+ if isinstance(tree.body[0], ast.FunctionDef)
639
+ else None
640
+ )
641
+ if func_node:
642
+ existing_docstring = ast.get_docstring(func_node)
643
+ if existing_docstring != self.func.__doc__:
644
+ func_node.body[0] = ast.Expr(
645
+ value=ast.Constant(value=self.func.__doc__, kind=None)
646
+ )
647
+ function_string = ast.unparse(tree)
648
+
649
+ # Append the args and kwargs information to the function string
650
+ if args:
651
+ function_string += f"\nargs:\n{list(args)}"
652
+ if kwargs:
653
+ function_string += f"\nkwargs:\n{kwargs}"
654
+
655
+ # Define the assistant system message
656
+ assistant_sys_msg = '''
657
+ **Role:** AI Assistant specialized in synthesizing tool execution outputs
658
+ without actual execution.
659
+
660
+ **Capabilities:**
661
+ - Analyzes function to understand their
662
+ purpose and expected outputs.
663
+ - Generates synthetic outputs based on the function logic.
664
+ - Ensures the synthesized output is contextually accurate and aligns with the
665
+ function's intended behavior.
666
+
667
+ **Instructions:**
668
+ 1. **Input:** Provide the function code, function docstring, args, and kwargs.
669
+ 2. **Output:** Synthesize the expected output of the function based on the
670
+ provided args and kwargs.
671
+
672
+ **Example:**
673
+ - **User Input:**
674
+ def sum(a, b, c=0):
675
+ """Adds three numbers together."""
676
+ return a + b + c
677
+
678
+ - **Input Arguments:**
679
+ args: (1, 2)
680
+ kwargs: {"c": 3}
681
+
682
+ - **Output:**
683
+ 6
684
+
685
+ **Note:**
686
+ - Just return the synthesized output of the function without any explanation.
687
+ - The output should be in plain text without any formatting.
688
+ '''
689
+
690
+ # Initialize the synthesis agent
691
+ synthesis_agent = ChatAgent(
692
+ assistant_sys_msg,
693
+ model=self.synthesize_output_model,
694
+ )
695
+
696
+ # User message combining function string and additional context
697
+ user_msg = function_string
698
+ response = synthesis_agent.step(
699
+ user_msg,
700
+ response_format=self.synthesize_output_format,
701
+ )
702
+
703
+ return response.msg.content
704
+
532
705
  @property
533
706
  def parameters(self) -> Dict[str, Any]:
534
707
  r"""Getter method for the property :obj:`parameters`.
@@ -555,25 +728,3 @@ class FunctionTool:
555
728
  except SchemaError as e:
556
729
  raise e
557
730
  self.openai_tool_schema["function"]["parameters"]["properties"] = value
558
-
559
-
560
- warnings.simplefilter('always', DeprecationWarning)
561
-
562
-
563
- # Alias for backwards compatibility
564
- class OpenAIFunction(FunctionTool):
565
- r"""Alias for backwards compatibility."""
566
-
567
- def __init__(self, *args, **kwargs):
568
- PURPLE = '\033[95m'
569
- RESET = '\033[0m'
570
-
571
- def purple_warning(msg):
572
- warnings.warn(
573
- PURPLE + msg + RESET, DeprecationWarning, stacklevel=2
574
- )
575
-
576
- purple_warning(
577
- "OpenAIFunction is deprecated, please use FunctionTool instead."
578
- )
579
- super().__init__(*args, **kwargs)
@@ -1,16 +1,16 @@
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
 
15
15
  import logging
16
16
  import os
@@ -1,16 +1,16 @@
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
  import os
15
15
  from functools import wraps
16
16
  from typing import Any, Callable, List, Optional, Union
@@ -1,16 +1,16 @@
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
  import re
15
15
  from typing import Any, Dict, List, Optional
16
16
 
@@ -0,0 +1,53 @@
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 logging
16
+ from typing import List
17
+
18
+ from camel.toolkits.base import BaseToolkit
19
+ from camel.toolkits.function_tool import FunctionTool
20
+
21
+ logger = logging.getLogger(__name__)
22
+
23
+
24
+ class HumanToolkit(BaseToolkit):
25
+ r"""A class representing a toolkit for human interaction."""
26
+
27
+ def __init__(self):
28
+ pass
29
+
30
+ def ask_human_via_console(self, question: str) -> str:
31
+ r"""Ask a question to the human via the console.
32
+
33
+ Args:
34
+ question (str): The question to ask the human.
35
+
36
+ Returns:
37
+ str: The answer from the human.
38
+ """
39
+ print(f"Question: {question}")
40
+ logger.info(f"Question: {question}")
41
+ reply = input("Your reply: ")
42
+ logger.info(f"User reply: {reply}")
43
+ return reply
44
+
45
+ def get_tools(self) -> List[FunctionTool]:
46
+ r"""Returns a list of FunctionTool objects representing the
47
+ functions in the toolkit.
48
+
49
+ Returns:
50
+ List[FunctionTool]: A list of FunctionTool objects
51
+ representing the functions in the toolkit.
52
+ """
53
+ return [FunctionTool(self.ask_human_via_console)]
@@ -1,16 +1,16 @@
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
 
15
15
  import json
16
16
  import os
@@ -1,16 +1,16 @@
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
 
15
15
  from typing import List
16
16
 
@@ -74,6 +74,3 @@ class MathToolkit(BaseToolkit):
74
74
  FunctionTool(self.sub),
75
75
  FunctionTool(self.mul),
76
76
  ]
77
-
78
-
79
- MATH_FUNCS: List[FunctionTool] = MathToolkit().get_tools()