camel-ai 0.1.5.6__py3-none-any.whl → 0.1.6.1__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 (133) hide show
  1. camel/__init__.py +1 -1
  2. camel/agents/chat_agent.py +249 -36
  3. camel/agents/critic_agent.py +18 -2
  4. camel/agents/deductive_reasoner_agent.py +16 -4
  5. camel/agents/embodied_agent.py +20 -6
  6. camel/agents/knowledge_graph_agent.py +24 -5
  7. camel/agents/role_assignment_agent.py +13 -1
  8. camel/agents/search_agent.py +16 -5
  9. camel/agents/task_agent.py +20 -5
  10. camel/configs/__init__.py +11 -9
  11. camel/configs/anthropic_config.py +5 -6
  12. camel/configs/base_config.py +50 -4
  13. camel/configs/gemini_config.py +69 -17
  14. camel/configs/groq_config.py +105 -0
  15. camel/configs/litellm_config.py +2 -8
  16. camel/configs/mistral_config.py +78 -0
  17. camel/configs/ollama_config.py +5 -7
  18. camel/configs/openai_config.py +12 -23
  19. camel/configs/vllm_config.py +102 -0
  20. camel/configs/zhipuai_config.py +5 -11
  21. camel/embeddings/__init__.py +2 -0
  22. camel/embeddings/mistral_embedding.py +89 -0
  23. camel/human.py +1 -1
  24. camel/interpreters/__init__.py +2 -0
  25. camel/interpreters/ipython_interpreter.py +167 -0
  26. camel/loaders/__init__.py +2 -0
  27. camel/loaders/firecrawl_reader.py +213 -0
  28. camel/memories/agent_memories.py +1 -4
  29. camel/memories/blocks/chat_history_block.py +6 -2
  30. camel/memories/blocks/vectordb_block.py +3 -1
  31. camel/memories/context_creators/score_based.py +6 -6
  32. camel/memories/records.py +9 -7
  33. camel/messages/base.py +1 -0
  34. camel/models/__init__.py +8 -0
  35. camel/models/anthropic_model.py +7 -2
  36. camel/models/azure_openai_model.py +152 -0
  37. camel/models/base_model.py +9 -2
  38. camel/models/gemini_model.py +14 -2
  39. camel/models/groq_model.py +131 -0
  40. camel/models/litellm_model.py +26 -4
  41. camel/models/mistral_model.py +169 -0
  42. camel/models/model_factory.py +30 -3
  43. camel/models/ollama_model.py +21 -2
  44. camel/models/open_source_model.py +13 -5
  45. camel/models/openai_model.py +7 -2
  46. camel/models/stub_model.py +4 -4
  47. camel/models/vllm_model.py +138 -0
  48. camel/models/zhipuai_model.py +7 -4
  49. camel/prompts/__init__.py +8 -1
  50. camel/prompts/image_craft.py +34 -0
  51. camel/prompts/multi_condition_image_craft.py +34 -0
  52. camel/prompts/task_prompt_template.py +10 -4
  53. camel/prompts/{descripte_video_prompt.py → video_description_prompt.py} +1 -1
  54. camel/responses/agent_responses.py +4 -3
  55. camel/retrievers/auto_retriever.py +2 -2
  56. camel/societies/babyagi_playing.py +6 -4
  57. camel/societies/role_playing.py +16 -8
  58. camel/storages/graph_storages/graph_element.py +10 -14
  59. camel/storages/graph_storages/neo4j_graph.py +5 -0
  60. camel/storages/vectordb_storages/base.py +24 -13
  61. camel/storages/vectordb_storages/milvus.py +1 -1
  62. camel/storages/vectordb_storages/qdrant.py +2 -3
  63. camel/tasks/__init__.py +22 -0
  64. camel/tasks/task.py +408 -0
  65. camel/tasks/task_prompt.py +65 -0
  66. camel/toolkits/__init__.py +39 -0
  67. camel/toolkits/base.py +4 -2
  68. camel/toolkits/code_execution.py +1 -1
  69. camel/toolkits/dalle_toolkit.py +146 -0
  70. camel/toolkits/github_toolkit.py +19 -34
  71. camel/toolkits/google_maps_toolkit.py +368 -0
  72. camel/toolkits/math_toolkit.py +79 -0
  73. camel/toolkits/open_api_toolkit.py +547 -0
  74. camel/{functions → toolkits}/openai_function.py +2 -7
  75. camel/toolkits/retrieval_toolkit.py +76 -0
  76. camel/toolkits/search_toolkit.py +326 -0
  77. camel/toolkits/slack_toolkit.py +308 -0
  78. camel/toolkits/twitter_toolkit.py +522 -0
  79. camel/toolkits/weather_toolkit.py +173 -0
  80. camel/types/enums.py +154 -35
  81. camel/utils/__init__.py +14 -2
  82. camel/utils/async_func.py +1 -1
  83. camel/utils/commons.py +152 -2
  84. camel/utils/constants.py +3 -0
  85. camel/utils/token_counting.py +148 -40
  86. camel/workforce/__init__.py +23 -0
  87. camel/workforce/base.py +50 -0
  88. camel/workforce/manager_node.py +299 -0
  89. camel/workforce/role_playing_node.py +168 -0
  90. camel/workforce/single_agent_node.py +77 -0
  91. camel/workforce/task_channel.py +173 -0
  92. camel/workforce/utils.py +97 -0
  93. camel/workforce/worker_node.py +115 -0
  94. camel/workforce/workforce.py +49 -0
  95. camel/workforce/workforce_prompt.py +125 -0
  96. {camel_ai-0.1.5.6.dist-info → camel_ai-0.1.6.1.dist-info}/METADATA +45 -3
  97. camel_ai-0.1.6.1.dist-info/RECORD +182 -0
  98. camel/functions/__init__.py +0 -51
  99. camel/functions/google_maps_function.py +0 -335
  100. camel/functions/math_functions.py +0 -61
  101. camel/functions/open_api_function.py +0 -508
  102. camel/functions/retrieval_functions.py +0 -61
  103. camel/functions/search_functions.py +0 -298
  104. camel/functions/slack_functions.py +0 -286
  105. camel/functions/twitter_function.py +0 -479
  106. camel/functions/weather_functions.py +0 -144
  107. camel_ai-0.1.5.6.dist-info/RECORD +0 -157
  108. /camel/{functions → toolkits}/open_api_specs/biztoc/__init__.py +0 -0
  109. /camel/{functions → toolkits}/open_api_specs/biztoc/ai-plugin.json +0 -0
  110. /camel/{functions → toolkits}/open_api_specs/biztoc/openapi.yaml +0 -0
  111. /camel/{functions → toolkits}/open_api_specs/coursera/__init__.py +0 -0
  112. /camel/{functions → toolkits}/open_api_specs/coursera/openapi.yaml +0 -0
  113. /camel/{functions → toolkits}/open_api_specs/create_qr_code/__init__.py +0 -0
  114. /camel/{functions → toolkits}/open_api_specs/create_qr_code/openapi.yaml +0 -0
  115. /camel/{functions → toolkits}/open_api_specs/klarna/__init__.py +0 -0
  116. /camel/{functions → toolkits}/open_api_specs/klarna/openapi.yaml +0 -0
  117. /camel/{functions → toolkits}/open_api_specs/nasa_apod/__init__.py +0 -0
  118. /camel/{functions → toolkits}/open_api_specs/nasa_apod/openapi.yaml +0 -0
  119. /camel/{functions → toolkits}/open_api_specs/outschool/__init__.py +0 -0
  120. /camel/{functions → toolkits}/open_api_specs/outschool/ai-plugin.json +0 -0
  121. /camel/{functions → toolkits}/open_api_specs/outschool/openapi.yaml +0 -0
  122. /camel/{functions → toolkits}/open_api_specs/outschool/paths/__init__.py +0 -0
  123. /camel/{functions → toolkits}/open_api_specs/outschool/paths/get_classes.py +0 -0
  124. /camel/{functions → toolkits}/open_api_specs/outschool/paths/search_teachers.py +0 -0
  125. /camel/{functions → toolkits}/open_api_specs/security_config.py +0 -0
  126. /camel/{functions → toolkits}/open_api_specs/speak/__init__.py +0 -0
  127. /camel/{functions → toolkits}/open_api_specs/speak/openapi.yaml +0 -0
  128. /camel/{functions → toolkits}/open_api_specs/web_scraper/__init__.py +0 -0
  129. /camel/{functions → toolkits}/open_api_specs/web_scraper/ai-plugin.json +0 -0
  130. /camel/{functions → toolkits}/open_api_specs/web_scraper/openapi.yaml +0 -0
  131. /camel/{functions → toolkits}/open_api_specs/web_scraper/paths/__init__.py +0 -0
  132. /camel/{functions → toolkits}/open_api_specs/web_scraper/paths/scraper.py +0 -0
  133. {camel_ai-0.1.5.6.dist-info → camel_ai-0.1.6.1.dist-info}/WHEEL +0 -0
