camel-ai 0.2.82__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 (481) hide show
  1. camel/__init__.py +3 -3
  2. camel/agents/__init__.py +2 -2
  3. camel/agents/_types.py +2 -2
  4. camel/agents/_utils.py +2 -2
  5. camel/agents/base.py +2 -2
  6. camel/agents/chat_agent.py +765 -541
  7. camel/agents/critic_agent.py +2 -2
  8. camel/agents/deductive_reasoner_agent.py +2 -2
  9. camel/agents/embodied_agent.py +2 -2
  10. camel/agents/knowledge_graph_agent.py +2 -2
  11. camel/agents/mcp_agent.py +2 -2
  12. camel/agents/multi_hop_generator_agent.py +2 -2
  13. camel/agents/programmed_agent_instruction.py +2 -2
  14. camel/agents/repo_agent.py +2 -2
  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 +2 -2
  21. camel/benchmarks/__init__.py +2 -2
  22. camel/benchmarks/apibank.py +2 -2
  23. camel/benchmarks/apibench.py +2 -2
  24. camel/benchmarks/base.py +2 -2
  25. camel/benchmarks/browsecomp.py +2 -2
  26. camel/benchmarks/gaia.py +2 -2
  27. camel/benchmarks/mock_website/mock_web.py +2 -2
  28. camel/benchmarks/mock_website/shopping_mall/app.py +2 -2
  29. camel/benchmarks/nexus.py +2 -2
  30. camel/benchmarks/ragbench.py +2 -2
  31. camel/bots/__init__.py +2 -2
  32. camel/bots/discord/__init__.py +2 -2
  33. camel/bots/discord/discord_app.py +2 -2
  34. camel/bots/discord/discord_installation.py +2 -2
  35. camel/bots/discord/discord_store.py +2 -2
  36. camel/bots/slack/__init__.py +2 -2
  37. camel/bots/slack/models.py +2 -2
  38. camel/bots/slack/slack_app.py +2 -2
  39. camel/bots/telegram_bot.py +2 -2
  40. camel/configs/__init__.py +8 -2
  41. camel/configs/aihubmix_config.py +2 -2
  42. camel/configs/aiml_config.py +2 -2
  43. camel/configs/amd_config.py +2 -2
  44. camel/configs/anthropic_config.py +2 -2
  45. camel/configs/base_config.py +2 -2
  46. camel/configs/bedrock_config.py +2 -2
  47. camel/configs/cerebras_config.py +2 -2
  48. camel/configs/cohere_config.py +2 -2
  49. camel/configs/cometapi_config.py +2 -2
  50. camel/configs/crynux_config.py +2 -2
  51. camel/configs/deepseek_config.py +2 -2
  52. camel/configs/function_gemma_config.py +59 -0
  53. camel/configs/gemini_config.py +2 -2
  54. camel/configs/groq_config.py +2 -2
  55. camel/configs/internlm_config.py +2 -2
  56. camel/configs/litellm_config.py +2 -2
  57. camel/configs/lmstudio_config.py +2 -2
  58. camel/configs/minimax_config.py +2 -2
  59. camel/configs/mistral_config.py +2 -2
  60. camel/configs/modelscope_config.py +2 -2
  61. camel/configs/moonshot_config.py +2 -2
  62. camel/configs/nebius_config.py +2 -2
  63. camel/configs/netmind_config.py +2 -2
  64. camel/configs/novita_config.py +2 -2
  65. camel/configs/nvidia_config.py +2 -2
  66. camel/configs/ollama_config.py +2 -2
  67. camel/configs/openai_config.py +2 -2
  68. camel/configs/openrouter_config.py +2 -2
  69. camel/configs/ppio_config.py +2 -2
  70. camel/configs/qianfan_config.py +2 -2
  71. camel/configs/qwen_config.py +2 -2
  72. camel/configs/reka_config.py +2 -2
  73. camel/configs/samba_config.py +2 -2
  74. camel/configs/sglang_config.py +2 -2
  75. camel/configs/siliconflow_config.py +2 -2
  76. camel/configs/togetherai_config.py +2 -2
  77. camel/configs/vllm_config.py +2 -2
  78. camel/configs/watsonx_config.py +2 -2
  79. camel/configs/yi_config.py +2 -2
  80. camel/configs/zhipuai_config.py +2 -2
  81. camel/data_collectors/__init__.py +2 -2
  82. camel/data_collectors/alpaca_collector.py +2 -2
  83. camel/data_collectors/base.py +2 -2
  84. camel/data_collectors/sharegpt_collector.py +2 -2
  85. camel/datagen/__init__.py +2 -2
  86. camel/datagen/cot_datagen.py +2 -2
  87. camel/datagen/evol_instruct/__init__.py +2 -2
  88. camel/datagen/evol_instruct/evol_instruct.py +2 -2
  89. camel/datagen/evol_instruct/scorer.py +2 -2
  90. camel/datagen/evol_instruct/templates.py +2 -2
  91. camel/datagen/self_improving_cot.py +2 -2
  92. camel/datagen/self_instruct/__init__.py +2 -2
  93. camel/datagen/self_instruct/filter/__init__.py +2 -2
  94. camel/datagen/self_instruct/filter/filter_function.py +2 -2
  95. camel/datagen/self_instruct/filter/filter_registry.py +2 -2
  96. camel/datagen/self_instruct/filter/instruction_filter.py +2 -2
  97. camel/datagen/self_instruct/self_instruct.py +2 -2
  98. camel/datagen/self_instruct/templates.py +2 -2
  99. camel/datagen/source2synth/__init__.py +2 -2
  100. camel/datagen/source2synth/data_processor.py +2 -2
  101. camel/datagen/source2synth/models.py +2 -2
  102. camel/datagen/source2synth/user_data_processor_config.py +2 -2
  103. camel/datahubs/__init__.py +2 -2
  104. camel/datahubs/base.py +2 -2
  105. camel/datahubs/huggingface.py +2 -2
  106. camel/datahubs/models.py +2 -2
  107. camel/datasets/__init__.py +2 -2
  108. camel/datasets/base_generator.py +2 -2
  109. camel/datasets/few_shot_generator.py +2 -2
  110. camel/datasets/models.py +2 -2
  111. camel/datasets/self_instruct_generator.py +2 -2
  112. camel/datasets/static_dataset.py +2 -2
  113. camel/embeddings/__init__.py +2 -2
  114. camel/embeddings/azure_embedding.py +2 -2
  115. camel/embeddings/base.py +2 -2
  116. camel/embeddings/gemini_embedding.py +2 -2
  117. camel/embeddings/jina_embedding.py +2 -2
  118. camel/embeddings/mistral_embedding.py +2 -2
  119. camel/embeddings/openai_compatible_embedding.py +2 -2
  120. camel/embeddings/openai_embedding.py +2 -2
  121. camel/embeddings/sentence_transformers_embeddings.py +2 -2
  122. camel/embeddings/together_embedding.py +2 -2
  123. camel/embeddings/vlm_embedding.py +2 -2
  124. camel/environments/__init__.py +2 -2
  125. camel/environments/models.py +2 -2
  126. camel/environments/multi_step.py +2 -2
  127. camel/environments/rlcards_env.py +2 -2
  128. camel/environments/single_step.py +2 -2
  129. camel/environments/tic_tac_toe.py +2 -2
  130. camel/extractors/__init__.py +2 -2
  131. camel/extractors/base.py +2 -2
  132. camel/extractors/python_strategies.py +2 -2
  133. camel/generators.py +2 -2
  134. camel/human.py +2 -2
  135. camel/interpreters/__init__.py +2 -2
  136. camel/interpreters/base.py +2 -2
  137. camel/interpreters/docker_interpreter.py +2 -2
  138. camel/interpreters/e2b_interpreter.py +2 -2
  139. camel/interpreters/internal_python_interpreter.py +2 -2
  140. camel/interpreters/interpreter_error.py +2 -2
  141. camel/interpreters/ipython_interpreter.py +2 -2
  142. camel/interpreters/microsandbox_interpreter.py +2 -2
  143. camel/interpreters/subprocess_interpreter.py +2 -2
  144. camel/loaders/__init__.py +2 -2
  145. camel/loaders/apify_reader.py +2 -2
  146. camel/loaders/base_io.py +2 -2
  147. camel/loaders/base_loader.py +2 -2
  148. camel/loaders/chunkr_reader.py +2 -2
  149. camel/loaders/crawl4ai_reader.py +2 -2
  150. camel/loaders/firecrawl_reader.py +2 -2
  151. camel/loaders/jina_url_reader.py +2 -2
  152. camel/loaders/markitdown.py +2 -2
  153. camel/loaders/mineru_extractor.py +2 -2
  154. camel/loaders/mistral_reader.py +2 -2
  155. camel/loaders/scrapegraph_reader.py +2 -2
  156. camel/loaders/unstructured_io.py +2 -2
  157. camel/logger.py +2 -2
  158. camel/memories/__init__.py +2 -2
  159. camel/memories/agent_memories.py +2 -2
  160. camel/memories/base.py +2 -2
  161. camel/memories/blocks/__init__.py +2 -2
  162. camel/memories/blocks/chat_history_block.py +2 -2
  163. camel/memories/blocks/vectordb_block.py +2 -2
  164. camel/memories/context_creators/__init__.py +2 -2
  165. camel/memories/context_creators/score_based.py +89 -2
  166. camel/memories/records.py +2 -2
  167. camel/messages/__init__.py +2 -2
  168. camel/messages/base.py +2 -2
  169. camel/messages/conversion/__init__.py +2 -2
  170. camel/messages/conversion/alpaca.py +2 -2
  171. camel/messages/conversion/conversation_models.py +2 -2
  172. camel/messages/conversion/sharegpt/__init__.py +2 -2
  173. camel/messages/conversion/sharegpt/function_call_formatter.py +2 -2
  174. camel/messages/conversion/sharegpt/hermes/__init__.py +2 -2
  175. camel/messages/conversion/sharegpt/hermes/hermes_function_formatter.py +2 -2
  176. camel/messages/func_message.py +2 -2
  177. camel/models/__init__.py +4 -2
  178. camel/models/_utils.py +2 -2
  179. camel/models/aihubmix_model.py +2 -2
  180. camel/models/aiml_model.py +2 -2
  181. camel/models/amd_model.py +2 -2
  182. camel/models/anthropic_model.py +2 -2
  183. camel/models/aws_bedrock_model.py +2 -2
  184. camel/models/azure_openai_model.py +4 -28
  185. camel/models/base_audio_model.py +2 -2
  186. camel/models/base_model.py +192 -14
  187. camel/models/cerebras_model.py +2 -2
  188. camel/models/cohere_model.py +4 -30
  189. camel/models/cometapi_model.py +2 -2
  190. camel/models/crynux_model.py +2 -2
  191. camel/models/deepseek_model.py +4 -28
  192. camel/models/fish_audio_model.py +2 -2
  193. camel/models/function_gemma_model.py +889 -0
  194. camel/models/gemini_model.py +4 -28
  195. camel/models/groq_model.py +2 -2
  196. camel/models/internlm_model.py +2 -2
  197. camel/models/litellm_model.py +3 -17
  198. camel/models/lmstudio_model.py +2 -2
  199. camel/models/minimax_model.py +2 -2
  200. camel/models/mistral_model.py +4 -30
  201. camel/models/model_factory.py +4 -2
  202. camel/models/model_manager.py +2 -2
  203. camel/models/modelscope_model.py +2 -2
  204. camel/models/moonshot_model.py +3 -15
  205. camel/models/nebius_model.py +2 -2
  206. camel/models/nemotron_model.py +2 -2
  207. camel/models/netmind_model.py +2 -2
  208. camel/models/novita_model.py +2 -2
  209. camel/models/nvidia_model.py +2 -2
  210. camel/models/ollama_model.py +2 -2
  211. camel/models/openai_audio_models.py +2 -2
  212. camel/models/openai_compatible_model.py +4 -28
  213. camel/models/openai_model.py +4 -43
  214. camel/models/openrouter_model.py +2 -2
  215. camel/models/ppio_model.py +2 -2
  216. camel/models/qianfan_model.py +2 -2
  217. camel/models/qwen_model.py +2 -2
  218. camel/models/reka_model.py +4 -30
  219. camel/models/reward/__init__.py +2 -2
  220. camel/models/reward/base_reward_model.py +2 -2
  221. camel/models/reward/evaluator.py +2 -2
  222. camel/models/reward/nemotron_model.py +2 -2
  223. camel/models/reward/skywork_model.py +2 -2
  224. camel/models/samba_model.py +4 -30
  225. camel/models/sglang_model.py +4 -30
  226. camel/models/siliconflow_model.py +2 -2
  227. camel/models/stub_model.py +2 -2
  228. camel/models/togetherai_model.py +2 -2
  229. camel/models/vllm_model.py +2 -2
  230. camel/models/volcano_model.py +147 -4
  231. camel/models/watsonx_model.py +4 -30
  232. camel/models/yi_model.py +2 -2
  233. camel/models/zhipuai_model.py +2 -2
  234. camel/parsers/__init__.py +2 -2
  235. camel/parsers/mcp_tool_call_parser.py +2 -2
  236. camel/personas/__init__.py +2 -2
  237. camel/personas/persona.py +2 -2
  238. camel/personas/persona_hub.py +2 -2
  239. camel/prompts/__init__.py +2 -2
  240. camel/prompts/ai_society.py +2 -2
  241. camel/prompts/base.py +2 -2
  242. camel/prompts/code.py +2 -2
  243. camel/prompts/evaluation.py +2 -2
  244. camel/prompts/generate_text_embedding_data.py +2 -2
  245. camel/prompts/image_craft.py +2 -2
  246. camel/prompts/misalignment.py +2 -2
  247. camel/prompts/multi_condition_image_craft.py +2 -2
  248. camel/prompts/object_recognition.py +2 -2
  249. camel/prompts/persona_hub.py +2 -2
  250. camel/prompts/prompt_templates.py +2 -2
  251. camel/prompts/role_description_prompt_template.py +2 -2
  252. camel/prompts/solution_extraction.py +2 -2
  253. camel/prompts/task_prompt_template.py +2 -2
  254. camel/prompts/translation.py +2 -2
  255. camel/prompts/video_description_prompt.py +2 -2
  256. camel/responses/__init__.py +2 -2
  257. camel/responses/agent_responses.py +2 -2
  258. camel/retrievers/__init__.py +2 -2
  259. camel/retrievers/auto_retriever.py +2 -2
  260. camel/retrievers/base.py +2 -2
  261. camel/retrievers/bm25_retriever.py +2 -2
  262. camel/retrievers/cohere_rerank_retriever.py +2 -2
  263. camel/retrievers/hybrid_retrival.py +2 -2
  264. camel/retrievers/vector_retriever.py +2 -2
  265. camel/runtimes/__init__.py +2 -2
  266. camel/runtimes/api.py +2 -2
  267. camel/runtimes/base.py +2 -2
  268. camel/runtimes/configs.py +2 -2
  269. camel/runtimes/daytona_runtime.py +2 -2
  270. camel/runtimes/docker_runtime.py +2 -2
  271. camel/runtimes/llm_guard_runtime.py +2 -2
  272. camel/runtimes/remote_http_runtime.py +2 -2
  273. camel/runtimes/ubuntu_docker_runtime.py +2 -2
  274. camel/runtimes/utils/__init__.py +2 -2
  275. camel/runtimes/utils/function_risk_toolkit.py +2 -2
  276. camel/runtimes/utils/ignore_risk_toolkit.py +2 -2
  277. camel/schemas/__init__.py +2 -2
  278. camel/schemas/base.py +2 -2
  279. camel/schemas/openai_converter.py +2 -2
  280. camel/schemas/outlines_converter.py +2 -2
  281. camel/services/agent_openapi_server.py +2 -2
  282. camel/societies/__init__.py +2 -2
  283. camel/societies/babyagi_playing.py +2 -2
  284. camel/societies/role_playing.py +2 -2
  285. camel/societies/workforce/__init__.py +2 -2
  286. camel/societies/workforce/base.py +2 -2
  287. camel/societies/workforce/events.py +4 -2
  288. camel/societies/workforce/prompts.py +9 -8
  289. camel/societies/workforce/role_playing_worker.py +2 -2
  290. camel/societies/workforce/single_agent_worker.py +2 -2
  291. camel/societies/workforce/structured_output_handler.py +2 -2
  292. camel/societies/workforce/task_channel.py +2 -2
  293. camel/societies/workforce/utils.py +2 -2
  294. camel/societies/workforce/worker.py +2 -2
  295. camel/societies/workforce/workflow_memory_manager.py +2 -2
  296. camel/societies/workforce/workforce.py +132 -71
  297. camel/societies/workforce/workforce_callback.py +2 -2
  298. camel/societies/workforce/workforce_logger.py +2 -2
  299. camel/societies/workforce/workforce_metrics.py +2 -2
  300. camel/storages/__init__.py +2 -2
  301. camel/storages/graph_storages/__init__.py +2 -2
  302. camel/storages/graph_storages/base.py +2 -2
  303. camel/storages/graph_storages/graph_element.py +2 -2
  304. camel/storages/graph_storages/nebula_graph.py +2 -2
  305. camel/storages/graph_storages/neo4j_graph.py +2 -2
  306. camel/storages/key_value_storages/__init__.py +2 -2
  307. camel/storages/key_value_storages/base.py +2 -2
  308. camel/storages/key_value_storages/in_memory.py +2 -2
  309. camel/storages/key_value_storages/json.py +2 -2
  310. camel/storages/key_value_storages/mem0_cloud.py +2 -2
  311. camel/storages/key_value_storages/redis.py +2 -2
  312. camel/storages/object_storages/__init__.py +2 -2
  313. camel/storages/object_storages/amazon_s3.py +2 -2
  314. camel/storages/object_storages/azure_blob.py +2 -2
  315. camel/storages/object_storages/base.py +2 -2
  316. camel/storages/object_storages/google_cloud.py +2 -2
  317. camel/storages/vectordb_storages/__init__.py +2 -2
  318. camel/storages/vectordb_storages/base.py +2 -2
  319. camel/storages/vectordb_storages/chroma.py +2 -2
  320. camel/storages/vectordb_storages/faiss.py +2 -2
  321. camel/storages/vectordb_storages/milvus.py +2 -2
  322. camel/storages/vectordb_storages/oceanbase.py +2 -2
  323. camel/storages/vectordb_storages/pgvector.py +2 -2
  324. camel/storages/vectordb_storages/qdrant.py +2 -2
  325. camel/storages/vectordb_storages/surreal.py +2 -2
  326. camel/storages/vectordb_storages/tidb.py +2 -2
  327. camel/storages/vectordb_storages/weaviate.py +2 -2
  328. camel/tasks/__init__.py +2 -2
  329. camel/tasks/task.py +2 -2
  330. camel/tasks/task_prompt.py +2 -2
  331. camel/terminators/__init__.py +2 -2
  332. camel/terminators/base.py +2 -2
  333. camel/terminators/response_terminator.py +2 -2
  334. camel/terminators/token_limit_terminator.py +2 -2
  335. camel/toolkits/__init__.py +6 -3
  336. camel/toolkits/aci_toolkit.py +2 -2
  337. camel/toolkits/arxiv_toolkit.py +2 -2
  338. camel/toolkits/ask_news_toolkit.py +2 -2
  339. camel/toolkits/async_browser_toolkit.py +2 -2
  340. camel/toolkits/audio_analysis_toolkit.py +2 -2
  341. camel/toolkits/base.py +47 -5
  342. camel/toolkits/bohrium_toolkit.py +2 -2
  343. camel/toolkits/browser_toolkit.py +2 -2
  344. camel/toolkits/browser_toolkit_commons.py +2 -2
  345. camel/toolkits/code_execution.py +2 -2
  346. camel/toolkits/context_summarizer_toolkit.py +2 -2
  347. camel/toolkits/craw4ai_toolkit.py +2 -2
  348. camel/toolkits/dappier_toolkit.py +2 -2
  349. camel/toolkits/data_commons_toolkit.py +2 -2
  350. camel/toolkits/dingtalk.py +2 -2
  351. camel/toolkits/earth_science_toolkit.py +2 -2
  352. camel/toolkits/edgeone_pages_mcp_toolkit.py +2 -2
  353. camel/toolkits/excel_toolkit.py +2 -2
  354. camel/toolkits/file_toolkit.py +2 -2
  355. camel/toolkits/function_tool.py +95 -25
  356. camel/toolkits/github_toolkit.py +2 -2
  357. camel/toolkits/gmail_toolkit.py +2 -2
  358. camel/toolkits/google_calendar_toolkit.py +2 -2
  359. camel/toolkits/google_drive_mcp_toolkit.py +2 -2
  360. camel/toolkits/google_maps_toolkit.py +2 -2
  361. camel/toolkits/google_scholar_toolkit.py +2 -2
  362. camel/toolkits/human_toolkit.py +2 -2
  363. camel/toolkits/hybrid_browser_toolkit/__init__.py +2 -2
  364. camel/toolkits/hybrid_browser_toolkit/config_loader.py +2 -2
  365. camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit.py +2 -2
  366. camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit_ts.py +89 -104
  367. camel/toolkits/hybrid_browser_toolkit/installer.py +2 -2
  368. camel/toolkits/hybrid_browser_toolkit/ts/src/browser-session.ts +25 -14
  369. camel/toolkits/hybrid_browser_toolkit/ts/websocket-server.js +6 -0
  370. camel/toolkits/hybrid_browser_toolkit/ws_wrapper.py +2 -2
  371. camel/toolkits/hybrid_browser_toolkit_py/__init__.py +2 -2
  372. camel/toolkits/hybrid_browser_toolkit_py/actions.py +2 -2
  373. camel/toolkits/hybrid_browser_toolkit_py/agent.py +2 -2
  374. camel/toolkits/hybrid_browser_toolkit_py/browser_session.py +2 -2
  375. camel/toolkits/hybrid_browser_toolkit_py/config_loader.py +2 -2
  376. camel/toolkits/hybrid_browser_toolkit_py/hybrid_browser_toolkit.py +2 -2
  377. camel/toolkits/hybrid_browser_toolkit_py/snapshot.py +2 -2
  378. camel/toolkits/image_analysis_toolkit.py +2 -2
  379. camel/toolkits/image_generation_toolkit.py +2 -2
  380. camel/toolkits/jina_reranker_toolkit.py +2 -2
  381. camel/toolkits/klavis_toolkit.py +2 -2
  382. camel/toolkits/linkedin_toolkit.py +2 -2
  383. camel/toolkits/markitdown_toolkit.py +2 -2
  384. camel/toolkits/math_toolkit.py +2 -2
  385. camel/toolkits/mcp_toolkit.py +2 -2
  386. camel/toolkits/memory_toolkit.py +2 -2
  387. camel/toolkits/meshy_toolkit.py +2 -2
  388. camel/toolkits/message_agent_toolkit.py +2 -2
  389. camel/toolkits/message_integration.py +6 -2
  390. camel/toolkits/microsoft_outlook_mail_toolkit.py +1885 -0
  391. camel/toolkits/mineru_toolkit.py +2 -2
  392. camel/toolkits/minimax_mcp_toolkit.py +2 -2
  393. camel/toolkits/networkx_toolkit.py +2 -2
  394. camel/toolkits/note_taking_toolkit.py +2 -2
  395. camel/toolkits/notion_mcp_toolkit.py +2 -2
  396. camel/toolkits/notion_toolkit.py +2 -2
  397. camel/toolkits/open_api_specs/biztoc/__init__.py +2 -2
  398. camel/toolkits/open_api_specs/coursera/__init__.py +2 -2
  399. camel/toolkits/open_api_specs/create_qr_code/__init__.py +2 -2
  400. camel/toolkits/open_api_specs/klarna/__init__.py +2 -2
  401. camel/toolkits/open_api_specs/nasa_apod/__init__.py +2 -2
  402. camel/toolkits/open_api_specs/outschool/__init__.py +2 -2
  403. camel/toolkits/open_api_specs/outschool/paths/__init__.py +2 -2
  404. camel/toolkits/open_api_specs/outschool/paths/get_classes.py +2 -2
  405. camel/toolkits/open_api_specs/outschool/paths/search_teachers.py +2 -2
  406. camel/toolkits/open_api_specs/security_config.py +2 -2
  407. camel/toolkits/open_api_specs/speak/__init__.py +2 -2
  408. camel/toolkits/open_api_specs/web_scraper/__init__.py +2 -2
  409. camel/toolkits/open_api_specs/web_scraper/paths/__init__.py +2 -2
  410. camel/toolkits/open_api_specs/web_scraper/paths/scraper.py +2 -2
  411. camel/toolkits/open_api_toolkit.py +2 -2
  412. camel/toolkits/openbb_toolkit.py +2 -2
  413. camel/toolkits/origene_mcp_toolkit.py +2 -2
  414. camel/toolkits/playwright_mcp_toolkit.py +2 -2
  415. camel/toolkits/pptx_toolkit.py +2 -2
  416. camel/toolkits/pubmed_toolkit.py +2 -2
  417. camel/toolkits/pulse_mcp_search_toolkit.py +2 -2
  418. camel/toolkits/pyautogui_toolkit.py +2 -2
  419. camel/toolkits/reddit_toolkit.py +2 -2
  420. camel/toolkits/resend_toolkit.py +2 -2
  421. camel/toolkits/retrieval_toolkit.py +2 -2
  422. camel/toolkits/screenshot_toolkit.py +2 -2
  423. camel/toolkits/search_toolkit.py +70 -13
  424. camel/toolkits/searxng_toolkit.py +2 -2
  425. camel/toolkits/semantic_scholar_toolkit.py +2 -2
  426. camel/toolkits/slack_toolkit.py +2 -2
  427. camel/toolkits/sql_toolkit.py +2 -2
  428. camel/toolkits/stripe_toolkit.py +2 -2
  429. camel/toolkits/sympy_toolkit.py +2 -2
  430. camel/toolkits/task_planning_toolkit.py +2 -2
  431. camel/toolkits/terminal_toolkit/__init__.py +2 -2
  432. camel/toolkits/terminal_toolkit/terminal_toolkit.py +323 -112
  433. camel/toolkits/terminal_toolkit/utils.py +179 -52
  434. camel/toolkits/thinking_toolkit.py +2 -2
  435. camel/toolkits/twitter_toolkit.py +2 -2
  436. camel/toolkits/vertex_ai_veo_toolkit.py +2 -2
  437. camel/toolkits/video_analysis_toolkit.py +2 -2
  438. camel/toolkits/video_download_toolkit.py +2 -2
  439. camel/toolkits/weather_toolkit.py +2 -2
  440. camel/toolkits/web_deploy_toolkit.py +2 -2
  441. camel/toolkits/wechat_official_toolkit.py +2 -2
  442. camel/toolkits/whatsapp_toolkit.py +2 -2
  443. camel/toolkits/wolfram_alpha_toolkit.py +2 -2
  444. camel/toolkits/zapier_toolkit.py +2 -2
  445. camel/types/__init__.py +2 -2
  446. camel/types/agents/__init__.py +2 -2
  447. camel/types/agents/tool_calling_record.py +2 -2
  448. camel/types/enums.py +5 -4
  449. camel/types/mcp_registries.py +2 -2
  450. camel/types/openai_types.py +2 -2
  451. camel/types/unified_model_type.py +10 -6
  452. camel/utils/__init__.py +5 -2
  453. camel/utils/agent_context.py +41 -0
  454. camel/utils/async_func.py +2 -2
  455. camel/utils/chunker/__init__.py +2 -2
  456. camel/utils/chunker/base.py +2 -2
  457. camel/utils/chunker/code_chunker.py +2 -2
  458. camel/utils/chunker/uio_chunker.py +2 -2
  459. camel/utils/commons.py +2 -2
  460. camel/utils/constants.py +2 -2
  461. camel/utils/context_utils.py +2 -2
  462. camel/utils/deduplication.py +2 -2
  463. camel/utils/filename.py +2 -2
  464. camel/utils/langfuse.py +18 -10
  465. camel/utils/mcp.py +2 -2
  466. camel/utils/mcp_client.py +2 -2
  467. camel/utils/message_summarizer.py +2 -2
  468. camel/utils/response_format.py +2 -2
  469. camel/utils/token_counting.py +2 -2
  470. camel/utils/tool_result.py +2 -2
  471. camel/verifiers/__init__.py +2 -2
  472. camel/verifiers/base.py +2 -2
  473. camel/verifiers/math_verifier.py +2 -2
  474. camel/verifiers/models.py +2 -2
  475. camel/verifiers/physics_verifier.py +2 -2
  476. camel/verifiers/python_verifier.py +2 -2
  477. {camel_ai-0.2.82.dist-info → camel_ai-0.2.83a6.dist-info}/METADATA +34 -29
  478. camel_ai-0.2.83a6.dist-info/RECORD +511 -0
  479. camel_ai-0.2.82.dist-info/RECORD +0 -507
  480. {camel_ai-0.2.82.dist-info → camel_ai-0.2.83a6.dist-info}/WHEEL +0 -0
  481. {camel_ai-0.2.82.dist-info → camel_ai-0.2.83a6.dist-info}/licenses/LICENSE +0 -0
