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,41 +10,30 @@
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. =========
14
- from typing import List, Optional, Tuple
13
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
15
14
 
16
- from pydantic import BaseModel
15
+ from typing import List, Optional, Tuple
17
16
 
18
- from camel.logger import get_logger
19
17
  from camel.memories.base import BaseContextCreator
20
18
  from camel.memories.records import ContextRecord
21
19
  from camel.messages import OpenAIMessage
22
20
  from camel.types.enums import OpenAIBackendRole
23
21
  from camel.utils import BaseTokenCounter
24
22
 
25
- logger = get_logger(__name__)
26
-
27
-
28
- class _ContextUnit(BaseModel):
29
- idx: int
30
- record: ContextRecord
31
- num_tokens: int
32
-
33
23
 
34
24
  class ScoreBasedContextCreator(BaseContextCreator):
35
- r"""A default implementation of context creation strategy, which inherits
36
- from :obj:`BaseContextCreator`.
25
+ r"""A context creation strategy that orders records chronologically.
37
26
 
38
- This class provides a strategy to generate a conversational context from
39
- a list of chat history records while ensuring the total token count of
40
- the context does not exceed a specified limit. It prunes messages based
41
- on their score if the total token count exceeds the limit.
27
+ This class supports token count estimation to reduce expensive repeated
28
+ token counting. When a cached token count is available, it estimates
29
+ new message tokens using character-based approximation instead of
30
+ calling the token counter for every message.
42
31
 
43
32
  Args:
