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,15 +10,31 @@
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 abc
15
+ import inspect
16
+ import os
15
17
  import re
16
18
  from abc import ABC, abstractmethod
17
- from typing import Any, Dict, List, Optional, Type, Union
19
+ from typing import (
20
+ Any,
21
+ AsyncGenerator,
22
+ Dict,
23
+ Generator,
24
+ List,
25
+ Optional,
26
+ Type,
27
+ Union,
28
+ )
18
29
 
19
30
  from openai import AsyncStream, Stream
31
+ from openai.lib.streaming.chat import (
32
+ AsyncChatCompletionStreamManager,
33
+ ChatCompletionStreamManager,
34
+ )
20
35
  from pydantic import BaseModel
21
36
 
37
+ from camel.logger import get_logger as camel_get_logger
22
38
  from camel.messages import OpenAIMessage
23
39
  from camel.types import (
24
40
  ChatCompletion,
@@ -27,7 +43,153 @@ from camel.types import (
27
43
  ParsedChatCompletion,
28
44
  UnifiedModelType,
29
45
  )
30
- from camel.utils import BaseTokenCounter
46
+ from camel.utils import (
47
+ BaseTokenCounter,
48
+ Constants,
49
+ get_current_agent_session_id,
50
+ update_langfuse_trace,
51
+ )
52
+
53
+ if os.environ.get("TRACEROOT_ENABLED", "False").lower() == "true":
54
+ try:
55
+ from traceroot import get_logger # type: ignore[import]
56
+ from traceroot import trace as observe # type: ignore[import]
57
+
58
+ logger = get_logger('base_model')
59
+ except ImportError:
60
+ from camel.utils import observe
61
+
62
+ logger = camel_get_logger('base_model')
63
+ else:
64
+ from camel.utils import observe
65
+
66
+ logger = camel_get_logger('base_model')
67
+
68
+
69
+ class _StreamLogger:
70
+ r"""Base for stream logging wrappers."""
71
+
72
+ def __init__(self, log_path: Optional[str], log_enabled: bool):
73
+ self._log_path = log_path
74
+ self._log_enabled = log_enabled
75
+ self._id = self._model = self._content = ""
76
+ self._finish_reason: Optional[str] = None
77
+ self._usage: Optional[Dict[str, Any]] = None
78
+ self._logged = False
79
+
80
+ def _collect(self, chunk: ChatCompletionChunk) -> None:
81
+ self._id = self._id or getattr(chunk, 'id', '')
82
+ self._model = self._model or getattr(chunk, 'model', '')
83
+ if chunk.usage:
84
+ u = chunk.usage
85
+ self._usage = (
86
+ u.model_dump() if hasattr(u, 'model_dump') else u.dict()
87
+ )
88
+ if chunk.choices:
89
+ choice = chunk.choices[0]
90
+ if choice.delta and choice.delta.content:
91
+ self._content += choice.delta.content
92
+ if choice.finish_reason:
93
+ self._finish_reason = choice.finish_reason
94
+
95
+ def _log(self) -> None:
96
+ if self._logged or not self._log_enabled or not self._log_path:
97
+ return
98
+ self._logged = True
99
+ import json
100
+ from datetime import datetime
101
+
102
+ try:
103
+ with open(self._log_path, "r+") as f:
104
+ data = json.load(f)
105
+ data["response_timestamp"] = datetime.now().isoformat()
106
+ data["response"] = {
107
+ "id": self._id,
108
+ "model": self._model,
109
+ "content": self._content,
110
+ "finish_reason": self._finish_reason,
111
+ "usage": self._usage,
112
+ "streaming": True,
113
+ }
114
+ f.seek(0)
115
+ json.dump(data, f, indent=4)
116
+ f.truncate()
117
+ except Exception:
118
+ pass
119
+
120
+
121
+ class _SyncStreamWrapper(_StreamLogger):
122
+ r"""Sync stream wrapper with logging."""
123
+
124
+ def __init__(
125
+ self,
126
+ stream: Union[
127
+ Stream[ChatCompletionChunk],
128
+ Generator[ChatCompletionChunk, None, None],
129
+ ],
130
+ log_path: Optional[str],
131
+ log_enabled: bool,
132
+ ):
133
+ super().__init__(log_path, log_enabled)
134
+ self._stream = stream
135
+
136
+ def __iter__(self):
137
+ return self
138
+
139
+ def __next__(self) -> ChatCompletionChunk:
140
+ try:
141
+ chunk = next(self._stream)
142
+ self._collect(chunk)
143
+ return chunk
144
+ except StopIteration:
145
+ self._log()
146
+ raise
147
+
148
+ def __enter__(self):
149
+ return self
150
+
151
+ def __exit__(self, *_):
152
+ return False
153
+
154
+ def __del__(self):
155
+ self._log()
156
+
157
+
158
+ class _AsyncStreamWrapper(_StreamLogger):
159
+ r"""Async stream wrapper with logging."""
160
+
161
+ def __init__(
162
+ self,
163
+ stream: Union[
164
+ AsyncStream[ChatCompletionChunk],
165
+ AsyncGenerator[ChatCompletionChunk, None],
166
+ ],
167
+ log_path: Optional[str],
168
+ log_enabled: bool,
169
+ ):
170
+ super().__init__(log_path, log_enabled)
171
+ self._stream = stream
172
+
173
+ def __aiter__(self):
174
+ return self
175
+
176
+ async def __anext__(self) -> ChatCompletionChunk:
177
+ try:
178
+ chunk = await self._stream.__anext__()
179
+ self._collect(chunk)
180
+ return chunk
181
+ except StopAsyncIteration:
182
+ self._log()
183
+ raise
184
+
185
+ async def __aenter__(self):
186
+ return self
187
+
188
+ async def __aexit__(self, *_):
189
+ return False
190
+
191
+ def __del__(self):
192
+ self._log()
31
193
 
32
194
 
33
195
  class ModelBackendMeta(abc.ABCMeta):
@@ -71,6 +233,8 @@ class BaseModelBackend(ABC, metaclass=ModelBackendMeta):
71
233
  :obj:`OpenAITokenCounter` will be used. (default: :obj:`None`)
72
234
  timeout (Optional[float], optional): The timeout value in seconds for
73
235
  API calls. (default: :obj:`None`)
236
+ max_retries (int, optional): Maximum number of retries
237
+ for API calls. (default: :obj:`3`)
74
238
  """
75
239
 
76
240
  def __init__(
@@ -80,7 +244,8 @@ class BaseModelBackend(ABC, metaclass=ModelBackendMeta):
80
244
  api_key: Optional[str] = None,
81
245
  url: Optional[str] = None,
82
246
  token_counter: Optional[BaseTokenCounter] = None,
83
- timeout: Optional[float] = None,
247
+ timeout: Optional[float] = Constants.TIMEOUT_THRESHOLD,
248
+ max_retries: int = 3,
84
249
  ) -> None:
85
250
  self.model_type: UnifiedModelType = UnifiedModelType(model_type)
86
251
  if model_config_dict is None:
@@ -90,7 +255,13 @@ class BaseModelBackend(ABC, metaclass=ModelBackendMeta):
90
255
  self._url = url
91
256
  self._token_counter = token_counter
92
257
  self._timeout = timeout
93
- self.check_model_config()
258
+ self._max_retries = max_retries
259
+ # Initialize logging configuration
260
+ self._log_enabled = (
261
+ os.environ.get("CAMEL_MODEL_LOG_ENABLED", "False").lower()
262
+ == "true"
263
+ )
264
+ self._log_dir = os.environ.get("CAMEL_LOG_DIR", "camel_logs")
94
265
 
95
266
  @property
96
267
  @abstractmethod
@@ -228,13 +399,130 @@ class BaseModelBackend(ABC, metaclass=ModelBackendMeta):
228
399
 
229
400
  return formatted_messages
230
401
 
402
+ def _log_request(self, messages: List[OpenAIMessage]) -> Optional[str]:
403
+ r"""Log the request messages to a JSON file if logging is enabled.
404
+
405
+ Args:
406
+ messages (List[OpenAIMessage]): The messages to log.
407
+
408
+ Returns:
409
+ Optional[str]: The path to the log file if logging is enabled,
410
+ None otherwise.
411
+ """
412
+ if not self._log_enabled:
413
+ return None
414
+
415
+ import json
416
+ from datetime import datetime
417
+
418
+ from camel.utils.agent_context import get_current_agent_id
419
+
420
+ agent_id = get_current_agent_id()
421
+
422
+ # Remove _context_summarizer suffix to keep all logs in one directory
423
+ log_agent_id = agent_id
424
+ if agent_id and agent_id.endswith("_context_summarizer"):
425
+ log_agent_id = agent_id[: -len("_context_summarizer")]
426
+
427
+ log_subdir = (
428
+ os.path.join(self._log_dir, log_agent_id)
429
+ if log_agent_id
430
+ else self._log_dir
431
+ )
432
+ os.makedirs(log_subdir, exist_ok=True)
433
+
434
+ timestamp = datetime.now().strftime('%Y%m%d_%H%M%S_%f')
435
+ log_file_path = os.path.join(log_subdir, f"conv_{timestamp}.json")
436
+
437
+ log_entry = {
438
+ "request_timestamp": datetime.now().isoformat(),
439
+ "model": str(self.model_type),
440
+ "agent_id": agent_id,
441
+ "request": {"messages": messages},
442
+ }
443
+
444
+ with open(log_file_path, "w") as f:
445
+ json.dump(log_entry, f, indent=4)
446
+
447
+ return log_file_path
448
+
449
+ def _log_response(self, log_path: str, response: Any) -> None:
450
+ r"""Log the response to the existing log file.
451
+
452
+ Args:
453
+ log_path (str): The path to the log file.
454
+ response (Any): The response to log.
455
+ """
456
+ if not self._log_enabled or not log_path:
457
+ return
458
+
459
+ import json
460
+ from datetime import datetime
461
+
462
+ with open(log_path, "r+") as f:
463
+ log_data = json.load(f)
464
+
465
+ log_data["response_timestamp"] = datetime.now().isoformat()
466
+ if isinstance(response, BaseModel):
467
+ log_data["response"] = response.model_dump()
468
+ else:
469
+ try:
470
+ json.dumps(response)
471
+ log_data["response"] = response
472
+ except TypeError:
473
+ log_data["response"] = str(response)
474
+
475
+ f.seek(0)
476
+ json.dump(log_data, f, indent=4)
477
+ f.truncate()
478
+
479
+ def _log_and_trace(self) -> None:
480
+ r"""Update Langfuse trace with session metadata.
481
+
482
+ This method updates the current Langfuse trace with agent session
483
+ information and model metadata. Called at the start of _run() and
484
+ _arun() methods before API execution.
485
+ """
486
+ agent_session_id = get_current_agent_session_id()
487
+ update_langfuse_trace(
488
+ session_id=agent_session_id,
489
+ metadata={
490
+ "source": "camel",
491
+ "agent_id": agent_session_id,
492
+ "agent_type": "camel_chat_agent",
493
+ "model_type": str(self.model_type),
494
+ },
495
+ tags=["CAMEL-AI", str(self.model_type)],
496
+ )
497
+
231
498
  @abstractmethod
232
499
  def _run(
233
500
  self,
234
501
  messages: List[OpenAIMessage],
235
502
  response_format: Optional[Type[BaseModel]] = None,
236
503
  tools: Optional[List[Dict[str, Any]]] = None,
237
- ) -> Union[ChatCompletion, Stream[ChatCompletionChunk]]:
504
+ ) -> Union[
505
+ ChatCompletion,
506
+ Stream[ChatCompletionChunk],
507
+ ChatCompletionStreamManager[BaseModel],
508
+ ]:
509
+ r"""Runs the query to the backend model in a non-stream mode.
510
+
511
+ Args:
512
+ messages (List[OpenAIMessage]): Message list with the chat history
513
+ in OpenAI API format.
514
+ response_format (Optional[Type[BaseModel]]): The format of the
515
+ response.
516
+ tools (Optional[List[Dict[str, Any]]]): The schema of the tools to
517
+ use for the request.
518
+
519
+ Returns:
520
+ Union[ChatCompletion, Stream[ChatCompletionChunk], Any]:
521
+ `ChatCompletion` in the non-stream mode, or
522
+ `Stream[ChatCompletionChunk]` in the stream mode,
523
+ or `ChatCompletionStreamManager[BaseModel]` in the structured
524
+ stream mode.
525
+ """
238
526
  pass
239
527
 
240
528
  @abstractmethod
@@ -243,15 +531,41 @@ class BaseModelBackend(ABC, metaclass=ModelBackendMeta):
243
531
  messages: List[OpenAIMessage],
244
532
  response_format: Optional[Type[BaseModel]] = None,
245
533
  tools: Optional[List[Dict[str, Any]]] = None,
246
- ) -> Union[ChatCompletion, AsyncStream[ChatCompletionChunk]]:
534
+ ) -> Union[
535
+ ChatCompletion,
536
+ AsyncStream[ChatCompletionChunk],
537
+ AsyncChatCompletionStreamManager[BaseModel],
538
+ ]:
539
+ r"""Runs the query to the backend model in async non-stream mode.
540
+
541
+ Args:
542
+ messages (List[OpenAIMessage]): Message list with the chat history
543
+ in OpenAI API format.
544
+ response_format (Optional[Type[BaseModel]]): The format of the
545
+ response.
546
+ tools (Optional[List[Dict[str, Any]]]): The schema of the tools to
547
+ use for the request.
548
+
549
+ Returns:
550
+ Union[ChatCompletion, AsyncStream[ChatCompletionChunk], Any]:
551
+ `ChatCompletion` in the non-stream mode, or
552
+ `AsyncStream[ChatCompletionChunk]` in the stream mode,
553
+ or `AsyncChatCompletionStreamManager[BaseModel]` in the
554
+ structured stream mode.
555
+ """
247
556
  pass
248
557
 
558
+ @observe()
249
559
  def run(
250
560
  self,
251
561
  messages: List[OpenAIMessage],
252
562
  response_format: Optional[Type[BaseModel]] = None,
253
563
  tools: Optional[List[Dict[str, Any]]] = None,
254
- ) -> Union[ChatCompletion, Stream[ChatCompletionChunk]]:
564
+ ) -> Union[
565
+ ChatCompletion,
566
+ Stream[ChatCompletionChunk],
567
+ ChatCompletionStreamManager[BaseModel],
568
+ ]:
255
569
  r"""Runs the query to the backend model.
256
570
 
257
571
  Args:
@@ -265,24 +579,50 @@ class BaseModelBackend(ABC, metaclass=ModelBackendMeta):
265
579
  (default: :obj:`None`)
266
580
 
267
581
  Returns:
268
- Union[ChatCompletion, Stream[ChatCompletionChunk]]:
269
- `ChatCompletion` in the non-stream mode, or
270
- `Stream[ChatCompletionChunk]` in the stream mode.
582
+ Union[ChatCompletion, Stream[ChatCompletionChunk], Any]:
583
+ `ChatCompletion` in the non-stream mode,
584
+ `Stream[ChatCompletionChunk]` in the stream mode, or
585
+ `ChatCompletionStreamManager[BaseModel]` in the structured
586
+ stream mode.
271
587
  """
588
+ # Log the request if logging is enabled
589
+ log_path = self._log_request(messages)
590
+
272
591
  # None -> use default tools
273
592
  if tools is None:
274
593
  tools = self.model_config_dict.get("tools", None)
275
594
  # Empty -> use no tools
276
595
  elif not tools:
277
596
  tools = None
278
- return self._run(messages, response_format, tools)
279
597
 
598
+ logger.info("Running model: %s", self.model_type)
599
+ logger.info("Messages: %s", messages)
600
+ logger.info("Response format: %s", response_format)
601
+ logger.info("Tools: %s", tools)
602
+
603
+ result = self._run(messages, response_format, tools)
604
+ logger.info("Result: %s", result)
605
+
606
+ # For streaming responses, wrap with logging; otherwise log immediately
607
+ if isinstance(result, Stream) or inspect.isgenerator(result):
608
+ return _SyncStreamWrapper( # type: ignore[return-value]
609
+ result, log_path, self._log_enabled
610
+ )
611
+ if log_path:
612
+ self._log_response(log_path, result)
613
+ return result
614
+
615
+ @observe()
280
616
  async def arun(
281
617
  self,
282
618
  messages: List[OpenAIMessage],
283
619
  response_format: Optional[Type[BaseModel]] = None,
284
620
  tools: Optional[List[Dict[str, Any]]] = None,
285
- ) -> Union[ChatCompletion, AsyncStream[ChatCompletionChunk]]:
621
+ ) -> Union[
622
+ ChatCompletion,
623
+ AsyncStream[ChatCompletionChunk],
624
+ AsyncChatCompletionStreamManager[BaseModel],
625
+ ]:
286
626
  r"""Runs the query to the backend model asynchronously.
287
627
 
288
628
  Args:
@@ -296,26 +636,36 @@ class BaseModelBackend(ABC, metaclass=ModelBackendMeta):
296
636
  (default: :obj:`None`)
297
637
 
298
638
  Returns:
299
- Union[ChatCompletion, AsyncStream[ChatCompletionChunk]]:
300
- `ChatCompletion` in the non-stream mode, or
301
- `AsyncStream[ChatCompletionChunk]` in the stream mode.
639
+ Union[ChatCompletion, AsyncStream[ChatCompletionChunk], Any]:
640
+ `ChatCompletion` in the non-stream mode,
641
+ `AsyncStream[ChatCompletionChunk]` in the stream mode, or
642
+ `AsyncChatCompletionStreamManager[BaseModel]` in the structured
643
+ stream mode.
302
644
  """
645
+ # Log the request if logging is enabled
646
+ log_path = self._log_request(messages)
647
+
303
648
  if tools is None:
304
649
  tools = self.model_config_dict.get("tools", None)
305
650
  elif not tools:
306
651
  tools = None
307
- return await self._arun(messages, response_format, tools)
308
652
 
309
- @abstractmethod
310
- def check_model_config(self):
311
- r"""Check whether the input model configuration contains unexpected
312
- arguments
653
+ logger.info("Running model: %s", self.model_type)
654
+ logger.info("Messages: %s", messages)
655
+ logger.info("Response format: %s", response_format)
656
+ logger.info("Tools: %s", tools)
313
657
 
314
- Raises:
315
- ValueError: If the model configuration dictionary contains any
316
- unexpected argument for this model class.
317
- """
318
- pass
658
+ result = await self._arun(messages, response_format, tools)
659
+ logger.info("Result: %s", result)
660
+
661
+ # For streaming responses, wrap with logging; otherwise log immediately
662
+ if isinstance(result, AsyncStream) or inspect.isasyncgen(result):
663
+ return _AsyncStreamWrapper( # type: ignore[return-value]
664
+ result, log_path, self._log_enabled
665
+ )
666
+ if log_path:
667
+ self._log_response(log_path, result)
668
+ return result
319
669
 
320
670
  def count_tokens_from_messages(self, messages: List[OpenAIMessage]) -> int:
321
671
  r"""Count the number of tokens in the messages using the specific
@@ -367,10 +717,7 @@ class BaseModelBackend(ABC, metaclass=ModelBackendMeta):
367
717
  Returns:
368
718
  int: The maximum token limit for the given model.
369
719
  """
370
- return (
371
- self.model_config_dict.get("max_tokens")
372
- or self.model_type.token_limit
373
- )
720
+ return self.model_type.token_limit
374
721
 
375
722
  @property
376
723
  def stream(self) -> bool:
@@ -0,0 +1,83 @@
1
+ # ========= Copyright 2023-2026 @ 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-2026 @ CAMEL-AI.org. All Rights Reserved. =========
14
+ import os
15
+ from typing import Any, Dict, Optional, Union
16
+
17
+ from camel.configs import CerebrasConfig
18
+ from camel.models.openai_compatible_model import OpenAICompatibleModel
19
+ from camel.types import ModelType
20
+ from camel.utils import (
21
+ BaseTokenCounter,
22
+ api_keys_required,
23
+ )
24
+
25
+
26
+ class CerebrasModel(OpenAICompatibleModel):
27
+ r"""LLM API served by Cerebras in a unified
28
+ OpenAICompatibleModel interface.
29
+
30
+ Args:
31
+ model_type (Union[ModelType, str]): Model for which a backend is
32
+ created.
33
+ model_config_dict (Optional[Dict[str, Any]], optional): A dictionary
34
+ that will be fed into:obj:`openai.ChatCompletion.create()`.
35
+ If:obj:`None`, :obj:`CerebrasConfig().as_dict()` will be used.
36
+ (default: :obj:`None`)
37
+ api_key (Optional[str], optional): The API key for authenticating
38
+ with the Cerebras service. (default: :obj:`None`).
39
+ url (Optional[str], optional): The url to the Cerebras service.
40
+ (default: :obj:`None`)
41
+ token_counter (Optional[BaseTokenCounter], optional): Token counter to
42
+ use for the model. If not provided, :obj:`OpenAITokenCounter(
43
+ ModelType.GPT_4O_MINI)` will be used.
44
+ (default: :obj:`None`)
45
+ timeout (Optional[float], optional): The timeout value in seconds for
46
+ API calls. If not provided, will fall back to the MODEL_TIMEOUT
47
+ environment variable or default to 180 seconds.
48
+ (default: :obj:`None`)
49
+ max_retries (int, optional): Maximum number of retries for API calls.
50
+ (default: :obj:`3`)
51
+ **kwargs (Any): Additional arguments to pass to the client
52
+ initialization.
53
+ """
54
+
55
+ @api_keys_required([("api_key", "CEREBRAS_API_KEY")])
56
+ def __init__(
57
+ self,
58
+ model_type: Union[ModelType, str],
59
+ model_config_dict: Optional[Dict[str, Any]] = None,
60
+ api_key: Optional[str] = None,
61
+ url: Optional[str] = None,
62
+ token_counter: Optional[BaseTokenCounter] = None,
63
+ timeout: Optional[float] = None,
64
+ max_retries: int = 3,
65
+ **kwargs: Any,
66
+ ) -> None:
67
+ if model_config_dict is None:
68
+ model_config_dict = CerebrasConfig().as_dict()
69
+ api_key = api_key or os.environ.get("CEREBRAS_API_KEY")
70
+ url = url or os.environ.get(
71
+ "CEREBRAS_API_BASE_URL", "https://api.cerebras.ai/v1"
72
+ )
73
+ timeout = timeout or float(os.environ.get("MODEL_TIMEOUT", 180))
74
+ super().__init__(
75
+ model_type=model_type,
76
+ model_config_dict=model_config_dict,
77
+ api_key=api_key,
78
+ url=url,
79
+ token_counter=token_counter,
80
+ timeout=timeout,
81
+ max_retries=max_retries,
82
+ **kwargs,
83
+ )