@@ -1,4 +1,4 @@
1
- # ========= Copyright 2023-2025 @ 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,9 +10,10 @@
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-2025 @ CAMEL-AI.org. All Rights Reserved. =========
13
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
  # =========
15
15
 
16
+ import asyncio
16
17
  import contextlib
17
18
  import time
18
19
  from typing import (
@@ -27,10 +28,9 @@ from typing import (
27
28
  )
28
29
 
29
30
  from camel.logger import get_logger
30
- from camel.messages import BaseMessage
31
31
  from camel.toolkits.base import BaseToolkit, RegisteredAgentToolkit
32
32
  from camel.toolkits.function_tool import FunctionTool
33
- from camel.utils.commons import dependencies_required
33
+ from camel.utils.tool_result import ToolResult
34
34
 
35
35
  from .config_loader import ConfigLoader
36
36
  from .ws_wrapper import WebSocketBrowserWrapper, high_level_action
@@ -554,12 +554,10 @@ class HybridBrowserToolkit(BaseToolkit, RegisteredAgentToolkit):
554
554
  logger.error(f"Failed to get page snapshot: {e}")
555
555
  return f"Error capturing snapshot: {e}"
556
556
 
557
- @dependencies_required('PIL')
558
557
  async def browser_get_som_screenshot(
559
558
  self,
560
559
  read_image: bool = True,
561
- instruction: Optional[str] = None,
562
- ) -> str:
560
+ ) -> "str | ToolResult":
563
561
  r"""Captures a screenshot with interactive elements highlighted.
564
562
 
565
563
  "SoM" stands for "Set of Marks". This tool takes a screenshot and
@@ -569,17 +567,17 @@ class HybridBrowserToolkit(BaseToolkit, RegisteredAgentToolkit):
569
567
  textual snapshot is not enough.
570
568
 
571
569
  Args:
572
- read_image (bool, optional): If `True`, the agent will analyze
573
- the screenshot. Requires agent to be registered.
570
+ read_image (bool, optional): If `True`, the screenshot image will
571
+ be included in the agent's context for direct visual analysis.
572
+ If `False`, only a text message (including the saved file
573
+ path) will be returned.
574
574
  (default: :obj:`True`)
575
- instruction (Optional[str], optional): A specific question or
576
- command for the agent regarding the screenshot, used only if
577
- `read_image` is `True`. For example: "Find the login button."
578
575
 
579
576
  Returns:
580
- str: A confirmation message indicating the screenshot was
581
- captured, the file path where it was saved, and optionally the
582
- agent's analysis if `read_image` is `True`.
577
+ str | ToolResult: If `read_image` is `True`, returns a ToolResult
578
+ containing the text message and the screenshot image (which
579
+ will be automatically added to agent's context). If `False`,
580
+ returns a string with the file path only.
583
581
  """