camel/types/enums.py CHANGED
@@ -29,11 +29,22 @@ class ModelType(Enum):
29
29
  GPT_4_32K = "gpt-4-32k"
30
30
  GPT_4_TURBO = "gpt-4-turbo"
31
31
  GPT_4O = "gpt-4o"
32
+ GPT_4O_MINI = "gpt-4o-mini"
33
+
32
34
  GLM_4 = "glm-4"
33
35
  GLM_4_OPEN_SOURCE = "glm-4-open-source"
34
36
  GLM_4V = 'glm-4v'
35
37
  GLM_3_TURBO = "glm-3-turbo"
36
38
 
39
+ GROQ_LLAMA_3_1_8B = "llama-3.1-8b-instant"
40
+ GROQ_LLAMA_3_1_70B = "llama-3.1-70b-versatile"
41
+ GROQ_LLAMA_3_1_405B = "llama-3.1-405b-reasoning"
42
+ GROQ_LLAMA_3_8B = "llama3-8b-8192"
43
+ GROQ_LLAMA_3_70B = "llama3-70b-8192"
44
+ GROQ_MIXTRAL_8_7B = "mixtral-8x7b-32768"
45
+ GROQ_GEMMA_7B_IT = "gemma-7b-it"
46
+ GROQ_GEMMA_2_9B_IT = "gemma2-9b-it"
47
+
37
48
  STUB = "stub"