44
- token_counter (BaseTokenCounter): An instance responsible for counting
45
- tokens in a message.
46
- token_limit (int): The maximum number of tokens allowed in the
47
- generated context.
33
+ token_counter (BaseTokenCounter): Token counter instance used to
34
+ compute the combined token count of the returned messages.
35
+ token_limit (int): Retained for API compatibility. No longer used to
36
+ filter records.
48
37
  """
49
38
 
50
39
  def __init__(
@@ -52,6 +41,10 @@ class ScoreBasedContextCreator(BaseContextCreator):
52
41
  ) -> None:
53
42
  self._token_counter = token_counter
54
43
  self._token_limit = token_limit
44
+ # Token count cache: stores the known token count and corresponding
45
+ # message count from the last LLM response
46
+ self._cached_token_count: Optional[int] = None
47
+ self._cached_message_count: int = 0
55
48
 
56
49
  @property
57
50
  def token_counter(self) -> BaseTokenCounter:
@@ -61,230 +54,116 @@ class ScoreBasedContextCreator(BaseContextCreator):
61
54
  def token_limit(self) -> int:
62
55
  return self._token_limit
63
56
 
64
- def create_context(
65
- self,
66
- records: List[ContextRecord],
67
- ) -> Tuple[List[OpenAIMessage], int]:
68
- r"""Constructs conversation context from chat history while respecting
69
- token limits.
70
-
71
- Key strategies:
72
- 1. System message is always prioritized and preserved
73
- 2. Truncation removes low-score messages first
74
- 3. Final output maintains chronological order and in history memory,
75
- the score of each message decreases according to keep_rate. The
76
- newer the message, the higher the score.
77
-
78
- Args:
79
- records (List[ContextRecord]): List of context records with scores
80
- and timestamps.
81
-
82
- Returns:
83
- Tuple[List[OpenAIMessage], int]:
84
- - Ordered list of OpenAI messages
85
- - Total token count of the final context
86
-
87
- Raises:
88
- RuntimeError: If system message alone exceeds token limit
89
- """
90
- # ======================
91
- # 1. System Message Handling
92
- # ======================
93
- system_unit, regular_units = self._extract_system_message(records)
94
- system_tokens = system_unit.num_tokens if system_unit else 0
95
-
96
- # Check early if system message alone exceeds token limit
97
- if system_tokens > self.token_limit:
98
- raise RuntimeError(
99
- f"System message alone exceeds token limit"
100
- f": {system_tokens} > {self.token_limit}",
101
- system_tokens,
102
- )
103
-
104
- # ======================
105
- # 2. Deduplication & Initial Processing
106
- # ======================
107
- seen_uuids = set()
108
- if system_unit:
109
- seen_uuids.add(system_unit.record.memory_record.uuid)
110
-
111
- # Process non-system messages with deduplication
112
- for idx, record in enumerate(records):
113
- if record.memory_record.uuid in seen_uuids:
114
- continue
115
- seen_uuids.add(record.memory_record.uuid)
116
-
117
- token_count = self.token_counter.count_tokens_from_messages(
118
- [record.memory_record.to_openai_message()]
119
- )
120
- regular_units.append(
121
- _ContextUnit(
122
- idx=idx,
123
- record=record,
124
- num_tokens=token_count,
125
- )
126
- )
127
-
128
- # ======================
129
- # 3. Token Calculation
130
- # ======================
131
- total_tokens = system_tokens + sum(u.num_tokens for u in regular_units)
132
-
133
- # ======================
134
- # 4. Early Return if Within Limit
135
- # ======================
136
- if total_tokens <= self.token_limit:
137
- sorted_units = sorted(
138
- regular_units, key=self._conversation_sort_key
139
- )
140
- return self._assemble_output(sorted_units, system_unit)
141
-
142
- # ======================
143
- # 5. Truncation Logic
144
- # ======================
145
- logger.warning(
146
- f"Context truncation required "
147
- f"({total_tokens} > {self.token_limit}), "
148
- f"pruning low-score messages."
149
- )
150
-
151
- # Sort for truncation: high scores first, older messages first at same
152
- # score
153
- sorted_for_truncation = sorted(
154
- regular_units, key=self._truncation_sort_key
155
- )
156
-
157
- # Reverse to process from lowest score (end of sorted list)
158
- remaining_units = []
159
- current_total = system_tokens
160
-
161
- for unit in sorted_for_truncation:
162
- potential_total = current_total + unit.num_tokens
163
- if potential_total <= self.token_limit:
164
- remaining_units.append(unit)
165
- current_total = potential_total
166
-
167
- # ======================
168
- # 6. Output Assembly
169
- # ======================
170
-
171
- # In case system message is the only message in memory when sorted
172
- # units are empty, raise an error
173
- if system_unit and len(remaining_units) == 0 and len(records) > 1:
174
- raise RuntimeError(
175
- "System message and current message exceeds token limit ",
176
- total_tokens,
177
- )
178
-
179
- # Sort remaining units chronologically
180
- final_units = sorted(remaining_units, key=self._conversation_sort_key)
181
- return self._assemble_output(final_units, system_unit)
182
-
183
- def _extract_system_message(
184
- self, records: List[ContextRecord]
185
- ) -> Tuple[Optional[_ContextUnit], List[_ContextUnit]]:
186
- r"""Extracts the system message from records and validates it.
57
+ def set_cached_token_count(
58
+ self, token_count: int, message_count: int
59
+ ) -> None:
60
+ r"""Set the cached token count from LLM response usage.
187
61
 
188
62
  Args:
189
- records (List[ContextRecord]): List of context records
190
- representing conversation history.
191
-
192
- Returns:
193
- Tuple[Optional[_ContextUnit], List[_ContextUnit]]: containing:
194
- - The system message as a `_ContextUnit`, if valid; otherwise,
195
- `None`.
196
- - An empty list, serving as the initial container for regular
197
- messages.
63
+ token_count (int): The total token count (prompt + completion)
64
+ from LLM response usage.
65
+ message_count (int): The number of messages including the
66
+ assistant response that will be added to memory.
198
67
  """