584
582
  import base64
585
583
  import datetime
@@ -631,38 +629,19 @@ class HybridBrowserToolkit(BaseToolkit, RegisteredAgentToolkit):
631
629
  result_text += f" (saved to: {file_path})"
632
630
  break
633
631
 
634
- if read_image and file_path:
635
- if self.agent is None:
636
- logger.error(
637
- "Cannot analyze screenshot: No agent registered. "
638
- "Please pass this toolkit to ChatAgent via "
639
- "toolkits_to_register_agent parameter."
640
- )
641
- result_text += (
642
- " Error: No agent registered for image analysis. "
643
- "Please pass this toolkit to ChatAgent via "
644
- "toolkits_to_register_agent parameter."
645
- )
646
- else:
647
- try:
648
- from PIL import Image
649
-
650
- img = Image.open(file_path)
651
- inst = instruction if instruction is not None else ""
652
- message = BaseMessage.make_user_message(
653
- role_name="User",
654
- content=inst,
655
- image_list=[img],
656
- )
657
-
658
- response = await self.agent.astep(message)
659
- agent_response = response.msgs[0].content
660
- result_text += f". Agent analysis: {agent_response}"
661
- except Exception as e:
662
- logger.error(f"Error analyzing screenshot: {e}")
663
- result_text += f". Error analyzing screenshot: {e}"
664
-
665
- return result_text
632
+ # Return ToolResult with image if read_image is True
633
+ if read_image and result.images:
634
+ logger.info(
635
+ f"Returning ToolResult with {len(result.images)} image(s) "
636
+ "for agent context"
637
+ )
638
+ return ToolResult(
639
+ text=result_text,
640
+ images=result.images, # Base64 images from WebSocket
641
+ )
642
+ else:
643
+ # Return plain text if read_image is False
644
+ return result_text
666
645
  except Exception as e:
667
646
  logger.error(f"Failed to get screenshot: {e}")
668
647
  return f"Error capturing screenshot: {e}"
@@ -1390,85 +1369,91 @@ class HybridBrowserToolkit(BaseToolkit, RegisteredAgentToolkit):
1390
1369
  ws_wrapper: Any,
1391
1370
  system: str,
1392
1371
  ) -> Dict[str, Any]:
1393
- r"""Input to sheet using batch keyboard input with relative
1394
- positioning.
1372
+ r"""Input to sheet using batch keyboard input with absolute positioning
1373
+ via Name Box (Cmd+J).
1395
1374
 
1396
- Builds all operations and sends them in ONE command to TypeScript,
1397
- which executes them and only waits for stability once at the end.
1375
+ This is more robust than relative navigation (arrow keys) because it
1376
+ handles hidden rows/columns and merged cells correctly.
1398
1377
  """
1399
1378
  operations: List[Dict[str, Any]] = []
1400
1379
 
1401
- # Go to A1 to ensure we start from a known position
1402
- if system == "Darwin":
1403
- operations.append({"type": "press", "keys": ["Meta", "Home"]})
1404
- else:
1405
- operations.append({"type": "press", "keys": ["Control", "Home"]})
1406
- operations.append({"type": "wait", "delay": 310})
1407
-
1408
- # Start at (0, 0)
1409
- current_row = 0
1410
- current_col = 0
1380
+ def col_to_letter(col_idx: int) -> str:
1381
+ """Convert 0-based column index to letter (0->A, 25->Z, 26->AA)."""
1382
+ result = ""
1383
+ col_idx += 1 # Convert to 1-based for calculation
1384
+ while col_idx > 0:
1385
+ col_idx, remainder = divmod(col_idx - 1, 26)
1386
+ result = chr(65 + remainder) + result
1387
+ return result
1411
1388
 
1412
1389
  for cell in cells:
1413
1390
  target_row = cell.get("row", 0)
1414
1391
  target_col = cell.get("col", 0)
1415
1392
  text = cell.get("text", "")
1416
1393
 
1417
- # Calculate relative movement needed
1418
- row_diff = target_row - current_row
1419
- col_diff = target_col - current_col
1420
-
1421
- # Navigate vertically
1422
- if row_diff > 0:
1423
- for _ in range(row_diff):
1424
- operations.append({"type": "press", "keys": ["ArrowDown"]})
1425
- operations.append({"type": "wait", "delay": 50})
1426
- elif row_diff < 0:
1427
- for _ in range(abs(row_diff)):
1428
- operations.append({"type": "press", "keys": ["ArrowUp"]})
1429
- operations.append({"type": "wait", "delay": 50})
1430
-
1431
- # Navigate horizontally
1432
- if col_diff > 0:
1433
- for _ in range(col_diff):
1434
- operations.append(
1435
- {"type": "press", "keys": ["ArrowRight"]}
1436
- )
1437
- operations.append({"type": "wait", "delay": 50})
1438
- elif col_diff < 0:
1439
- for _ in range(abs(col_diff)):
1440
- operations.append({"type": "press", "keys": ["ArrowLeft"]})
1441
- operations.append({"type": "wait", "delay": 50})
1394
+ # Convert to A1 notation
1395
+ col_letter = col_to_letter(target_col)
1396
+ row_number = target_row + 1
1397
+ cell_address = f"{col_letter}{row_number}"
1398
+
1399
+ # 1. Focus Name Box
1400
+ if system == "Darwin":
1401
+ operations.append({"type": "press", "keys": ["Meta", "j"]})
1402
+ else:
1403
+ # On Windows/Linux, it's usually Ctrl+J or Alt+D
1404
+ # The snapshot showed Cmd+J for Mac.
1405
+ # Standard Google Sheets shortcut for
1406
+ # "Go to range" is F5 or Ctrl+J
1407
+ operations.append({"type": "press", "keys": ["Control", "j"]})
1408
+
1409
+ operations.append({"type": "wait", "delay": 500})
1442
1410
 
1443
- # Wait after navigation if moved
1444
- if row_diff != 0 or col_diff != 0:
1445
- operations.append({"type": "wait", "delay": 100})
1411
+ # 2. Type Address
1412
+ operations.append(
1413
+ {"type": "type", "text": cell_address, "delay": 0}
1414
+ )
1415
+ operations.append({"type": "wait", "delay": 200})
1416
+ operations.append({"type": "press", "keys": ["Enter"]})
1417
+ operations.append({"type": "wait", "delay": 500})
1446
1418
 
1447
- # Clear and input
1419
+ # 3. Clear content (Delete/Backspace)
1420
+ # Just in case, press Delete to clear existing content
1448
1421
  operations.append({"type": "press", "keys": ["Delete"]})
1449
- operations.append({"type": "wait", "delay": 120})
1422
+ operations.append({"type": "wait", "delay": 100})
1450
1423
 
1424
+ # 4. Type Text
1451
1425
  if text:
1452
1426
  operations.append({"type": "type", "text": text, "delay": 0})
1453
- operations.append({"type": "wait", "delay": 120})
1427
+ operations.append({"type": "wait", "delay": 200})
1428
+ # Press Enter to confirm input
1429
+ operations.append({"type": "press", "keys": ["Enter"]})
1430
+ operations.append({"type": "wait", "delay": 300})
1454
1431
 
1455
- # Press Enter to confirm
1456
- operations.append({"type": "press", "keys": ["Enter"]})
1457
- operations.append({"type": "wait", "delay": 130})
1458
-
1459
- # Update current position (after Enter, cursor moves to next row)
1460
- current_row = target_row + 1
1461
- current_col = target_col
1432
+ # Chunk operations to avoid 100-op limit in TypeScript backend
1433
+ # Each cell update takes ~10 ops, so 100 ops is only ~10 cells.
1434
+ # We split into chunks of 50 ops to be safe.
1435
+ CHUNK_SIZE = 50
1462
1436
 
1463
1437
  try:
1464
- await ws_wrapper._send_command(
1465
- 'batch_keyboard_input',
1466
- {'operations': operations, 'skipStabilityWait': True},
1467
- )
1438
+ for i in range(0, len(operations), CHUNK_SIZE):
1439
+ chunk = operations[i : i + CHUNK_SIZE]
1440
+ await ws_wrapper._send_command(
1441
+ 'batch_keyboard_input',
1442
+ {'operations': chunk, 'skipStabilityWait': True},
1443
+ )
1444
+ # Small delay between chunks
1445
+ await asyncio.sleep(0.2)
1446
+
1447
+ # Wait a bit for the last input to settle
1448
+ await asyncio.sleep(1.0)
1449
+
1468
1450
  tab_info = await ws_wrapper.get_tab_info()
1469
1451
 
1470
1452
  return {
1471
- "result": f"Successfully input to {len(cells)} cells",
1453
+ "result": (
1454
+ f"Successfully input to {len(cells)} cells "
1455
+ "using absolute navigation"
1456
+ ),
1472
1457
  "snapshot": "",
1473
1458
  "tabs": tab_info,
1474
1459
  "current_tab": next(
@@ -1,4 +1,4 @@
1
- # ========= Copyright 2023-2025 @ 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-2025 @ CAMEL-AI.org. All Rights Reserved. =========
13
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
 
15
15
  import os
16
16
  import platform
@@ -22,6 +22,17 @@ export class HybridBrowserSession {
22
22
  this.logLimit = this.configLoader.getBrowserConfig().consoleLogLimit || 1000;
23
23
  }
24
24
 
25
+ /**
26
+ * Compatibility wrapper for _snapshotForAI() API
27
+ * Handles both old (string return) and new (object with .full) versions
28
+ */
29
+ private async getSnapshot(page: Page): Promise<string> {
30
+ const result = await (page as any)._snapshotForAI();
31
+ // Version compatibility: if result is object (v1.57.0+), use .full property
32
+ // If result is string (v1.56.x and earlier), return directly
33
+ return typeof result === 'string' ? result : result.full;
34
+ }
35
+
25
36
  private registerNewPage(tabId: string, page: Page): void {
26
37
  // Register page and logs with tabId
27
38
  this.pages.set(tabId, page);
@@ -442,7 +453,7 @@ export class HybridBrowserSession {
442
453
  try {
443
454
  // Use _snapshotForAI() to properly update _lastAriaSnapshot
444
455
  const snapshotStart = Date.now();
445
- const snapshotText = await (page as any)._snapshotForAI();
456
+ const snapshotText = await this.getSnapshot(page);
446
457
  const snapshotTime = Date.now() - snapshotStart;
447
458
 
448
459
  // Extract refs from the snapshot text
@@ -559,7 +570,7 @@ export class HybridBrowserSession {
559
570
 
560
571
  try {
561
572
  // Ensure we have the latest snapshot and mapping
562
- await (page as any)._snapshotForAI();
573
+ await this.getSnapshot(page);
563
574
 
564
575
  // Use Playwright's aria-ref selector engine
565
576
  const selector = `aria-ref=${ref}`;
@@ -581,7 +592,7 @@ export class HybridBrowserSession {
581
592
  let snapshotBefore: string | null = null;
582
593
  let comboboxAriaLabel: string | null = null;
583
594
  if (shouldCheckDiff) {
584
- snapshotBefore = await (page as any)._snapshotForAI();
595
+ snapshotBefore = await this.getSnapshot(page);
585
596
  // Capture aria-label for combobox to find it again after click (ref may change)
586
597
  if (isCombobox) {
587
598
  comboboxAriaLabel = await element.getAttribute('aria-label');
@@ -673,7 +684,7 @@ export class HybridBrowserSession {
673
684
 
674
685
  if (shouldCheckDiff && snapshotBefore) {
675
686
  await page.waitForTimeout(300);
676
- const snapshotAfter = await (page as any)._snapshotForAI();
687
+ const snapshotAfter = await this.getSnapshot(page);
677
688
  let diffSnapshot = this.getSnapshotDiff(snapshotBefore, snapshotAfter, ['option', 'menuitem']);
678
689
 
679
690
  // For combobox, find the new ref based on aria-label and prepend to diffSnapshot
@@ -795,7 +806,7 @@ export class HybridBrowserSession {
795
806
  private async performType(page: Page, ref: string | undefined, text: string | undefined, inputs?: Array<{ ref: string; text: string }>): Promise<{ success: boolean; error?: string; details?: Record<string, any>; diffSnapshot?: string }> {
796
807
  try {
797
808
  // Ensure we have the latest snapshot
798
- await (page as any)._snapshotForAI();
809
+ await this.getSnapshot(page);
799
810
 
800
811
  // Handle multiple inputs if provided
801
812
  if (inputs && inputs.length > 0) {
@@ -871,7 +882,7 @@ export class HybridBrowserSession {
871
882
  }
872
883
 
873
884
  // Get snapshot before action to record existing elements
874
- const snapshotBefore = await (page as any)._snapshotForAI();
885
+ const snapshotBefore = await this.getSnapshot(page);
875
886
  const existingRefs = new Set<string>();
876
887
  const refPattern = /\[ref=([^\]]+)\]/g;
877
888
  let match;
@@ -929,7 +940,7 @@ export class HybridBrowserSession {
929
940
  // If this element might show dropdown, wait and check for new elements
930
941
  if (shouldCheckDiff) {
931
942
  await page.waitForTimeout(300);
932
- const snapshotAfter = await (page as any)._snapshotForAI();
943
+ const snapshotAfter = await this.getSnapshot(page);
933
944
  const diffSnapshot = this.getSnapshotDiff(snapshotBefore, snapshotAfter, ['option', 'menuitem']);
934
945
 
935
946
  if (diffSnapshot && diffSnapshot.trim() !== '') {
@@ -982,7 +993,7 @@ export class HybridBrowserSession {
982
993
  // If element might show dropdown, check for new elements
983
994
  if (shouldCheckDiff) {
984
995
  await page.waitForTimeout(300);
985
- const snapshotFinal = await (page as any)._snapshotForAI();
996
+ const snapshotFinal = await this.getSnapshot(page);
986
997
  const diffSnapshot = this.getSnapshotDiff(snapshotBefore, snapshotFinal, ['option', 'menuitem']);
987
998
 
988
999
  if (diffSnapshot && diffSnapshot.trim() !== '') {
@@ -1000,7 +1011,7 @@ export class HybridBrowserSession {
1000
1011
  console.log(`Looking for new elements that appeared after action...`);
1001
1012
 
1002
1013
  // Get snapshot after action to find new elements
1003
- const snapshotAfter = await (page as any)._snapshotForAI();
1014
+ const snapshotAfter = await this.getSnapshot(page);
1004
1015
  const newRefs = new Set<string>();
1005
1016
  const afterRefPattern = /\[ref=([^\]]+)\]/g;
1006
1017
  let afterMatch;
@@ -1047,7 +1058,7 @@ export class HybridBrowserSession {
1047
1058
  // If element might show dropdown, check for new elements
1048
1059
  if (shouldCheckDiff) {
1049
1060
  await page.waitForTimeout(300);
1050
- const snapshotFinal = await (page as any)._snapshotForAI();
1061
+ const snapshotFinal = await this.getSnapshot(page);
1051
1062
  const diffSnapshot = this.getSnapshotDiff(snapshotBefore, snapshotFinal, ['option', 'menuitem']);
1052
1063
 
1053
1064
  if (diffSnapshot && diffSnapshot.trim() !== '') {
@@ -1077,7 +1088,7 @@ export class HybridBrowserSession {
1077
1088
  console.log(`Looking for new elements that appeared after clicking readonly element...`);
1078
1089
 
1079
1090
  // Get snapshot after action to find new elements
1080
- const snapshotAfter = await (page as any)._snapshotForAI();
1091
+ const snapshotAfter = await this.getSnapshot(page);
1081
1092
  const newRefs = new Set<string>();
1082
1093
  const afterRefPattern = /\[ref=([^\]]+)\]/g;
1083
1094
  let afterMatch;
@@ -1124,7 +1135,7 @@ export class HybridBrowserSession {
1124
1135
  // If element might show dropdown, check for new elements
1125
1136
  if (shouldCheckDiff) {
1126
1137
  await page.waitForTimeout(300);
1127
- const snapshotFinal = await (page as any)._snapshotForAI();
1138
+ const snapshotFinal = await this.getSnapshot(page);
1128
1139
  const diffSnapshot = this.getSnapshotDiff(snapshotBefore, snapshotFinal, ['option', 'menuitem']);
1129
1140
 
1130
1141
  if (diffSnapshot && diffSnapshot.trim() !== '') {
@@ -1158,7 +1169,7 @@ export class HybridBrowserSession {
1158
1169
  private async performSelect(page: Page, ref: string, value: string): Promise<{ success: boolean; error?: string }> {
1159
1170
  try {
1160
1171
  // Ensure we have the latest snapshot
1161
- await (page as any)._snapshotForAI();
1172
+ await this.getSnapshot(page);
1162
1173
 
1163
1174
  // Use Playwright's aria-ref selector
1164
1175
  const selector = `aria-ref=${ref}`;
@@ -1219,7 +1230,7 @@ export class HybridBrowserSession {
1219
1230
  private async performMouseDrag(page: Page, fromRef: string, toRef: string): Promise<{ success: boolean; error?: string }> {
1220
1231
  try {
1221
1232
  // Ensure we have the latest snapshot
1222
- await (page as any)._snapshotForAI();
1233
+ await this.getSnapshot(page);
1223
1234
 
1224
1235
  // Get elements using Playwright's aria-ref selector
1225
1236
  const fromSelector = `aria-ref=${fromRef}`;
@@ -86,6 +86,12 @@ class WebSocketBrowserServer {
86
86
  // Extract base URL and port for validation
87
87
  const baseUrl = cdpUrl.includes('/devtools/') ? cdpUrl.split('/devtools/')[0] : cdpUrl;
88
88
 
89
+ // Validate CDP URL to prevent SSRF - only allow localhost
90
+ const parsed = new URL(baseUrl);
91
+ if (!['localhost', '127.0.0.1'].includes(parsed.hostname)) {
92
+ throw new Error('CDP URL must use localhost or 127.0.0.1');
93
+ }
94
+
89
95
  try {
90
96
  // Test if Chrome debug port is accessible and get page URL
91
97
  const response = await fetch(`${baseUrl}/json`);
@@ -1,4 +1,4 @@
1
- # ========= Copyright 2023-2025 @ 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-2025 @ CAMEL-AI.org. All Rights Reserved. =========
13
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
 
15
15
  import asyncio
16
16
  import contextlib
@@ -1,4 +1,4 @@
1
- # ========= Copyright 2023-2025 @ 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-2025 @ CAMEL-AI.org. All Rights Reserved. =========
13
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
 
15
15
  from .hybrid_browser_toolkit import HybridBrowserToolkit
16
16
 
@@ -1,4 +1,4 @@
1
- # ========= Copyright 2023-2025 @ 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-2025 @ CAMEL-AI.org. All Rights Reserved. =========
13
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
  import asyncio
15
15
  from typing import TYPE_CHECKING, Any, Dict, Optional
16
16
 
@@ -1,4 +1,4 @@
1
- # ========= Copyright 2023-2025 @ 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-2025 @ CAMEL-AI.org. All Rights Reserved. =========
13
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
  import json
15
15
  import re
16
16
  from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
@@ -1,4 +1,4 @@
1
- # ========= Copyright 2023-2025 @ 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-2025 @ CAMEL-AI.org. All Rights Reserved. =========
13
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
  from __future__ import annotations
15
15
 
16
16
  import asyncio
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python3
2
- # ========= Copyright 2023-2025 @ CAMEL-AI.org. All Rights Reserved. =========
2
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at
@@ -11,7 +11,7 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
- # ========= Copyright 2023-2025 @ CAMEL-AI.org. All Rights Reserved. =========
14
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
15
15
 
16
16
  """