38
49
 
39
50
  LLAMA_2 = "llama-2"
@@ -44,7 +55,7 @@ class ModelType(Enum):
44
55
  QWEN_2 = "qwen-2"
45
56
 
46
57
  # Legacy anthropic models
47
- # NOTE: anthropic lagecy models only Claude 2.1 has system prompt support
58
+ # NOTE: anthropic legacy models only Claude 2.1 has system prompt support
48
59
  CLAUDE_2_1 = "claude-2.1"
49
60
  CLAUDE_2_0 = "claude-2.0"
50
61
  CLAUDE_INSTANT_1_2 = "claude-instant-1.2"
@@ -62,6 +73,15 @@ class ModelType(Enum):
62
73
  GEMINI_1_5_FLASH = "gemini-1.5-flash"
63
74
  GEMINI_1_5_PRO = "gemini-1.5-pro"
64
75
 
76
+ # Mistral AI Model
77
+ MISTRAL_LARGE = "mistral-large-latest"
78
+ MISTRAL_NEMO = "open-mistral-nemo"
79
+ MISTRAL_CODESTRAL = "codestral-latest"
80
+ MISTRAL_7B = "open-mistral-7b"
81
+ MISTRAL_MIXTRAL_8x7B = "open-mixtral-8x7b"
82
+ MISTRAL_MIXTRAL_8x22B = "open-mixtral-8x22b"
83
+ MISTRAL_CODESTRAL_MAMBA = "open-codestral-mamba"
84
+
65
85
  @property
66
86
  def value_for_tiktoken(self) -> str:
67
87
  return (
@@ -73,6 +93,20 @@ class ModelType(Enum):
73
93
  @property
74
94
  def is_openai(self) -> bool:
75
95
  r"""Returns whether this type of models is an OpenAI-released model."""
96
+ return self in {
97
+ ModelType.GPT_3_5_TURBO,
98
+ ModelType.GPT_4,
99
+ ModelType.GPT_4_32K,
100
+ ModelType.GPT_4_TURBO,
101
+ ModelType.GPT_4O,
102
+ ModelType.GPT_4O_MINI,
103
+ }
104
+
105
+ @property
106
+ def is_azure_openai(self) -> bool:
107
+ r"""Returns whether this type of models is an OpenAI-released model
108
+ from Azure.
109
+ """
76
110
  return self in {
77
111
  ModelType.GPT_3_5_TURBO,
78
112
  ModelType.GPT_4,
@@ -119,6 +153,33 @@ class ModelType(Enum):
119
153
  ModelType.CLAUDE_3_5_SONNET,
120
154
  }
121
155
 
156
+ @property
157
+ def is_groq(self) -> bool:
158
+ r"""Returns whether this type of models is served by Groq."""
159
+ return self in {
160
+ ModelType.GROQ_LLAMA_3_1_8B,
161
+ ModelType.GROQ_LLAMA_3_1_70B,
162
+ ModelType.GROQ_LLAMA_3_1_405B,
163
+ ModelType.GROQ_LLAMA_3_8B,
164
+ ModelType.GROQ_LLAMA_3_70B,
165
+ ModelType.GROQ_MIXTRAL_8_7B,
166
+ ModelType.GROQ_GEMMA_7B_IT,
167
+ ModelType.GROQ_GEMMA_2_9B_IT,
168
+ }
169
+
170
+ @property
171
+ def is_mistral(self) -> bool:
172
+ r"""Returns whether this type of models is served by Mistral."""
173
+ return self in {
174
+ ModelType.MISTRAL_LARGE,
175
+ ModelType.MISTRAL_NEMO,
176
+ ModelType.MISTRAL_CODESTRAL,
177
+ ModelType.MISTRAL_7B,
178
+ ModelType.MISTRAL_MIXTRAL_8x7B,
179
+ ModelType.MISTRAL_MIXTRAL_8x22B,
180
+ ModelType.MISTRAL_CODESTRAL_MAMBA,
181
+ }
182
+
122
183
  @property
123
184
  def is_nvidia(self) -> bool:
124
185
  r"""Returns whether this type of models is Nvidia-released model.
@@ -137,46 +198,65 @@ class ModelType(Enum):
137
198
  @property
138
199
  def token_limit(self) -> int:
139
200
  r"""Returns the maximum token limit for a given model.
201
+
140
202
  Returns:
141
203
  int: The maximum token limit for the given model.
142
204
  """
143
- if self is ModelType.GPT_3_5_TURBO:
144
- return 16385
145
- elif self is ModelType.GPT_4:
146
- return 8192
147
- elif self is ModelType.GPT_4_32K:
148
- return 32768
149
- elif self is ModelType.GPT_4_TURBO:
150
- return 128000
151
- elif self is ModelType.GPT_4O:
152
- return 128000
153
- elif self == ModelType.GEMINI_1_5_FLASH:
154
- return 1048576
155
- elif self == ModelType.GEMINI_1_5_PRO:
156
- return 1048576
157
- elif self == ModelType.GLM_4_OPEN_SOURCE:
158
- return 8192
159
- elif self == ModelType.GLM_3_TURBO:
160
- return 8192
161
- elif self == ModelType.GLM_4V:
205
+ if self is ModelType.GLM_4V:
162
206
  return 1024
163
- elif self is ModelType.STUB:
164
- return 4096
165
- elif self is ModelType.LLAMA_2:
166
- return 4096
167
- elif self is ModelType.LLAMA_3:
168
- return 8192
169
- elif self is ModelType.QWEN_2:
170
- return 128000
171
- elif self is ModelType.GLM_4:
172
- return 8192
173
207
  elif self is ModelType.VICUNA:
174
208
  # reference: https://lmsys.org/blog/2023-03-30-vicuna/
175
209
  return 2048
176
- elif self is ModelType.VICUNA_16K:
177
- return 16384
210
+ elif self in {
211
+ ModelType.LLAMA_2,
212
+ ModelType.NEMOTRON_4_REWARD,
213
+ ModelType.STUB,
214
+ }:
215
+ return 4_096
216
+ elif self in {
217
+ ModelType.GPT_4,
218
+ ModelType.GROQ_LLAMA_3_8B,
219
+ ModelType.GROQ_LLAMA_3_70B,
220
+ ModelType.GROQ_GEMMA_7B_IT,
221
+ ModelType.GROQ_GEMMA_2_9B_IT,
222
+ ModelType.LLAMA_3,
223
+ ModelType.GLM_3_TURBO,
224
+ ModelType.GLM_4,
225
+ ModelType.GLM_4_OPEN_SOURCE,
226
+ }:
227
+ return 8_192
228
+ elif self in {
229
+ ModelType.GPT_3_5_TURBO,
230
+ ModelType.VICUNA_16K,
231
+ }:
232
+ return 16_384
233
+ elif self in {
234
+ ModelType.GPT_4_32K,
235
+ ModelType.MISTRAL_CODESTRAL,
236
+ ModelType.MISTRAL_7B,
237
+ ModelType.MISTRAL_MIXTRAL_8x7B,
238
+ ModelType.GROQ_MIXTRAL_8_7B,
239
+ }:
240
+ return 32_768
241
+ elif self in {ModelType.MISTRAL_MIXTRAL_8x22B}:
242
+ return 64_000
178
243
  elif self in {ModelType.CLAUDE_2_0, ModelType.CLAUDE_INSTANT_1_2}:
179
244
  return 100_000
245
+ elif self in {
246
+ ModelType.GPT_4O,
247
+ ModelType.GPT_4O_MINI,
248
+ ModelType.GPT_4_TURBO,
249
+ ModelType.MISTRAL_LARGE,
250
+ ModelType.MISTRAL_NEMO,
251
+ ModelType.QWEN_2,
252
+ }:
253
+ return 128_000
254
+ elif self in {
255
+ ModelType.GROQ_LLAMA_3_1_8B,
256
+ ModelType.GROQ_LLAMA_3_1_70B,
257
+ ModelType.GROQ_LLAMA_3_1_405B,
258
+ }:
259
+ return 131_072
180
260
  elif self in {
181
261
  ModelType.CLAUDE_2_1,
182
262
  ModelType.CLAUDE_3_OPUS,
@@ -185,8 +265,12 @@ class ModelType(Enum):
185
265
  ModelType.CLAUDE_3_5_SONNET,
186
266
  }:
187
267
  return 200_000
188
- elif self is ModelType.NEMOTRON_4_REWARD:
189
- return 4096
268
+ elif self in {
269
+ ModelType.MISTRAL_CODESTRAL_MAMBA,
270
+ }:
271
+ return 256_000
272
+ elif self in {ModelType.GEMINI_1_5_FLASH, ModelType.GEMINI_1_5_PRO}:
273
+ return 1_048_576
190
274
  else:
191
275
  raise ValueError("Unknown model type")
192
276
 
@@ -195,8 +279,9 @@ class ModelType(Enum):
195
279
 
196
280
  Args:
197
281
  model_name (str): The name of the model, e.g. "vicuna-7b-v1.5".
282
+
198
283
  Returns:
199
- bool: Whether the model type mathches the model name.
284
+ bool: Whether the model type matches the model name.
200
285
  """
201
286
  if self is ModelType.VICUNA:
202
287
  pattern = r'^vicuna-\d+b-v\d+\.\d+$'
@@ -232,6 +317,8 @@ class EmbeddingModelType(Enum):
232
317
  TEXT_EMBEDDING_3_SMALL = "text-embedding-3-small"
233
318
  TEXT_EMBEDDING_3_LARGE = "text-embedding-3-large"
234
319
 
320
+ MISTRAL_EMBED = "mistral-embed"
321
+
235
322
  @property
236
323
  def is_openai(self) -> bool:
237
324
  r"""Returns whether this type of models is an OpenAI-released model."""
@@ -241,6 +328,15 @@ class EmbeddingModelType(Enum):
241
328
  EmbeddingModelType.TEXT_EMBEDDING_3_LARGE,
242
329
  }