199
- if not records:
200
- return None, []
201
-
202
- first_record = records[0]
203
- if (
204
- first_record.memory_record.role_at_backend
205
- != OpenAIBackendRole.SYSTEM
206
- ):
207
- return None, []
208
-
209
- message = first_record.memory_record.to_openai_message()
210
- tokens = self.token_counter.count_tokens_from_messages([message])
211
- system_message_unit = _ContextUnit(
212
- idx=0,
213
- record=first_record,
214
- num_tokens=tokens,
215
- )
216
- return system_message_unit, []
217
-
218
- def _truncation_sort_key(self, unit: _ContextUnit) -> Tuple[float, float]:
219
- r"""Defines the sorting key for the truncation phase.
220
-
221
- Sorting priority:
222
- - Primary: Sort by score in descending order (higher scores first).
223
- - Secondary: Sort by timestamp in ascending order (older messages
224
- first when scores are equal).
225
-
226
- Args:
227
- unit (_ContextUnit): A `_ContextUnit` representing a conversation
228
- record.
68
+ self._cached_token_count = token_count
69
+ self._cached_message_count = message_count
229
70
 
230
- Returns:
231
- Tuple[float, float]:
232
- - Negative score for descending order sorting.
233
- - Timestamp for ascending order sorting.
234
- """
235
- return (-unit.record.score, unit.record.timestamp)
71
+ def clear_cache(self) -> None:
72
+ r"""Clear the cached token count."""
73
+ self._cached_token_count = None
74
+ self._cached_message_count = 0
236
75
 
237
- def _conversation_sort_key(
238
- self, unit: _ContextUnit
239
- ) -> Tuple[float, float]:
240
- r"""Defines the sorting key for assembling the final output.
76
+ def _estimate_message_tokens(self, message: OpenAIMessage) -> int:
77
+ r"""Estimate token count for a single message.
241
78
 
242
- Sorting priority:
243
- - Primary: Sort by timestamp in ascending order (chronological order).
244
- - Secondary: Sort by score in descending order (higher scores first
245
- when timestamps are equal).
79
+ Uses ~2 chars/token as a conservative approximation to handle both
80
+ ASCII (~4 chars/token) and CJK text (~1-2 chars/token).
246
81
 
247
82
  Args:
248
- unit (_ContextUnit): A `_ContextUnit` representing a conversation
249
- record.
83
+ message: The OpenAI message to estimate.
250
84
 
251
85
  Returns:
252
- Tuple[float, float]:
253
- - Timestamp for chronological sorting.
254
- - Negative score for descending order sorting.
86
+ Estimated token count (intentionally conservative).
255
87
  """
256
- return (unit.record.timestamp, -unit.record.score)
88
+ content = message.get("content", "")
89
+ token_estimate = 4 # message overhead
90
+
91
+ if isinstance(content, list):
92
+ # Multimodal content
93
+ for part in content:
94
+ if isinstance(part, dict):
95
+ if part.get("type") == "image_url":
96
+ # Images: 85 (low) to ~1500 (high detail large image)
97
+ # Use 1500 as conservative estimate
98
+ token_estimate += 1500
99
+ else:
100
+ token_estimate += len(str(part)) // 2
101
+ else:
102
+ token_estimate += len(str(part)) // 2
103
+ else:
104
+ token_estimate += len(str(content)) // 2
105
+
106
+ # Add tool_calls if present (already text, safe to serialize)
107
+ if message.get("tool_calls"):
108
+ token_estimate += len(str(message.get("tool_calls"))) // 2
109
+
110
+ return token_estimate
257
111
 
258
- def _assemble_output(
112
+ def create_context(
259
113
  self,
260
- context_units: List[_ContextUnit],
261
- system_unit: Optional[_ContextUnit],
114
+ records: List[ContextRecord],
262
115
  ) -> Tuple[List[OpenAIMessage], int]:
263
- r"""Assembles final message list with proper ordering and token count.
116
+ """Returns messages sorted by timestamp and their total token count."""
117
+
118
+ system_record: Optional[ContextRecord] = None
119
+ remaining_records: List[ContextRecord] = []
120
+
121
+ for record in records:
122
+ if (
123
+ system_record is None
124
+ and record.memory_record.role_at_backend
125
+ == OpenAIBackendRole.SYSTEM
126
+ ):
127
+ system_record = record
128
+ continue
129
+ remaining_records.append(record)
264
130
 
