camel-ai 0.2.65__py3-none-any.whl → 0.2.83a6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of camel-ai might be problematic. Click here for more details.
- camel/__init__.py +3 -3
- camel/agents/__init__.py +2 -2
- camel/agents/_types.py +9 -4
- camel/agents/_utils.py +40 -2
- camel/agents/base.py +2 -2
- camel/agents/chat_agent.py +5107 -995
- camel/agents/critic_agent.py +2 -2
- camel/agents/deductive_reasoner_agent.py +56 -56
- camel/agents/embodied_agent.py +2 -2
- camel/agents/knowledge_graph_agent.py +20 -20
- camel/agents/mcp_agent.py +35 -36
- camel/agents/multi_hop_generator_agent.py +3 -3
- camel/agents/programmed_agent_instruction.py +2 -2
- camel/agents/repo_agent.py +4 -3
- camel/agents/role_assignment_agent.py +2 -2
- camel/agents/search_agent.py +2 -2
- camel/agents/task_agent.py +2 -2
- camel/agents/tool_agents/__init__.py +2 -2
- camel/agents/tool_agents/base.py +2 -2
- camel/agents/tool_agents/hugging_face_tool_agent.py +3 -3
- camel/benchmarks/__init__.py +2 -2
- camel/benchmarks/apibank.py +5 -5
- camel/benchmarks/apibench.py +2 -2
- camel/benchmarks/base.py +2 -2
- camel/benchmarks/browsecomp.py +44 -33
- camel/benchmarks/gaia.py +17 -13
- camel/benchmarks/mock_website/README.md +1 -3
- camel/benchmarks/mock_website/mock_web.py +2 -2
- camel/benchmarks/mock_website/requirements.txt +1 -1
- camel/benchmarks/mock_website/shopping_mall/app.py +2 -2
- camel/benchmarks/mock_website/task.json +1 -1
- camel/benchmarks/nexus.py +3 -3
- camel/benchmarks/ragbench.py +2 -2
- camel/bots/__init__.py +2 -2
- camel/bots/discord/__init__.py +2 -2
- camel/bots/discord/discord_app.py +2 -2
- camel/bots/discord/discord_installation.py +2 -2
- camel/bots/discord/discord_store.py +3 -3
- camel/bots/slack/__init__.py +2 -2
- camel/bots/slack/models.py +4 -4
- camel/bots/slack/slack_app.py +2 -2
- camel/bots/telegram_bot.py +2 -2
- camel/configs/__init__.py +29 -2
- camel/configs/aihubmix_config.py +90 -0
- camel/configs/aiml_config.py +2 -2
- camel/configs/amd_config.py +70 -0
- camel/configs/anthropic_config.py +2 -2
- camel/configs/base_config.py +2 -2
- camel/configs/bedrock_config.py +5 -3
- camel/configs/cerebras_config.py +98 -0
- camel/configs/cohere_config.py +2 -2
- camel/configs/cometapi_config.py +106 -0
- camel/configs/crynux_config.py +2 -2
- camel/configs/deepseek_config.py +9 -8
- camel/configs/function_gemma_config.py +59 -0
- camel/configs/gemini_config.py +6 -4
- camel/configs/groq_config.py +6 -4
- camel/configs/internlm_config.py +6 -4
- camel/configs/litellm_config.py +2 -2
- camel/configs/lmstudio_config.py +6 -4
- camel/configs/minimax_config.py +95 -0
- camel/configs/mistral_config.py +2 -2
- camel/configs/modelscope_config.py +5 -3
- camel/configs/moonshot_config.py +2 -2
- camel/configs/nebius_config.py +105 -0
- camel/configs/netmind_config.py +2 -2
- camel/configs/novita_config.py +2 -2
- camel/configs/nvidia_config.py +2 -2
- camel/configs/ollama_config.py +2 -2
- camel/configs/openai_config.py +5 -3
- camel/configs/openrouter_config.py +6 -4
- camel/configs/ppio_config.py +2 -2
- camel/configs/qianfan_config.py +85 -0
- camel/configs/qwen_config.py +2 -2
- camel/configs/reka_config.py +2 -2
- camel/configs/samba_config.py +6 -4
- camel/configs/sglang_config.py +2 -2
- camel/configs/siliconflow_config.py +2 -2
- camel/configs/togetherai_config.py +2 -2
- camel/configs/vllm_config.py +4 -2
- camel/configs/watsonx_config.py +2 -2
- camel/configs/yi_config.py +6 -4
- camel/configs/zhipuai_config.py +6 -4
- camel/data_collectors/__init__.py +2 -2
- camel/data_collectors/alpaca_collector.py +18 -9
- camel/data_collectors/base.py +2 -2
- camel/data_collectors/sharegpt_collector.py +2 -2
- camel/datagen/__init__.py +2 -2
- camel/datagen/cot_datagen.py +3 -3
- camel/datagen/evol_instruct/__init__.py +2 -2
- camel/datagen/evol_instruct/evol_instruct.py +2 -2
- camel/datagen/evol_instruct/scorer.py +12 -12
- camel/datagen/evol_instruct/templates.py +16 -16
- camel/datagen/self_improving_cot.py +5 -5
- camel/datagen/self_instruct/__init__.py +2 -2
- camel/datagen/self_instruct/filter/__init__.py +2 -2
- camel/datagen/self_instruct/filter/filter_function.py +2 -2
- camel/datagen/self_instruct/filter/filter_registry.py +2 -2
- camel/datagen/self_instruct/filter/instruction_filter.py +2 -2
- camel/datagen/self_instruct/self_instruct.py +2 -2
- camel/datagen/self_instruct/templates.py +47 -47
- camel/datagen/source2synth/__init__.py +2 -2
- camel/datagen/source2synth/data_processor.py +2 -2
- camel/datagen/source2synth/models.py +2 -2
- camel/datagen/source2synth/user_data_processor_config.py +2 -2
- camel/datahubs/__init__.py +2 -2
- camel/datahubs/base.py +2 -2
- camel/datahubs/huggingface.py +2 -2
- camel/datahubs/models.py +2 -2
- camel/datasets/__init__.py +2 -2
- camel/datasets/base_generator.py +41 -12
- camel/datasets/few_shot_generator.py +18 -18
- camel/datasets/models.py +2 -2
- camel/datasets/self_instruct_generator.py +2 -2
- camel/datasets/static_dataset.py +2 -2
- camel/embeddings/__init__.py +2 -2
- camel/embeddings/azure_embedding.py +2 -2
- camel/embeddings/base.py +2 -2
- camel/embeddings/gemini_embedding.py +2 -2
- camel/embeddings/jina_embedding.py +2 -2
- camel/embeddings/mistral_embedding.py +2 -2
- camel/embeddings/openai_compatible_embedding.py +2 -2
- camel/embeddings/openai_embedding.py +2 -2
- camel/embeddings/sentence_transformers_embeddings.py +2 -2
- camel/embeddings/together_embedding.py +2 -2
- camel/embeddings/vlm_embedding.py +2 -2
- camel/environments/__init__.py +14 -2
- camel/environments/models.py +2 -2
- camel/environments/multi_step.py +2 -2
- camel/environments/rlcards_env.py +860 -0
- camel/environments/single_step.py +30 -5
- camel/environments/tic_tac_toe.py +3 -3
- camel/extractors/__init__.py +2 -2
- camel/extractors/base.py +2 -2
- camel/extractors/python_strategies.py +2 -2
- camel/generators.py +2 -2
- camel/human.py +2 -2
- camel/interpreters/__init__.py +4 -2
- camel/interpreters/base.py +2 -2
- camel/interpreters/docker/Dockerfile +14 -24
- camel/interpreters/docker_interpreter.py +5 -4
- camel/interpreters/e2b_interpreter.py +36 -3
- camel/interpreters/internal_python_interpreter.py +53 -4
- camel/interpreters/interpreter_error.py +2 -2
- camel/interpreters/ipython_interpreter.py +2 -2
- camel/interpreters/microsandbox_interpreter.py +395 -0
- camel/interpreters/subprocess_interpreter.py +2 -2
- camel/loaders/__init__.py +13 -4
- camel/loaders/apify_reader.py +2 -2
- camel/loaders/base_io.py +2 -2
- camel/loaders/base_loader.py +85 -0
- camel/loaders/chunkr_reader.py +11 -2
- camel/loaders/crawl4ai_reader.py +2 -2
- camel/loaders/firecrawl_reader.py +6 -6
- camel/loaders/jina_url_reader.py +2 -2
- camel/loaders/markitdown.py +2 -2
- camel/loaders/mineru_extractor.py +2 -2
- camel/loaders/mistral_reader.py +2 -2
- camel/loaders/scrapegraph_reader.py +2 -2
- camel/loaders/unstructured_io.py +2 -2
- camel/logger.py +5 -5
- camel/memories/__init__.py +2 -2
- camel/memories/agent_memories.py +86 -3
- camel/memories/base.py +36 -2
- camel/memories/blocks/__init__.py +2 -2
- camel/memories/blocks/chat_history_block.py +125 -7
- camel/memories/blocks/vectordb_block.py +10 -3
- camel/memories/context_creators/__init__.py +2 -2
- camel/memories/context_creators/score_based.py +109 -230
- camel/memories/records.py +90 -10
- camel/messages/__init__.py +2 -2
- camel/messages/base.py +178 -43
- camel/messages/conversion/__init__.py +2 -2
- camel/messages/conversion/alpaca.py +2 -2
- camel/messages/conversion/conversation_models.py +2 -2
- camel/messages/conversion/sharegpt/__init__.py +2 -2
- camel/messages/conversion/sharegpt/function_call_formatter.py +2 -2
- camel/messages/conversion/sharegpt/hermes/__init__.py +2 -2
- camel/messages/conversion/sharegpt/hermes/hermes_function_formatter.py +2 -2
- camel/messages/func_message.py +54 -17
- camel/models/__init__.py +18 -2
- camel/models/_utils.py +3 -3
- camel/models/aihubmix_model.py +83 -0
- camel/models/aiml_model.py +11 -18
- camel/models/amd_model.py +101 -0
- camel/models/anthropic_model.py +127 -20
- camel/models/aws_bedrock_model.py +12 -35
- camel/models/azure_openai_model.py +214 -115
- camel/models/base_audio_model.py +5 -3
- camel/models/base_model.py +378 -31
- camel/models/cerebras_model.py +83 -0
- camel/models/cohere_model.py +18 -49
- camel/models/cometapi_model.py +83 -0
- camel/models/crynux_model.py +11 -18
- camel/models/deepseek_model.py +20 -84
- camel/models/fish_audio_model.py +8 -2
- camel/models/function_gemma_model.py +889 -0
- camel/models/gemini_model.py +391 -52
- camel/models/groq_model.py +11 -19
- camel/models/internlm_model.py +11 -18
- camel/models/litellm_model.py +57 -49
- camel/models/lmstudio_model.py +17 -20
- camel/models/minimax_model.py +83 -0
- camel/models/mistral_model.py +20 -47
- camel/models/model_factory.py +39 -3
- camel/models/model_manager.py +26 -8
- camel/models/modelscope_model.py +13 -193
- camel/models/moonshot_model.py +183 -21
- camel/models/nebius_model.py +83 -0
- camel/models/nemotron_model.py +19 -9
- camel/models/netmind_model.py +11 -18
- camel/models/novita_model.py +11 -18
- camel/models/nvidia_model.py +11 -18
- camel/models/ollama_model.py +14 -21
- camel/models/openai_audio_models.py +2 -2
- camel/models/openai_compatible_model.py +190 -71
- camel/models/openai_model.py +192 -86
- camel/models/openrouter_model.py +11 -19
- camel/models/ppio_model.py +11 -18
- camel/models/qianfan_model.py +89 -0
- camel/models/qwen_model.py +13 -193
- camel/models/reka_model.py +23 -49
- camel/models/reward/__init__.py +2 -2
- camel/models/reward/base_reward_model.py +2 -2
- camel/models/reward/evaluator.py +2 -2
- camel/models/reward/nemotron_model.py +2 -2
- camel/models/reward/skywork_model.py +2 -2
- camel/models/samba_model.py +50 -75
- camel/models/sglang_model.py +90 -68
- camel/models/siliconflow_model.py +12 -35
- camel/models/stub_model.py +10 -7
- camel/models/togetherai_model.py +11 -18
- camel/models/vllm_model.py +10 -18
- camel/models/volcano_model.py +158 -19
- camel/models/watsonx_model.py +9 -47
- camel/models/yi_model.py +11 -18
- camel/models/zhipuai_model.py +70 -18
- camel/parsers/__init__.py +18 -0
- camel/parsers/mcp_tool_call_parser.py +176 -0
- camel/personas/__init__.py +2 -2
- camel/personas/persona.py +2 -2
- camel/personas/persona_hub.py +2 -2
- camel/prompts/__init__.py +2 -2
- camel/prompts/ai_society.py +2 -2
- camel/prompts/base.py +2 -2
- camel/prompts/code.py +2 -2
- camel/prompts/evaluation.py +2 -2
- camel/prompts/generate_text_embedding_data.py +2 -2
- camel/prompts/image_craft.py +2 -2
- camel/prompts/misalignment.py +2 -2
- camel/prompts/multi_condition_image_craft.py +2 -2
- camel/prompts/object_recognition.py +2 -2
- camel/prompts/persona_hub.py +3 -3
- camel/prompts/prompt_templates.py +2 -2
- camel/prompts/role_description_prompt_template.py +2 -2
- camel/prompts/solution_extraction.py +8 -8
- camel/prompts/task_prompt_template.py +2 -2
- camel/prompts/translation.py +2 -2
- camel/prompts/video_description_prompt.py +3 -3
- camel/responses/__init__.py +2 -2
- camel/responses/agent_responses.py +2 -2
- camel/retrievers/__init__.py +2 -2
- camel/retrievers/auto_retriever.py +3 -2
- camel/retrievers/base.py +2 -2
- camel/retrievers/bm25_retriever.py +2 -2
- camel/retrievers/cohere_rerank_retriever.py +2 -2
- camel/retrievers/hybrid_retrival.py +2 -2
- camel/retrievers/vector_retriever.py +2 -2
- camel/runtimes/Dockerfile.multi-toolkit +90 -0
- camel/runtimes/__init__.py +2 -2
- camel/runtimes/api.py +79 -23
- camel/runtimes/base.py +2 -2
- camel/runtimes/configs.py +13 -13
- camel/runtimes/daytona_runtime.py +17 -18
- camel/runtimes/docker_runtime.py +12 -12
- camel/runtimes/llm_guard_runtime.py +26 -26
- camel/runtimes/remote_http_runtime.py +11 -11
- camel/runtimes/ubuntu_docker_runtime.py +2 -2
- camel/runtimes/utils/__init__.py +2 -2
- camel/runtimes/utils/function_risk_toolkit.py +2 -2
- camel/runtimes/utils/ignore_risk_toolkit.py +2 -2
- camel/schemas/__init__.py +2 -2
- camel/schemas/base.py +2 -2
- camel/schemas/openai_converter.py +3 -3
- camel/schemas/outlines_converter.py +2 -2
- camel/services/agent_openapi_server.py +380 -0
- camel/societies/__init__.py +4 -2
- camel/societies/babyagi_playing.py +2 -2
- camel/societies/role_playing.py +201 -80
- camel/societies/workforce/__init__.py +10 -3
- camel/societies/workforce/base.py +2 -2
- camel/societies/workforce/events.py +145 -0
- camel/societies/workforce/prompts.py +259 -33
- camel/societies/workforce/role_playing_worker.py +88 -31
- camel/societies/workforce/single_agent_worker.py +638 -40
- camel/societies/workforce/structured_output_handler.py +512 -0
- camel/societies/workforce/task_channel.py +182 -38
- camel/societies/workforce/utils.py +780 -65
- camel/societies/workforce/worker.py +92 -26
- camel/societies/workforce/workflow_memory_manager.py +1746 -0
- camel/societies/workforce/workforce.py +5354 -372
- camel/societies/workforce/workforce_callback.py +103 -0
- camel/societies/workforce/workforce_logger.py +647 -0
- camel/societies/workforce/workforce_metrics.py +33 -0
- camel/storages/__init__.py +6 -2
- camel/storages/graph_storages/__init__.py +2 -2
- camel/storages/graph_storages/base.py +2 -2
- camel/storages/graph_storages/graph_element.py +2 -2
- camel/storages/graph_storages/nebula_graph.py +4 -4
- camel/storages/graph_storages/neo4j_graph.py +7 -7
- camel/storages/key_value_storages/__init__.py +2 -2
- camel/storages/key_value_storages/base.py +2 -2
- camel/storages/key_value_storages/in_memory.py +2 -2
- camel/storages/key_value_storages/json.py +17 -4
- camel/storages/key_value_storages/mem0_cloud.py +50 -49
- camel/storages/key_value_storages/redis.py +2 -2
- camel/storages/object_storages/__init__.py +2 -2
- camel/storages/object_storages/amazon_s3.py +2 -2
- camel/storages/object_storages/azure_blob.py +2 -2
- camel/storages/object_storages/base.py +2 -2
- camel/storages/object_storages/google_cloud.py +3 -3
- camel/storages/vectordb_storages/__init__.py +8 -2
- camel/storages/vectordb_storages/base.py +2 -2
- camel/storages/vectordb_storages/chroma.py +731 -0
- camel/storages/vectordb_storages/faiss.py +2 -2
- camel/storages/vectordb_storages/milvus.py +2 -2
- camel/storages/vectordb_storages/oceanbase.py +15 -15
- camel/storages/vectordb_storages/pgvector.py +349 -0
- camel/storages/vectordb_storages/qdrant.py +6 -6
- camel/storages/vectordb_storages/surreal.py +372 -0
- camel/storages/vectordb_storages/tidb.py +11 -8
- camel/storages/vectordb_storages/weaviate.py +2 -2
- camel/tasks/__init__.py +2 -2
- camel/tasks/task.py +348 -26
- camel/tasks/task_prompt.py +3 -3
- camel/terminators/__init__.py +2 -2
- camel/terminators/base.py +2 -2
- camel/terminators/response_terminator.py +2 -2
- camel/terminators/token_limit_terminator.py +2 -2
- camel/toolkits/__init__.py +57 -10
- camel/toolkits/aci_toolkit.py +66 -21
- camel/toolkits/arxiv_toolkit.py +8 -8
- camel/toolkits/ask_news_toolkit.py +2 -2
- camel/toolkits/async_browser_toolkit.py +4 -4
- camel/toolkits/audio_analysis_toolkit.py +3 -3
- camel/toolkits/base.py +106 -6
- camel/toolkits/bohrium_toolkit.py +2 -2
- camel/toolkits/browser_toolkit.py +34 -21
- camel/toolkits/browser_toolkit_commons.py +4 -4
- camel/toolkits/code_execution.py +31 -4
- camel/toolkits/context_summarizer_toolkit.py +684 -0
- camel/toolkits/craw4ai_toolkit.py +93 -0
- camel/toolkits/dappier_toolkit.py +12 -8
- camel/toolkits/data_commons_toolkit.py +2 -2
- camel/toolkits/dingtalk.py +1135 -0
- camel/toolkits/earth_science_toolkit.py +5367 -0
- camel/toolkits/edgeone_pages_mcp_toolkit.py +49 -0
- camel/toolkits/excel_toolkit.py +905 -71
- camel/toolkits/file_toolkit.py +1402 -0
- camel/toolkits/function_tool.py +205 -27
- camel/toolkits/github_toolkit.py +109 -22
- camel/toolkits/gmail_toolkit.py +1839 -0
- camel/toolkits/google_calendar_toolkit.py +40 -6
- camel/toolkits/google_drive_mcp_toolkit.py +54 -0
- camel/toolkits/google_maps_toolkit.py +2 -2
- camel/toolkits/google_scholar_toolkit.py +2 -2
- camel/toolkits/human_toolkit.py +36 -12
- camel/toolkits/hybrid_browser_toolkit/__init__.py +18 -0
- camel/toolkits/hybrid_browser_toolkit/config_loader.py +185 -0
- camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit.py +246 -0
- camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit_ts.py +1958 -0
- camel/toolkits/hybrid_browser_toolkit/installer.py +203 -0
- camel/toolkits/hybrid_browser_toolkit/ts/package-lock.json +4589 -0
- camel/toolkits/hybrid_browser_toolkit/ts/package.json +33 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/browser-scripts.js +125 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/browser-session.ts +1940 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/config-loader.ts +233 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/hybrid-browser-toolkit.ts +589 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/index.ts +7 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/parent-child-filter.ts +226 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/snapshot-parser.ts +219 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/som-screenshot-injected.ts +543 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/types.ts +129 -0
- camel/toolkits/hybrid_browser_toolkit/ts/tsconfig.json +27 -0
- camel/toolkits/hybrid_browser_toolkit/ts/websocket-server.js +325 -0
- camel/toolkits/hybrid_browser_toolkit/ws_wrapper.py +1037 -0
- camel/toolkits/hybrid_browser_toolkit_py/__init__.py +17 -0
- camel/toolkits/hybrid_browser_toolkit_py/actions.py +575 -0
- camel/toolkits/hybrid_browser_toolkit_py/agent.py +311 -0
- camel/toolkits/hybrid_browser_toolkit_py/browser_session.py +787 -0
- camel/toolkits/hybrid_browser_toolkit_py/config_loader.py +490 -0
- camel/toolkits/hybrid_browser_toolkit_py/hybrid_browser_toolkit.py +2390 -0
- camel/toolkits/hybrid_browser_toolkit_py/snapshot.py +233 -0
- camel/toolkits/hybrid_browser_toolkit_py/stealth_script.js +0 -0
- camel/toolkits/hybrid_browser_toolkit_py/unified_analyzer.js +1043 -0
- camel/toolkits/image_analysis_toolkit.py +3 -6
- camel/toolkits/image_generation_toolkit.py +390 -0
- camel/toolkits/jina_reranker_toolkit.py +5 -6
- camel/toolkits/klavis_toolkit.py +7 -3
- camel/toolkits/linkedin_toolkit.py +2 -2
- camel/toolkits/markitdown_toolkit.py +104 -0
- camel/toolkits/math_toolkit.py +66 -12
- camel/toolkits/mcp_toolkit.py +412 -36
- camel/toolkits/memory_toolkit.py +7 -3
- camel/toolkits/meshy_toolkit.py +2 -2
- camel/toolkits/message_agent_toolkit.py +608 -0
- camel/toolkits/message_integration.py +728 -0
- camel/toolkits/microsoft_outlook_mail_toolkit.py +1885 -0
- camel/toolkits/mineru_toolkit.py +2 -2
- camel/toolkits/minimax_mcp_toolkit.py +195 -0
- camel/toolkits/networkx_toolkit.py +2 -2
- camel/toolkits/note_taking_toolkit.py +277 -0
- camel/toolkits/notion_mcp_toolkit.py +224 -0
- camel/toolkits/notion_toolkit.py +2 -2
- camel/toolkits/open_api_specs/biztoc/__init__.py +2 -2
- camel/toolkits/open_api_specs/biztoc/ai-plugin.json +1 -1
- camel/toolkits/open_api_specs/coursera/__init__.py +2 -2
- camel/toolkits/open_api_specs/create_qr_code/__init__.py +2 -2
- camel/toolkits/open_api_specs/klarna/__init__.py +2 -2
- camel/toolkits/open_api_specs/nasa_apod/__init__.py +2 -2
- camel/toolkits/open_api_specs/outschool/__init__.py +2 -2
- camel/toolkits/open_api_specs/outschool/ai-plugin.json +1 -1
- camel/toolkits/open_api_specs/outschool/openapi.yaml +1 -1
- camel/toolkits/open_api_specs/outschool/paths/__init__.py +2 -2
- camel/toolkits/open_api_specs/outschool/paths/get_classes.py +2 -2
- camel/toolkits/open_api_specs/outschool/paths/search_teachers.py +2 -2
- camel/toolkits/open_api_specs/security_config.py +2 -2
- camel/toolkits/open_api_specs/speak/__init__.py +2 -2
- camel/toolkits/open_api_specs/web_scraper/__init__.py +2 -2
- camel/toolkits/open_api_specs/web_scraper/ai-plugin.json +1 -1
- camel/toolkits/open_api_specs/web_scraper/paths/__init__.py +2 -2
- camel/toolkits/open_api_specs/web_scraper/paths/scraper.py +2 -2
- camel/toolkits/open_api_toolkit.py +2 -2
- camel/toolkits/openbb_toolkit.py +7 -3
- camel/toolkits/origene_mcp_toolkit.py +56 -0
- camel/toolkits/page_script.js +53 -53
- camel/toolkits/playwright_mcp_toolkit.py +13 -31
- camel/toolkits/pptx_toolkit.py +36 -23
- camel/toolkits/pubmed_toolkit.py +2 -2
- camel/toolkits/pulse_mcp_search_toolkit.py +2 -2
- camel/toolkits/pyautogui_toolkit.py +2 -2
- camel/toolkits/reddit_toolkit.py +2 -2
- camel/toolkits/resend_toolkit.py +168 -0
- camel/toolkits/retrieval_toolkit.py +2 -2
- camel/toolkits/screenshot_toolkit.py +213 -0
- camel/toolkits/search_toolkit.py +606 -156
- camel/toolkits/searxng_toolkit.py +2 -2
- camel/toolkits/semantic_scholar_toolkit.py +2 -2
- camel/toolkits/slack_toolkit.py +108 -58
- camel/toolkits/sql_toolkit.py +712 -0
- camel/toolkits/stripe_toolkit.py +2 -2
- camel/toolkits/sympy_toolkit.py +3 -3
- camel/toolkits/task_planning_toolkit.py +5 -5
- camel/toolkits/terminal_toolkit/__init__.py +18 -0
- camel/toolkits/terminal_toolkit/terminal_toolkit.py +1281 -0
- camel/toolkits/terminal_toolkit/utils.py +659 -0
- camel/toolkits/thinking_toolkit.py +3 -3
- camel/toolkits/twitter_toolkit.py +2 -2
- camel/toolkits/vertex_ai_veo_toolkit.py +590 -0
- camel/toolkits/video_analysis_toolkit.py +109 -29
- camel/toolkits/video_download_toolkit.py +19 -16
- camel/toolkits/weather_toolkit.py +2 -2
- camel/toolkits/web_deploy_toolkit.py +1219 -0
- camel/toolkits/wechat_official_toolkit.py +483 -0
- camel/toolkits/whatsapp_toolkit.py +2 -2
- camel/toolkits/wolfram_alpha_toolkit.py +2 -2
- camel/toolkits/zapier_toolkit.py +7 -3
- camel/types/__init__.py +4 -4
- camel/types/agents/__init__.py +2 -2
- camel/types/agents/tool_calling_record.py +6 -3
- camel/types/enums.py +381 -41
- camel/types/mcp_registries.py +2 -2
- camel/types/openai_types.py +4 -4
- camel/types/unified_model_type.py +46 -10
- camel/utils/__init__.py +5 -2
- camel/utils/agent_context.py +41 -0
- camel/utils/async_func.py +2 -2
- camel/utils/chunker/__init__.py +2 -2
- camel/utils/chunker/base.py +2 -2
- camel/utils/chunker/code_chunker.py +2 -2
- camel/utils/chunker/uio_chunker.py +2 -2
- camel/utils/commons.py +38 -7
- camel/utils/constants.py +5 -2
- camel/utils/context_utils.py +1134 -0
- camel/utils/deduplication.py +2 -2
- camel/utils/filename.py +2 -2
- camel/utils/langfuse.py +18 -10
- camel/utils/mcp.py +140 -6
- camel/utils/mcp_client.py +48 -38
- camel/utils/message_summarizer.py +148 -0
- camel/utils/response_format.py +2 -2
- camel/utils/token_counting.py +45 -22
- camel/utils/tool_result.py +44 -0
- camel/verifiers/__init__.py +2 -2
- camel/verifiers/base.py +2 -2
- camel/verifiers/math_verifier.py +2 -2
- camel/verifiers/models.py +2 -2
- camel/verifiers/physics_verifier.py +2 -2
- camel/verifiers/python_verifier.py +2 -2
- {camel_ai-0.2.65.dist-info → camel_ai-0.2.83a6.dist-info}/METADATA +355 -117
- camel_ai-0.2.83a6.dist-info/RECORD +511 -0
- {camel_ai-0.2.65.dist-info → camel_ai-0.2.83a6.dist-info}/WHEEL +1 -1
- {camel_ai-0.2.65.dist-info → camel_ai-0.2.83a6.dist-info}/licenses/LICENSE +1 -1
- camel/loaders/pandas_reader.py +0 -368
- camel/toolkits/dalle_toolkit.py +0 -175
- camel/toolkits/file_write_toolkit.py +0 -444
- camel/toolkits/openai_agent_toolkit.py +0 -135
- camel/toolkits/terminal_toolkit.py +0 -1037
- camel_ai-0.2.65.dist-info/RECORD +0 -426
|
@@ -0,0 +1,659 @@
|
|
|
1
|
+
# ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
# ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
|
|
14
|
+
|
|
15
|
+
import os
|
|
16
|
+
import platform
|
|
17
|
+
import re
|
|
18
|
+
import shutil
|
|
19
|
+
import subprocess
|
|
20
|
+
import sys
|
|
21
|
+
import tempfile
|
|
22
|
+
import venv
|
|
23
|
+
from typing import Optional, Set, Tuple
|
|
24
|
+
|
|
25
|
+
from camel.logger import get_logger
|
|
26
|
+
|
|
27
|
+
logger = get_logger(__name__)
|
|
28
|
+
|
|
29
|
+
# Pre-compiled regex patterns for command safety checks
|
|
30
|
+
_CMD_PATTERN = re.compile(
|
|
31
|
+
r'(?:^|;|\||&&)\s*\b([a-zA-Z_/][\w\-/]*)', re.IGNORECASE
|
|
32
|
+
)
|
|
33
|
+
_QUOTED_STRING_PATTERN = re.compile(r'''["'][^"']*["']''')
|
|
34
|
+
# Match cd command with optional quoted or unquoted path
|
|
35
|
+
# Handles: cd path, cd "path with spaces", cd 'path with spaces'
|
|
36
|
+
_CD_PATTERN = re.compile(r'\bcd\s+(["\'][^"\']*["\']|[^\s;|&]+)')
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def check_command_safety(
|
|
40
|
+
command: str,
|
|
41
|
+
allowed_commands: Optional[Set[str]] = None,
|
|
42
|
+
) -> Tuple[bool, str]:
|
|
43
|
+
r"""Check if a command (potentially with chaining) is safe to execute.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
command (str): The command string to check
|
|
47
|
+
allowed_commands (Optional[Set[str]]): Set of allowed commands
|
|
48
|
+
(whitelist mode)
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
Tuple[bool, str]: (is_safe, reason)
|
|
52
|
+
"""
|
|
53
|
+
if not command.strip():
|
|
54
|
+
return False, "Empty command is not allowed."
|
|
55
|
+
|
|
56
|
+
# Dangerous commands list - including ALL rm operations
|
|
57
|
+
dangerous_commands = [
|
|
58
|
+
# System administration
|
|
59
|
+
'sudo',
|
|
60
|
+
'su',
|
|
61
|
+
'reboot',
|
|
62
|
+
'shutdown',
|
|
63
|
+
'halt',
|
|
64
|
+
'poweroff',
|
|
65
|
+
'init',
|
|
66
|
+
# File system manipulation
|
|
67
|
+
'rm',
|
|
68
|
+
'chown',
|
|
69
|
+
'chgrp',
|
|
70
|
+
'umount',
|
|
71
|
+
'mount',
|
|
72
|
+
# Disk operations
|
|
73
|
+
'dd',
|
|
74
|
+
'mkfs',
|
|
75
|
+
'fdisk',
|
|
76
|
+
'parted',
|
|
77
|
+
'fsck',
|
|
78
|
+
'mkswap',
|
|
79
|
+
'swapon',
|
|
80
|
+
'swapoff',
|
|
81
|
+
# Process management
|
|
82
|
+
'service',
|
|
83
|
+
'systemctl',
|
|
84
|
+
'systemd',
|
|
85
|
+
# Network configuration
|
|
86
|
+
'iptables',
|
|
87
|
+
'ip6tables',
|
|
88
|
+
'ifconfig',
|
|
89
|
+
'route',
|
|
90
|
+
'iptables-save',
|
|
91
|
+
# Cron and scheduling
|
|
92
|
+
'crontab',
|
|
93
|
+
'at',
|
|
94
|
+
'batch',
|
|
95
|
+
# User management
|
|
96
|
+
'useradd',
|
|
97
|
+
'userdel',
|
|
98
|
+
'usermod',
|
|
99
|
+
'passwd',
|
|
100
|
+
'chpasswd',
|
|
101
|
+
'newgrp',
|
|
102
|
+
# Kernel modules
|
|
103
|
+
'modprobe',
|
|
104
|
+
'rmmod',
|
|
105
|
+
'insmod',
|
|
106
|
+
'lsmod',
|
|
107
|
+
]
|
|
108
|
+
|
|
109
|
+
# Remove quoted strings to avoid false positives
|
|
110
|
+
clean_command = _QUOTED_STRING_PATTERN.sub(' ', command)
|
|
111
|
+
|
|
112
|
+
# If whitelist mode, check ALL commands against the whitelist
|
|
113
|
+
if allowed_commands is not None:
|
|
114
|
+
# Extract all command words (at start or after operators)
|
|
115
|
+
found_commands = _CMD_PATTERN.findall(clean_command)
|
|
116
|
+
for cmd in found_commands:
|
|
117
|
+
if cmd.lower() not in allowed_commands:
|
|
118
|
+
return (
|
|
119
|
+
False,
|
|
120
|
+
f"Command '{cmd}' is not in the allowed commands list.",
|
|
121
|
+
)
|
|
122
|
+
return True, ""
|
|
123
|
+
|
|
124
|
+
# Check for dangerous commands
|
|
125
|
+
for cmd in dangerous_commands:
|
|
126
|
+
pattern = rf'(?:^|;|\||&&)\s*\b{re.escape(cmd)}\b'
|
|
127
|
+
if re.search(pattern, clean_command, re.IGNORECASE):
|
|
128
|
+
return False, f"Command '{cmd}' is blocked for safety."
|
|
129
|
+
|
|
130
|
+
return True, ""
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def sanitize_command(
|
|
134
|
+
command: str,
|
|
135
|
+
use_docker_backend: bool = False,
|
|
136
|
+
safe_mode: bool = True,
|
|
137
|
+
working_dir: Optional[str] = None,
|
|
138
|
+
allowed_commands: Optional[Set[str]] = None,
|
|
139
|
+
) -> Tuple[bool, str]:
|
|
140
|
+
r"""A comprehensive command sanitizer for both local and Docker backends.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
command (str): The command to sanitize
|
|
144
|
+
use_docker_backend (bool): Whether using Docker backend
|
|
145
|
+
safe_mode (bool): Whether to apply security checks
|
|
146
|
+
working_dir (Optional[str]): Working directory for path validation
|
|
147
|
+
allowed_commands (Optional[Set[str]]): Set of allowed commands
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
Tuple[bool, str]: (is_safe, message_or_command)
|
|
151
|
+
"""
|
|
152
|
+
if not safe_mode:
|
|
153
|
+
return True, command # Skip all checks if safe_mode is disabled
|
|
154
|
+
|
|
155
|
+
# Use safety checker
|
|
156
|
+
is_safe, reason = check_command_safety(command, allowed_commands)
|
|
157
|
+
if not is_safe:
|
|
158
|
+
return False, reason
|
|
159
|
+
|
|
160
|
+
# Additional check for local backend: prevent cd outside working directory
|
|
161
|
+
if not use_docker_backend and working_dir and 'cd ' in command:
|
|
162
|
+
# Extract cd commands and check their targets
|
|
163
|
+
# Normalize working_dir to ensure consistent comparison
|
|
164
|
+
normalized_working_dir = os.path.normpath(os.path.abspath(working_dir))
|
|
165
|
+
for match in _CD_PATTERN.finditer(command):
|
|
166
|
+
target_path = match.group(1).strip('\'"')
|
|
167
|
+
target_dir = os.path.normpath(
|
|
168
|
+
os.path.abspath(os.path.join(working_dir, target_path))
|
|
169
|
+
)
|
|
170
|
+
# Use os.path.commonpath for safe path comparison
|
|
171
|
+
try:
|
|
172
|
+
common = os.path.commonpath(
|
|
173
|
+
[normalized_working_dir, target_dir]
|
|
174
|
+
)
|
|
175
|
+
if common != normalized_working_dir:
|
|
176
|
+
return (
|
|
177
|
+
False,
|
|
178
|
+
"Cannot 'cd' outside of the working directory.",
|
|
179
|
+
)
|
|
180
|
+
except ValueError:
|
|
181
|
+
# Different drives on Windows or other path issues
|
|
182
|
+
return False, "Cannot 'cd' outside of the working directory."
|
|
183
|
+
|
|
184
|
+
return True, command
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
# Environment management utilities
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def is_uv_environment() -> bool:
|
|
191
|
+
r"""Detect whether the current Python runtime is managed by uv."""
|
|
192
|
+
return (
|
|
193
|
+
"UV_CACHE_DIR" in os.environ
|
|
194
|
+
or "uv" in sys.executable
|
|
195
|
+
or shutil.which("uv") is not None
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def ensure_uv_available(update_callback=None) -> Tuple[bool, Optional[str]]:
|
|
200
|
+
r"""Ensure uv is available, installing it if necessary.
|
|
201
|
+
|
|
202
|
+
Args:
|
|
203
|
+
update_callback: Optional callback function to receive status updates
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
Tuple[bool, Optional[str]]: (success, uv_path)
|
|
207
|
+
"""
|
|
208
|
+
# Check if uv is already available
|
|
209
|
+
existing_uv = shutil.which("uv")
|
|
210
|
+
if existing_uv is not None:
|
|
211
|
+
if update_callback:
|
|
212
|
+
update_callback(f"uv is already available at: {existing_uv}\n")
|
|
213
|
+
return True, existing_uv
|
|
214
|
+
|
|
215
|
+
try:
|
|
216
|
+
if update_callback:
|
|
217
|
+
update_callback("uv not found, installing...\n")
|
|
218
|
+
|
|
219
|
+
os_type = platform.system()
|
|
220
|
+
|
|
221
|
+
# Install uv using the official installer script
|
|
222
|
+
if os_type.lower() in [
|
|
223
|
+
'darwin',
|
|
224
|
+
'linux',
|
|
225
|
+
] or os_type.lower().startswith('linux'):
|
|
226
|
+
# Use curl to download and execute the installer
|
|
227
|
+
install_cmd = "curl -LsSf https://astral.sh/uv/install.sh | sh"
|
|
228
|
+
result = subprocess.run(
|
|
229
|
+
install_cmd,
|
|
230
|
+
shell=True,
|
|
231
|
+
capture_output=True,
|
|
232
|
+
text=True,
|
|
233
|
+
timeout=60,
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
if result.returncode != 0:
|
|
237
|
+
if update_callback:
|
|
238
|
+
update_callback(f"Failed to install uv: {result.stderr}\n")
|
|
239
|
+
return False, None
|
|
240
|
+
|
|
241
|
+
# Check if uv was installed in the expected location
|
|
242
|
+
home = os.path.expanduser("~")
|
|
243
|
+
uv_bin_path = os.path.join(home, ".cargo", "bin")
|
|
244
|
+
uv_executable = os.path.join(uv_bin_path, "uv")
|
|
245
|
+
|
|
246
|
+
if os.path.exists(uv_executable):
|
|
247
|
+
if update_callback:
|
|
248
|
+
update_callback(
|
|
249
|
+
f"uv installed successfully at: {uv_executable}\n"
|
|
250
|
+
)
|
|
251
|
+
return True, uv_executable
|
|
252
|
+
|
|
253
|
+
elif os_type.lower() == 'windows':
|
|
254
|
+
# Use PowerShell to install uv on Windows
|
|
255
|
+
install_cmd = (
|
|
256
|
+
"powershell -ExecutionPolicy Bypass -c "
|
|
257
|
+
"\"irm https://astral.sh/uv/install.ps1 | iex\""
|
|
258
|
+
)
|
|
259
|
+
result = subprocess.run(
|
|
260
|
+
install_cmd,
|
|
261
|
+
shell=True,
|
|
262
|
+
capture_output=True,
|
|
263
|
+
text=True,
|
|
264
|
+
timeout=60,
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
if result.returncode != 0:
|
|
268
|
+
if update_callback:
|
|
269
|
+
update_callback(f"Failed to install uv: {result.stderr}\n")
|
|
270
|
+
return False, None
|
|
271
|
+
|
|
272
|
+
# Check if uv was installed in the expected location on Windows
|
|
273
|
+
home = os.path.expanduser("~")
|
|
274
|
+
uv_bin_path = os.path.join(home, ".cargo", "bin")
|
|
275
|
+
uv_executable = os.path.join(uv_bin_path, "uv.exe")
|
|
276
|
+
|
|
277
|
+
if os.path.exists(uv_executable):
|
|
278
|
+
if update_callback:
|
|
279
|
+
update_callback(
|
|
280
|
+
f"uv installed successfully at: {uv_executable}\n"
|
|
281
|
+
)
|
|
282
|
+
return True, uv_executable
|
|
283
|
+
|
|
284
|
+
if update_callback:
|
|
285
|
+
update_callback("Failed to verify uv installation\n")
|
|
286
|
+
return False, None
|
|
287
|
+
|
|
288
|
+
except Exception as e:
|
|
289
|
+
if update_callback:
|
|
290
|
+
update_callback(f"Error installing uv: {e!s}\n")
|
|
291
|
+
logger.error(f"Failed to install uv: {e}")
|
|
292
|
+
return False, None
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
def setup_initial_env_with_uv(
|
|
296
|
+
env_path: str, uv_path: str, working_dir: str, update_callback=None
|
|
297
|
+
) -> bool:
|
|
298
|
+
r"""Set up initial environment using uv."""
|
|
299
|
+
try:
|
|
300
|
+
# Create virtual environment with Python 3.10 using uv
|
|
301
|
+
subprocess.run(
|
|
302
|
+
[uv_path, "venv", "--python", "3.10", env_path],
|
|
303
|
+
check=True,
|
|
304
|
+
capture_output=True,
|
|
305
|
+
cwd=working_dir,
|
|
306
|
+
timeout=300,
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
# Get the python path from the new environment
|
|
310
|
+
if platform.system() == 'Windows':
|
|
311
|
+
python_path = os.path.join(env_path, "Scripts", "python.exe")
|
|
312
|
+
else:
|
|
313
|
+
python_path = os.path.join(env_path, "bin", "python")
|
|
314
|
+
|
|
315
|
+
# Install essential packages using uv
|
|
316
|
+
essential_packages = [
|
|
317
|
+
"pip",
|
|
318
|
+
"setuptools",
|
|
319
|
+
"wheel",
|
|
320
|
+
]
|
|
321
|
+
subprocess.run(
|
|
322
|
+
[
|
|
323
|
+
uv_path,
|
|
324
|
+
"pip",
|
|
325
|
+
"install",
|
|
326
|
+
"--python",
|
|
327
|
+
python_path,
|
|
328
|
+
*essential_packages,
|
|
329
|
+
],
|
|
330
|
+
check=True,
|
|
331
|
+
capture_output=True,
|
|
332
|
+
cwd=working_dir,
|
|
333
|
+
timeout=300,
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
if update_callback:
|
|
337
|
+
update_callback(
|
|
338
|
+
"[UV] Initial environment created with Python 3.10 "
|
|
339
|
+
"and essential packages"
|
|
340
|
+
)
|
|
341
|
+
return True
|
|
342
|
+
|
|
343
|
+
except subprocess.CalledProcessError as e:
|
|
344
|
+
error_msg = e.stderr.decode() if e.stderr else str(e)
|
|
345
|
+
if update_callback:
|
|
346
|
+
update_callback(f"UV setup failed: {error_msg}\n")
|
|
347
|
+
return False
|
|
348
|
+
except subprocess.TimeoutExpired:
|
|
349
|
+
if update_callback:
|
|
350
|
+
update_callback("UV setup timed out after 5 minutes\n")
|
|
351
|
+
return False
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
def setup_initial_env_with_venv(
|
|
355
|
+
env_path: str, working_dir: str, update_callback=None
|
|
356
|
+
) -> bool:
|
|
357
|
+
r"""Set up initial environment using standard venv."""
|
|
358
|
+
try:
|
|
359
|
+
# Create virtual environment with system Python
|
|
360
|
+
try:
|
|
361
|
+
venv.create(
|
|
362
|
+
env_path,
|
|
363
|
+
with_pip=True,
|
|
364
|
+
system_site_packages=False,
|
|
365
|
+
symlinks=True,
|
|
366
|
+
)
|
|
367
|
+
except Exception:
|
|
368
|
+
# Fallback to symlinks=False if symlinks=True fails
|
|
369
|
+
# (e.g., on some Windows configurations)
|
|
370
|
+
venv.create(
|
|
371
|
+
env_path,
|
|
372
|
+
with_pip=True,
|
|
373
|
+
system_site_packages=False,
|
|
374
|
+
symlinks=False,
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
# Get pip path
|
|
378
|
+
if platform.system() == 'Windows':
|
|
379
|
+
pip_path = os.path.join(env_path, "Scripts", "pip.exe")
|
|
380
|
+
else:
|
|
381
|
+
pip_path = os.path.join(env_path, "bin", "pip")
|
|
382
|
+
|
|
383
|
+
# Upgrade pip and install essential packages
|
|
384
|
+
essential_packages = [
|
|
385
|
+
"pip",
|
|
386
|
+
"setuptools",
|
|
387
|
+
"wheel",
|
|
388
|
+
]
|
|
389
|
+
subprocess.run(
|
|
390
|
+
[pip_path, "install", "--upgrade", *essential_packages],
|
|
391
|
+
check=True,
|
|
392
|
+
capture_output=True,
|
|
393
|
+
cwd=working_dir,
|
|
394
|
+
timeout=300,
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
if update_callback:
|
|
398
|
+
update_callback(
|
|
399
|
+
"Initial environment created with system Python "
|
|
400
|
+
"and essential packages"
|
|
401
|
+
)
|
|
402
|
+
return True
|
|
403
|
+
|
|
404
|
+
except subprocess.CalledProcessError as e:
|
|
405
|
+
error_msg = e.stderr.decode() if e.stderr else str(e)
|
|
406
|
+
if update_callback:
|
|
407
|
+
update_callback(f"Venv setup failed: {error_msg}\n")
|
|
408
|
+
return False
|
|
409
|
+
except subprocess.TimeoutExpired:
|
|
410
|
+
if update_callback:
|
|
411
|
+
update_callback("Venv setup timed out after 5 minutes\n")
|
|
412
|
+
return False
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
def clone_current_environment(
|
|
416
|
+
env_path: str, working_dir: str, update_callback=None
|
|
417
|
+
) -> bool:
|
|
418
|
+
r"""Clone the current Python environment to a new virtual environment.
|
|
419
|
+
|
|
420
|
+
This function creates a new virtual environment with the same Python
|
|
421
|
+
version as the current environment and installs all packages from
|
|
422
|
+
the current environment.
|
|
423
|
+
|
|
424
|
+
Args:
|
|
425
|
+
env_path: Path where the new environment will be created.
|
|
426
|
+
working_dir: Working directory for subprocess commands.
|
|
427
|
+
update_callback: Optional callback for status updates.
|
|
428
|
+
|
|
429
|
+
Returns:
|
|
430
|
+
True if the environment was created successfully, False otherwise.
|
|
431
|
+
"""
|
|
432
|
+
try:
|
|
433
|
+
if os.path.exists(env_path):
|
|
434
|
+
if update_callback:
|
|
435
|
+
update_callback(f"Using existing environment: {env_path}\n")
|
|
436
|
+
return True
|
|
437
|
+
|
|
438
|
+
if update_callback:
|
|
439
|
+
update_callback(
|
|
440
|
+
f"Cloning current Python environment to: {env_path}\n"
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
# Get current Python version
|
|
444
|
+
current_version = f"{sys.version_info.major}.{sys.version_info.minor}"
|
|
445
|
+
|
|
446
|
+
# Get list of installed packages in current environment
|
|
447
|
+
if update_callback:
|
|
448
|
+
update_callback("Collecting installed packages...\n")
|
|
449
|
+
|
|
450
|
+
freeze_result = subprocess.run(
|
|
451
|
+
[sys.executable, "-m", "pip", "freeze"],
|
|
452
|
+
capture_output=True,
|
|
453
|
+
text=True,
|
|
454
|
+
timeout=60,
|
|
455
|
+
)
|
|
456
|
+
if freeze_result.returncode != 0:
|
|
457
|
+
if update_callback:
|
|
458
|
+
update_callback(
|
|
459
|
+
"Warning: Failed to get installed packages, "
|
|
460
|
+
"creating empty environment\n"
|
|
461
|
+
)
|
|
462
|
+
installed_packages = ""
|
|
463
|
+
else:
|
|
464
|
+
installed_packages = freeze_result.stdout.strip()
|
|
465
|
+
|
|
466
|
+
# Try to use uv if available
|
|
467
|
+
success, uv_path = ensure_uv_available(update_callback)
|
|
468
|
+
|
|
469
|
+
if success and uv_path:
|
|
470
|
+
# Create venv with uv
|
|
471
|
+
subprocess.run(
|
|
472
|
+
[uv_path, "venv", "--python", current_version, env_path],
|
|
473
|
+
check=True,
|
|
474
|
+
capture_output=True,
|
|
475
|
+
cwd=working_dir,
|
|
476
|
+
timeout=300,
|
|
477
|
+
)
|
|
478
|
+
|
|
479
|
+
# Get the python path from the new environment
|
|
480
|
+
if platform.system() == 'Windows':
|
|
481
|
+
python_path = os.path.join(env_path, "Scripts", "python.exe")
|
|
482
|
+
else:
|
|
483
|
+
python_path = os.path.join(env_path, "bin", "python")
|
|
484
|
+
|
|
485
|
+
# Install pip, setuptools, wheel first
|
|
486
|
+
subprocess.run(
|
|
487
|
+
[
|
|
488
|
+
uv_path,
|
|
489
|
+
"pip",
|
|
490
|
+
"install",
|
|
491
|
+
"--python",
|
|
492
|
+
python_path,
|
|
493
|
+
"pip",
|
|
494
|
+
"setuptools",
|
|
495
|
+
"wheel",
|
|
496
|
+
],
|
|
497
|
+
check=True,
|
|
498
|
+
capture_output=True,
|
|
499
|
+
cwd=working_dir,
|
|
500
|
+
timeout=300,
|
|
501
|
+
)
|
|
502
|
+
|
|
503
|
+
# Install cloned packages if any
|
|
504
|
+
if installed_packages:
|
|
505
|
+
if update_callback:
|
|
506
|
+
update_callback("Installing cloned packages with uv...\n")
|
|
507
|
+
# Write requirements to temp file (auto-deleted)
|
|
508
|
+
fd, requirements_file = tempfile.mkstemp(
|
|
509
|
+
suffix=".txt", prefix="requirements_", dir=working_dir
|
|
510
|
+
)
|
|
511
|
+
try:
|
|
512
|
+
with os.fdopen(fd, "w") as f:
|
|
513
|
+
f.write(installed_packages)
|
|
514
|
+
subprocess.run(
|
|
515
|
+
[
|
|
516
|
+
uv_path,
|
|
517
|
+
"pip",
|
|
518
|
+
"install",
|
|
519
|
+
"--python",
|
|
520
|
+
python_path,
|
|
521
|
+
"-r",
|
|
522
|
+
requirements_file,
|
|
523
|
+
],
|
|
524
|
+
check=True,
|
|
525
|
+
capture_output=True,
|
|
526
|
+
cwd=working_dir,
|
|
527
|
+
timeout=600,
|
|
528
|
+
)
|
|
529
|
+
finally:
|
|
530
|
+
if os.path.exists(requirements_file):
|
|
531
|
+
os.remove(requirements_file)
|
|
532
|
+
|
|
533
|
+
if update_callback:
|
|
534
|
+
update_callback("[UV] Environment cloned successfully!\n")
|
|
535
|
+
return True
|
|
536
|
+
else:
|
|
537
|
+
# Fallback to standard venv
|
|
538
|
+
if update_callback:
|
|
539
|
+
update_callback(
|
|
540
|
+
"Falling back to standard venv for cloning environment\n"
|
|
541
|
+
)
|
|
542
|
+
try:
|
|
543
|
+
venv.create(env_path, with_pip=True, symlinks=True)
|
|
544
|
+
except Exception:
|
|
545
|
+
# Fallback to symlinks=False if symlinks=True fails
|
|
546
|
+
venv.create(env_path, with_pip=True, symlinks=False)
|
|
547
|
+
|
|
548
|
+
# Get python/pip path
|
|
549
|
+
if platform.system() == 'Windows':
|
|
550
|
+
python_path = os.path.join(env_path, "Scripts", "python.exe")
|
|
551
|
+
else:
|
|
552
|
+
python_path = os.path.join(env_path, "bin", "python")
|
|
553
|
+
|
|
554
|
+
if not os.path.exists(python_path):
|
|
555
|
+
if update_callback:
|
|
556
|
+
update_callback(
|
|
557
|
+
f"Warning: Python executable not found at "
|
|
558
|
+
f"{python_path}\n"
|
|
559
|
+
)
|
|
560
|
+
return False
|
|
561
|
+
|
|
562
|
+
# Upgrade pip
|
|
563
|
+
subprocess.run(
|
|
564
|
+
[python_path, "-m", "pip", "install", "--upgrade", "pip"],
|
|
565
|
+
check=True,
|
|
566
|
+
capture_output=True,
|
|
567
|
+
cwd=working_dir,
|
|
568
|
+
timeout=60,
|
|
569
|
+
)
|
|
570
|
+
|
|
571
|
+
# Install cloned packages if any
|
|
572
|
+
if installed_packages:
|
|
573
|
+
if update_callback:
|
|
574
|
+
update_callback("Installing cloned packages with pip...\n")
|
|
575
|
+
# Write requirements to temp file (auto-deleted)
|
|
576
|
+
fd, requirements_file = tempfile.mkstemp(
|
|
577
|
+
suffix=".txt", prefix="requirements_", dir=working_dir
|
|
578
|
+
)
|
|
579
|
+
try:
|
|
580
|
+
with os.fdopen(fd, "w") as f:
|
|
581
|
+
f.write(installed_packages)
|
|
582
|
+
subprocess.run(
|
|
583
|
+
[
|
|
584
|
+
python_path,
|
|
585
|
+
"-m",
|
|
586
|
+
"pip",
|
|
587
|
+
"install",
|
|
588
|
+
"-r",
|
|
589
|
+
requirements_file,
|
|
590
|
+
],
|
|
591
|
+
check=True,
|
|
592
|
+
capture_output=True,
|
|
593
|
+
cwd=working_dir,
|
|
594
|
+
timeout=600,
|
|
595
|
+
)
|
|
596
|
+
finally:
|
|
597
|
+
if os.path.exists(requirements_file):
|
|
598
|
+
os.remove(requirements_file)
|
|
599
|
+
|
|
600
|
+
if update_callback:
|
|
601
|
+
update_callback("Environment cloned successfully!\n")
|
|
602
|
+
return True
|
|
603
|
+
|
|
604
|
+
except subprocess.CalledProcessError as e:
|
|
605
|
+
error_msg = e.stderr.decode() if e.stderr else str(e)
|
|
606
|
+
if update_callback:
|
|
607
|
+
update_callback(f"Failed to clone environment: {error_msg}\n")
|
|
608
|
+
logger.error(f"Failed to clone environment: {error_msg}")
|
|
609
|
+
return False
|
|
610
|
+
except subprocess.TimeoutExpired:
|
|
611
|
+
if update_callback:
|
|
612
|
+
update_callback("Environment cloning timed out\n")
|
|
613
|
+
return False
|
|
614
|
+
except Exception as e:
|
|
615
|
+
if update_callback:
|
|
616
|
+
update_callback(f"Failed to clone environment: {e!s}\n")
|
|
617
|
+
logger.error(f"Failed to clone environment: {e}")
|
|
618
|
+
return False
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
def check_nodejs_availability(update_callback=None) -> Tuple[bool, str]:
|
|
622
|
+
r"""Check if Node.js is available without modifying the system."""
|
|
623
|
+
try:
|
|
624
|
+
# Check if Node.js is already available in the system
|
|
625
|
+
node_result = subprocess.run(
|
|
626
|
+
["node", "--version"],
|
|
627
|
+
check=False,
|
|
628
|
+
capture_output=True,
|
|
629
|
+
timeout=10,
|
|
630
|
+
)
|
|
631
|
+
|
|
632
|
+
npm_result = subprocess.run(
|
|
633
|
+
["npm", "--version"],
|
|
634
|
+
check=False,
|
|
635
|
+
capture_output=True,
|
|
636
|
+
timeout=10,
|
|
637
|
+
)
|
|
638
|
+
|
|
639
|
+
if node_result.returncode == 0 and npm_result.returncode == 0:
|
|
640
|
+
node_version = node_result.stdout.decode().strip()
|
|
641
|
+
npm_version = npm_result.stdout.decode().strip()
|
|
642
|
+
info = (
|
|
643
|
+
f"Node.js {node_version} and npm {npm_version} are available"
|
|
644
|
+
)
|
|
645
|
+
if update_callback:
|
|
646
|
+
update_callback(f"{info}\n")
|
|
647
|
+
return True, info
|
|
648
|
+
else:
|
|
649
|
+
info = "Node.js not found. If needed, please install it manually."
|
|
650
|
+
if update_callback:
|
|
651
|
+
update_callback(f"Note: {info}\n")
|
|
652
|
+
return False, info
|
|
653
|
+
|
|
654
|
+
except Exception as e:
|
|
655
|
+
info = f"Could not check Node.js availability - {e}"
|
|
656
|
+
if update_callback:
|
|
657
|
+
update_callback(f"Note: {info}.\n")
|
|
658
|
+
logger.warning(f"Failed to check Node.js: {e}")
|
|
659
|
+
return False, info
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ========= Copyright 2023-
|
|
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-
|
|
13
|
+
# ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
|
|
14
14
|
|
|
15
15
|
from typing import List, Optional
|
|
16
16
|
|
|
@@ -32,7 +32,7 @@ class ThinkingToolkit(BaseToolkit):
|
|
|
32
32
|
|
|
33
33
|
Args:
|
|
34
34
|
timeout (Optional[float]): The timeout for the toolkit.
|
|
35
|
-
(default: :obj
|
|
35
|
+
(default: :obj:`None`)
|
|
36
36
|
"""
|
|
37
37
|
super().__init__(timeout=timeout)
|
|
38
38
|
self.plans: List[str] = []
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ========= Copyright 2023-
|
|
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-
|
|
13
|
+
# ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
|
|
14
14
|
import datetime
|
|
15
15
|
import os
|
|
16
16
|
from http import HTTPStatus
|