243
330
 
331
+ @property
332
+ def is_mistral(self) -> bool:
333
+ r"""Returns whether this type of models is an Mistral-released
334
+ model.
335
+ """
336
+ return self in {
337
+ EmbeddingModelType.MISTRAL_EMBED,
338
+ }
339
+
244
340
  @property
245
341
  def output_dim(self) -> int:
246
342
  if self is EmbeddingModelType.TEXT_EMBEDDING_ADA_2:
@@ -249,6 +345,8 @@ class EmbeddingModelType(Enum):
249
345
  return 1536
250
346
  elif self is EmbeddingModelType.TEXT_EMBEDDING_3_LARGE:
251
347
  return 3072
348
+ elif self is EmbeddingModelType.MISTRAL_EMBED:
349
+ return 1024
252
350
  else:
253
351
  raise ValueError(f"Unknown model type {self}.")
254
352
 
@@ -263,6 +361,8 @@ class TaskType(Enum):
263
361
  ROLE_DESCRIPTION = "role_description"
264
362
  GENERATE_TEXT_EMBEDDING_DATA = "generate_text_embedding_data"
265
363
  OBJECT_RECOGNITION = "object_recognition"
364
+ IMAGE_CRAFT = "image_craft"
365
+ MULTI_CONDITION_IMAGE_CRAFT = "multi_condition_image_craft"
266
366
  DEFAULT = "default"