265
- Args:
266
- context_units (List[_ContextUnit]): Sorted list of regular message
267
- units.
268
- system_unit (Optional[_ContextUnit]): System message unit (if
269
- present).
131
+ remaining_records.sort(key=lambda record: record.timestamp)
270
132
 
271
- Returns:
272
- Tuple[List[OpenAIMessage], int]: Tuple of (ordered messages, total
273
- tokens)
274
- """
275
- messages = []
276
- total_tokens = 0
133
+ messages: List[OpenAIMessage] = []
134
+ if system_record is not None:
135
+ messages.append(system_record.memory_record.to_openai_message())
277
136
 
278
- # Add system message first if present
279
- if system_unit:
280
- messages.append(
281
- system_unit.record.memory_record.to_openai_message()
282
- )
283
- total_tokens += system_unit.num_tokens
137
+ messages.extend(
138
+ record.memory_record.to_openai_message()
139
+ for record in remaining_records
140
+ )
141
+
142
+ if not messages:
143
+ return [], 0
284
144
 
285
- # Add sorted regular messages
286
- for unit in context_units:
287
- messages.append(unit.record.memory_record.to_openai_message())
288
- total_tokens += unit.num_tokens
145
+ current_count = len(messages)
146
+
147
+ # Use cache if available and valid
148
+ if (
149
+ self._cached_token_count is not None
150
+ and self._cached_message_count > 0
151
+ ):
152
+ if current_count == self._cached_message_count:
153
+ # Same message count, use cached value directly
154
+ return messages, self._cached_token_count
155
+ elif current_count > self._cached_message_count:
156
+ # New messages added, estimate incrementally
157
+ new_messages = messages[self._cached_message_count :]
158
+ estimated_new_tokens = sum(
159
+ self._estimate_message_tokens(msg) for msg in new_messages
160
+ )
161
+ return (
162
+ messages,
163
+ self._cached_token_count + estimated_new_tokens,
164
+ )
165
+ # current_count < cached: messages were removed, cache invalid
289
166
 
167
+ # No cache or cache is stale - do full calculation
168
+ total_tokens = self.token_counter.count_tokens_from_messages(messages)
290
169
  return messages, total_tokens
camel/memories/records.py CHANGED
@@ -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,13 +10,13 @@
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
  # Enables postponed evaluation of annotations (for string-based type hints)
16
16
  from __future__ import annotations
17
17
 
18
+ import inspect
18
19
  import time
19
- from dataclasses import asdict
20
20
  from typing import Any, ClassVar, Dict
21
21
  from uuid import UUID, uuid4
22
22
 
@@ -63,6 +63,20 @@ class MemoryRecord(BaseModel):
63
63
  "FunctionCallingMessage": FunctionCallingMessage,
64
64
  }
65
65
 
66
+ # Cache for constructor parameters (performance optimization)
67
+ _constructor_params_cache: ClassVar[Dict[str, set]] = {}
68
+
69
+ @classmethod
70
+ def _get_constructor_params(cls, message_cls) -> set:
71
+ """Get constructor parameters for a message class with caching."""
72
+ cls_name = message_cls.__name__
73
+ if cls_name not in cls._constructor_params_cache:
74
+ sig = inspect.signature(message_cls.__init__)
75
+ cls._constructor_params_cache[cls_name] = set(
76
+ sig.parameters.keys()
77
+ ) - {'self'}
78
+ return cls._constructor_params_cache[cls_name]
79
+
66
80
  @classmethod
67
81
  def from_dict(cls, record_dict: Dict[str, Any]) -> "MemoryRecord":
68
82
  r"""Reconstruct a :obj:`MemoryRecord` from the input dict.
@@ -70,14 +84,78 @@ class MemoryRecord(BaseModel):
70
84
  Args:
71
85
  record_dict(Dict[str, Any]): A dict generated by :meth:`to_dict`.
