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
@@ -0,0 +1,608 @@
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
+
15
+ import json
16
+ import time
17
+ import uuid
18
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional
19
+
20
+ from camel.logger import get_logger
21
+ from camel.messages import BaseMessage
22
+ from camel.toolkits.base import BaseToolkit
23
+ from camel.toolkits.function_tool import FunctionTool
24
+ from camel.types import RoleType
25
+
26
+ if TYPE_CHECKING:
27
+ from camel.agents import ChatAgent
28
+
29
+ logger = get_logger(__name__)
30
+
31
+
32
+ class AgentMessage(BaseMessage):
33
+ r"""Represents a message between agents, extending BaseMessage.
34
+
35
+ This class extends the standard CAMEL BaseMessage with additional
36
+ attributes needed for inter-agent communication.
37
+ """
38
+
39
+ def __init__(
40
+ self,
41
+ message_id: str,
42
+ sender_id: str,
43
+ receiver_id: str,
44
+ content: str,
45
+ timestamp: float,
46
+ reply_to: Optional[str] = None,
47
+ metadata: Optional[Dict[str, Any]] = None,
48
+ ):
49
+ # Initialize BaseMessage with standard fields
50
+ super().__init__(
51
+ role_name=sender_id,
52
+ role_type=RoleType.ASSISTANT,
53
+ meta_dict=metadata or {},
54
+ content=content,
55
+ )
56
+
57
+ # Add agent-specific fields
58
+ self.id = message_id
59
+ self.sender_id = sender_id
60
+ self.receiver_id = receiver_id
61
+ self.timestamp = timestamp
62
+ self.reply_to = reply_to
63
+ self.metadata = metadata or {}
64
+
65
+
66
+ class AgentCommunicationToolkit(BaseToolkit):
67
+ r"""A toolkit for agent-to-agent communication in multi-agent systems.
68
+
69
+ Enables agents to send messages to each other with message history tracking
70
+ and integration with the CAMEL workforce system.
71
+
72
+ Args:
73
+ agents (Optional[Dict[str, ChatAgent]]): Dictionary mapping agent IDs
74
+ to ChatAgent instances. (default: :obj:`None`)
75
+ timeout (Optional[float]): Maximum execution time for operations in
76
+ seconds. (default: :obj:`None`)
77
+ max_message_history (int): Maximum messages to keep per agent.
78
+ (default: :obj:`100`)
79
+ get_response (bool): Whether to get responses from receiving agents
80
+ by default. (default: :obj:`False`)
81
+
82
+ Example:
83
+ >>> msg_toolkit = AgentCommunicationToolkit(get_response=False)
84
+ >>> msg_toolkit.register_agent("agent1", agent1)
85
+ >>> msg_toolkit.register_agent("agent2", agent2)
86
+ >>>
87
+ >>> # Add tools to agents
88
+ >>> for tool in msg_toolkit.get_tools():
89
+ ... agent1.add_tool(tool)
90
+ ... agent2.add_tool(tool)
91
+ """
92
+
93
+ def __init__(
94
+ self,
95
+ agents: Optional[Dict[str, "ChatAgent"]] = None,
96
+ timeout: Optional[float] = None,
97
+ max_message_history: int = 100,
98
+ get_response: bool = False,
99
+ ) -> None:
100
+ super().__init__(timeout=timeout)
101
+ self.agents = agents or {}
102
+ self.max_message_history = max_message_history
103
+ self.get_response = get_response
104
+
105
+ # Message management
106
+ self._message_history: Dict[str, List[AgentMessage]] = {}
107
+ self._conversation_threads: Dict[str, List[str]] = {}
108
+
109
+ logger.info(
110
+ f"AgentCommunicationToolkit initialized with {len(self.agents)} "
111
+ f"agents. "
112
+ f"Max history: {max_message_history}, Get response: {get_response}"
113
+ )
114
+
115
+ def register_agent(self, agent_id: str, agent: "ChatAgent") -> str:
116
+ r"""Register a new agent for communication.
117
+
118
+ Args:
119
+ agent_id (str): Unique identifier for the agent.
120
+ agent (ChatAgent): The ChatAgent instance to register.
121
+
122
+ Returns:
123
+ str: Confirmation message with registration details.
124
+
125
+ Raises:
126
+ ValueError: If agent_id is empty or agent is None.
127
+ """
128
+ if agent_id in self.agents:
129
+ logger.warning(f"Agent {agent_id} already exists, overwriting")
130
+
131
+ self.agents[agent_id] = agent
132
+
133
+ # Initialize message history for new agent
134
+ if agent_id not in self._message_history:
135
+ self._message_history[agent_id] = []
136
+
137
+ logger.info(f"Registered agent: {agent_id}")
138
+ return (
139
+ f"Agent {agent_id} registered successfully. "
140
+ f"Total agents: {len(self.agents)}"
141
+ )
142
+
143
+ def _find_agent_id(self, agent_id: str) -> Optional[str]:
144
+ r"""Find agent ID with flexible matching (case-insensitive, partial
145
+ matches).
146
+ """
147
+ # First try exact match
148
+ if agent_id in self.agents:
149
+ return agent_id
150
+
151
+ # Try case-insensitive exact match
152
+ agent_id_lower = agent_id.lower()
153
+ for registered_id in self.agents.keys():
154
+ if registered_id.lower() == agent_id_lower:
155
+ return registered_id
156
+
157
+ # Try partial matching for common patterns like "writer_01" -> "Writer"
158
+ # Remove common suffixes and prefixes
159
+ clean_id = agent_id_lower
160
+
161
+ # Remove common patterns: _01, _123, _agent, etc.
162
+ import re
163
+
164
+ clean_id = re.sub(r'_\d+$', '', clean_id) # Remove trailing _numbers
165
+ clean_id = re.sub(r'_agent$', '', clean_id) # Remove trailing _agent
166
+ clean_id = re.sub(r'^agent_', '', clean_id) # Remove leading agent_
167
+
168
+ # Try to match cleaned ID
169
+ for registered_id in self.agents.keys():
170
+ if registered_id.lower() == clean_id:
171
+ return registered_id
172
+ # Also try if the registered ID starts with our cleaned ID
173
+ if registered_id.lower().startswith(clean_id):
174
+ return registered_id
175
+
176
+ return None
177
+
178
+ def send_message(
179
+ self,
180
+ message: str,
181
+ receiver_id: str,
182
+ sender_id: str = "system",
183
+ reply_to: Optional[str] = None,
184
+ metadata_json: Optional[str] = None,
185
+ ) -> str:
186
+ r"""Sends a message to a specific agent.
187
+
188
+ This function allows one agent to communicate directly with another by
189
+ sending a message. The toolkit's get_response setting determines
190
+ whether to get an immediate response or just send a notification. To
191
+ get the `receiver_id` of the agent you want to communicate with, you
192
+ can use the `list_available_agents` tool.
193
+
194
+ Args:
195
+ message (str): The content of the message to send.
196
+ receiver_id (str): The unique identifier of the agent to receive
197
+ the message. Use `list_available_agents()` to find the ID of
198
+ the agent you want to talk to.
199
+ sender_id (str): The unique identifier of the agent sending the
200
+ message. This is typically your agent's ID.
201
+ (default: :obj:`"system"`)
202
+ reply_to (Optional[str]): The ID of a previous message this new
203
+ message is a reply to. This helps create conversation threads.
204
+ (default: :obj:`None`)
205
+ metadata_json (Optional[str]): A JSON string containing extra
206
+ information about the message.
207
+ (default: :obj:`None`)
208
+
209
+ Returns:
210
+ str: A confirmation that the message was sent. If the toolkit's
211
+ get_response setting is True, includes the response from the
212
+ receiving agent.
213
+ """
214
+ if not message or not message.strip():
215
+ raise ValueError("Message content cannot be empty")
216
+
217
+ # Find the actual agent ID (case-insensitive)
218
+ actual_receiver_id = self._find_agent_id(receiver_id)
219
+ if not actual_receiver_id:
220
+ available_agents = ", ".join(self.agents.keys())
221
+ error_msg = (
222
+ f"Agent {receiver_id} not found. "
223
+ f"Available agents: {available_agents}"
224
+ )
225
+ logger.error(error_msg)
226
+ return f"Error: {error_msg}"
227
+
228
+ # Parse metadata from JSON string
229
+ metadata = {}
230
+ if metadata_json:
231
+ try:
232
+ metadata = json.loads(metadata_json)
233
+ if not isinstance(metadata, dict):
234
+ logger.warning(
235
+ "Metadata must be a JSON object, using empty dict"
236
+ )
237
+ metadata = {}
238
+ except json.JSONDecodeError:
239
+ logger.warning(
240
+ "Invalid JSON in metadata_json, using empty dict"
241
+ )
242
+ metadata = {}
243
+
244
+ # Create message
245
+ agent_message = AgentMessage(
246
+ message_id=str(uuid.uuid4()),
247
+ sender_id=sender_id,
248
+ receiver_id=actual_receiver_id, # Use the resolved agent ID
249
+ content=message,
250
+ timestamp=time.time(),
251
+ reply_to=reply_to,
252
+ metadata=metadata,
253
+ )
254
+
255
+ # Handle threading
256
+ if reply_to:
257
+ self._update_conversation_thread(reply_to, agent_message.id)
258
+
259
+ # Deliver message (with or without response)
260
+ return self._deliver_message(agent_message, self.get_response)
261
+
262
+ def _deliver_message(
263
+ self, message: AgentMessage, get_response: bool
264
+ ) -> str:
265
+ r"""Deliver a message to the target agent, optionally getting a
266
+ response.
267
+ """
268
+ try:
269
+ target_agent = self.agents[message.receiver_id]
270
+ logger.info(
271
+ f"Delivering message {message.id} to agent "
272
+ f"{message.receiver_id}"
273
+ )
274
+
275
+ self._add_to_history(message)
276
+
277
+ # Create a clear, structured message for the agent
278
+ structured_message = (
279
+ f"A message has been received from agent with "
280
+ f"ID '{message.sender_id}'.\n\n"
281
+ "--- Message Content ---\n"
282
+ f"{message.content}\n"
283
+ "--- End of Message ---"
284
+ )
285
+ response = target_agent.step(structured_message)
286
+
287
+ if get_response:
288
+ # Extract and return response content
289
+ if hasattr(response, 'msgs') and response.msgs:
290
+ response_content = response.msgs[0].content
291
+ else:
292
+ response_content = str(response)
293
+
294
+ logger.info(
295
+ f"Message {message.id} delivered with response. "
296
+ f"Response length: {len(response_content)}"
297
+ )
298
+
299
+ return (
300
+ f"Message {message.id} delivered to "
301
+ f"{message.receiver_id}. "
302
+ f"Response: {response_content[:100]}"
303
+ f"{'...' if len(response_content) > 100 else ''}"
304
+ )
305
+ else:
306
+ # Message delivered but response not requested
307
+ logger.info(
308
+ f"Message {message.id} delivered to agent "
309
+ f"{message.receiver_id} (response not requested)"
310
+ )
311
+
312
+ return (
313
+ f"Message {message.id} delivered to "
314
+ f"{message.receiver_id}. "
315
+ f"Message: '{message.content[:50]}"
316
+ f"{'...' if len(message.content) > 50 else ''}'"
317
+ )
318
+
319
+ except Exception as e:
320
+ error_msg = f"Failed to deliver message {message.id}: {e!s}"
321
+ logger.error(error_msg)
322
+ return f"Error: {error_msg}"
323
+
324
+ def broadcast_message(
325
+ self,
326
+ message: str,
327
+ sender_id: str = "system",
328
+ exclude_agents: Optional[List[str]] = None,
329
+ ) -> str:
330
+ r"""Sends a message to all other agents in the system.
331
+
332
+ This function is useful for making announcements or sending information
333
+ that every agent needs. The message will be sent to all registered
334
+ agents except for the sender and any agents specified in the
335
+ `exclude_agents` list.
336
+
337
+ Args:
338
+ message (str): The content of the message to broadcast.
339
+ sender_id (str): The unique identifier of the agent sending the
340
+ message. This is typically your agent's ID.
341
+ (default: :obj:`"system"`)
342
+ exclude_agents (Optional[List[str]]): A list of agent IDs to
343
+ exclude from the broadcast. The sender is automatically
344
+ excluded.
345
+ (default: :obj:`None`)
346
+
347
+ Returns:
348
+ str: A summary of the broadcast, showing which agents received the
349
+ message and their responses.
350
+ """
351
+ if not message or not message.strip():
352
+ return "Error: Message content cannot be empty"
353
+
354
+ exclude_set = set(exclude_agents or [])
355
+ if sender_id:
356
+ exclude_set.add(sender_id) # Don't send to self
357
+
358
+ target_agents = [
359
+ agent_id
360
+ for agent_id in self.agents.keys()
361
+ if agent_id not in exclude_set
362
+ ]
363
+
364
+ if not target_agents:
365
+ return "No target agents available for broadcast"
366
+
367
+ results = []
368
+ for agent_id in target_agents:
369
+ try:
370
+ result = self.send_message(
371
+ message=message,
372
+ receiver_id=agent_id,
373
+ sender_id=sender_id,
374
+ metadata_json='{"broadcast": true}',
375
+ )
376
+ results.append(f"{agent_id}: {result}")
377
+ except Exception as e:
378
+ results.append(f"{agent_id}: Error - {e}")
379
+
380
+ logger.info(f"Broadcast sent to {len(target_agents)} agents")
381
+ return "Broadcast completed. Results:\n" + "\n".join(results)
382
+
383
+ def get_message_history(
384
+ self, agent_id: str, limit: Optional[int] = None
385
+ ) -> str:
386
+ r"""Retrieves the message history for a specific agent.
387
+
388
+ This function allows you to see the messages sent and received by a
389
+ particular agent, which can be useful for understanding past
390
+ conversations. To get the `agent_id` for another agent, use the
391
+ `list_available_agents` tool. You can also use this tool to get
392
+ your own message history by providing your agent ID.
393
+
394
+ Args:
395
+ agent_id (str): The unique identifier of the agent whose message
396
+ history you want to retrieve. Use `list_available_agents()`
397
+ to find available agent IDs.
398
+ limit (Optional[int]): The maximum number of recent messages to
399
+ return. If not specified, it will return all messages up to
400
+ the system's limit.
401
+ (default: :obj:`None`)
402
+
403
+ Returns:
404
+ str: A formatted string containing the message history for the
405
+ specified agent, or an error if the agent is not found.
406
+ """
407
+ actual_agent_id = self._find_agent_id(agent_id)
408
+ if not actual_agent_id:
409
+ return f"No message history found for agent {agent_id}"
410
+
411
+ history = self._message_history.get(actual_agent_id, [])
412
+ if limit:
413
+ history = history[-limit:]
414
+
415
+ if not history:
416
+ return f"No messages in history for agent {agent_id}"
417
+
418
+ formatted_history = []
419
+ for msg in history:
420
+ timestamp_str = time.strftime(
421
+ '%Y-%m-%d %H:%M:%S', time.localtime(msg.timestamp)
422
+ )
423
+ formatted_history.append(
424
+ f"[{timestamp_str}] {msg.sender_id} -> {msg.receiver_id}: "
425
+ f"{msg.content[:100]}{'...' if len(msg.content) > 100 else ''}"
426
+ )
427
+
428
+ return (
429
+ f"Message history for {agent_id} "
430
+ f"({len(formatted_history)} messages):\n"
431
+ + "\n".join(formatted_history)
432
+ )
433
+
434
+ def get_conversation_thread(self, message_id: str) -> str:
435
+ r"""Retrieves a full conversation thread based on a message ID.
436
+
437
+ When you send a message that is a reply to another, it creates a
438
+ conversation thread. This function lets you retrieve all messages
439
+ that are part of that thread. You can find message IDs in the
440
+ message history or from the output of the `send_message` tool.
441
+
442
+ Args:
443
+ message_id (str): The unique identifier of any message within the
444
+ conversation thread you want to retrieve.
445
+
446
+ Returns:
447
+ str: A formatted string containing all messages in the
448
+ conversation, sorted by time, or an error if the thread is
449
+ not found.
450
+ """
451
+ if message_id not in self._conversation_threads:
452
+ return f"No conversation thread found for message {message_id}"
453
+
454
+ thread_ids = self._conversation_threads[message_id]
455
+ thread_messages = []
456
+
457
+ # Find messages in history
458
+ for agent_history in self._message_history.values():
459
+ for msg in agent_history:
460
+ if msg.id in thread_ids:
461
+ thread_messages.append(msg)
462
+
463
+ # Sort by timestamp
464
+ thread_messages.sort(key=lambda x: x.timestamp)
465
+
466
+ if not thread_messages:
467
+ return f"No messages found in thread for {message_id}"
468
+
469
+ formatted_thread = []
470
+ for msg in thread_messages:
471
+ timestamp_str = time.strftime(
472
+ '%H:%M:%S', time.localtime(msg.timestamp)
473
+ )
474
+ formatted_thread.append(
475
+ f"[{timestamp_str}] {msg.sender_id}: {msg.content}"
476
+ )
477
+
478
+ return (
479
+ f"Conversation thread ({len(formatted_thread)} messages):\n"
480
+ + "\n".join(formatted_thread)
481
+ )
482
+
483
+ def list_available_agents(self) -> str:
484
+ r"""Lists all agents currently available for communication.
485
+
486
+ Call this function to discover which other agents are in the system
487
+ that you can communicate with. The returned list will contain the
488
+ unique IDs for each agent, which you can then use with tools like
489
+ `send_message` and `get_message_history`.
490
+
491
+ Returns:
492
+ str: A formatted string listing the IDs and status of all
493
+ available agents.
494
+ """
495
+ if not self.agents:
496
+ return "No agents registered"
497
+
498
+ agent_info = []
499
+ for agent_id, agent in self.agents.items():
500
+ # Get message count for this agent
501
+ msg_count = len(self._message_history.get(agent_id, []))
502
+
503
+ # Check if agent has pause support
504
+ has_pause = hasattr(agent, 'pause_event')
505
+
506
+ status_info = f"Messages: {msg_count}"
507
+ if has_pause:
508
+ status_info += ", Workforce-compatible"
509
+
510
+ agent_info.append(f" - {agent_id}: {status_info}")
511
+
512
+ return f"Available agents ({len(self.agents)}):\n" + "\n".join(
513
+ agent_info
514
+ )
515
+
516
+ def remove_agent(self, agent_id: str) -> str:
517
+ r"""Remove an agent from the communication registry.
518
+
519
+ Args:
520
+ agent_id (str): Unique identifier of the agent to remove.
521
+
522
+ Returns:
523
+ str: Confirmation message with cleanup details.
524
+ """
525
+ if agent_id not in self.agents:
526
+ return f"Error: Agent {agent_id} not found"
527
+
528
+ del self.agents[agent_id]
529
+
530
+ # Keep message history for audit purposes but note agent removal
531
+ if agent_id in self._message_history:
532
+ logger.info(
533
+ f"Preserved {len(self._message_history[agent_id])} "
534
+ f"messages for removed agent {agent_id}"
535
+ )
536
+
537
+ logger.info(f"Removed agent: {agent_id}")
538
+ return (
539
+ f"Agent {agent_id} removed successfully. "
540
+ f"Remaining agents: {len(self.agents)}"
541
+ )
542
+
543
+ def get_toolkit_status(self) -> str:
544
+ r"""Get comprehensive status of the message toolkit.
545
+
546
+ Returns:
547
+ str: Detailed status information including metrics and queue state.
548
+ """
549
+ total_messages = sum(
550
+ len(history) for history in self._message_history.values()
551
+ )
552
+
553
+ status_info = [
554
+ "AgentCommunicationToolkit Status:",
555
+ f" - Registered agents: {len(self.agents)}",
556
+ f" - Total message history: {total_messages}",
557
+ f" - Max history per agent: {self.max_message_history}",
558
+ ]
559
+
560
+ return "\n".join(status_info)
561
+
562
+ def _add_to_history(self, message: AgentMessage) -> None:
563
+ r"""Add a message to the history with size management."""
564
+ # Add to sender's history
565
+ sender_history = self._message_history.setdefault(
566
+ message.sender_id, []
567
+ )
568
+ sender_history.append(message)
569
+
570
+ # Add to receiver's history
571
+ receiver_history = self._message_history.setdefault(
572
+ message.receiver_id, []
573
+ )
574
+ receiver_history.append(message)
575
+
576
+ # Trim history if needed
577
+ for agent_id, history in self._message_history.items():
578
+ if len(history) > self.max_message_history:
579
+ self._message_history[agent_id] = history[
580
+ -self.max_message_history :
581
+ ]
582
+
583
+ def _update_conversation_thread(self, parent_id: str, new_id: str) -> None:
584
+ r"""Update conversation threading."""
585
+ if parent_id in self._conversation_threads:
586
+ self._conversation_threads[parent_id].append(new_id)
587
+ else:
588
+ self._conversation_threads[new_id] = [parent_id, new_id]
589
+
590
+ def get_tools(self) -> List[FunctionTool]:
591
+ r"""Returns a list of FunctionTool objects representing the
592
+ communication functions in the toolkit.
593
+
594
+ Note: Only includes functions that are safe and useful for LLMs to
595
+ call. Administrative functions like register_agent and remove_agent are
596
+ excluded as they should only be called programmatically.
597
+
598
+ Returns:
599
+ List[FunctionTool]: A list of FunctionTool objects for agent
600
+ communication and management.
601
+ """
602
+ return [
603
+ FunctionTool(self.send_message),
604
+ FunctionTool(self.broadcast_message),
605
+ FunctionTool(self.list_available_agents),
606
+ FunctionTool(self.get_message_history),
607
+ FunctionTool(self.get_conversation_thread),
608
+ ]