267
367
  VIDEO_DESCRIPTION = "video_description"
268
368
 
@@ -285,6 +385,7 @@ class OpenAIBackendRole(Enum):
285
385
  SYSTEM = "system"
286
386
  USER = "user"
287
387
  FUNCTION = "function"
388
+ TOOL = "tool"
288
389
 
289
390
 
290
391
  class TerminationMode(Enum):
@@ -338,12 +439,15 @@ class ModelPlatformType(Enum):
338
439
  OPENAI = "openai"
339
440
  AZURE = "azure"
340
441
  ANTHROPIC = "anthropic"
442
+ GROQ = "groq"
341
443
  OPENSOURCE = "opensource"
342
444
  OLLAMA = "ollama"
343
445
  LITELLM = "litellm"
344
446
  ZHIPU = "zhipuai"
345
447
  DEFAULT = "default"
346
448
  GEMINI = "gemini"
449
+ VLLM = "vllm"
450
+ MISTRAL = "mistral"
347
451
 
348
452
  @property
349
453
  def is_openai(self) -> bool:
@@ -360,11 +464,21 @@ class ModelPlatformType(Enum):
360
464
  r"""Returns whether this platform is anthropic."""
361
465
  return self is ModelPlatformType.ANTHROPIC
362
466
 
467
+ @property
468
+ def is_groq(self) -> bool:
469
+ r"""Returns whether this platform is groq."""
470
+ return self is ModelPlatformType.GROQ
471
+
363
472
  @property
364
473
  def is_ollama(self) -> bool:
365
474
  r"""Returns whether this platform is ollama."""
366
475
  return self is ModelPlatformType.OLLAMA
367
476
 
477
+ @property
478
+ def is_vllm(self) -> bool:
479
+ r"""Returns whether this platform is vllm."""
480
+ return self is ModelPlatformType.VLLM
481
+
368
482
  @property
369
483
  def is_litellm(self) -> bool:
370
484
  r"""Returns whether this platform is litellm."""
@@ -375,6 +489,11 @@ class ModelPlatformType(Enum):
375
489
  r"""Returns whether this platform is zhipu."""
376
490
  return self is ModelPlatformType.ZHIPU
377
491
 
492
+ @property
493
+ def is_mistral(self) -> bool:
494
+ r"""Returns whether this platform is mistral."""
495
+ return self is ModelPlatformType.MISTRAL
496
+
378
497
  @property
379
498
  def is_open_source(self) -> bool:
380
499
  r"""Returns whether this platform is opensource."""
camel/utils/__init__.py CHANGED
@@ -13,17 +13,22 @@
13
13
  # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
14
14
 