72
86
  """
87
+ from camel.types import OpenAIBackendRole, RoleType
88
+
73
89
  message_cls = cls._MESSAGE_TYPES[record_dict["message"]["__class__"]]
74
- kwargs: Dict = record_dict["message"].copy()
75
- kwargs.pop("__class__")
76
- reconstructed_message = message_cls(**kwargs)
90
+ data = record_dict["message"].copy()
91
+ data.pop("__class__")
92
+
93
+ # Convert role_type string to enum
94
+ if "role_type" in data and isinstance(data["role_type"], str):
95
+ data["role_type"] = RoleType(data["role_type"])
96
+
97
+ # Deserialize image_list from base64 strings/URLs back to PIL Images/
98
+ # URLs
99
+ if "image_list" in data and data["image_list"] is not None:
100
+ import base64
101
+ from io import BytesIO
102
+
103
+ from PIL import Image
104
+
105
+ image_objects = []
106
+ for img_item in data["image_list"]:
107
+ if isinstance(img_item, dict):
108
+ # New format with type indicator
109
+ if img_item["type"] == "url":
110
+ # URL string, keep as-is
111
+ image_objects.append(img_item["data"])
112
+ else: # type == "base64"
113
+ # Base64 encoded image, convert to PIL Image
114
+ img_bytes = base64.b64decode(img_item["data"])
115
+ img = Image.open(BytesIO(img_bytes))
116
+ # Restore the format attribute if it was saved
117
+ if "format" in img_item:
118
+ img.format = img_item["format"]
119
+ image_objects.append(img)
120
+ else:
121
+ # Legacy format: assume it's a base64 string
122
+ img_bytes = base64.b64decode(img_item)
123
+ img = Image.open(BytesIO(img_bytes))
124
+ image_objects.append(img)
125
+ data["image_list"] = image_objects
126
+
127
+ # Deserialize video_bytes from base64 string
128
+ if "video_bytes" in data and data["video_bytes"] is not None:
129
+ import base64
130
+
131
+ data["video_bytes"] = base64.b64decode(data["video_bytes"])
132
+
133
+ # Get valid constructor parameters (cached)
134
+ valid_params = cls._get_constructor_params(message_cls)
135
+
136
+ # Separate constructor args from extra fields
137
+ kwargs = {k: v for k, v in data.items() if k in valid_params}
138
+ extra_fields = {k: v for k, v in data.items() if k not in valid_params}
139
+
140
+ # Handle meta_dict properly: merge existing meta_dict with extra fields
141
+ existing_meta = kwargs.get("meta_dict", {}) or {}
142
+ if extra_fields:
143
+ # Extra fields take precedence, but preserve existing meta_dict
144
+ # structure
145
+ merged_meta = {**existing_meta, **extra_fields}
146
+ kwargs["meta_dict"] = merged_meta
147
+ elif not existing_meta:
148
+ kwargs["meta_dict"] = None
149
+
150
+ # Convert role_at_backend
151
+ role_at_backend = record_dict["role_at_backend"]
152
+ if isinstance(role_at_backend, str):
153
+ role_at_backend = OpenAIBackendRole(role_at_backend)
154
+
77
155
  return cls(
78
156
  uuid=UUID(record_dict["uuid"]),
79
- message=reconstructed_message,
80
- role_at_backend=record_dict["role_at_backend"],
157
+ message=message_cls(**kwargs),
158
+ role_at_backend=role_at_backend,
81
159
  extra_info=record_dict["extra_info"],
82
160
  timestamp=record_dict["timestamp"],
83
161
  agent_id=record_dict["agent_id"],
@@ -91,9 +169,11 @@ class MemoryRecord(BaseModel):
91
169
  "uuid": str(self.uuid),
92
170
  "message": {
93
171
  "__class__": self.message.__class__.__name__,
94
- **asdict(self.message),
172
+ **self.message.to_dict(),
95
173
  },
96
- "role_at_backend": self.role_at_backend,
174
+ "role_at_backend": self.role_at_backend.value
175
+ if hasattr(self.role_at_backend, "value")
176
+ else self.role_at_backend,
97
177
  "extra_info": self.extra_info,
98
178
  "timestamp": self.timestamp,
99
179
  "agent_id": self.agent_id,
@@ -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
  from typing import Union
15
15
 
16
16
  from camel.types import (