camel-ai 0.2.65__py3-none-any.whl → 0.2.83a6__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 (509) hide show
  1. camel/__init__.py +3 -3
  2. camel/agents/__init__.py +2 -2
  3. camel/agents/_types.py +9 -4
  4. camel/agents/_utils.py +40 -2
  5. camel/agents/base.py +2 -2
  6. camel/agents/chat_agent.py +5107 -995
  7. camel/agents/critic_agent.py +2 -2
  8. camel/agents/deductive_reasoner_agent.py +56 -56
  9. camel/agents/embodied_agent.py +2 -2
  10. camel/agents/knowledge_graph_agent.py +20 -20
  11. camel/agents/mcp_agent.py +35 -36
  12. camel/agents/multi_hop_generator_agent.py +3 -3
  13. camel/agents/programmed_agent_instruction.py +2 -2
  14. camel/agents/repo_agent.py +4 -3
  15. camel/agents/role_assignment_agent.py +2 -2
  16. camel/agents/search_agent.py +2 -2
  17. camel/agents/task_agent.py +2 -2
  18. camel/agents/tool_agents/__init__.py +2 -2
  19. camel/agents/tool_agents/base.py +2 -2
  20. camel/agents/tool_agents/hugging_face_tool_agent.py +3 -3
  21. camel/benchmarks/__init__.py +2 -2
  22. camel/benchmarks/apibank.py +5 -5
  23. camel/benchmarks/apibench.py +2 -2
  24. camel/benchmarks/base.py +2 -2
  25. camel/benchmarks/browsecomp.py +44 -33
  26. camel/benchmarks/gaia.py +17 -13
  27. camel/benchmarks/mock_website/README.md +1 -3
  28. camel/benchmarks/mock_website/mock_web.py +2 -2
  29. camel/benchmarks/mock_website/requirements.txt +1 -1
  30. camel/benchmarks/mock_website/shopping_mall/app.py +2 -2
  31. camel/benchmarks/mock_website/task.json +1 -1
  32. camel/benchmarks/nexus.py +3 -3
  33. camel/benchmarks/ragbench.py +2 -2
  34. camel/bots/__init__.py +2 -2
  35. camel/bots/discord/__init__.py +2 -2
  36. camel/bots/discord/discord_app.py +2 -2
  37. camel/bots/discord/discord_installation.py +2 -2
  38. camel/bots/discord/discord_store.py +3 -3
  39. camel/bots/slack/__init__.py +2 -2
  40. camel/bots/slack/models.py +4 -4
  41. camel/bots/slack/slack_app.py +2 -2
  42. camel/bots/telegram_bot.py +2 -2
  43. camel/configs/__init__.py +29 -2
  44. camel/configs/aihubmix_config.py +90 -0
  45. camel/configs/aiml_config.py +2 -2
  46. camel/configs/amd_config.py +70 -0
  47. camel/configs/anthropic_config.py +2 -2
  48. camel/configs/base_config.py +2 -2
  49. camel/configs/bedrock_config.py +5 -3
  50. camel/configs/cerebras_config.py +98 -0
  51. camel/configs/cohere_config.py +2 -2
  52. camel/configs/cometapi_config.py +106 -0
  53. camel/configs/crynux_config.py +2 -2
  54. camel/configs/deepseek_config.py +9 -8
  55. camel/configs/function_gemma_config.py +59 -0
  56. camel/configs/gemini_config.py +6 -4
  57. camel/configs/groq_config.py +6 -4
  58. camel/configs/internlm_config.py +6 -4
  59. camel/configs/litellm_config.py +2 -2
  60. camel/configs/lmstudio_config.py +6 -4
  61. camel/configs/minimax_config.py +95 -0
  62. camel/configs/mistral_config.py +2 -2
  63. camel/configs/modelscope_config.py +5 -3
  64. camel/configs/moonshot_config.py +2 -2
  65. camel/configs/nebius_config.py +105 -0
  66. camel/configs/netmind_config.py +2 -2
  67. camel/configs/novita_config.py +2 -2
  68. camel/configs/nvidia_config.py +2 -2
  69. camel/configs/ollama_config.py +2 -2
  70. camel/configs/openai_config.py +5 -3
  71. camel/configs/openrouter_config.py +6 -4
  72. camel/configs/ppio_config.py +2 -2
  73. camel/configs/qianfan_config.py +85 -0
  74. camel/configs/qwen_config.py +2 -2
  75. camel/configs/reka_config.py +2 -2
  76. camel/configs/samba_config.py +6 -4
  77. camel/configs/sglang_config.py +2 -2
  78. camel/configs/siliconflow_config.py +2 -2
  79. camel/configs/togetherai_config.py +2 -2
  80. camel/configs/vllm_config.py +4 -2
  81. camel/configs/watsonx_config.py +2 -2
  82. camel/configs/yi_config.py +6 -4
  83. camel/configs/zhipuai_config.py +6 -4
  84. camel/data_collectors/__init__.py +2 -2
  85. camel/data_collectors/alpaca_collector.py +18 -9
  86. camel/data_collectors/base.py +2 -2
  87. camel/data_collectors/sharegpt_collector.py +2 -2
  88. camel/datagen/__init__.py +2 -2
  89. camel/datagen/cot_datagen.py +3 -3
  90. camel/datagen/evol_instruct/__init__.py +2 -2
  91. camel/datagen/evol_instruct/evol_instruct.py +2 -2
  92. camel/datagen/evol_instruct/scorer.py +12 -12
  93. camel/datagen/evol_instruct/templates.py +16 -16
  94. camel/datagen/self_improving_cot.py +5 -5
  95. camel/datagen/self_instruct/__init__.py +2 -2
  96. camel/datagen/self_instruct/filter/__init__.py +2 -2
  97. camel/datagen/self_instruct/filter/filter_function.py +2 -2
  98. camel/datagen/self_instruct/filter/filter_registry.py +2 -2
  99. camel/datagen/self_instruct/filter/instruction_filter.py +2 -2
  100. camel/datagen/self_instruct/self_instruct.py +2 -2
  101. camel/datagen/self_instruct/templates.py +47 -47
  102. camel/datagen/source2synth/__init__.py +2 -2
  103. camel/datagen/source2synth/data_processor.py +2 -2
  104. camel/datagen/source2synth/models.py +2 -2
  105. camel/datagen/source2synth/user_data_processor_config.py +2 -2
  106. camel/datahubs/__init__.py +2 -2
  107. camel/datahubs/base.py +2 -2
  108. camel/datahubs/huggingface.py +2 -2
  109. camel/datahubs/models.py +2 -2
  110. camel/datasets/__init__.py +2 -2
  111. camel/datasets/base_generator.py +41 -12
  112. camel/datasets/few_shot_generator.py +18 -18
  113. camel/datasets/models.py +2 -2
  114. camel/datasets/self_instruct_generator.py +2 -2
  115. camel/datasets/static_dataset.py +2 -2
  116. camel/embeddings/__init__.py +2 -2
  117. camel/embeddings/azure_embedding.py +2 -2
  118. camel/embeddings/base.py +2 -2
  119. camel/embeddings/gemini_embedding.py +2 -2
  120. camel/embeddings/jina_embedding.py +2 -2
  121. camel/embeddings/mistral_embedding.py +2 -2
  122. camel/embeddings/openai_compatible_embedding.py +2 -2
  123. camel/embeddings/openai_embedding.py +2 -2
  124. camel/embeddings/sentence_transformers_embeddings.py +2 -2
  125. camel/embeddings/together_embedding.py +2 -2
  126. camel/embeddings/vlm_embedding.py +2 -2
  127. camel/environments/__init__.py +14 -2
  128. camel/environments/models.py +2 -2
  129. camel/environments/multi_step.py +2 -2
  130. camel/environments/rlcards_env.py +860 -0
  131. camel/environments/single_step.py +30 -5
  132. camel/environments/tic_tac_toe.py +3 -3
  133. camel/extractors/__init__.py +2 -2
  134. camel/extractors/base.py +2 -2
  135. camel/extractors/python_strategies.py +2 -2
  136. camel/generators.py +2 -2
  137. camel/human.py +2 -2
  138. camel/interpreters/__init__.py +4 -2
  139. camel/interpreters/base.py +2 -2
  140. camel/interpreters/docker/Dockerfile +14 -24
  141. camel/interpreters/docker_interpreter.py +5 -4
  142. camel/interpreters/e2b_interpreter.py +36 -3
  143. camel/interpreters/internal_python_interpreter.py +53 -4
  144. camel/interpreters/interpreter_error.py +2 -2
  145. camel/interpreters/ipython_interpreter.py +2 -2
  146. camel/interpreters/microsandbox_interpreter.py +395 -0
  147. camel/interpreters/subprocess_interpreter.py +2 -2
  148. camel/loaders/__init__.py +13 -4
  149. camel/loaders/apify_reader.py +2 -2
  150. camel/loaders/base_io.py +2 -2
  151. camel/loaders/base_loader.py +85 -0
  152. camel/loaders/chunkr_reader.py +11 -2
  153. camel/loaders/crawl4ai_reader.py +2 -2
  154. camel/loaders/firecrawl_reader.py +6 -6
  155. camel/loaders/jina_url_reader.py +2 -2
  156. camel/loaders/markitdown.py +2 -2
  157. camel/loaders/mineru_extractor.py +2 -2
  158. camel/loaders/mistral_reader.py +2 -2
  159. camel/loaders/scrapegraph_reader.py +2 -2
  160. camel/loaders/unstructured_io.py +2 -2
  161. camel/logger.py +5 -5
  162. camel/memories/__init__.py +2 -2
  163. camel/memories/agent_memories.py +86 -3
  164. camel/memories/base.py +36 -2
  165. camel/memories/blocks/__init__.py +2 -2
  166. camel/memories/blocks/chat_history_block.py +125 -7
  167. camel/memories/blocks/vectordb_block.py +10 -3
  168. camel/memories/context_creators/__init__.py +2 -2
  169. camel/memories/context_creators/score_based.py +109 -230
  170. camel/memories/records.py +90 -10
  171. camel/messages/__init__.py +2 -2
  172. camel/messages/base.py +178 -43
  173. camel/messages/conversion/__init__.py +2 -2
  174. camel/messages/conversion/alpaca.py +2 -2
  175. camel/messages/conversion/conversation_models.py +2 -2
  176. camel/messages/conversion/sharegpt/__init__.py +2 -2
  177. camel/messages/conversion/sharegpt/function_call_formatter.py +2 -2
  178. camel/messages/conversion/sharegpt/hermes/__init__.py +2 -2
  179. camel/messages/conversion/sharegpt/hermes/hermes_function_formatter.py +2 -2
  180. camel/messages/func_message.py +54 -17
  181. camel/models/__init__.py +18 -2
  182. camel/models/_utils.py +3 -3
  183. camel/models/aihubmix_model.py +83 -0
  184. camel/models/aiml_model.py +11 -18
  185. camel/models/amd_model.py +101 -0
  186. camel/models/anthropic_model.py +127 -20
  187. camel/models/aws_bedrock_model.py +12 -35
  188. camel/models/azure_openai_model.py +214 -115
  189. camel/models/base_audio_model.py +5 -3
  190. camel/models/base_model.py +378 -31
  191. camel/models/cerebras_model.py +83 -0
  192. camel/models/cohere_model.py +18 -49
  193. camel/models/cometapi_model.py +83 -0
  194. camel/models/crynux_model.py +11 -18
  195. camel/models/deepseek_model.py +20 -84
  196. camel/models/fish_audio_model.py +8 -2
  197. camel/models/function_gemma_model.py +889 -0
  198. camel/models/gemini_model.py +391 -52
  199. camel/models/groq_model.py +11 -19
  200. camel/models/internlm_model.py +11 -18
  201. camel/models/litellm_model.py +57 -49
  202. camel/models/lmstudio_model.py +17 -20
  203. camel/models/minimax_model.py +83 -0
  204. camel/models/mistral_model.py +20 -47
  205. camel/models/model_factory.py +39 -3
  206. camel/models/model_manager.py +26 -8
  207. camel/models/modelscope_model.py +13 -193
  208. camel/models/moonshot_model.py +183 -21
  209. camel/models/nebius_model.py +83 -0
  210. camel/models/nemotron_model.py +19 -9
  211. camel/models/netmind_model.py +11 -18
  212. camel/models/novita_model.py +11 -18
  213. camel/models/nvidia_model.py +11 -18
  214. camel/models/ollama_model.py +14 -21
  215. camel/models/openai_audio_models.py +2 -2
  216. camel/models/openai_compatible_model.py +190 -71
  217. camel/models/openai_model.py +192 -86
  218. camel/models/openrouter_model.py +11 -19
  219. camel/models/ppio_model.py +11 -18
  220. camel/models/qianfan_model.py +89 -0
  221. camel/models/qwen_model.py +13 -193
  222. camel/models/reka_model.py +23 -49
  223. camel/models/reward/__init__.py +2 -2
  224. camel/models/reward/base_reward_model.py +2 -2
  225. camel/models/reward/evaluator.py +2 -2
  226. camel/models/reward/nemotron_model.py +2 -2
  227. camel/models/reward/skywork_model.py +2 -2
  228. camel/models/samba_model.py +50 -75
  229. camel/models/sglang_model.py +90 -68
  230. camel/models/siliconflow_model.py +12 -35
  231. camel/models/stub_model.py +10 -7
  232. camel/models/togetherai_model.py +11 -18
  233. camel/models/vllm_model.py +10 -18
  234. camel/models/volcano_model.py +158 -19
  235. camel/models/watsonx_model.py +9 -47
  236. camel/models/yi_model.py +11 -18
  237. camel/models/zhipuai_model.py +70 -18
  238. camel/parsers/__init__.py +18 -0
  239. camel/parsers/mcp_tool_call_parser.py +176 -0
  240. camel/personas/__init__.py +2 -2
  241. camel/personas/persona.py +2 -2
  242. camel/personas/persona_hub.py +2 -2
  243. camel/prompts/__init__.py +2 -2
  244. camel/prompts/ai_society.py +2 -2
  245. camel/prompts/base.py +2 -2
  246. camel/prompts/code.py +2 -2
  247. camel/prompts/evaluation.py +2 -2
  248. camel/prompts/generate_text_embedding_data.py +2 -2
  249. camel/prompts/image_craft.py +2 -2
  250. camel/prompts/misalignment.py +2 -2
  251. camel/prompts/multi_condition_image_craft.py +2 -2
  252. camel/prompts/object_recognition.py +2 -2
  253. camel/prompts/persona_hub.py +3 -3
  254. camel/prompts/prompt_templates.py +2 -2
  255. camel/prompts/role_description_prompt_template.py +2 -2
  256. camel/prompts/solution_extraction.py +8 -8
  257. camel/prompts/task_prompt_template.py +2 -2
  258. camel/prompts/translation.py +2 -2
  259. camel/prompts/video_description_prompt.py +3 -3
  260. camel/responses/__init__.py +2 -2
  261. camel/responses/agent_responses.py +2 -2
  262. camel/retrievers/__init__.py +2 -2
  263. camel/retrievers/auto_retriever.py +3 -2
  264. camel/retrievers/base.py +2 -2
  265. camel/retrievers/bm25_retriever.py +2 -2
  266. camel/retrievers/cohere_rerank_retriever.py +2 -2
  267. camel/retrievers/hybrid_retrival.py +2 -2
  268. camel/retrievers/vector_retriever.py +2 -2
  269. camel/runtimes/Dockerfile.multi-toolkit +90 -0
  270. camel/runtimes/__init__.py +2 -2
  271. camel/runtimes/api.py +79 -23
  272. camel/runtimes/base.py +2 -2
  273. camel/runtimes/configs.py +13 -13
  274. camel/runtimes/daytona_runtime.py +17 -18
  275. camel/runtimes/docker_runtime.py +12 -12
  276. camel/runtimes/llm_guard_runtime.py +26 -26
  277. camel/runtimes/remote_http_runtime.py +11 -11
  278. camel/runtimes/ubuntu_docker_runtime.py +2 -2
  279. camel/runtimes/utils/__init__.py +2 -2
  280. camel/runtimes/utils/function_risk_toolkit.py +2 -2
  281. camel/runtimes/utils/ignore_risk_toolkit.py +2 -2
  282. camel/schemas/__init__.py +2 -2
  283. camel/schemas/base.py +2 -2
  284. camel/schemas/openai_converter.py +3 -3
  285. camel/schemas/outlines_converter.py +2 -2
  286. camel/services/agent_openapi_server.py +380 -0
  287. camel/societies/__init__.py +4 -2
  288. camel/societies/babyagi_playing.py +2 -2
  289. camel/societies/role_playing.py +201 -80
  290. camel/societies/workforce/__init__.py +10 -3
  291. camel/societies/workforce/base.py +2 -2
  292. camel/societies/workforce/events.py +145 -0
  293. camel/societies/workforce/prompts.py +259 -33
  294. camel/societies/workforce/role_playing_worker.py +88 -31
  295. camel/societies/workforce/single_agent_worker.py +638 -40
  296. camel/societies/workforce/structured_output_handler.py +512 -0
  297. camel/societies/workforce/task_channel.py +182 -38
  298. camel/societies/workforce/utils.py +780 -65
  299. camel/societies/workforce/worker.py +92 -26
  300. camel/societies/workforce/workflow_memory_manager.py +1746 -0
  301. camel/societies/workforce/workforce.py +5354 -372
  302. camel/societies/workforce/workforce_callback.py +103 -0
  303. camel/societies/workforce/workforce_logger.py +647 -0
  304. camel/societies/workforce/workforce_metrics.py +33 -0
  305. camel/storages/__init__.py +6 -2
  306. camel/storages/graph_storages/__init__.py +2 -2
  307. camel/storages/graph_storages/base.py +2 -2
  308. camel/storages/graph_storages/graph_element.py +2 -2
  309. camel/storages/graph_storages/nebula_graph.py +4 -4
  310. camel/storages/graph_storages/neo4j_graph.py +7 -7
  311. camel/storages/key_value_storages/__init__.py +2 -2
  312. camel/storages/key_value_storages/base.py +2 -2
  313. camel/storages/key_value_storages/in_memory.py +2 -2
  314. camel/storages/key_value_storages/json.py +17 -4
  315. camel/storages/key_value_storages/mem0_cloud.py +50 -49
  316. camel/storages/key_value_storages/redis.py +2 -2
  317. camel/storages/object_storages/__init__.py +2 -2
  318. camel/storages/object_storages/amazon_s3.py +2 -2
  319. camel/storages/object_storages/azure_blob.py +2 -2
  320. camel/storages/object_storages/base.py +2 -2
  321. camel/storages/object_storages/google_cloud.py +3 -3
  322. camel/storages/vectordb_storages/__init__.py +8 -2
  323. camel/storages/vectordb_storages/base.py +2 -2
  324. camel/storages/vectordb_storages/chroma.py +731 -0
  325. camel/storages/vectordb_storages/faiss.py +2 -2
  326. camel/storages/vectordb_storages/milvus.py +2 -2
  327. camel/storages/vectordb_storages/oceanbase.py +15 -15
  328. camel/storages/vectordb_storages/pgvector.py +349 -0
  329. camel/storages/vectordb_storages/qdrant.py +6 -6
  330. camel/storages/vectordb_storages/surreal.py +372 -0
  331. camel/storages/vectordb_storages/tidb.py +11 -8
  332. camel/storages/vectordb_storages/weaviate.py +2 -2
  333. camel/tasks/__init__.py +2 -2
  334. camel/tasks/task.py +348 -26
  335. camel/tasks/task_prompt.py +3 -3
  336. camel/terminators/__init__.py +2 -2
  337. camel/terminators/base.py +2 -2
  338. camel/terminators/response_terminator.py +2 -2
  339. camel/terminators/token_limit_terminator.py +2 -2
  340. camel/toolkits/__init__.py +57 -10
  341. camel/toolkits/aci_toolkit.py +66 -21
  342. camel/toolkits/arxiv_toolkit.py +8 -8
  343. camel/toolkits/ask_news_toolkit.py +2 -2
  344. camel/toolkits/async_browser_toolkit.py +4 -4
  345. camel/toolkits/audio_analysis_toolkit.py +3 -3
  346. camel/toolkits/base.py +106 -6
  347. camel/toolkits/bohrium_toolkit.py +2 -2
  348. camel/toolkits/browser_toolkit.py +34 -21
  349. camel/toolkits/browser_toolkit_commons.py +4 -4
  350. camel/toolkits/code_execution.py +31 -4
  351. camel/toolkits/context_summarizer_toolkit.py +684 -0
  352. camel/toolkits/craw4ai_toolkit.py +93 -0
  353. camel/toolkits/dappier_toolkit.py +12 -8
  354. camel/toolkits/data_commons_toolkit.py +2 -2
  355. camel/toolkits/dingtalk.py +1135 -0
  356. camel/toolkits/earth_science_toolkit.py +5367 -0
  357. camel/toolkits/edgeone_pages_mcp_toolkit.py +49 -0
  358. camel/toolkits/excel_toolkit.py +905 -71
  359. camel/toolkits/file_toolkit.py +1402 -0
  360. camel/toolkits/function_tool.py +205 -27
  361. camel/toolkits/github_toolkit.py +109 -22
  362. camel/toolkits/gmail_toolkit.py +1839 -0
  363. camel/toolkits/google_calendar_toolkit.py +40 -6
  364. camel/toolkits/google_drive_mcp_toolkit.py +54 -0
  365. camel/toolkits/google_maps_toolkit.py +2 -2
  366. camel/toolkits/google_scholar_toolkit.py +2 -2
  367. camel/toolkits/human_toolkit.py +36 -12
  368. camel/toolkits/hybrid_browser_toolkit/__init__.py +18 -0
  369. camel/toolkits/hybrid_browser_toolkit/config_loader.py +185 -0
  370. camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit.py +246 -0
  371. camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit_ts.py +1958 -0
  372. camel/toolkits/hybrid_browser_toolkit/installer.py +203 -0
  373. camel/toolkits/hybrid_browser_toolkit/ts/package-lock.json +4589 -0
  374. camel/toolkits/hybrid_browser_toolkit/ts/package.json +33 -0
  375. camel/toolkits/hybrid_browser_toolkit/ts/src/browser-scripts.js +125 -0
  376. camel/toolkits/hybrid_browser_toolkit/ts/src/browser-session.ts +1940 -0
  377. camel/toolkits/hybrid_browser_toolkit/ts/src/config-loader.ts +233 -0
  378. camel/toolkits/hybrid_browser_toolkit/ts/src/hybrid-browser-toolkit.ts +589 -0
  379. camel/toolkits/hybrid_browser_toolkit/ts/src/index.ts +7 -0
  380. camel/toolkits/hybrid_browser_toolkit/ts/src/parent-child-filter.ts +226 -0
  381. camel/toolkits/hybrid_browser_toolkit/ts/src/snapshot-parser.ts +219 -0
  382. camel/toolkits/hybrid_browser_toolkit/ts/src/som-screenshot-injected.ts +543 -0
  383. camel/toolkits/hybrid_browser_toolkit/ts/src/types.ts +129 -0
  384. camel/toolkits/hybrid_browser_toolkit/ts/tsconfig.json +27 -0
  385. camel/toolkits/hybrid_browser_toolkit/ts/websocket-server.js +325 -0
  386. camel/toolkits/hybrid_browser_toolkit/ws_wrapper.py +1037 -0
  387. camel/toolkits/hybrid_browser_toolkit_py/__init__.py +17 -0
  388. camel/toolkits/hybrid_browser_toolkit_py/actions.py +575 -0
  389. camel/toolkits/hybrid_browser_toolkit_py/agent.py +311 -0
  390. camel/toolkits/hybrid_browser_toolkit_py/browser_session.py +787 -0
  391. camel/toolkits/hybrid_browser_toolkit_py/config_loader.py +490 -0
  392. camel/toolkits/hybrid_browser_toolkit_py/hybrid_browser_toolkit.py +2390 -0
  393. camel/toolkits/hybrid_browser_toolkit_py/snapshot.py +233 -0
  394. camel/toolkits/hybrid_browser_toolkit_py/stealth_script.js +0 -0
  395. camel/toolkits/hybrid_browser_toolkit_py/unified_analyzer.js +1043 -0
  396. camel/toolkits/image_analysis_toolkit.py +3 -6
  397. camel/toolkits/image_generation_toolkit.py +390 -0
  398. camel/toolkits/jina_reranker_toolkit.py +5 -6
  399. camel/toolkits/klavis_toolkit.py +7 -3
  400. camel/toolkits/linkedin_toolkit.py +2 -2
  401. camel/toolkits/markitdown_toolkit.py +104 -0
  402. camel/toolkits/math_toolkit.py +66 -12
  403. camel/toolkits/mcp_toolkit.py +412 -36
  404. camel/toolkits/memory_toolkit.py +7 -3
  405. camel/toolkits/meshy_toolkit.py +2 -2
  406. camel/toolkits/message_agent_toolkit.py +608 -0
  407. camel/toolkits/message_integration.py +728 -0
  408. camel/toolkits/microsoft_outlook_mail_toolkit.py +1885 -0
  409. camel/toolkits/mineru_toolkit.py +2 -2
  410. camel/toolkits/minimax_mcp_toolkit.py +195 -0
  411. camel/toolkits/networkx_toolkit.py +2 -2
  412. camel/toolkits/note_taking_toolkit.py +277 -0
  413. camel/toolkits/notion_mcp_toolkit.py +224 -0
  414. camel/toolkits/notion_toolkit.py +2 -2
  415. camel/toolkits/open_api_specs/biztoc/__init__.py +2 -2
  416. camel/toolkits/open_api_specs/biztoc/ai-plugin.json +1 -1
  417. camel/toolkits/open_api_specs/coursera/__init__.py +2 -2
  418. camel/toolkits/open_api_specs/create_qr_code/__init__.py +2 -2
  419. camel/toolkits/open_api_specs/klarna/__init__.py +2 -2
  420. camel/toolkits/open_api_specs/nasa_apod/__init__.py +2 -2
  421. camel/toolkits/open_api_specs/outschool/__init__.py +2 -2
  422. camel/toolkits/open_api_specs/outschool/ai-plugin.json +1 -1
  423. camel/toolkits/open_api_specs/outschool/openapi.yaml +1 -1
  424. camel/toolkits/open_api_specs/outschool/paths/__init__.py +2 -2
  425. camel/toolkits/open_api_specs/outschool/paths/get_classes.py +2 -2
  426. camel/toolkits/open_api_specs/outschool/paths/search_teachers.py +2 -2
  427. camel/toolkits/open_api_specs/security_config.py +2 -2
  428. camel/toolkits/open_api_specs/speak/__init__.py +2 -2
  429. camel/toolkits/open_api_specs/web_scraper/__init__.py +2 -2
  430. camel/toolkits/open_api_specs/web_scraper/ai-plugin.json +1 -1
  431. camel/toolkits/open_api_specs/web_scraper/paths/__init__.py +2 -2
  432. camel/toolkits/open_api_specs/web_scraper/paths/scraper.py +2 -2
  433. camel/toolkits/open_api_toolkit.py +2 -2
  434. camel/toolkits/openbb_toolkit.py +7 -3
  435. camel/toolkits/origene_mcp_toolkit.py +56 -0
  436. camel/toolkits/page_script.js +53 -53
  437. camel/toolkits/playwright_mcp_toolkit.py +13 -31
  438. camel/toolkits/pptx_toolkit.py +36 -23
  439. camel/toolkits/pubmed_toolkit.py +2 -2
  440. camel/toolkits/pulse_mcp_search_toolkit.py +2 -2
  441. camel/toolkits/pyautogui_toolkit.py +2 -2
  442. camel/toolkits/reddit_toolkit.py +2 -2
  443. camel/toolkits/resend_toolkit.py +168 -0
  444. camel/toolkits/retrieval_toolkit.py +2 -2
  445. camel/toolkits/screenshot_toolkit.py +213 -0
  446. camel/toolkits/search_toolkit.py +606 -156
  447. camel/toolkits/searxng_toolkit.py +2 -2
  448. camel/toolkits/semantic_scholar_toolkit.py +2 -2
  449. camel/toolkits/slack_toolkit.py +108 -58
  450. camel/toolkits/sql_toolkit.py +712 -0
  451. camel/toolkits/stripe_toolkit.py +2 -2
  452. camel/toolkits/sympy_toolkit.py +3 -3
  453. camel/toolkits/task_planning_toolkit.py +5 -5
  454. camel/toolkits/terminal_toolkit/__init__.py +18 -0
  455. camel/toolkits/terminal_toolkit/terminal_toolkit.py +1281 -0
  456. camel/toolkits/terminal_toolkit/utils.py +659 -0
  457. camel/toolkits/thinking_toolkit.py +3 -3
  458. camel/toolkits/twitter_toolkit.py +2 -2
  459. camel/toolkits/vertex_ai_veo_toolkit.py +590 -0
  460. camel/toolkits/video_analysis_toolkit.py +109 -29
  461. camel/toolkits/video_download_toolkit.py +19 -16
  462. camel/toolkits/weather_toolkit.py +2 -2
  463. camel/toolkits/web_deploy_toolkit.py +1219 -0
  464. camel/toolkits/wechat_official_toolkit.py +483 -0
  465. camel/toolkits/whatsapp_toolkit.py +2 -2
  466. camel/toolkits/wolfram_alpha_toolkit.py +2 -2
  467. camel/toolkits/zapier_toolkit.py +7 -3
  468. camel/types/__init__.py +4 -4
  469. camel/types/agents/__init__.py +2 -2
  470. camel/types/agents/tool_calling_record.py +6 -3
  471. camel/types/enums.py +381 -41
  472. camel/types/mcp_registries.py +2 -2
  473. camel/types/openai_types.py +4 -4
  474. camel/types/unified_model_type.py +46 -10
  475. camel/utils/__init__.py +5 -2
  476. camel/utils/agent_context.py +41 -0
  477. camel/utils/async_func.py +2 -2
  478. camel/utils/chunker/__init__.py +2 -2
  479. camel/utils/chunker/base.py +2 -2
  480. camel/utils/chunker/code_chunker.py +2 -2
  481. camel/utils/chunker/uio_chunker.py +2 -2
  482. camel/utils/commons.py +38 -7
  483. camel/utils/constants.py +5 -2
  484. camel/utils/context_utils.py +1134 -0
  485. camel/utils/deduplication.py +2 -2
  486. camel/utils/filename.py +2 -2
  487. camel/utils/langfuse.py +18 -10
  488. camel/utils/mcp.py +140 -6
  489. camel/utils/mcp_client.py +48 -38
  490. camel/utils/message_summarizer.py +148 -0
  491. camel/utils/response_format.py +2 -2
  492. camel/utils/token_counting.py +45 -22
  493. camel/utils/tool_result.py +44 -0
  494. camel/verifiers/__init__.py +2 -2
  495. camel/verifiers/base.py +2 -2
  496. camel/verifiers/math_verifier.py +2 -2
  497. camel/verifiers/models.py +2 -2
  498. camel/verifiers/physics_verifier.py +2 -2
  499. camel/verifiers/python_verifier.py +2 -2
  500. {camel_ai-0.2.65.dist-info → camel_ai-0.2.83a6.dist-info}/METADATA +355 -117
  501. camel_ai-0.2.83a6.dist-info/RECORD +511 -0
  502. {camel_ai-0.2.65.dist-info → camel_ai-0.2.83a6.dist-info}/WHEEL +1 -1
  503. {camel_ai-0.2.65.dist-info → camel_ai-0.2.83a6.dist-info}/licenses/LICENSE +1 -1
  504. camel/loaders/pandas_reader.py +0 -368
  505. camel/toolkits/dalle_toolkit.py +0 -175
  506. camel/toolkits/file_write_toolkit.py +0 -444
  507. camel/toolkits/openai_agent_toolkit.py +0 -135
  508. camel/toolkits/terminal_toolkit.py +0 -1037
  509. camel_ai-0.2.65.dist-info/RECORD +0 -426