15
15
  from .commons import (
16
- PYDANTIC_V2,
16
+ AgentOpsMeta,
17
+ agentops_decorator,
17
18
  api_keys_required,
18
19
  check_server_running,
19
20
  create_chunks,
20
21
  dependencies_required,
21
22
  download_tasks,
23
+ func_string_to_callable,
22
24
  get_first_int,
23
25
  get_prompt_template_key_words,
26
+ get_pydantic_major_version,
27
+ get_pydantic_object_schema,
24
28
  get_system_information,
25
29
  get_task_list,
26
30
  is_docker_running,
31
+ json_to_function_code,
27
32
  print_text_animated,
28
33
  text_extract_from_web,
29
34
  to_pascal,
@@ -34,6 +39,7 @@ from .token_counting import (
34
39
  BaseTokenCounter,
35
40
  GeminiTokenCounter,
36
41
  LiteLLMTokenCounter,
42
+ MistralTokenCounter,
37
43
  OpenAITokenCounter,
38
44
  OpenSourceTokenCounter,
39
45
  get_model_encoding,
@@ -49,7 +55,6 @@ __all__ = [
49
55
  'AnthropicTokenCounter',
50
56
  'get_system_information',
51
57
  'to_pascal',
52
- 'PYDANTIC_V2',
53
58
  'get_model_encoding',
54
59
  'BaseTokenCounter',
55
60
  'OpenAITokenCounter',
@@ -62,4 +67,11 @@ __all__ = [
62
67
  'api_keys_required',
63
68
  'is_docker_running',
64
69
  'GeminiTokenCounter',
70
+ 'MistralTokenCounter',
71
+ 'get_pydantic_major_version',
72
+ 'get_pydantic_object_schema',
73
+ 'func_string_to_callable',
74
+ 'json_to_function_code',
75
+ 'agentops_decorator',
76
+ 'AgentOpsMeta',
65
77
  ]
camel/utils/async_func.py CHANGED
@@ -14,7 +14,7 @@
14
14
  import asyncio
15
15
  from copy import deepcopy
16
16
 
17
- from camel.functions.openai_function import OpenAIFunction
17
+ from camel.toolkits import OpenAIFunction
18
18
 
19
19
 
20
20
  def sync_funcs_to_async(funcs: list[OpenAIFunction]) -> list[OpenAIFunction]:
camel/utils/commons.py CHANGED
@@ -20,14 +20,27 @@ import subprocess
20
20
  import time
21
21
  import zipfile
22
22
  from functools import wraps
23
- from typing import Any, Callable, List, Optional, Set, TypeVar, cast
23
+ from typing import (
24
+ Any,
25
+ Callable,
26
+ Dict,
27
+ List,
28
+ Mapping,
29
+ Optional,
30
+ Set,
31
+ TypeVar,
32
+ cast,
33
+ )
24
34
  from urllib.parse import urlparse
25
35
 
26
36
  import pydantic
27
37
  import requests
38
+ from pydantic import BaseModel
28
39
 
29
40
  from camel.types import TaskType
30
41
 
42
+ from .constants import Constants
43
+
31
44
  F = TypeVar('F', bound=Callable[..., Any])
32
45
 
33
46
 
@@ -303,7 +316,97 @@ def to_pascal(snake: str) -> str:
303
316
  )
304
317
 
305
318
 
306
- PYDANTIC_V2 = pydantic.VERSION.startswith("2.")
319
+ def get_pydantic_major_version() -> int:
320
+ r"""Get the major version of Pydantic.
321
+
322
+ Returns:
323
+ int: The major version number of Pydantic if installed, otherwise 0.
324
+ """
325
+ try:
326
+ return int(pydantic.__version__.split(".")[0])
327
+ except ImportError:
328
+ return 0
329
+
330
+
331
+ def get_pydantic_object_schema(pydantic_params: BaseModel) -> Dict:
332
+ r"""Get the JSON schema of a Pydantic model.
333
+
334
+ Args:
335
+ pydantic_params (BaseModel): The Pydantic model to retrieve the schema
336
+ for.
337
+
338
+ Returns:
339
+ dict: The JSON schema of the Pydantic model.
340
+ """
341
+ return pydantic_params.model_json_schema()
342
+
343
+
344
+ def func_string_to_callable(code: str):
345
+ r"""Convert a function code string to a callable function object.
346
+
347
+ Args:
348
+ code (str): The function code as a string.
349
+
350
+ Returns:
351
+ Callable[..., Any]: The callable function object extracted from the
352
+ code string.
353
+ """
354
+ local_vars: Mapping[str, object] = {}
355
+ exec(code, globals(), local_vars)
356
+ func = local_vars.get(Constants.FUNC_NAME_FOR_STRUCTURE_OUTPUT)
357
+ return func
358
+
359
+
360
+ def json_to_function_code(json_obj: Dict) -> str:
361
+ r"""Generate a Python function code from a JSON schema.
362
+
363
+ Args:
364
+ json_obj (dict): The JSON schema object containing properties and
365
+ required fields, and json format is follow openai tools schema
366
+
367
+ Returns:
368
+ str: The generated Python function code as a string.
369
+ """
370
+ properties = json_obj.get('properties', {})
371
+ required = json_obj.get('required', [])
372
+
373
+ if not properties or not required:
374
+ raise ValueError(
375
+ "JSON schema must contain 'properties' and 'required' fields"
376
+ )
377
+
378
+ args = []
379
+ docstring_args = []
380
+ return_keys = []
381
+
382
+ for prop in required:
383
+ description = properties[prop]['description']
384
+ prop_type = properties[prop]['type']
385
+ python_type = 'str' if prop_type == 'string' else prop_type
386
+ args.append(f"{prop}: {python_type}")
387
+ docstring_args.append(
388
+ f" {prop} ({python_type}): {description}."
389
+ )
390
+ return_keys.append(prop)
391
+
392
+ # extract entity of schema
393
+ args_str = ", ".join(args)
394
+ docstring_args_str = "\n".join(docstring_args)
395
+ return_keys_str = ", ".join(return_keys)
396
+
397
+ # function template
398
+ function_code = f'''
399
+ def {Constants.FUNC_NAME_FOR_STRUCTURE_OUTPUT}({args_str}):
400
+ r"""Return response with a specified json format.
401
+ Args:
402
+ {docstring_args_str}
403
+ Returns:
404
+ Dict: A dictionary containing {return_keys_str}.
405
+ """
406
+ return {{{", ".join([f'"{prop}": {prop}' for prop in required])}}}
407
+ '''
408
+
409
+ return function_code
307
410
 
308
411
 
309
412
  def text_extract_from_web(url: str) -> str:
@@ -382,3 +485,50 @@ def is_docker_running() -> bool:
382
485
  return result.returncode == 0
383
486
  except (subprocess.CalledProcessError, FileNotFoundError):
384
487
  return False
488
+
489
+
490
+ try:
491
+ from agentops import ToolEvent, record
492
+ except ImportError:
493
+ ToolEvent = None
494
+
495
+
496
+ def agentops_decorator(func):
497
+ r"""Decorator that records the execution of a function if ToolEvent is
498
+ available.
499
+
500
+ Parameters:
501
+ func (callable): The function to be decorated.
502
+
503
+ Returns:
504
+ callable: The wrapped function which records its execution details.
505
+ """
506
+
507
+ @wraps(func)
508
+ def wrapper(*args, **kwargs):
509
+ if ToolEvent:
510
+ tool_event = ToolEvent(name=func.__name__, params=kwargs)
511
+ result = func(*args, **kwargs)
512
+ tool_event.returns = result
513
+ record(tool_event)
514
+ return result
515
+ return func(*args, **kwargs)
516
+
517
+ return wrapper
518
+
519
+
520
+ class AgentOpsMeta(type):
521
+ r"""Metaclass that automatically decorates all callable attributes with
522
+ the agentops_decorator,
523
+ except for the 'get_tools' method.
524
+
525
+ Methods:
526
+ __new__(cls, name, bases, dct):
527
+ Creates a new class with decorated methods.
528
+ """
529
+
530
+ def __new__(cls, name, bases, dct):
531
+ for attr, value in dct.items():
532
+ if callable(value) and attr != 'get_tools':
533
+ dct[attr] = agentops_decorator(value)
534
+ return super(AgentOpsMeta, cls).__new__(cls, name, bases, dct)
camel/utils/constants.py CHANGED
@@ -24,3 +24,6 @@ class Constants:
24
24
 
25
25
  # default plug of imageio to read video
26
26
  VIDEO_DEFAULT_PLUG_PYAV = "pyav"
27
+
28
+ # return response with json format
29
+ FUNC_NAME_FOR_STRUCTURE_OUTPUT = "return_json_response"