camel-ai 0.2.59__py3-none-any.whl → 0.2.82__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 (506) 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 +5012 -902
  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 +39 -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 +94 -0
  28. camel/benchmarks/mock_website/mock_web.py +299 -0
  29. camel/benchmarks/mock_website/requirements.txt +3 -0
  30. camel/benchmarks/mock_website/shopping_mall/app.py +465 -0
  31. camel/benchmarks/mock_website/task.json +104 -0
  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 +26 -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 +8 -7
  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 +3 -3
  52. camel/configs/cometapi_config.py +106 -0
  53. camel/configs/crynux_config.py +94 -0
  54. camel/configs/deepseek_config.py +9 -8
  55. camel/configs/gemini_config.py +6 -4
  56. camel/configs/groq_config.py +6 -4
  57. camel/configs/internlm_config.py +6 -4
  58. camel/configs/litellm_config.py +2 -2
  59. camel/configs/lmstudio_config.py +6 -4
  60. camel/configs/minimax_config.py +95 -0
  61. camel/configs/mistral_config.py +3 -3
  62. camel/configs/modelscope_config.py +5 -3
  63. camel/configs/moonshot_config.py +2 -2
  64. camel/configs/nebius_config.py +105 -0
  65. camel/configs/netmind_config.py +2 -2
  66. camel/configs/novita_config.py +2 -2
  67. camel/configs/nvidia_config.py +2 -2
  68. camel/configs/ollama_config.py +2 -2
  69. camel/configs/openai_config.py +8 -3
  70. camel/configs/openrouter_config.py +6 -4
  71. camel/configs/ppio_config.py +2 -2
  72. camel/configs/qianfan_config.py +85 -0
  73. camel/configs/qwen_config.py +2 -2
  74. camel/configs/reka_config.py +3 -3
  75. camel/configs/samba_config.py +8 -6
  76. camel/configs/sglang_config.py +2 -2
  77. camel/configs/siliconflow_config.py +2 -2
  78. camel/configs/togetherai_config.py +2 -2
  79. camel/configs/vllm_config.py +4 -2
  80. camel/configs/watsonx_config.py +2 -2
  81. camel/configs/yi_config.py +6 -4
  82. camel/configs/zhipuai_config.py +6 -4
  83. camel/{data_collector → data_collectors}/__init__.py +2 -2
  84. camel/{data_collector → data_collectors}/alpaca_collector.py +19 -10
  85. camel/{data_collector → data_collectors}/base.py +2 -2
  86. camel/{data_collector → data_collectors}/sharegpt_collector.py +3 -3
  87. camel/datagen/__init__.py +2 -2
  88. camel/datagen/cot_datagen.py +32 -37
  89. camel/datagen/evol_instruct/__init__.py +2 -2
  90. camel/datagen/evol_instruct/evol_instruct.py +2 -2
  91. camel/datagen/evol_instruct/scorer.py +24 -25
  92. camel/datagen/evol_instruct/templates.py +48 -48
  93. camel/datagen/self_improving_cot.py +5 -5
  94. camel/datagen/self_instruct/__init__.py +2 -2
  95. camel/datagen/self_instruct/filter/__init__.py +2 -2
  96. camel/datagen/self_instruct/filter/filter_function.py +2 -2
  97. camel/datagen/self_instruct/filter/filter_registry.py +2 -2
  98. camel/datagen/self_instruct/filter/instruction_filter.py +2 -2
  99. camel/datagen/self_instruct/self_instruct.py +2 -2
  100. camel/datagen/self_instruct/templates.py +47 -47
  101. camel/datagen/source2synth/__init__.py +2 -2
  102. camel/datagen/source2synth/data_processor.py +2 -2
  103. camel/datagen/source2synth/models.py +2 -2
  104. camel/datagen/source2synth/user_data_processor_config.py +2 -2
  105. camel/datahubs/__init__.py +2 -2
  106. camel/datahubs/base.py +2 -2
  107. camel/datahubs/huggingface.py +2 -2
  108. camel/datahubs/models.py +2 -2
  109. camel/datasets/__init__.py +2 -2
  110. camel/datasets/base_generator.py +41 -12
  111. camel/datasets/few_shot_generator.py +18 -18
  112. camel/datasets/models.py +3 -3
  113. camel/datasets/self_instruct_generator.py +2 -2
  114. camel/datasets/static_dataset.py +152 -2
  115. camel/embeddings/__init__.py +2 -2
  116. camel/embeddings/azure_embedding.py +2 -2
  117. camel/embeddings/base.py +2 -2
  118. camel/embeddings/gemini_embedding.py +2 -2
  119. camel/embeddings/jina_embedding.py +10 -3
  120. camel/embeddings/mistral_embedding.py +2 -2
  121. camel/embeddings/openai_compatible_embedding.py +2 -2
  122. camel/embeddings/openai_embedding.py +2 -2
  123. camel/embeddings/sentence_transformers_embeddings.py +4 -4
  124. camel/embeddings/together_embedding.py +2 -2
  125. camel/embeddings/vlm_embedding.py +11 -4
  126. camel/environments/__init__.py +14 -2
  127. camel/environments/models.py +2 -2
  128. camel/environments/multi_step.py +2 -2
  129. camel/environments/rlcards_env.py +860 -0
  130. camel/environments/single_step.py +30 -5
  131. camel/environments/tic_tac_toe.py +3 -3
  132. camel/extractors/__init__.py +2 -2
  133. camel/extractors/base.py +2 -2
  134. camel/extractors/python_strategies.py +2 -2
  135. camel/generators.py +2 -2
  136. camel/human.py +2 -2
  137. camel/interpreters/__init__.py +4 -2
  138. camel/interpreters/base.py +16 -3
  139. camel/interpreters/docker/Dockerfile +53 -7
  140. camel/interpreters/docker_interpreter.py +70 -11
  141. camel/interpreters/e2b_interpreter.py +59 -11
  142. camel/interpreters/internal_python_interpreter.py +81 -4
  143. camel/interpreters/interpreter_error.py +2 -2
  144. camel/interpreters/ipython_interpreter.py +23 -5
  145. camel/interpreters/microsandbox_interpreter.py +395 -0
  146. camel/interpreters/subprocess_interpreter.py +36 -4
  147. camel/loaders/__init__.py +17 -5
  148. camel/loaders/apify_reader.py +2 -2
  149. camel/loaders/base_io.py +2 -2
  150. camel/loaders/base_loader.py +85 -0
  151. camel/loaders/chunkr_reader.py +128 -93
  152. camel/loaders/crawl4ai_reader.py +2 -2
  153. camel/loaders/firecrawl_reader.py +6 -6
  154. camel/loaders/jina_url_reader.py +2 -2
  155. camel/loaders/markitdown.py +2 -2
  156. camel/loaders/mineru_extractor.py +2 -2
  157. camel/loaders/mistral_reader.py +148 -0
  158. camel/loaders/scrapegraph_reader.py +2 -2
  159. camel/loaders/unstructured_io.py +2 -2
  160. camel/logger.py +5 -5
  161. camel/memories/__init__.py +2 -2
  162. camel/memories/agent_memories.py +86 -3
  163. camel/memories/base.py +36 -2
  164. camel/memories/blocks/__init__.py +2 -2
  165. camel/memories/blocks/chat_history_block.py +126 -9
  166. camel/memories/blocks/vectordb_block.py +10 -3
  167. camel/memories/context_creators/__init__.py +2 -2
  168. camel/memories/context_creators/score_based.py +31 -239
  169. camel/memories/records.py +98 -13
  170. camel/messages/__init__.py +2 -2
  171. camel/messages/base.py +193 -46
  172. camel/messages/conversion/__init__.py +2 -2
  173. camel/messages/conversion/alpaca.py +2 -2
  174. camel/messages/conversion/conversation_models.py +2 -2
  175. camel/messages/conversion/sharegpt/__init__.py +2 -2
  176. camel/messages/conversion/sharegpt/function_call_formatter.py +2 -2
  177. camel/messages/conversion/sharegpt/hermes/__init__.py +2 -2
  178. camel/messages/conversion/sharegpt/hermes/hermes_function_formatter.py +2 -2
  179. camel/messages/func_message.py +54 -17
  180. camel/models/__init__.py +18 -2
  181. camel/models/_utils.py +3 -3
  182. camel/models/aihubmix_model.py +83 -0
  183. camel/models/aiml_model.py +11 -18
  184. camel/models/amd_model.py +101 -0
  185. camel/models/anthropic_model.py +127 -20
  186. camel/models/aws_bedrock_model.py +12 -35
  187. camel/models/azure_openai_model.py +263 -63
  188. camel/models/base_audio_model.py +5 -3
  189. camel/models/base_model.py +195 -26
  190. camel/models/cerebras_model.py +83 -0
  191. camel/models/cohere_model.py +81 -21
  192. camel/models/cometapi_model.py +83 -0
  193. camel/models/crynux_model.py +87 -0
  194. camel/models/deepseek_model.py +61 -59
  195. camel/models/fish_audio_model.py +8 -2
  196. camel/models/gemini_model.py +439 -30
  197. camel/models/groq_model.py +11 -19
  198. camel/models/internlm_model.py +11 -18
  199. camel/models/litellm_model.py +94 -34
  200. camel/models/lmstudio_model.py +17 -20
  201. camel/models/minimax_model.py +83 -0
  202. camel/models/mistral_model.py +84 -19
  203. camel/models/model_factory.py +49 -6
  204. camel/models/model_manager.py +33 -11
  205. camel/models/modelscope_model.py +13 -193
  206. camel/models/moonshot_model.py +195 -21
  207. camel/models/nebius_model.py +83 -0
  208. camel/models/nemotron_model.py +19 -9
  209. camel/models/netmind_model.py +11 -18
  210. camel/models/novita_model.py +11 -18
  211. camel/models/nvidia_model.py +11 -18
  212. camel/models/ollama_model.py +14 -21
  213. camel/models/openai_audio_models.py +2 -2
  214. camel/models/openai_compatible_model.py +234 -27
  215. camel/models/openai_model.py +255 -39
  216. camel/models/openrouter_model.py +11 -19
  217. camel/models/ppio_model.py +11 -18
  218. camel/models/qianfan_model.py +89 -0
  219. camel/models/qwen_model.py +13 -193
  220. camel/models/reka_model.py +90 -21
  221. camel/models/reward/__init__.py +2 -2
  222. camel/models/reward/base_reward_model.py +2 -2
  223. camel/models/reward/evaluator.py +2 -2
  224. camel/models/reward/nemotron_model.py +2 -2
  225. camel/models/reward/skywork_model.py +2 -2
  226. camel/models/samba_model.py +117 -49
  227. camel/models/sglang_model.py +162 -42
  228. camel/models/siliconflow_model.py +12 -35
  229. camel/models/stub_model.py +10 -7
  230. camel/models/togetherai_model.py +11 -18
  231. camel/models/vllm_model.py +10 -18
  232. camel/models/volcano_model.py +16 -20
  233. camel/models/watsonx_model.py +69 -19
  234. camel/models/yi_model.py +11 -18
  235. camel/models/zhipuai_model.py +70 -18
  236. camel/parsers/__init__.py +18 -0
  237. camel/parsers/mcp_tool_call_parser.py +176 -0
  238. camel/personas/__init__.py +2 -2
  239. camel/personas/persona.py +2 -2
  240. camel/personas/persona_hub.py +2 -2
  241. camel/prompts/__init__.py +2 -2
  242. camel/prompts/ai_society.py +2 -2
  243. camel/prompts/base.py +2 -2
  244. camel/prompts/code.py +2 -2
  245. camel/prompts/evaluation.py +2 -2
  246. camel/prompts/generate_text_embedding_data.py +2 -2
  247. camel/prompts/image_craft.py +2 -2
  248. camel/prompts/misalignment.py +2 -2
  249. camel/prompts/multi_condition_image_craft.py +2 -2
  250. camel/prompts/object_recognition.py +2 -2
  251. camel/prompts/persona_hub.py +3 -3
  252. camel/prompts/prompt_templates.py +2 -2
  253. camel/prompts/role_description_prompt_template.py +2 -2
  254. camel/prompts/solution_extraction.py +8 -8
  255. camel/prompts/task_prompt_template.py +2 -2
  256. camel/prompts/translation.py +2 -2
  257. camel/prompts/video_description_prompt.py +3 -3
  258. camel/responses/__init__.py +2 -2
  259. camel/responses/agent_responses.py +2 -2
  260. camel/retrievers/__init__.py +2 -2
  261. camel/retrievers/auto_retriever.py +23 -3
  262. camel/retrievers/base.py +2 -2
  263. camel/retrievers/bm25_retriever.py +3 -4
  264. camel/retrievers/cohere_rerank_retriever.py +2 -2
  265. camel/retrievers/hybrid_retrival.py +4 -4
  266. camel/retrievers/vector_retriever.py +2 -2
  267. camel/runtimes/Dockerfile.multi-toolkit +90 -0
  268. camel/{runtime → runtimes}/__init__.py +2 -2
  269. camel/runtimes/api.py +153 -0
  270. camel/{runtime → runtimes}/base.py +2 -2
  271. camel/{runtime → runtimes}/configs.py +13 -13
  272. camel/{runtime → runtimes}/daytona_runtime.py +18 -19
  273. camel/{runtime → runtimes}/docker_runtime.py +13 -13
  274. camel/{runtime → runtimes}/llm_guard_runtime.py +28 -28
  275. camel/{runtime → runtimes}/remote_http_runtime.py +12 -12
  276. camel/{runtime → runtimes}/ubuntu_docker_runtime.py +3 -3
  277. camel/{runtime → runtimes}/utils/__init__.py +2 -2
  278. camel/{runtime → runtimes}/utils/function_risk_toolkit.py +2 -2
  279. camel/{runtime → runtimes}/utils/ignore_risk_toolkit.py +2 -2
  280. camel/schemas/__init__.py +2 -2
  281. camel/schemas/base.py +2 -2
  282. camel/schemas/openai_converter.py +3 -3
  283. camel/schemas/outlines_converter.py +2 -2
  284. camel/services/agent_openapi_server.py +380 -0
  285. camel/societies/__init__.py +4 -2
  286. camel/societies/babyagi_playing.py +2 -2
  287. camel/societies/role_playing.py +201 -80
  288. camel/societies/workforce/__init__.py +10 -3
  289. camel/societies/workforce/base.py +9 -5
  290. camel/societies/workforce/events.py +143 -0
  291. camel/societies/workforce/prompts.py +258 -33
  292. camel/societies/workforce/role_playing_worker.py +95 -30
  293. camel/societies/workforce/single_agent_worker.py +659 -30
  294. camel/societies/workforce/structured_output_handler.py +512 -0
  295. camel/societies/workforce/task_channel.py +182 -38
  296. camel/societies/workforce/utils.py +784 -18
  297. camel/societies/workforce/worker.py +96 -28
  298. camel/societies/workforce/workflow_memory_manager.py +1746 -0
  299. camel/societies/workforce/workforce.py +5730 -366
  300. camel/societies/workforce/workforce_callback.py +103 -0
  301. camel/societies/workforce/workforce_logger.py +647 -0
  302. camel/societies/workforce/workforce_metrics.py +33 -0
  303. camel/storages/__init__.py +10 -2
  304. camel/storages/graph_storages/__init__.py +2 -2
  305. camel/storages/graph_storages/base.py +2 -2
  306. camel/storages/graph_storages/graph_element.py +2 -2
  307. camel/storages/graph_storages/nebula_graph.py +4 -4
  308. camel/storages/graph_storages/neo4j_graph.py +7 -7
  309. camel/storages/key_value_storages/__init__.py +2 -2
  310. camel/storages/key_value_storages/base.py +2 -2
  311. camel/storages/key_value_storages/in_memory.py +2 -2
  312. camel/storages/key_value_storages/json.py +17 -4
  313. camel/storages/key_value_storages/mem0_cloud.py +50 -49
  314. camel/storages/key_value_storages/redis.py +2 -2
  315. camel/storages/object_storages/__init__.py +2 -2
  316. camel/storages/object_storages/amazon_s3.py +2 -2
  317. camel/storages/object_storages/azure_blob.py +2 -2
  318. camel/storages/object_storages/base.py +2 -2
  319. camel/storages/object_storages/google_cloud.py +3 -3
  320. camel/storages/vectordb_storages/__init__.py +12 -2
  321. camel/storages/vectordb_storages/base.py +2 -2
  322. camel/storages/vectordb_storages/chroma.py +731 -0
  323. camel/storages/vectordb_storages/faiss.py +712 -0
  324. camel/storages/vectordb_storages/milvus.py +2 -2
  325. camel/storages/vectordb_storages/oceanbase.py +16 -17
  326. camel/storages/vectordb_storages/pgvector.py +349 -0
  327. camel/storages/vectordb_storages/qdrant.py +6 -6
  328. camel/storages/vectordb_storages/surreal.py +372 -0
  329. camel/storages/vectordb_storages/tidb.py +11 -8
  330. camel/storages/vectordb_storages/weaviate.py +714 -0
  331. camel/tasks/__init__.py +2 -2
  332. camel/tasks/task.py +366 -27
  333. camel/tasks/task_prompt.py +3 -3
  334. camel/terminators/__init__.py +2 -2
  335. camel/terminators/base.py +2 -2
  336. camel/terminators/response_terminator.py +2 -2
  337. camel/terminators/token_limit_terminator.py +2 -2
  338. camel/toolkits/__init__.py +58 -10
  339. camel/toolkits/aci_toolkit.py +66 -21
  340. camel/toolkits/arxiv_toolkit.py +8 -8
  341. camel/toolkits/ask_news_toolkit.py +2 -2
  342. camel/toolkits/async_browser_toolkit.py +174 -575
  343. camel/toolkits/audio_analysis_toolkit.py +3 -3
  344. camel/toolkits/base.py +65 -7
  345. camel/toolkits/bohrium_toolkit.py +318 -0
  346. camel/toolkits/browser_toolkit.py +306 -566
  347. camel/toolkits/browser_toolkit_commons.py +568 -0
  348. camel/toolkits/code_execution.py +67 -11
  349. camel/toolkits/context_summarizer_toolkit.py +684 -0
  350. camel/toolkits/craw4ai_toolkit.py +93 -0
  351. camel/toolkits/dappier_toolkit.py +12 -8
  352. camel/toolkits/data_commons_toolkit.py +2 -2
  353. camel/toolkits/dingtalk.py +1135 -0
  354. camel/toolkits/earth_science_toolkit.py +5367 -0
  355. camel/toolkits/edgeone_pages_mcp_toolkit.py +49 -0
  356. camel/toolkits/excel_toolkit.py +910 -70
  357. camel/toolkits/file_toolkit.py +1402 -0
  358. camel/toolkits/function_tool.py +128 -20
  359. camel/toolkits/github_toolkit.py +148 -43
  360. camel/toolkits/gmail_toolkit.py +1839 -0
  361. camel/toolkits/google_calendar_toolkit.py +40 -6
  362. camel/toolkits/google_drive_mcp_toolkit.py +54 -0
  363. camel/toolkits/google_maps_toolkit.py +2 -2
  364. camel/toolkits/google_scholar_toolkit.py +2 -2
  365. camel/toolkits/human_toolkit.py +36 -12
  366. camel/toolkits/hybrid_browser_toolkit/__init__.py +18 -0
  367. camel/toolkits/hybrid_browser_toolkit/config_loader.py +185 -0
  368. camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit.py +246 -0
  369. camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit_ts.py +1973 -0
  370. camel/toolkits/hybrid_browser_toolkit/installer.py +203 -0
  371. camel/toolkits/hybrid_browser_toolkit/ts/package-lock.json +4589 -0
  372. camel/toolkits/hybrid_browser_toolkit/ts/package.json +33 -0
  373. camel/toolkits/hybrid_browser_toolkit/ts/src/browser-scripts.js +125 -0
  374. camel/toolkits/hybrid_browser_toolkit/ts/src/browser-session.ts +1929 -0
  375. camel/toolkits/hybrid_browser_toolkit/ts/src/config-loader.ts +233 -0
  376. camel/toolkits/hybrid_browser_toolkit/ts/src/hybrid-browser-toolkit.ts +589 -0
  377. camel/toolkits/hybrid_browser_toolkit/ts/src/index.ts +7 -0
  378. camel/toolkits/hybrid_browser_toolkit/ts/src/parent-child-filter.ts +226 -0
  379. camel/toolkits/hybrid_browser_toolkit/ts/src/snapshot-parser.ts +219 -0
  380. camel/toolkits/hybrid_browser_toolkit/ts/src/som-screenshot-injected.ts +543 -0
  381. camel/toolkits/hybrid_browser_toolkit/ts/src/types.ts +129 -0
  382. camel/toolkits/hybrid_browser_toolkit/ts/tsconfig.json +27 -0
  383. camel/toolkits/hybrid_browser_toolkit/ts/websocket-server.js +319 -0
  384. camel/toolkits/hybrid_browser_toolkit/ws_wrapper.py +1037 -0
  385. camel/toolkits/hybrid_browser_toolkit_py/__init__.py +17 -0
  386. camel/toolkits/hybrid_browser_toolkit_py/actions.py +575 -0
  387. camel/toolkits/hybrid_browser_toolkit_py/agent.py +311 -0
  388. camel/toolkits/hybrid_browser_toolkit_py/browser_session.py +787 -0
  389. camel/toolkits/hybrid_browser_toolkit_py/config_loader.py +490 -0
  390. camel/toolkits/hybrid_browser_toolkit_py/hybrid_browser_toolkit.py +2390 -0
  391. camel/toolkits/hybrid_browser_toolkit_py/snapshot.py +233 -0
  392. camel/toolkits/hybrid_browser_toolkit_py/stealth_script.js +0 -0
  393. camel/toolkits/hybrid_browser_toolkit_py/unified_analyzer.js +1043 -0
  394. camel/toolkits/image_analysis_toolkit.py +3 -3
  395. camel/toolkits/image_generation_toolkit.py +390 -0
  396. camel/toolkits/jina_reranker_toolkit.py +195 -79
  397. camel/toolkits/klavis_toolkit.py +7 -3
  398. camel/toolkits/linkedin_toolkit.py +2 -2
  399. camel/toolkits/markitdown_toolkit.py +104 -0
  400. camel/toolkits/math_toolkit.py +66 -12
  401. camel/toolkits/mcp_toolkit.py +841 -600
  402. camel/toolkits/memory_toolkit.py +7 -3
  403. camel/toolkits/meshy_toolkit.py +2 -2
  404. camel/toolkits/message_agent_toolkit.py +608 -0
  405. camel/toolkits/message_integration.py +724 -0
  406. camel/toolkits/mineru_toolkit.py +2 -2
  407. camel/toolkits/minimax_mcp_toolkit.py +195 -0
  408. camel/toolkits/networkx_toolkit.py +2 -2
  409. camel/toolkits/note_taking_toolkit.py +277 -0
  410. camel/toolkits/notion_mcp_toolkit.py +224 -0
  411. camel/toolkits/notion_toolkit.py +2 -2
  412. camel/toolkits/open_api_specs/biztoc/__init__.py +2 -2
  413. camel/toolkits/open_api_specs/biztoc/ai-plugin.json +1 -1
  414. camel/toolkits/open_api_specs/coursera/__init__.py +2 -2
  415. camel/toolkits/open_api_specs/create_qr_code/__init__.py +2 -2
  416. camel/toolkits/open_api_specs/klarna/__init__.py +2 -2
  417. camel/toolkits/open_api_specs/nasa_apod/__init__.py +2 -2
  418. camel/toolkits/open_api_specs/outschool/__init__.py +2 -2
  419. camel/toolkits/open_api_specs/outschool/ai-plugin.json +1 -1
  420. camel/toolkits/open_api_specs/outschool/openapi.yaml +1 -1
  421. camel/toolkits/open_api_specs/outschool/paths/__init__.py +2 -2
  422. camel/toolkits/open_api_specs/outschool/paths/get_classes.py +2 -2
  423. camel/toolkits/open_api_specs/outschool/paths/search_teachers.py +2 -2
  424. camel/toolkits/open_api_specs/security_config.py +2 -2
  425. camel/toolkits/open_api_specs/speak/__init__.py +2 -2
  426. camel/toolkits/open_api_specs/web_scraper/__init__.py +2 -2
  427. camel/toolkits/open_api_specs/web_scraper/ai-plugin.json +1 -1
  428. camel/toolkits/open_api_specs/web_scraper/paths/__init__.py +2 -2
  429. camel/toolkits/open_api_specs/web_scraper/paths/scraper.py +2 -2
  430. camel/toolkits/open_api_toolkit.py +2 -2
  431. camel/toolkits/openbb_toolkit.py +7 -3
  432. camel/toolkits/origene_mcp_toolkit.py +56 -0
  433. camel/toolkits/page_script.js +86 -74
  434. camel/toolkits/playwright_mcp_toolkit.py +27 -32
  435. camel/toolkits/pptx_toolkit.py +790 -0
  436. camel/toolkits/pubmed_toolkit.py +2 -2
  437. camel/toolkits/pulse_mcp_search_toolkit.py +2 -2
  438. camel/toolkits/pyautogui_toolkit.py +2 -2
  439. camel/toolkits/reddit_toolkit.py +2 -2
  440. camel/toolkits/resend_toolkit.py +168 -0
  441. camel/toolkits/retrieval_toolkit.py +2 -2
  442. camel/toolkits/screenshot_toolkit.py +213 -0
  443. camel/toolkits/search_toolkit.py +539 -146
  444. camel/toolkits/searxng_toolkit.py +2 -2
  445. camel/toolkits/semantic_scholar_toolkit.py +2 -2
  446. camel/toolkits/slack_toolkit.py +108 -58
  447. camel/toolkits/sql_toolkit.py +712 -0
  448. camel/toolkits/stripe_toolkit.py +2 -2
  449. camel/toolkits/sympy_toolkit.py +3 -3
  450. camel/toolkits/task_planning_toolkit.py +134 -0
  451. camel/toolkits/terminal_toolkit/__init__.py +18 -0
  452. camel/toolkits/terminal_toolkit/terminal_toolkit.py +1070 -0
  453. camel/toolkits/terminal_toolkit/utils.py +532 -0
  454. camel/toolkits/thinking_toolkit.py +3 -3
  455. camel/toolkits/twitter_toolkit.py +8 -3
  456. camel/toolkits/vertex_ai_veo_toolkit.py +590 -0
  457. camel/toolkits/video_analysis_toolkit.py +112 -29
  458. camel/toolkits/video_download_toolkit.py +22 -16
  459. camel/toolkits/weather_toolkit.py +2 -2
  460. camel/toolkits/web_deploy_toolkit.py +1219 -0
  461. camel/toolkits/wechat_official_toolkit.py +483 -0
  462. camel/toolkits/whatsapp_toolkit.py +2 -2
  463. camel/toolkits/wolfram_alpha_toolkit.py +53 -25
  464. camel/toolkits/zapier_toolkit.py +7 -3
  465. camel/types/__init__.py +4 -4
  466. camel/types/agents/__init__.py +2 -2
  467. camel/types/agents/tool_calling_record.py +6 -3
  468. camel/types/enums.py +454 -35
  469. camel/types/mcp_registries.py +2 -2
  470. camel/types/openai_types.py +4 -4
  471. camel/types/unified_model_type.py +43 -6
  472. camel/utils/__init__.py +20 -2
  473. camel/utils/async_func.py +2 -2
  474. camel/utils/chunker/__init__.py +2 -2
  475. camel/utils/chunker/base.py +2 -2
  476. camel/utils/chunker/code_chunker.py +2 -2
  477. camel/utils/chunker/uio_chunker.py +2 -2
  478. camel/utils/commons.py +65 -7
  479. camel/utils/constants.py +5 -2
  480. camel/utils/context_utils.py +1134 -0
  481. camel/utils/deduplication.py +2 -2
  482. camel/utils/filename.py +2 -2
  483. camel/utils/langfuse.py +258 -0
  484. camel/utils/mcp.py +140 -6
  485. camel/utils/mcp_client.py +1056 -0
  486. camel/utils/message_summarizer.py +148 -0
  487. camel/utils/response_format.py +2 -2
  488. camel/utils/token_counting.py +45 -22
  489. camel/utils/tool_result.py +44 -0
  490. camel/verifiers/__init__.py +2 -2
  491. camel/verifiers/base.py +2 -2
  492. camel/verifiers/math_verifier.py +2 -2
  493. camel/verifiers/models.py +2 -2
  494. camel/verifiers/physics_verifier.py +2 -2
  495. camel/verifiers/python_verifier.py +2 -2
  496. {camel_ai-0.2.59.dist-info → camel_ai-0.2.82.dist-info}/METADATA +349 -108
  497. camel_ai-0.2.82.dist-info/RECORD +507 -0
  498. {camel_ai-0.2.59.dist-info → camel_ai-0.2.82.dist-info}/WHEEL +1 -1
  499. {camel_ai-0.2.59.dist-info → camel_ai-0.2.82.dist-info}/licenses/LICENSE +1 -1
  500. camel/loaders/pandas_reader.py +0 -368
  501. camel/runtime/api.py +0 -97
  502. camel/toolkits/dalle_toolkit.py +0 -171
  503. camel/toolkits/file_write_toolkit.py +0 -395
  504. camel/toolkits/openai_agent_toolkit.py +0 -135
  505. camel/toolkits/terminal_toolkit.py +0 -1037
  506. camel_ai-0.2.59.dist-info/RECORD +0 -410
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Parent-child filtering logic for SOM-labels
3
+ * Filters out child elements that are contained within propagating parent elements
4
+ */
5
+
6
+ export interface ElementInfo {
7
+ ref: string;
8
+ coordinates?: {
9
+ x: number;
10
+ y: number;
11
+ width: number;
12
+ height: number;
13
+ };
14
+ role?: string;
15
+ type?: string;
16
+ tagName?: string;
17
+ attributes?: Record<string, any>;
18
+ text?: string;
19
+ }
20
+
21
+ // Elements that propagate bounds to their children
22
+ const PROPAGATING_ELEMENTS = [
23
+ { tag: 'a', role: null },
24
+ { tag: 'button', role: null },
25
+ { tag: 'div', role: 'button' },
26
+ { tag: 'div', role: 'combobox' },
27
+ { tag: 'span', role: 'button' },
28
+ { tag: 'span', role: 'combobox' },
29
+ { tag: 'input', role: 'combobox' },
30
+ ];
31
+
32
+ const CONTAINMENT_THRESHOLD = 0.99; // 99% containment required
33
+
34
+ /**
35
+ * Check if element is a propagating element
36
+ */
37
+ function isPropagatingElement(element: ElementInfo): boolean {
38
+ const tagName = element.tagName || element.type || '';
39
+ const tag = tagName.toLowerCase();
40
+ const role = element.role || element.attributes?.role || null;
41
+
42
+ // For generic elements with cursor=pointer, we need to be more selective
43
+ // Only treat them as propagating if they don't have text content
44
+ // (text-containing generics are usually labels, not containers)
45
+ if ((tag === 'generic' || element.type === 'generic') &&
46
+ element.attributes?.['cursor'] === 'pointer') {
47
+ // If element has direct text content, it's likely a label, not a container
48
+ if (element.text && element.text.trim()) {
49
+ return false;
50
+ }
51
+ // If no text, it might be a container
52
+ return true;
53
+ }
54
+
55
+ for (const pattern of PROPAGATING_ELEMENTS) {
56
+ if (pattern.tag === tag) {
57
+ if (pattern.role === null || pattern.role === role) {
58
+ return true;
59
+ }
60
+ }
61
+ }
62
+ return false;
63
+ }
64
+
65
+ /**
66
+ * Check if child bounds are contained within parent bounds
67
+ */
68
+ function isContained(
69
+ childBounds: { x: number; y: number; width: number; height: number },
70
+ parentBounds: { x: number; y: number; width: number; height: number },
71
+ threshold: number
72
+ ): boolean {
73
+ // Calculate intersection
74
+ const xOverlap = Math.max(0,
75
+ Math.min(childBounds.x + childBounds.width, parentBounds.x + parentBounds.width) -
76
+ Math.max(childBounds.x, parentBounds.x)
77
+ );
78
+ const yOverlap = Math.max(0,
79
+ Math.min(childBounds.y + childBounds.height, parentBounds.y + parentBounds.height) -
80
+ Math.max(childBounds.y, parentBounds.y)
81
+ );
82
+
83
+ const intersectionArea = xOverlap * yOverlap;
84
+ const childArea = childBounds.width * childBounds.height;
85
+
86
+ if (childArea === 0) return false;
87
+
88
+ return (intersectionArea / childArea) >= threshold;
89
+ }
90
+
91
+ /**
92
+ * Check if child element should be filtered out
93
+ */
94
+ function shouldFilterChild(childEl: ElementInfo, parentEl: ElementInfo): boolean {
95
+ // Never filter if parent is not a propagating element
96
+ if (!isPropagatingElement(parentEl)) {
97
+ return false;
98
+ }
99
+
100
+ // Never filter if elements don't have coordinates
101
+ if (!childEl.coordinates || !parentEl.coordinates) {
102
+ return false;
103
+ }
104
+
105
+ // Check containment
106
+ if (!isContained(childEl.coordinates, parentEl.coordinates, CONTAINMENT_THRESHOLD)) {
107
+ return false;
108
+ }
109
+
110
+ const childTag = (childEl.tagName || childEl.type || '').toLowerCase();
111
+ const childRole = childEl.role || childEl.attributes?.role || null;
112
+
113
+ // Exception rules - never filter these:
114
+
115
+ // 1. Form elements (need individual interaction)
116
+ if (['input', 'select', 'textarea', 'label'].includes(childTag)) {
117
+ return false;
118
+ }
119
+
120
+ // 2. Child is also a propagating element (might have stopPropagation)
121
+ if (isPropagatingElement(childEl)) {
122
+ return false;
123
+ }
124
+
125
+ // 3. Has onclick handler
126
+ if (childEl.attributes?.onclick) {
127
+ return false;
128
+ }
129
+
130
+ // 4. Has meaningful aria-label
131
+ if (childEl.attributes?.['aria-label']?.trim()) {
132
+ return false;
133
+ }
134
+
135
+ // 5. Has interactive role
136
+ if (['button', 'link', 'checkbox', 'radio', 'tab', 'menuitem'].includes(childRole || '')) {
137
+ return false;
138
+ }
139
+
140
+ // Default: filter this child
141
+ return true;
142
+ }
143
+
144
+ /**
145
+ * Filter clickable elements based on parent-child relationships
146
+ * @param elements - Map of all elements with their info
147
+ * @param clickableRefs - Set of refs that are clickable
148
+ * @returns Filtered set of element refs and debug info
149
+ */
150
+ export function filterParentChildElements(
151
+ elements: Record<string, ElementInfo>,
152
+ clickableRefs: Set<string>
153
+ ): {
154
+ filteredElements: Set<string>;
155
+ debugInfo: any[];
156
+ } {
157
+ const elementRefs = Array.from(clickableRefs);
158
+ const filteredElements = new Set<string>(elementRefs);
159
+ const debugInfo: any[] = [];
160
+
161
+ console.log(`[Parent-Child Filter] Analyzing ${elementRefs.length} clickable elements`);
162
+
163
+ // Check each pair of elements for parent-child filtering
164
+ for (let i = 0; i < elementRefs.length; i++) {
165
+ const parentRef = elementRefs[i];
166
+ const parentEl = elements[parentRef];
167
+
168
+ if (!parentEl?.coordinates) continue;
169
+
170
+ const isParentPropagating = isPropagatingElement(parentEl);
171
+
172
+ for (let j = 0; j < elementRefs.length; j++) {
173
+ if (i === j) continue;
174
+
175
+ const childRef = elementRefs[j];
176
+ const childEl = elements[childRef];
177
+
178
+ if (!childEl?.coordinates) continue;
179
+
180
+ // Debug parent-child relationships when enabled
181
+ const DEBUG_PARENT_CHILD = process.env.DEBUG_PARENT_CHILD === 'true';
182
+ if (DEBUG_PARENT_CHILD) {
183
+ const shouldFilter = shouldFilterChild(childEl, parentEl);
184
+ console.log(`\n[Debug] Checking ${parentRef} -> ${childRef}:`);
185
+ console.log(`Parent:`, {
186
+ ref: parentRef,
187
+ type: parentEl.type || parentEl.tagName,
188
+ role: parentEl.role,
189
+ coords: parentEl.coordinates,
190
+ isPropagating: isParentPropagating
191
+ });
192
+ console.log(`Child:`, {
193
+ ref: childRef,
194
+ type: childEl.type || childEl.tagName,
195
+ role: childEl.role,
196
+ coords: childEl.coordinates
197
+ });
198
+ console.log(`Should filter? ${shouldFilter}`);
199
+ }
200
+
201
+ if (shouldFilterChild(childEl, parentEl)) {
202
+ filteredElements.delete(childRef);
203
+
204
+ debugInfo.push({
205
+ type: 'filtered',
206
+ childRef,
207
+ parentRef,
208
+ reason: 'Contained within propagating parent',
209
+ parentType: parentEl.type || parentEl.tagName,
210
+ childType: childEl.type || childEl.tagName,
211
+ parentRole: parentEl.role,
212
+ childRole: childEl.role,
213
+ containment: isContained(childEl.coordinates, parentEl.coordinates, CONTAINMENT_THRESHOLD)
214
+ });
215
+ }
216
+ }
217
+ }
218
+
219
+ const filteredCount = elementRefs.length - filteredElements.size;
220
+ console.log(`[Parent-Child Filter] Filtered out ${filteredCount} child elements`);
221
+
222
+ return {
223
+ filteredElements,
224
+ debugInfo
225
+ };
226
+ }
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Parse snapshot text to extract parent-child relationships
3
+ */
4
+
5
+ export interface SnapshotNode {
6
+ ref: string;
7
+ type: string;
8
+ text?: string;
9
+ attributes: Record<string, string>;
10
+ children: string[]; // refs of child elements
11
+ parent?: string; // ref of parent element
12
+ }
13
+
14
+ export function parseSnapshotHierarchy(snapshotText: string): Map<string, SnapshotNode> {
15
+ const nodes = new Map<string, SnapshotNode>();
16
+ const lines = snapshotText.split('\n');
17
+
18
+ // Stack to track parent elements at each indentation level
19
+ const parentStack: { ref: string; indent: number }[] = [];
20
+
21
+ for (const line of lines) {
22
+ if (!line.trim()) continue;
23
+
24
+ const indent = line.length - line.trimStart().length;
25
+
26
+ // Extract type and optional label
27
+ const headerMatch = line.match(/^\s*(?:-\s*)?'?([a-z0-9_-]+)(?:\s+"((?:[^"\\]|\\.)*)")?/i);
28
+ if (!headerMatch) continue;
29
+ const [, typeRaw, label] = headerMatch;
30
+ const type = (typeRaw || 'unknown');
31
+
32
+ const refMatch = line.match(/\[ref=([^\]]+)\]/i);
33
+ if (!refMatch) continue;
34
+ const ref = refMatch[1];
35
+
36
+ // Parse bracketed attributes
37
+ const attrs: Record<string, string> = {};
38
+ for (const block of line.matchAll(/\[([^\]]+)\]/g)) {
39
+ const content = block[1];
40
+ if (/^ref=/i.test(content)) continue;
41
+ const attrMatches = content.matchAll(/([a-z0-9_-]+)(?:=(?:"([^"]*)"|'([^']*)'|([^\s\]]+)))?/gi);
42
+ for (const m of attrMatches) {
43
+ const key = m[1].toLowerCase();
44
+ const val = m[2] ?? m[3] ?? m[4] ?? 'true';
45
+ attrs[key] = val;
46
+ }
47
+ }
48
+
49
+ while (parentStack.length > 0 && parentStack[parentStack.length - 1].indent >= indent) {
50
+ parentStack.pop();
51
+ }
52
+
53
+ const node: SnapshotNode = {
54
+ ref,
55
+ type: type.toLowerCase(),
56
+ text: label || '',
57
+ attributes: attrs,
58
+ children: [],
59
+ parent: parentStack.length > 0 ? parentStack[parentStack.length - 1].ref : undefined
60
+ };
61
+
62
+ if (node.parent && nodes.has(node.parent)) {
63
+ nodes.get(node.parent)!.children.push(ref);
64
+ }
65
+
66
+ nodes.set(ref, node);
67
+
68
+ parentStack.push({ ref, indent });
69
+ }
70
+
71
+ return nodes;
72
+ }
73
+
74
+ /**
75
+ * Find clickable elements that should be filtered based on DOM hierarchy
76
+ */
77
+ export function filterClickableByHierarchy(
78
+ snapshotText: string,
79
+ clickableElements: Set<string>
80
+ ): Set<string> {
81
+ const hierarchy = parseSnapshotHierarchy(snapshotText);
82
+ const filtered = new Set<string>(clickableElements);
83
+ const debugInfo: any[] = [];
84
+
85
+ // Debug clickable elements when enabled
86
+ const DEBUG_SNAPSHOT_PARSER = process.env.DEBUG_SNAPSHOT_PARSER === 'true';
87
+ if (DEBUG_SNAPSHOT_PARSER) {
88
+ clickableElements.forEach(ref => {
89
+ const node = hierarchy.get(ref);
90
+ if (node) {
91
+ console.log(`[Debug] ${ref} type: ${node.type}, parent: ${node.parent || 'none'}`);
92
+ } else {
93
+ console.log(`[Debug] ${ref} NOT FOUND in hierarchy!`);
94
+ }
95
+ });
96
+ }
97
+
98
+ // First pass: identify parent-child relationships where both are clickable
99
+ const parentChildPairs: Array<{parent: string, child: string, parentType: string, childType: string}> = [];
100
+
101
+ for (const childRef of clickableElements) {
102
+ const childNode = hierarchy.get(childRef);
103
+ if (!childNode || !childNode.parent) continue;
104
+
105
+ const parentRef = childNode.parent;
106
+ if (clickableElements.has(parentRef)) {
107
+ const parentNode = hierarchy.get(parentRef);
108
+ if (parentNode) {
109
+ parentChildPairs.push({
110
+ parent: parentRef,
111
+ child: childRef,
112
+ parentType: parentNode.type.toLowerCase(),
113
+ childType: childNode.type.toLowerCase()
114
+ });
115
+
116
+ // Debug specific pairs
117
+ if ((parentRef === 'e296' && childRef === 'e297') ||
118
+ (parentRef === 'e361' && childRef === 'e363') ||
119
+ (parentRef === 'e371' && childRef === 'e373') ||
120
+ (parentRef === 'e344' && childRef === 'e346') ||
121
+ (parentRef === 'e348' && childRef === 'e350')) {
122
+ console.log(`[Debug] Found pair: ${parentRef} (${parentNode.type}) -> ${childRef} (${childNode.type})`);
123
+ }
124
+ }
125
+ }
126
+ }
127
+
128
+ // Decide which elements to filter based on parent-child relationships
129
+ for (const pair of parentChildPairs) {
130
+ const { parent, child, parentType, childType } = pair;
131
+
132
+ // Rules for what to filter:
133
+ // 1. link > img: filter img (keep link)
134
+ // 2. button > generic: filter generic (keep button)
135
+ // 3. generic > button: filter generic (keep button)
136
+ // 4. link > generic: filter generic (keep link)
137
+ // 5. generic > generic: filter child (keep parent)
138
+ // 6. generic > unknown: filter child (keep parent)
139
+
140
+ if ((parentType === 'link' && childType === 'img') ||
141
+ (parentType === 'button' && childType === 'generic') ||
142
+ (parentType === 'link' && childType === 'generic') ||
143
+ (parentType === 'generic' && childType === 'generic') ||
144
+ (parentType === 'generic' && childType === 'unknown')) {
145
+ // Filter child
146
+ filtered.delete(child);
147
+ console.log(`[Hierarchy Filter] Filtered ${child} (${childType}) - keeping parent ${parent} (${parentType})`);
148
+ } else if (parentType === 'generic' && childType === 'button') {
149
+ // Special case: filter parent generic, keep child button
150
+ filtered.delete(parent);
151
+ console.log(`[Hierarchy Filter] Filtered ${parent} (${parentType}) - keeping child ${child} (${childType})`);
152
+ }
153
+ }
154
+
155
+ // Original logic for nested hierarchies (keep for deep nesting)
156
+ for (const childRef of clickableElements) {
157
+ if (!filtered.has(childRef)) continue; // Already filtered
158
+
159
+ const childNode = hierarchy.get(childRef);
160
+ if (!childNode || !childNode.parent) continue;
161
+
162
+ // Check if any ancestor is a propagating element
163
+ let currentParent: string | undefined = childNode.parent;
164
+ while (currentParent) {
165
+ if (clickableElements.has(currentParent) && filtered.has(currentParent)) {
166
+ const parentNode = hierarchy.get(currentParent);
167
+ if (parentNode) {
168
+ // Check if parent is a propagating element
169
+ const parentType = parentNode.type.toLowerCase();
170
+ const isPropagating = ['button', 'link', 'a'].includes(parentType) ||
171
+ (parentType === 'generic' && parentNode.attributes.cursor === 'pointer' && !parentNode.text);
172
+
173
+ if (isPropagating) {
174
+ // Filter child elements that should be contained within propagating parents
175
+ const childType = childNode.type.toLowerCase();
176
+
177
+ // Filter these types of children:
178
+ // 1. Generic elements with cursor=pointer
179
+ // 2. Images within links/buttons
180
+ // 3. Text elements (span, generic without specific role)
181
+ const shouldFilter =
182
+ (childType === 'generic' && childNode.attributes.cursor === 'pointer') ||
183
+ childType === 'img' ||
184
+ childType === 'span' ||
185
+ (childType === 'generic' && !childNode.attributes.role);
186
+
187
+ if (shouldFilter) {
188
+ filtered.delete(childRef);
189
+ console.log(`[Hierarchy Filter] Filtered ${childRef} (${childType}) contained in ${currentParent} (${parentType})`);
190
+ break;
191
+ }
192
+ }
193
+ }
194
+ }
195
+ // Move up the hierarchy
196
+ const nextParent = hierarchy.get(currentParent);
197
+ currentParent = nextParent?.parent;
198
+ }
199
+ }
200
+
201
+ // Additional pass: if a generic parent contains only one button child, filter the parent
202
+ for (const ref of Array.from(filtered)) {
203
+ const node = hierarchy.get(ref);
204
+ if (!node || node.type.toLowerCase() !== 'generic') continue;
205
+
206
+ // Check if this generic has exactly one clickable child that's a button
207
+ const clickableChildren = node.children.filter(childRef =>
208
+ filtered.has(childRef) && hierarchy.get(childRef)?.type.toLowerCase() === 'button'
209
+ );
210
+
211
+ if (clickableChildren.length === 1) {
212
+ // This generic wraps a single button - filter it out
213
+ filtered.delete(ref);
214
+ console.log(`[Hierarchy Filter] Filtered ${ref} (generic wrapper around button ${clickableChildren[0]})`);
215
+ }
216
+ }
217
+
218
+ return filtered;
219
+ }