@@ -1,4 +1,4 @@
1
- # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
1
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
2
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
@@ -10,14 +10,23 @@
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-2024 @ CAMEL-AI.org. All Rights Reserved. =========
13
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
  import os
15
- from typing import Any, Dict, List, Optional, Type, Union
15
+ from typing import (
16
+ Any,
17
+ AsyncGenerator,
18
+ Dict,
19
+ Generator,
20
+ List,
21
+ Optional,
22
+ Type,
23
+ Union,
24
+ )
16
25
 
17
26
  from openai import AsyncStream, Stream
18
27
  from pydantic import BaseModel
19
28
 
20
- from camel.configs import Gemini_API_PARAMS, GeminiConfig
29
+ from camel.configs import GeminiConfig
21
30
  from camel.messages import OpenAIMessage
22
31
  from camel.models.openai_compatible_model import OpenAICompatibleModel
23
32
  from camel.types import (
@@ -28,8 +37,6 @@ from camel.types import (
28
37
  from camel.utils import (
29
38
  BaseTokenCounter,
30
39
  api_keys_required,
31
- get_current_agent_session_id,
32
- update_langfuse_trace,
33
40
  )
34
41
 
35
42
  if os.environ.get("LANGFUSE_ENABLED", "False").lower() == "true":
@@ -37,6 +44,11 @@ if os.environ.get("LANGFUSE_ENABLED", "False").lower() == "true":
37
44
  from langfuse.decorators import observe
38
45
  except ImportError:
39
46
  from camel.utils import observe
47
+ elif os.environ.get("TRACEROOT_ENABLED", "False").lower() == "true":
48
+ try:
49
+ from traceroot import trace as observe # type: ignore[import]
50
+ except ImportError:
51
+ from camel.utils import observe
40
52
  else:
41
53
  from camel.utils import observe
42
54
 
@@ -64,6 +76,10 @@ class GeminiModel(OpenAICompatibleModel):
64
76
  API calls. If not provided, will fall back to the MODEL_TIMEOUT
65
77
  environment variable or default to 180 seconds.
66
78
  (default: :obj:`None`)
79
+ max_retries (int, optional): Maximum number of retries for API calls.
80
+ (default: :obj:`3`)
81
+ **kwargs (Any): Additional arguments to pass to the client
82
+ initialization.
67
83
  """
68
84
 
69
85
  @api_keys_required(
@@ -79,6 +95,8 @@ class GeminiModel(OpenAICompatibleModel):
79
95
  url: Optional[str] = None,
80
96
  token_counter: Optional[BaseTokenCounter] = None,
81
97
  timeout: Optional[float] = None,
98
+ max_retries: int = 3,
99
+ **kwargs: Any,
82
100
  ) -> None:
83
101
  if model_config_dict is None:
84
102
  model_config_dict = GeminiConfig().as_dict()
@@ -95,20 +113,344 @@ class GeminiModel(OpenAICompatibleModel):
95
113
  url=url,
96
114
  token_counter=token_counter,
97
115
  timeout=timeout,
116
+ max_retries=max_retries,
117
+ **kwargs,
98
118
  )
99
119
 
100
120
  def _process_messages(self, messages) -> List[OpenAIMessage]:
101
121
  r"""Process the messages for Gemini API to ensure no empty content,
102
- which is not accepted by Gemini.
122
+ which is not accepted by Gemini. Also preserves thought signatures
123
+ required for Gemini 3 Pro function calling.
124
+
125
+ This method also merges consecutive assistant messages with single
126
+ tool calls into a single assistant message with multiple tool calls,
127
+ as required by Gemini's OpenAI-compatible API for parallel function
128
+ calling.
103
129
  """
104
- processed_messages = []
105
- for msg in messages:
106
- msg_copy = msg.copy()
130
+ import copy
131
+
132
+ processed_messages: List[OpenAIMessage] = []
133
+ i = 0
134
+ n = len(messages)
135
+
136
+ while i < n:
137
+ msg = messages[i]
138
+
139
+ # Check if this is an assistant message with a single tool_call
140
+ # that might need to be merged with subsequent ones
141
+ if (
142
+ msg.get('role') == 'assistant'
143
+ and 'tool_calls' in msg
144
+ and isinstance(msg['tool_calls'], list)
145
+ and len(msg['tool_calls']) == 1
146
+ ):
147
+ # Look ahead to check if there are more assistant messages
148
+ # with single tool calls (interleaved with their tool results)
149
+ j = i + 1
150
+ has_more_tool_calls = False
151
+
152
+ # Collect tool_call_ids we've seen so far
153
+ first_tool_call_id = msg['tool_calls'][0].get('id')
154
+ seen_tool_call_ids = (
155
+ {first_tool_call_id} if first_tool_call_id else set()
156
+ )
157
+
158
+ # Scan ahead to find pattern: tool_result, assistant,
159
+ # tool_result, ...
160
+ while j < n:
161
+ next_msg = messages[j]
162
+ next_role = next_msg.get('role')
163
+
164
+ if next_role == 'tool':
165
+ # Tool result - check if it belongs to our batch
166
+ if next_msg.get('tool_call_id') in seen_tool_call_ids:
167
+ j += 1
168
+ continue
169
+ else:
170
+ # Tool result for unknown call, stop scanning
171
+ break
172
+ elif (
173
+ next_role == 'assistant'
174
+ and 'tool_calls' in next_msg
175
+ and isinstance(next_msg['tool_calls'], list)
176
+ and len(next_msg['tool_calls']) == 1
177
+ ):
178
+ # Another single tool call - mark for merging
179
+ has_more_tool_calls = True
180
+ tc_id = next_msg['tool_calls'][0].get('id')
181
+ if tc_id:
182
+ seen_tool_call_ids.add(tc_id)
183
+ j += 1
184
+ continue
185
+ else:
186
+ # Something else, stop scanning
187
+ break
188
+
189
+ if has_more_tool_calls:
190
+ # Need to merge: collect all tool calls and results
191
+ merged_tool_calls = []
192
+ tool_results = []
193
+ is_first = True
194
+
195
+ for k in range(i, j):
196
+ m = messages[k]
197
+ if m.get('role') == 'assistant' and 'tool_calls' in m:
198
+ tc = m['tool_calls'][0]
199
+ if is_first:
200
+ # Keep extra_content only on first tool call
201
+ merged_tool_calls.append(copy.deepcopy(tc))
202
+ is_first = False
203
+ else:
204
+ # Remove extra_content from subsequent tool
205
+ # calls
206
+ tc_copy = {
207
+ k: v
208
+ for k, v in tc.items()
209
+ if k != 'extra_content'
210
+ }
211
+ merged_tool_calls.append(tc_copy)
212
+ elif m.get('role') == 'tool':
213
+ tool_results.append(copy.deepcopy(m))
214
+
215
+ # Build merged assistant message
216
+ merged_msg = copy.deepcopy(msg)
217
+ merged_msg['tool_calls'] = merged_tool_calls
218
+ if 'content' in merged_msg and merged_msg['content'] == '':
219
+ merged_msg['content'] = 'null'
220
+
221
+ processed_messages.append(merged_msg)
222
+ processed_messages.extend(tool_results)
223
+ i = j
224
+ continue
225
+
226
+ # Regular message processing (no merging needed)
227
+ msg_copy = copy.deepcopy(msg)
107
228
  if 'content' in msg_copy and msg_copy['content'] == '':
108
229
  msg_copy['content'] = 'null'
109
230
  processed_messages.append(msg_copy)
231
+ i += 1
232
+
110
233
  return processed_messages
111
234
 
235
+ def _preserve_thought_signatures(
236
+ self,
237
+ response: Union[
238
+ ChatCompletion,
239
+ Stream[ChatCompletionChunk],
240
+ AsyncStream[ChatCompletionChunk],
241
+ ],
242
+ ) -> Union[
243
+ ChatCompletion,
244
+ Generator[ChatCompletionChunk, None, None],
245
+ AsyncGenerator[ChatCompletionChunk, None],
246
+ ]:
247
+ r"""Preserve thought signatures from Gemini responses for future
248
+ requests.
249
+
250
+ According to the Gemini documentation, when a response contains tool
251
+ calls with thought signatures, these signatures must be preserved
252
+ exactly as received when the response is added to conversation history
253
+ for subsequent requests.
254
+
255
+ Args:
256
+ response: The response from Gemini API
257
+
258
+ Returns:
259
+ The response with thought signatures properly preserved.
260
+ For streaming responses, returns generators that preserve
261
+ signatures.
262
+ """
263
+ # For streaming responses, we need to wrap the stream to preserve
264
+ # thought signatures in tool calls as they come in
265
+ if isinstance(response, Stream):
266
+ return self._wrap_stream_with_thought_preservation(response)
267
+ elif isinstance(response, AsyncStream):
268
+ return self._wrap_async_stream_with_thought_preservation(response)
269
+
270
+ # For non-streaming responses, thought signatures are already preserved
271
+ # in _process_messages when the response becomes part of conversation
272
+ # history
273
+ return response
274
+
275
+ def _wrap_stream_with_thought_preservation(
276
+ self, stream: Stream[ChatCompletionChunk]
277
+ ) -> Generator[ChatCompletionChunk, None, None]:
278
+ r"""Wrap a streaming response to preserve thought signatures in tool
279
+ calls.
280
+
281
+ This method ensures that when Gemini streaming responses contain tool
282
+ calls with thought signatures, these are properly preserved in the
283
+ extra_content field for future conversation context.
284
+
285
+ Args:
286
+ stream: The original streaming response from Gemini
287
+
288
+ Returns:
289
+ A wrapped stream that preserves thought signatures
290
+ """
291
+
292
+ def thought_preserving_generator():
293
+ accumulated_signatures = {} # Store signatures by tool call index
294
+
295
+ for chunk in stream:
296
+ # Process chunk normally first
297
+ processed_chunk = chunk
298
+
299
+ # Check if this chunk contains tool call deltas with thought
300
+ # signatures
301
+ if (
302
+ hasattr(chunk, 'choices')
303
+ and chunk.choices
304
+ and hasattr(chunk.choices[0], 'delta')
305
+ and hasattr(chunk.choices[0].delta, 'tool_calls')
306
+ ):
307
+ delta_tool_calls = chunk.choices[0].delta.tool_calls
308
+ if delta_tool_calls:
309
+ for tool_call_delta in delta_tool_calls:
310
+ index = tool_call_delta.index
311
+
312
+ # Check for thought signatures in the tool call
313
+ # response Gemini may include these in custom
314
+ # fields
315
+ if hasattr(tool_call_delta, 'extra_content'):
316
+ extra_content = tool_call_delta.extra_content
317
+ if (
318
+ isinstance(extra_content, dict)
319
+ and 'google' in extra_content
320
+ ):
321
+ google_content = extra_content['google']
322
+ if 'thought_signature' in google_content:
323
+ # Store the thought signature for this
324
+ # tool call
325
+ accumulated_signatures[index] = (
326
+ extra_content
327
+ )
328
+
329
+ # Also check if thought signature is in function
330
+ # response
331
+ elif hasattr(
332
+ tool_call_delta, 'function'
333
+ ) and hasattr(
334
+ tool_call_delta.function, 'extra_content'
335
+ ):
336
+ func_extra = (
337
+ tool_call_delta.function.extra_content
338
+ )
339
+ if (
340
+ isinstance(func_extra, dict)
341
+ and 'google' in func_extra
342
+ ):
343
+ accumulated_signatures[index] = func_extra
344
+
345
+ # If we have accumulated signature for this tool
346
+ # call, ensure it's preserved in the chunk
347
+ if index in accumulated_signatures:
348
+ # Add extra_content to tool call delta if it
349
+ # doesn't exist
350
+ if not hasattr(
351
+ tool_call_delta, 'extra_content'
352
+ ):
353
+ tool_call_delta.extra_content = (
354
+ accumulated_signatures[index]
355
+ )
356
+ elif tool_call_delta.extra_content is None:
357
+ tool_call_delta.extra_content = (
358
+ accumulated_signatures[index]
359
+ )
360
+
361
+ yield processed_chunk
362
+
363
+ return thought_preserving_generator()
364
+
365
+ def _wrap_async_stream_with_thought_preservation(
366
+ self, stream: AsyncStream[ChatCompletionChunk]
367
+ ) -> AsyncGenerator[ChatCompletionChunk, None]:
368
+ r"""Wrap an async streaming response to preserve thought signatures in
369
+ tool calls.
370
+
371
+ This method ensures that when Gemini async streaming responses contain
372
+ tool calls with thought signatures, these are properly preserved in
373
+ the extra_content field for future conversation context.
374
+
375
+ Args:
376
+ stream: The original async streaming response from Gemini
377
+
378
+ Returns:
379
+ A wrapped async stream that preserves thought signatures
380
+ """
381
+
382
+ async def async_thought_preserving_generator():
383
+ accumulated_signatures = {} # Store signatures by tool call index
384
+
385
+ async for chunk in stream:
386
+ # Process chunk normally first
387
+ processed_chunk = chunk
388
+
389
+ # Check if this chunk contains tool call deltas with thought
390
+ # signatures
391
+ if (
392
+ hasattr(chunk, 'choices')
393
+ and chunk.choices
394
+ and hasattr(chunk.choices[0], 'delta')
395
+ and hasattr(chunk.choices[0].delta, 'tool_calls')
396
+ ):
397
+ delta_tool_calls = chunk.choices[0].delta.tool_calls
398
+ if delta_tool_calls:
399
+ for tool_call_delta in delta_tool_calls:
400
+ index = tool_call_delta.index
401
+
402
+ # Check for thought signatures in the tool call
403
+ # response
404
+ if hasattr(tool_call_delta, 'extra_content'):
405
+ extra_content = tool_call_delta.extra_content
406
+ if (
407
+ isinstance(extra_content, dict)
408
+ and 'google' in extra_content
409
+ ):
410
+ google_content = extra_content['google']
411
+ if 'thought_signature' in google_content:
412
+ # Store the thought signature for this
413
+ # tool call
414
+ accumulated_signatures[index] = (
415
+ extra_content
416
+ )
417
+
418
+ # Also check if thought signature is in function
419
+ # response
420
+ elif hasattr(
421
+ tool_call_delta, 'function'
422
+ ) and hasattr(
423
+ tool_call_delta.function, 'extra_content'
424
+ ):
425
+ func_extra = (
426
+ tool_call_delta.function.extra_content
427
+ )
428
+ if (
429
+ isinstance(func_extra, dict)
430
+ and 'google' in func_extra
431
+ ):
432
+ accumulated_signatures[index] = func_extra
433
+
434
+ # If we have accumulated signature for this tool
435
+ # call, ensure it's preserved in the chunk
436
+ if index in accumulated_signatures:
437
+ # Add extra_content to tool call delta if it
438
+ # doesn't exist
439
+ if not hasattr(
440
+ tool_call_delta, 'extra_content'
441
+ ):
442
+ tool_call_delta.extra_content = (
443
+ accumulated_signatures[index]
444
+ )
445
+ elif tool_call_delta.extra_content is None:
446
+ tool_call_delta.extra_content = (
447
+ accumulated_signatures[index]
448
+ )
449
+
450
+ yield processed_chunk
451
+
452
+ return async_thought_preserving_generator()
453
+
112
454
  @observe()
113
455
  def _run(
114
456
  self,
@@ -131,18 +473,7 @@ class GeminiModel(OpenAICompatibleModel):
131
473
  `ChatCompletion` in the non-stream mode, or
132
474
  `Stream[ChatCompletionChunk]` in the stream mode.
133
475
  """
134
-
135
- # Update Langfuse trace with current agent session and metadata
136
- agent_session_id = get_current_agent_session_id()
137
- if agent_session_id:
138
- update_langfuse_trace(
139
- session_id=agent_session_id,
140
- metadata={
141
- "agent_id": agent_session_id,
142
- "model_type": str(self.model_type),
143
- },
144
- tags=["CAMEL-AI", str(self.model_type)],
145
- )
476
+ self._log_and_trace()
146
477
 
147
478
  response_format = response_format or self.model_config_dict.get(
148
479
  "response_format", None
@@ -184,18 +515,7 @@ class GeminiModel(OpenAICompatibleModel):
184
515
  `ChatCompletion` in the non-stream mode, or
185
516
  `AsyncStream[ChatCompletionChunk]` in the stream mode.
186
517
  """
187
-
188
- # Update Langfuse trace with current agent session and metadata
189
- agent_session_id = get_current_agent_session_id()
190
- if agent_session_id:
191
- update_langfuse_trace(
192
- session_id=agent_session_id,
193
- metadata={
194
- "agent_id": agent_session_id,
195
- "model_type": str(self.model_type),
196
- },
197
- tags=["CAMEL-AI", str(self.model_type)],
198
- )
518
+ self._log_and_trace()
199
519
 
200
520
  response_format = response_format or self.model_config_dict.get(
201
521
  "response_format", None
@@ -230,7 +550,7 @@ class GeminiModel(OpenAICompatibleModel):
230
550
  function_dict = tool.get('function', {})
231
551
  function_dict.pop("strict", None)
232
552
 
233
- # Process parameters to remove anyOf
553
+ # Process parameters to remove anyOf and handle enum/format
234
554
  if 'parameters' in function_dict:
235
555
  params = function_dict['parameters']
236
556
  if 'properties' in params:
@@ -247,14 +567,31 @@ class GeminiModel(OpenAICompatibleModel):
247
567
  'description'
248
568
  ] = prop_value['description']
249
569
 
570
+ # Handle enum and format restrictions for Gemini
571
+ # API enum: only allowed for string type
572
+ if prop_value.get('type') != 'string':
573
+ prop_value.pop('enum', None)
574
+
575
+ # format: only allowed for string, integer, and
576
+ # number types
577
+ if prop_value.get('type') not in [
578
+ 'string',
579
+ 'integer',
580
+ 'number',
581
+ ]:
582
+ prop_value.pop('format', None)
583
+
250
584
  request_config["tools"] = tools
251
585
 
252
- return self._client.chat.completions.create(
586
+ response = self._client.chat.completions.create(
253
587
  messages=messages,
254
588
  model=self.model_type,
255
589
  **request_config,
256
590
  )
257
591
 
592
+ # Preserve thought signatures from the response for future requests
593
+ return self._preserve_thought_signatures(response) # type: ignore[return-value]
594
+
258
595
  async def _arequest_chat_completion(
259
596
  self,
260
597
  messages: List[OpenAIMessage],
@@ -270,7 +607,7 @@ class GeminiModel(OpenAICompatibleModel):
270
607
  function_dict = tool.get('function', {})
271
608
  function_dict.pop("strict", None)
272
609
 
273
- # Process parameters to remove anyOf
610
+ # Process parameters to remove anyOf and handle enum/format
274
611
  if 'parameters' in function_dict:
275
612
  params = function_dict['parameters']
276
613
  if 'properties' in params:
@@ -287,25 +624,27 @@ class GeminiModel(OpenAICompatibleModel):
287
624
  'description'
288
625
  ] = prop_value['description']
289
626
 
627
+ # Handle enum and format restrictions for Gemini
628
+ # API enum: only allowed for string type
629
+ if prop_value.get('type') != 'string':
630
+ prop_value.pop('enum', None)
631
+
632
+ # format: only allowed for string, integer, and
633
+ # number types
634
+ if prop_value.get('type') not in [
635
+ 'string',
636
+ 'integer',
637
+ 'number',
638
+ ]:
639
+ prop_value.pop('format', None)
640
+
290
641
  request_config["tools"] = tools
291
642
 
292
- return await self._async_client.chat.completions.create(
643
+ response = await self._async_client.chat.completions.create(
293
644
  messages=messages,
294
645
  model=self.model_type,
295
646
  **request_config,
296
647
  )
297
648
 
298
- def check_model_config(self):
299
- r"""Check whether the model configuration contains any
300
- unexpected arguments to Gemini API.
301
-
302
- Raises:
303
- ValueError: If the model configuration dictionary contains any
304
- unexpected arguments to Gemini API.
305
- """
306
- for param in self.model_config_dict:
307
- if param not in Gemini_API_PARAMS:
308
- raise ValueError(
309
- f"Unexpected argument `{param}` is "
310
- "input into Gemini model backend."
311
- )
649
+ # Preserve thought signatures from the response for future requests
650
+ return self._preserve_thought_signatures(response) # type: ignore[return-value]
@@ -1,4 +1,4 @@
1
- # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
1
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
2
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
@@ -10,11 +10,11 @@
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-2024 @ CAMEL-AI.org. All Rights Reserved. =========
13
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
  import os
15
15
  from typing import Any, Dict, Optional, Union
16
16
 
17
- from camel.configs import GROQ_API_PARAMS, GroqConfig
17
+ from camel.configs import GroqConfig
18
18
  from camel.models.openai_compatible_model import OpenAICompatibleModel
19
19
  from camel.types import ModelType
20
20
  from camel.utils import (
@@ -45,6 +45,10 @@ class GroqModel(OpenAICompatibleModel):
45
45
  API calls. If not provided, will fall back to the MODEL_TIMEOUT
46
46
  environment variable or default to 180 seconds.
47
47
  (default: :obj:`None`)
48
+ max_retries (int, optional): Maximum number of retries for API calls.
49
+ (default: :obj:`3`)
50
+ **kwargs (Any): Additional arguments to pass to the client
51
+ initialization.
48
52
  """
49
53
 
50
54
  @api_keys_required([("api_key", "GROQ_API_KEY")])
@@ -56,6 +60,8 @@ class GroqModel(OpenAICompatibleModel):
56
60
  url: Optional[str] = None,
57
61
  token_counter: Optional[BaseTokenCounter] = None,
58
62
  timeout: Optional[float] = None,
63
+ max_retries: int = 3,
64
+ **kwargs: Any,
59
65
  ) -> None:
60
66
  if model_config_dict is None:
61
67
  model_config_dict = GroqConfig().as_dict()
@@ -71,20 +77,6 @@ class GroqModel(OpenAICompatibleModel):
71
77
  url=url,
72
78
  token_counter=token_counter,
73
79
  timeout=timeout,
80
+ max_retries=max_retries,
81
+ **kwargs,
74
82
  )
75
-
76
- def check_model_config(self):
77
- r"""Check whether the model configuration contains any unexpected
78
- arguments to Groq API. But Groq API does not have any additional
79
- arguments to check.
80
-
81
- Raises:
82
- ValueError: If the model configuration dictionary contains any
83
- unexpected arguments to Groq API.
84
- """
85
- for param in self.model_config_dict:
86
- if param not in GROQ_API_PARAMS:
87
- raise ValueError(
88
- f"Unexpected argument `{param}` is "
89
- "input into Groq model backend."
90
- )
@@ -1,4 +1,4 @@
1
- # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
1
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
2
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
@@ -10,7 +10,7 @@
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-2024 @ CAMEL-AI.org. All Rights Reserved. =========
13
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
 
15
15
  import os
16
16
  from typing import Any, Dict, List, Optional, Type, Union
@@ -18,7 +18,7 @@ from typing import Any, Dict, List, Optional, Type, Union
18
18
  from openai import AsyncStream
19
19
  from pydantic import BaseModel
20
20
 
21
- from camel.configs import INTERNLM_API_PARAMS, InternLMConfig
21
+ from camel.configs import InternLMConfig
22
22
  from camel.messages import OpenAIMessage
23
23
  from camel.models.openai_compatible_model import OpenAICompatibleModel
24
24
  from camel.types import (
@@ -54,6 +54,10 @@ class InternLMModel(OpenAICompatibleModel):
54
54
  API calls. If not provided, will fall back to the MODEL_TIMEOUT
55
55
  environment variable or default to 180 seconds.
56
56
  (default: :obj:`None`)
57
+ max_retries (int, optional): Maximum number of retries for API calls.
58
+ (default: :obj:`3`)
59
+ **kwargs (Any): Additional arguments to pass to the client
60
+ initialization.
57
61
  """
58
62
 
59
63
  @api_keys_required(
@@ -69,6 +73,8 @@ class InternLMModel(OpenAICompatibleModel):
69
73
  url: Optional[str] = None,
70
74
  token_counter: Optional[BaseTokenCounter] = None,
71
75
  timeout: Optional[float] = None,
76
+ max_retries: int = 3,
77
+ **kwargs: Any,
72
78
  ) -> None:
73
79
  self.model_config = model_config_dict or InternLMConfig().as_dict()
74
80
  api_key = api_key or os.environ.get("INTERNLM_API_KEY")
@@ -84,6 +90,8 @@ class InternLMModel(OpenAICompatibleModel):
84
90
  url=url,
85
91
  token_counter=token_counter,
86
92
  timeout=timeout,
93
+ max_retries=max_retries,
94
+ **kwargs,
87
95
  )
88
96
 
89
97
  async def _arun(
@@ -93,18 +101,3 @@ class InternLMModel(OpenAICompatibleModel):
93
101
  tools: Optional[List[Dict[str, Any]]] = None,
94
102
  ) -> Union[ChatCompletion, AsyncStream[ChatCompletionChunk]]:
95
103
  raise NotImplementedError("InternLM does not support async inference.")
96
-
97
- def check_model_config(self):
98
- r"""Check whether the model configuration contains any
99
- unexpected arguments to InternLM API.
100
-
101
- Raises:
102
- ValueError: If the model configuration dictionary contains any
103
- unexpected arguments to InternLM API.
104
- """
105
- for param in self.model_config_dict:
106
- if param not in INTERNLM_API_PARAMS:
107
- raise ValueError(
108
- f"Unexpected argument `{param}` is "
109
- "input into InternLM model backend."
110
- )