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,543 @@
1
+ /**
2
+ * Alternative implementation of SOM-screenshot using JS injection
3
+ * This avoids CDP resolution issues by rendering labels directly in the page
4
+ */
5
+
6
+ import { Page } from 'playwright';
7
+ import { SnapshotResult, VisualMarkResult } from './types';
8
+ import { writeFile } from 'fs/promises';
9
+
10
+ export class SomScreenshotInjected {
11
+ /**
12
+ * Take a screenshot with SOM-labels injected into the page
13
+ * This approach uses a single script injection for better performance
14
+ */
15
+ static async captureOptimized(
16
+ page: Page,
17
+ snapshotResult: SnapshotResult,
18
+ clickableElements: Set<string>,
19
+ exportPath?: string
20
+ ): Promise<VisualMarkResult & { timing: any }> {
21
+ const startTime = Date.now();
22
+
23
+ try {
24
+ // Use the already filtered clickableElements directly
25
+ const filterStartTime = Date.now();
26
+ const filterTime = Date.now() - filterStartTime;
27
+ console.log(`Using pre-filtered clickable elements: ${clickableElements.size} elements`);
28
+
29
+ // Prepare element geometry data for export
30
+ const elementGeometry: any[] = [];
31
+ // Inject and capture in one go
32
+ // Collect visibility debug info
33
+ const visibilityDebugInfo: any[] = [];
34
+
35
+ const result = await page.evaluate(async (data) => {
36
+ const { elements, clickable, filterDebugInfo } = data;
37
+ const markedElements: any[] = [];
38
+
39
+ // Debug info collector - include filter debug info
40
+ const debugInfo: any[] = [...filterDebugInfo];
41
+
42
+ // Helper function to check element visibility based on coordinates
43
+ function checkElementVisibilityByCoords(
44
+ coords: { x: number, y: number, width: number, height: number },
45
+ ref: string,
46
+ elementInfo: any
47
+ ): 'visible' | 'partial' | 'hidden' {
48
+ // Skip if element is outside viewport
49
+ if (coords.y + coords.height < 0 || coords.y > window.innerHeight ||
50
+ coords.x + coords.width < 0 || coords.x > window.innerWidth) {
51
+ return 'hidden';
52
+ }
53
+
54
+ // Simple approach: just check the center point
55
+ // If center is visible and shows our element (or its child), consider it visible
56
+ const centerX = coords.x + coords.width * 0.5;
57
+ const centerY = coords.y + coords.height * 0.5;
58
+
59
+ try {
60
+ const elementsAtCenter = document.elementsFromPoint(centerX, centerY);
61
+ if (!elementsAtCenter || elementsAtCenter.length === 0) {
62
+ return 'hidden';
63
+ }
64
+
65
+ // Find our target element in the stack
66
+ let targetFound = false;
67
+ let targetIsTopmost = false;
68
+
69
+ for (let i = 0; i < elementsAtCenter.length; i++) {
70
+ const elem = elementsAtCenter[i];
71
+ const rect = elem.getBoundingClientRect();
72
+
73
+ // Check if this element matches our expected bounds (within tolerance)
74
+ if (Math.abs(rect.left - coords.x) < 5 &&
75
+ Math.abs(rect.top - coords.y) < 5 &&
76
+ Math.abs(rect.width - coords.width) < 10 &&
77
+ Math.abs(rect.height - coords.height) < 10) {
78
+ targetFound = true;
79
+ targetIsTopmost = (i === 0);
80
+
81
+ // If target is topmost, it's definitely visible
82
+ if (targetIsTopmost) {
83
+ return 'visible';
84
+ }
85
+
86
+ // If not topmost, check if the topmost element is a child of our target
87
+ const topmostElem = elementsAtCenter[0];
88
+ if (elem.contains(topmostElem)) {
89
+ // Topmost is our child - element is visible
90
+ return 'visible';
91
+ }
92
+
93
+ // Otherwise, we're obscured
94
+ return 'hidden';
95
+ }
96
+ }
97
+
98
+ // If we didn't find our target element at all
99
+ if (!targetFound) {
100
+ // Special handling for composite widgets
101
+ const topElement = elementsAtCenter[0];
102
+ const tagName = topElement.tagName.toUpperCase();
103
+
104
+ // Get element role/type for better decision making
105
+ const elementRole = elementInfo?.role || '';
106
+ const elementTagName = elementInfo?.tagName || '';
107
+
108
+ // Only apply special handling for form controls that are part of composite widgets
109
+ if (['SELECT', 'INPUT', 'TEXTAREA', 'BUTTON'].includes(tagName)) {
110
+ const isFormRelatedElement = ['combobox', 'select', 'textbox', 'searchbox', 'spinbutton'].includes(elementRole) ||
111
+ ['SELECT', 'INPUT', 'TEXTAREA', 'BUTTON', 'OPTION'].includes(elementTagName.toUpperCase());
112
+
113
+ // Check if the form control approximately matches our area
114
+ const rect = topElement.getBoundingClientRect();
115
+ const overlap = Math.min(rect.right, coords.x + coords.width) - Math.max(rect.left, coords.x) > 0 &&
116
+ Math.min(rect.bottom, coords.y + coords.height) - Math.max(rect.top, coords.y) > 0;
117
+
118
+ if (overlap && isFormRelatedElement) {
119
+ // Check for specific composite widget patterns
120
+ // For combobox with search input (like Amazon search)
121
+ if (elementRole === 'combobox' && tagName === 'INPUT') {
122
+ // This is likely a search box with category selector - mark as visible
123
+ return 'visible';
124
+ }
125
+
126
+ // For button/generic elements covered by INPUT with exact same bounds
127
+ // This usually indicates the INPUT is the actual interactive element for the button
128
+ if ((elementRole === 'button' || elementRole === 'generic') && tagName === 'INPUT') {
129
+ const rectMatch = Math.abs(rect.left - coords.x) < 2 &&
130
+ Math.abs(rect.top - coords.y) < 2 &&
131
+ Math.abs(rect.width - coords.width) < 2 &&
132
+ Math.abs(rect.height - coords.height) < 2;
133
+ if (rectMatch) {
134
+ // The INPUT is the actual interactive element for this button
135
+ return 'visible';
136
+ }
137
+ }
138
+
139
+ // For other form-related elements, only mark as visible if they share similar positioning
140
+ // (i.e., they're likely part of the same widget)
141
+ const sizeDiff = Math.abs(rect.width - coords.width) + Math.abs(rect.height - coords.height);
142
+ if (sizeDiff < 50) { // Tolerance for size difference
143
+ return 'visible';
144
+ }
145
+ }
146
+ }
147
+
148
+ return 'hidden';
149
+ }
150
+
151
+ return 'partial';
152
+
153
+ } catch (e) {
154
+ // Fallback: use simple elementFromPoint check
155
+ const elem = document.elementFromPoint(centerX, centerY);
156
+ if (!elem) return 'hidden';
157
+
158
+ const rect = elem.getBoundingClientRect();
159
+ // Check if the element at center matches our bounds
160
+ if (Math.abs(rect.left - coords.x) < 5 &&
161
+ Math.abs(rect.top - coords.y) < 5) {
162
+ return 'visible';
163
+ }
164
+ return 'partial';
165
+ }
166
+ }
167
+
168
+
169
+ // Create overlay
170
+ const overlay = document.createElement('div');
171
+ overlay.id = 'camel-som-overlay-temp'; // Set ID immediately for cleanup
172
+ overlay.style.cssText = `
173
+ position: fixed;
174
+ top: 0;
175
+ left: 0;
176
+ width: 100%;
177
+ height: 100%;
178
+ pointer-events: none;
179
+ z-index: 2147483647;
180
+ `;
181
+
182
+ // Check visibility for each element using coordinates
183
+ const elementStates = new Map<string, 'visible' | 'partial' | 'hidden'>();
184
+
185
+ Object.entries(elements).forEach(([ref, element]: [string, any]) => {
186
+ if (element.coordinates && clickable.includes(ref)) {
187
+ const visibility = checkElementVisibilityByCoords(element.coordinates, ref, element);
188
+ elementStates.set(ref, visibility);
189
+
190
+ // Add debug info
191
+ const centerX = element.coordinates.x + element.coordinates.width * 0.5;
192
+ const centerY = element.coordinates.y + element.coordinates.height * 0.5;
193
+
194
+ try {
195
+ const elementsAtCenter = document.elementsFromPoint(centerX, centerY);
196
+ const topmostElement = elementsAtCenter[0];
197
+
198
+ debugInfo.push({
199
+ ref,
200
+ coords: element.coordinates,
201
+ centerPoint: { x: centerX, y: centerY },
202
+ visibilityResult: visibility,
203
+ elementRole: element.role || 'unknown',
204
+ elementTagName: element.tagName || '',
205
+ topmostElement: topmostElement ? {
206
+ tagName: topmostElement.tagName,
207
+ className: topmostElement.className,
208
+ id: topmostElement.id
209
+ } : null,
210
+ elementsAtCenterCount: elementsAtCenter.length
211
+ });
212
+ } catch (e) {
213
+ debugInfo.push({
214
+ ref,
215
+ coords: element.coordinates,
216
+ visibilityResult: visibility,
217
+ elementRole: element.role || 'unknown',
218
+ elementTagName: element.tagName || '',
219
+ error: 'Failed to get elements at center'
220
+ });
221
+ }
222
+ }
223
+ });
224
+
225
+ // Track label positions to avoid overlap
226
+ const labelPositions: Array<{x: number, y: number, width: number, height: number, ref: string}> = [];
227
+
228
+ // Helper to check if two rectangles overlap
229
+ function rectsOverlap(r1: any, r2: any): boolean {
230
+ return !(r1.x + r1.width < r2.x ||
231
+ r2.x + r2.width < r1.x ||
232
+ r1.y + r1.height < r2.y ||
233
+ r2.y + r2.height < r1.y);
234
+ }
235
+
236
+ // Helper to find non-overlapping position for label
237
+ function findLabelPosition(element: any, labelWidth: number, labelHeight: number): {x: number, y: number} {
238
+ const { x, y, width, height } = element.coordinates;
239
+ const isSmallElement = height < 70;
240
+ const margin = 2; // Space between label and element
241
+
242
+ // Try different positions in order of preference
243
+ const positions = [];
244
+
245
+ if (isSmallElement) {
246
+ // For small elements, try outside positions
247
+ // 1. Above element
248
+ positions.push({ x: x - 2, y: y - labelHeight - margin });
249
+ // 2. Below element
250
+ positions.push({ x: x - 2, y: y + height + margin });
251
+ // 3. Left of element
252
+ positions.push({ x: x - labelWidth - margin, y: y });
253
+ // 4. Right of element
254
+ positions.push({ x: x + width + margin, y: y });
255
+ } else {
256
+ // For large elements, inside top-left
257
+ positions.push({ x: x + 4, y: y + 4 });
258
+ }
259
+
260
+ // Check each position
261
+ for (const pos of positions) {
262
+ // Adjust for viewport boundaries
263
+ const adjustedPos = { ...pos };
264
+
265
+ // Keep within viewport
266
+ adjustedPos.x = Math.max(0, Math.min(adjustedPos.x, window.innerWidth - labelWidth));
267
+ adjustedPos.y = Math.max(0, Math.min(adjustedPos.y, window.innerHeight - labelHeight));
268
+
269
+ // Check for overlaps with existing labels
270
+ const testRect = { x: adjustedPos.x, y: adjustedPos.y, width: labelWidth, height: labelHeight };
271
+ let hasOverlap = false;
272
+
273
+ for (const existing of labelPositions) {
274
+ if (rectsOverlap(testRect, existing)) {
275
+ hasOverlap = true;
276
+ break;
277
+ }
278
+ }
279
+
280
+ if (!hasOverlap) {
281
+ return adjustedPos;
282
+ }
283
+ }
284
+
285
+ // If all positions overlap, try to find space by offsetting
286
+ // Try positions around the element in a spiral pattern
287
+ const offsets = [
288
+ { dx: 0, dy: -labelHeight - margin - 20 }, // Further above
289
+ { dx: 0, dy: height + margin + 20 }, // Further below
290
+ { dx: -labelWidth - margin - 20, dy: 0 }, // Further left
291
+ { dx: width + margin + 20, dy: 0 }, // Further right
292
+ { dx: -labelWidth - margin, dy: -labelHeight - margin }, // Top-left
293
+ { dx: width + margin, dy: -labelHeight - margin }, // Top-right
294
+ { dx: -labelWidth - margin, dy: height + margin }, // Bottom-left
295
+ { dx: width + margin, dy: height + margin }, // Bottom-right
296
+ ];
297
+
298
+ for (const offset of offsets) {
299
+ const pos = {
300
+ x: Math.max(0, Math.min(x + offset.dx, window.innerWidth - labelWidth)),
301
+ y: Math.max(0, Math.min(y + offset.dy, window.innerHeight - labelHeight))
302
+ };
303
+
304
+ const testRect = { x: pos.x, y: pos.y, width: labelWidth, height: labelHeight };
305
+ let hasOverlap = false;
306
+
307
+ for (const existing of labelPositions) {
308
+ if (rectsOverlap(testRect, existing)) {
309
+ hasOverlap = true;
310
+ break;
311
+ }
312
+ }
313
+
314
+ if (!hasOverlap) {
315
+ return pos;
316
+ }
317
+ }
318
+
319
+ // Fallback: use original logic but ensure within viewport
320
+ if (isSmallElement) {
321
+ const fallbackY = y >= 25 ? y - 25 : y + height + 2;
322
+ return {
323
+ x: Math.max(0, Math.min(x - 2, window.innerWidth - labelWidth)),
324
+ y: Math.max(0, Math.min(fallbackY, window.innerHeight - labelHeight))
325
+ };
326
+ } else {
327
+ return { x: x + 4, y: y + 4 };
328
+ }
329
+ }
330
+
331
+ // Add labels and collect geometry data (only for filtered elements)
332
+ Object.entries(elements).forEach(([ref, element]: [string, any]) => {
333
+ if (element.coordinates && clickable.includes(ref)) {
334
+ const state = elementStates.get(ref);
335
+
336
+ // Skip completely hidden elements
337
+ if (state === 'hidden') return;
338
+ const label = document.createElement('div');
339
+ const { x, y, width, height } = element.coordinates;
340
+
341
+ label.style.cssText = `
342
+ position: absolute;
343
+ left: ${x}px;
344
+ top: ${y}px;
345
+ width: ${width}px;
346
+ height: ${height}px;
347
+ border: 2px ${state === 'partial' ? 'dashed' : 'solid'} #FF0066;
348
+ border-radius: 4px;
349
+ box-shadow: 0 2px 8px rgba(0,0,0,0.3);
350
+ `;
351
+
352
+ // Add ref number with smart positioning
353
+ const refLabel = document.createElement('div');
354
+ refLabel.textContent = ref;
355
+
356
+ // Create temporary label to measure its size
357
+ refLabel.style.cssText = `
358
+ position: absolute;
359
+ visibility: hidden;
360
+ background: #FF0066;
361
+ color: white;
362
+ font: bold 12px Arial, sans-serif;
363
+ padding: 2px 6px;
364
+ border-radius: 2px;
365
+ min-width: 20px;
366
+ text-align: center;
367
+ white-space: nowrap;
368
+ `;
369
+ document.body.appendChild(refLabel);
370
+ const labelWidth = refLabel.offsetWidth;
371
+ const labelHeight = refLabel.offsetHeight;
372
+ document.body.removeChild(refLabel);
373
+
374
+ // Find non-overlapping position
375
+ const labelPos = findLabelPosition(element, labelWidth, labelHeight);
376
+
377
+ // Apply final position
378
+ refLabel.style.cssText = `
379
+ position: absolute;
380
+ left: ${labelPos.x - x}px;
381
+ top: ${labelPos.y - y}px;
382
+ background: #FF0066;
383
+ color: white;
384
+ font: bold 12px Arial, sans-serif;
385
+ padding: 2px 6px;
386
+ border-radius: 2px;
387
+ min-width: 20px;
388
+ text-align: center;
389
+ box-shadow: 0 2px 4px rgba(0,0,0,0.2);
390
+ opacity: ${state === 'partial' ? '0.8' : '1'};
391
+ z-index: 1;
392
+ white-space: nowrap;
393
+ `;
394
+
395
+ // Track this label position
396
+ labelPositions.push({
397
+ x: labelPos.x,
398
+ y: labelPos.y,
399
+ width: labelWidth,
400
+ height: labelHeight,
401
+ ref: ref
402
+ });
403
+
404
+ label.appendChild(refLabel);
405
+ overlay.appendChild(label);
406
+
407
+ // Collect geometry data
408
+ markedElements.push({
409
+ ref,
410
+ x,
411
+ y,
412
+ width,
413
+ height,
414
+ center: {
415
+ x: x + width / 2,
416
+ y: y + height / 2
417
+ },
418
+ area: width * height,
419
+ type: element.role || 'unknown',
420
+ text: element.text || '',
421
+ attributes: element.attributes || {},
422
+ tagName: element.tagName || '',
423
+ isFiltered: false
424
+ });
425
+ }
426
+ });
427
+
428
+ document.body.appendChild(overlay);
429
+
430
+ // Force repaint
431
+ await new Promise(resolve => requestAnimationFrame(resolve));
432
+
433
+ return {
434
+ overlayId: overlay.id, // Use the ID that was set earlier
435
+ elementCount: overlay.children.length,
436
+ markedElements,
437
+ debugInfo
438
+ };
439
+ }, {
440
+ elements: snapshotResult.elements,
441
+ clickable: Array.from(clickableElements),
442
+ filterDebugInfo: []
443
+ });
444
+
445
+ // Take screenshot
446
+ const screenshotBuffer = await page.screenshot({
447
+ fullPage: false,
448
+ type: 'png'
449
+ });
450
+
451
+ // Keep the overlay visible for 1 second before cleanup
452
+ await page.waitForTimeout(1000);
453
+
454
+ // Clean up
455
+ await page.evaluate((overlayId) => {
456
+ const overlay = document.getElementById(overlayId);
457
+ if (overlay) overlay.remove();
458
+ }, result.overlayId);
459
+
460
+ // Export element geometry if path is provided
461
+ if (exportPath && result.markedElements) {
462
+ try {
463
+ const pageUrl = page.url();
464
+ const timestamp = new Date().toISOString();
465
+ const exportData = {
466
+ timestamp,
467
+ url: pageUrl,
468
+ viewport: await page.viewportSize(),
469
+ elements: result.markedElements,
470
+ summary: {
471
+ totalElements: result.markedElements.length,
472
+ byType: result.markedElements.reduce((acc: any, el: any) => {
473
+ acc[el.type] = (acc[el.type] || 0) + 1;
474
+ return acc;
475
+ }, {}),
476
+ averageSize: {
477
+ width: result.markedElements.reduce((sum: number, el: any) => sum + el.width, 0) / result.markedElements.length,
478
+ height: result.markedElements.reduce((sum: number, el: any) => sum + el.height, 0) / result.markedElements.length
479
+ }
480
+ }
481
+ };
482
+
483
+ if (typeof writeFile !== 'undefined') {
484
+ await writeFile(exportPath, JSON.stringify(exportData, null, 2));
485
+ console.log(`Element geometry exported to: ${exportPath}`);
486
+ }
487
+
488
+ // Also save visibility debug info
489
+ if (result.debugInfo) {
490
+ const debugPath = exportPath.replace('.json', '-visibility-debug.json');
491
+
492
+ const debugData = {
493
+ timestamp,
494
+ url: pageUrl,
495
+ totalElements: result.debugInfo.length,
496
+ summary: {
497
+ visible: result.debugInfo.filter((d: any) => d.visibilityResult === 'visible').length,
498
+ partial: result.debugInfo.filter((d: any) => d.visibilityResult === 'partial').length,
499
+ hidden: result.debugInfo.filter((d: any) => d.visibilityResult === 'hidden').length
500
+ },
501
+ elements: result.debugInfo.sort((a: any, b: any) => {
502
+ // Sort by visibility status: hidden first, then partial, then visible
503
+ const order: any = { hidden: 0, partial: 1, visible: 2 };
504
+ return order[a.visibilityResult] - order[b.visibilityResult];
505
+ })
506
+ };
507
+
508
+ if (typeof writeFile !== 'undefined') {
509
+ await writeFile(debugPath, JSON.stringify(debugData, null, 2));
510
+ console.log(`Visibility debug info exported to: ${debugPath}`);
511
+ }
512
+ }
513
+ } catch (error) {
514
+ console.error('Failed to export element geometry:', error);
515
+ }
516
+ }
517
+
518
+ const base64Image = screenshotBuffer.toString('base64');
519
+ const dataUrl = `data:image/png;base64,${base64Image}`;
520
+
521
+ return {
522
+ text: `Visual webpage screenshot captured with ${result.elementCount} interactive elements marked`,
523
+ images: [dataUrl],
524
+ timing: {
525
+ total_time_ms: Date.now() - startTime,
526
+ screenshot_time_ms: Date.now() - startTime - 1100, // Approximate screenshot time (excluding 1s wait)
527
+ snapshot_time_ms: 0, // Will be filled by caller
528
+ coordinate_enrichment_time_ms: 0, // Will be filled by caller
529
+ visual_marking_time_ms: 1100, // Injection, rendering and 1s display time
530
+ injection_method: 'optimized',
531
+ elements_count: result.elementCount,
532
+ display_duration_ms: 1000, // Time the overlay is kept visible
533
+ parent_child_filter_time_ms: filterTime,
534
+ filtered_count: 0 // Filtering is done before this method is called
535
+ }
536
+ };
537
+
538
+ } catch (error) {
539
+ console.error('SOM screenshot injection error:', error);
540
+ throw error;
541
+ }
542
+ }
543
+ }
@@ -0,0 +1,129 @@
1
+ export interface SnapshotElement {
2
+ ref: string;
3
+ role: string;
4
+ name: string;
5
+ coordinates?: {
6
+ x: number;
7
+ y: number;
8
+ width: number;
9
+ height: number;
10
+ };
11
+ disabled?: boolean;
12
+ checked?: boolean;
13
+ expanded?: boolean;
14
+ tagName?: string;
15
+ [key: string]: any;
16
+ }
17
+
18
+
19
+ export interface SnapshotResult {
20
+ snapshot: string;
21
+ elements: Record<string, SnapshotElement>;
22
+ metadata: {
23
+ elementCount: number;
24
+ url: string;
25
+ timestamp: string;
26
+ };
27
+ }
28
+
29
+ export interface DetailedTiming {
30
+ total_time_ms: number;
31
+ navigation_time_ms?: number;
32
+ page_load_time_ms?: number;
33
+ stability_wait_time_ms?: number;
34
+ dom_content_loaded_time_ms?: number;
35
+ network_idle_time_ms?: number;
36
+ snapshot_time_ms?: number;
37
+ element_search_time_ms?: number;
38
+ action_execution_time_ms?: number;
39
+ screenshot_time_ms?: number;
40
+ coordinate_enrichment_time_ms?: number;
41
+ visual_marking_time_ms?: number;
42
+ aria_mapping_time_ms?: number;
43
+ }
44
+
45
+ export interface ActionResult {
46
+ success: boolean;
47
+ message: string;
48
+ snapshot?: string;
49
+ details?: Record<string, any>;
50
+ timing?: DetailedTiming;
51
+ newTabId?: string; // ID of newly opened tab if click opened a new tab
52
+ }
53
+
54
+ export interface TabInfo {
55
+ tab_id: string;
56
+ title: string;
57
+ url: string;
58
+ is_current: boolean;
59
+ }
60
+
61
+ import { StealthConfig } from './config-loader';
62
+
63
+ export interface BrowserToolkitConfig {
64
+ headless?: boolean;
65
+ userDataDir?: string;
66
+ stealth?: boolean | StealthConfig; // Support both legacy boolean and new object format
67
+ defaultStartUrl?: string;
68
+ navigationTimeout?: number;
69
+ networkIdleTimeout?: number;
70
+ screenshotTimeout?: number;
71
+ pageStabilityTimeout?: number;
72
+ useNativePlaywrightMapping?: boolean; // New option to control mapping implementation
73
+ connectOverCdp?: boolean; // Whether to connect to existing browser via CDP
74
+ cdpUrl?: string; // WebSocket endpoint URL for CDP connection
75
+ cdpKeepCurrentPage?: boolean; // When true, CDP mode will keep the current page instead of creating new one
76
+ }
77
+
78
+ export interface ClickAction {
79
+ type: 'click';
80
+ ref: string;
81
+ }
82
+
83
+ export interface TypeAction {
84
+ type: 'type';
85
+ ref?: string; // Optional for backward compatibility
86
+ text?: string; // Optional for backward compatibility
87
+ inputs?: Array<{ ref: string; text: string }>; // New field for multiple inputs
88
+ }
89
+
90
+ export interface SelectAction {
91
+ type: 'select';
92
+ ref: string;
93
+ value: string;
94
+ }
95
+
96
+ export interface ScrollAction {
97
+ type: 'scroll';
98
+ direction: 'up' | 'down';
99
+ amount: number;
100
+ }
101
+
102
+ export interface EnterAction {
103
+ type: 'enter';
104
+ }
105
+
106
+ export interface MouseAction {
107
+ type: 'mouse_control';
108
+ control: 'click' | 'right_click' | 'dblclick';
109
+ x: number;
110
+ y: number;
111
+ }
112
+
113
+ export interface MouseDragAction {
114
+ type: 'mouse_drag';
115
+ from_ref: string;
116
+ to_ref: string;
117
+ }
118
+
119
+ export interface PressKeyAction {
120
+ type: 'press_key';
121
+ keys: string[];
122
+ }
123
+
124
+ export type BrowserAction = ClickAction | TypeAction | SelectAction | ScrollAction | EnterAction | MouseAction | MouseDragAction | PressKeyAction;
125
+
126
+ export interface VisualMarkResult {
127
+ text: string;
128
+ images: string[];
129
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "lib": ["ES2020", "DOM"],
6
+ "outDir": "./dist",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "declaration": true,
13
+ "declarationMap": true,
14
+ "sourceMap": true,
15
+ "moduleResolution": "node",
16
+ "resolveJsonModule": true,
17
+ "types": ["jest", "node"]
18
+ },
19
+ "include": [
20
+ "src/**/*"
21
+ ],
22
+ "exclude": [
23
+ "node_modules",
24
+ "dist",
25
+ "**/*.test.ts"
26
+ ]
27
+ }