17
17
  Configuration for browser automation including stealth mode and timeouts.
@@ -1,4 +1,4 @@
1
- # ========= Copyright 2023-2025 @ 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-2025 @ CAMEL-AI.org. All Rights Reserved. =========
13
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
 
15
15
  import datetime
16
16
  import io
@@ -1,4 +1,4 @@
1
- # ========= Copyright 2023-2025 @ 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-2025 @ CAMEL-AI.org. All Rights Reserved. =========
13
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
  from pathlib import Path
15
15
  from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
16
16
 
@@ -1,4 +1,4 @@
1
- # ========= Copyright 2023-2025 @ 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-2025 @ CAMEL-AI.org. All Rights Reserved. =========
13
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
 
15
15
  from io import BytesIO
16
16
  from typing import List, Optional
@@ -1,4 +1,4 @@
1
- # ========= Copyright 2023-2025 @ 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-2025 @ CAMEL-AI.org. All Rights Reserved. =========
13
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
 
15
15
  import base64
16
16
  import os
@@ -1,4 +1,4 @@
1
- # ========= Copyright 2023-2025 @ 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-2025 @ CAMEL-AI.org. All Rights Reserved. =========
13
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
  import json
15
15
  import os
16
16
  from typing import Any, Dict, List, Optional
@@ -1,4 +1,4 @@
1
- # ========= Copyright 2023-2025 @ 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-2025 @ CAMEL-AI.org. All Rights Reserved. =========
13
+ # ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
 
15
15
  import os
16
16
  import urllib.parse