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.
- 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 +5012 -902
- 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 +39 -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 +94 -0
- camel/benchmarks/mock_website/mock_web.py +299 -0
- camel/benchmarks/mock_website/requirements.txt +3 -0
- camel/benchmarks/mock_website/shopping_mall/app.py +465 -0
- camel/benchmarks/mock_website/task.json +104 -0
- 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 +26 -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 +8 -7
- 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 +3 -3
- camel/configs/cometapi_config.py +106 -0
- camel/configs/crynux_config.py +94 -0
- camel/configs/deepseek_config.py +9 -8
- 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 +3 -3
- 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 +8 -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 +3 -3
- camel/configs/samba_config.py +8 -6
- 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_collector → data_collectors}/__init__.py +2 -2
- camel/{data_collector → data_collectors}/alpaca_collector.py +19 -10
- camel/{data_collector → data_collectors}/base.py +2 -2
- camel/{data_collector → data_collectors}/sharegpt_collector.py +3 -3
- camel/datagen/__init__.py +2 -2
- camel/datagen/cot_datagen.py +32 -37
- camel/datagen/evol_instruct/__init__.py +2 -2
- camel/datagen/evol_instruct/evol_instruct.py +2 -2
- camel/datagen/evol_instruct/scorer.py +24 -25
- camel/datagen/evol_instruct/templates.py +48 -48
- 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 +3 -3
- camel/datasets/self_instruct_generator.py +2 -2
- camel/datasets/static_dataset.py +152 -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 +10 -3
- 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 +4 -4
- camel/embeddings/together_embedding.py +2 -2
- camel/embeddings/vlm_embedding.py +11 -4
- 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 +16 -3
- camel/interpreters/docker/Dockerfile +53 -7
- camel/interpreters/docker_interpreter.py +70 -11
- camel/interpreters/e2b_interpreter.py +59 -11
- camel/interpreters/internal_python_interpreter.py +81 -4
- camel/interpreters/interpreter_error.py +2 -2
- camel/interpreters/ipython_interpreter.py +23 -5
- camel/interpreters/microsandbox_interpreter.py +395 -0
- camel/interpreters/subprocess_interpreter.py +36 -4
- camel/loaders/__init__.py +17 -5
- 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 +128 -93
- 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 +148 -0
- 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 +126 -9
- camel/memories/blocks/vectordb_block.py +10 -3
- camel/memories/context_creators/__init__.py +2 -2
- camel/memories/context_creators/score_based.py +31 -239
- camel/memories/records.py +98 -13
- camel/messages/__init__.py +2 -2
- camel/messages/base.py +193 -46
- 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 +263 -63
- camel/models/base_audio_model.py +5 -3
- camel/models/base_model.py +195 -26
- camel/models/cerebras_model.py +83 -0
- camel/models/cohere_model.py +81 -21
- camel/models/cometapi_model.py +83 -0
- camel/models/crynux_model.py +87 -0
- camel/models/deepseek_model.py +61 -59
- camel/models/fish_audio_model.py +8 -2
- camel/models/gemini_model.py +439 -30
- camel/models/groq_model.py +11 -19
- camel/models/internlm_model.py +11 -18
- camel/models/litellm_model.py +94 -34
- camel/models/lmstudio_model.py +17 -20
- camel/models/minimax_model.py +83 -0
- camel/models/mistral_model.py +84 -19
- camel/models/model_factory.py +49 -6
- camel/models/model_manager.py +33 -11
- camel/models/modelscope_model.py +13 -193
- camel/models/moonshot_model.py +195 -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 +234 -27
- camel/models/openai_model.py +255 -39
- 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 +90 -21
- 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 +117 -49
- camel/models/sglang_model.py +162 -42
- 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 +16 -20
- camel/models/watsonx_model.py +69 -19
- 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 +23 -3
- camel/retrievers/base.py +2 -2
- camel/retrievers/bm25_retriever.py +3 -4
- camel/retrievers/cohere_rerank_retriever.py +2 -2
- camel/retrievers/hybrid_retrival.py +4 -4
- camel/retrievers/vector_retriever.py +2 -2
- camel/runtimes/Dockerfile.multi-toolkit +90 -0
- camel/{runtime → runtimes}/__init__.py +2 -2
- camel/runtimes/api.py +153 -0
- camel/{runtime → runtimes}/base.py +2 -2
- camel/{runtime → runtimes}/configs.py +13 -13
- camel/{runtime → runtimes}/daytona_runtime.py +18 -19
- camel/{runtime → runtimes}/docker_runtime.py +13 -13
- camel/{runtime → runtimes}/llm_guard_runtime.py +28 -28
- camel/{runtime → runtimes}/remote_http_runtime.py +12 -12
- camel/{runtime → runtimes}/ubuntu_docker_runtime.py +3 -3
- camel/{runtime → runtimes}/utils/__init__.py +2 -2
- camel/{runtime → runtimes}/utils/function_risk_toolkit.py +2 -2
- camel/{runtime → 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 +9 -5
- camel/societies/workforce/events.py +143 -0
- camel/societies/workforce/prompts.py +258 -33
- camel/societies/workforce/role_playing_worker.py +95 -30
- camel/societies/workforce/single_agent_worker.py +659 -30
- camel/societies/workforce/structured_output_handler.py +512 -0
- camel/societies/workforce/task_channel.py +182 -38
- camel/societies/workforce/utils.py +784 -18
- camel/societies/workforce/worker.py +96 -28
- camel/societies/workforce/workflow_memory_manager.py +1746 -0
- camel/societies/workforce/workforce.py +5730 -366
- 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 +10 -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 +12 -2
- camel/storages/vectordb_storages/base.py +2 -2
- camel/storages/vectordb_storages/chroma.py +731 -0
- camel/storages/vectordb_storages/faiss.py +712 -0
- camel/storages/vectordb_storages/milvus.py +2 -2
- camel/storages/vectordb_storages/oceanbase.py +16 -17
- 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 +714 -0
- camel/tasks/__init__.py +2 -2
- camel/tasks/task.py +366 -27
- 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 +58 -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 +174 -575
- camel/toolkits/audio_analysis_toolkit.py +3 -3
- camel/toolkits/base.py +65 -7
- camel/toolkits/bohrium_toolkit.py +318 -0
- camel/toolkits/browser_toolkit.py +306 -566
- camel/toolkits/browser_toolkit_commons.py +568 -0
- camel/toolkits/code_execution.py +67 -11
- 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 +910 -70
- camel/toolkits/file_toolkit.py +1402 -0
- camel/toolkits/function_tool.py +128 -20
- camel/toolkits/github_toolkit.py +148 -43
- 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 +1973 -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 +1929 -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 +319 -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 -3
- camel/toolkits/image_generation_toolkit.py +390 -0
- camel/toolkits/jina_reranker_toolkit.py +195 -79
- 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 +841 -600
- 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 +724 -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 +86 -74
- camel/toolkits/playwright_mcp_toolkit.py +27 -32
- camel/toolkits/pptx_toolkit.py +790 -0
- 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 +539 -146
- 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 +134 -0
- camel/toolkits/terminal_toolkit/__init__.py +18 -0
- camel/toolkits/terminal_toolkit/terminal_toolkit.py +1070 -0
- camel/toolkits/terminal_toolkit/utils.py +532 -0
- camel/toolkits/thinking_toolkit.py +3 -3
- camel/toolkits/twitter_toolkit.py +8 -3
- camel/toolkits/vertex_ai_veo_toolkit.py +590 -0
- camel/toolkits/video_analysis_toolkit.py +112 -29
- camel/toolkits/video_download_toolkit.py +22 -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 +53 -25
- 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 +454 -35
- camel/types/mcp_registries.py +2 -2
- camel/types/openai_types.py +4 -4
- camel/types/unified_model_type.py +43 -6
- camel/utils/__init__.py +20 -2
- 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 +65 -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 +258 -0
- camel/utils/mcp.py +140 -6
- camel/utils/mcp_client.py +1056 -0
- 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.59.dist-info → camel_ai-0.2.82.dist-info}/METADATA +349 -108
- camel_ai-0.2.82.dist-info/RECORD +507 -0
- {camel_ai-0.2.59.dist-info → camel_ai-0.2.82.dist-info}/WHEEL +1 -1
- {camel_ai-0.2.59.dist-info → camel_ai-0.2.82.dist-info}/licenses/LICENSE +1 -1
- camel/loaders/pandas_reader.py +0 -368
- camel/runtime/api.py +0 -97
- camel/toolkits/dalle_toolkit.py +0 -171
- camel/toolkits/file_write_toolkit.py +0 -395
- camel/toolkits/openai_agent_toolkit.py +0 -135
- camel/toolkits/terminal_toolkit.py +0 -1037
- camel_ai-0.2.59.dist-info/RECORD +0 -410
camel/utils/deduplication.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ========= Copyright 2023-
|
|
1
|
+
# ========= Copyright 2023-2025 @ 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-2025 @ CAMEL-AI.org. All Rights Reserved. =========
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
from typing import Dict, List, Literal, Optional
|
camel/utils/filename.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ========= Copyright 2023-
|
|
1
|
+
# ========= Copyright 2023-2025 @ 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-2025 @ CAMEL-AI.org. All Rights Reserved. =========
|
|
14
14
|
import platform
|
|
15
15
|
import re
|
|
16
16
|
import unicodedata
|
camel/utils/langfuse.py
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# ========= Copyright 2023-2025 @ 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-2025 @ CAMEL-AI.org. All Rights Reserved. =========
|
|
14
|
+
import os
|
|
15
|
+
import threading
|
|
16
|
+
from typing import Any, Dict, List, Optional
|
|
17
|
+
|
|
18
|
+
from camel.logger import get_logger
|
|
19
|
+
from camel.utils import dependencies_required
|
|
20
|
+
|
|
21
|
+
logger = get_logger(__name__)
|
|
22
|
+
# Thread-local storage for agent session IDs
|
|
23
|
+
_local = threading.local()
|
|
24
|
+
|
|
25
|
+
# Global flag to track if Langfuse has been configured
|
|
26
|
+
_langfuse_configured = False
|
|
27
|
+
|
|
28
|
+
try:
|
|
29
|
+
from langfuse.decorators import langfuse_context
|
|
30
|
+
|
|
31
|
+
LANGFUSE_AVAILABLE = True
|
|
32
|
+
except ImportError:
|
|
33
|
+
LANGFUSE_AVAILABLE = False
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dependencies_required('langfuse')
|
|
37
|
+
def configure_langfuse(
|
|
38
|
+
public_key: Optional[str] = None,
|
|
39
|
+
secret_key: Optional[str] = None,
|
|
40
|
+
host: Optional[str] = None,
|
|
41
|
+
debug: Optional[bool] = None,
|
|
42
|
+
enabled: Optional[bool] = None,
|
|
43
|
+
):
|
|
44
|
+
r"""Configure Langfuse for CAMEL models.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
public_key(Optional[str]): Langfuse public key. Can be set via LANGFUSE_PUBLIC_KEY.
|
|
48
|
+
(default: :obj:`None`)
|
|
49
|
+
secret_key(Optional[str]): Langfuse secret key. Can be set via LANGFUSE_SECRET_KEY.
|
|
50
|
+
(default: :obj:`None`)
|
|
51
|
+
host(Optional[str]): Langfuse host URL. Can be set via LANGFUSE_HOST.
|
|
52
|
+
(default: :obj:`https://cloud.langfuse.com`)
|
|
53
|
+
debug(Optional[bool]): Enable debug mode. Can be set via LANGFUSE_DEBUG.
|
|
54
|
+
(default: :obj:`None`)
|
|
55
|
+
enabled(Optional[bool]): Enable/disable tracing. Can be set via LANGFUSE_ENABLED.
|
|
56
|
+
(default: :obj:`None`)
|
|
57
|
+
|
|
58
|
+
Note:
|
|
59
|
+
This function configures the native langfuse_context which works with
|
|
60
|
+
@observe() decorators. Set enabled=False to disable all tracing.
|
|
61
|
+
""" # noqa: E501
|
|
62
|
+
global _langfuse_configured
|
|
63
|
+
|
|
64
|
+
# Get configuration from environment or parameters
|
|
65
|
+
public_key = public_key or os.environ.get("LANGFUSE_PUBLIC_KEY")
|
|
66
|
+
secret_key = secret_key or os.environ.get("LANGFUSE_SECRET_KEY")
|
|
67
|
+
host = host or os.environ.get(
|
|
68
|
+
"LANGFUSE_HOST", "https://cloud.langfuse.com"
|
|
69
|
+
)
|
|
70
|
+
debug = (
|
|
71
|
+
debug
|
|
72
|
+
if debug is not None
|
|
73
|
+
else os.environ.get("LANGFUSE_DEBUG", "False").lower() == "true"
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# Handle enabled parameter
|
|
77
|
+
if enabled is None:
|
|
78
|
+
env_enabled_str = os.environ.get("LANGFUSE_ENABLED")
|
|
79
|
+
if env_enabled_str is not None:
|
|
80
|
+
enabled = env_enabled_str.lower() == "true"
|
|
81
|
+
else:
|
|
82
|
+
enabled = False # Default to disabled
|
|
83
|
+
|
|
84
|
+
# If not enabled, don't configure anything and don't call langfuse function
|
|
85
|
+
if not enabled:
|
|
86
|
+
_langfuse_configured = False
|
|
87
|
+
logger.info("Langfuse tracing disabled for CAMEL models")
|
|
88
|
+
|
|
89
|
+
logger.debug(
|
|
90
|
+
f"Configuring Langfuse - enabled: {enabled}, "
|
|
91
|
+
f"public_key: {'***' + public_key[-4:] if public_key else None}, "
|
|
92
|
+
f"host: {host}, debug: {debug}"
|
|
93
|
+
)
|
|
94
|
+
if enabled and public_key and secret_key and LANGFUSE_AVAILABLE:
|
|
95
|
+
_langfuse_configured = True
|
|
96
|
+
else:
|
|
97
|
+
_langfuse_configured = False
|
|
98
|
+
|
|
99
|
+
try:
|
|
100
|
+
# Configure langfuse_context with native method
|
|
101
|
+
langfuse_context.configure(
|
|
102
|
+
public_key=public_key,
|
|
103
|
+
secret_key=secret_key,
|
|
104
|
+
host=host,
|
|
105
|
+
debug=debug,
|
|
106
|
+
enabled=True, # Always True here since we checked enabled above
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
logger.info("Langfuse tracing enabled for CAMEL models")
|
|
110
|
+
|
|
111
|
+
except Exception as e:
|
|
112
|
+
logger.error(f"Failed to configure Langfuse: {e}")
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def is_langfuse_available() -> bool:
|
|
116
|
+
r"""Check if Langfuse is configured."""
|
|
117
|
+
return _langfuse_configured
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def set_current_agent_session_id(session_id: str) -> None:
|
|
121
|
+
r"""Set the session ID for the current agent in thread-local storage.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
session_id(str): The session ID to set for the current agent.
|
|
125
|
+
"""
|
|
126
|
+
|
|
127
|
+
_local.agent_session_id = session_id
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def get_current_agent_session_id() -> Optional[str]:
|
|
131
|
+
r"""Get the session ID for the current agent from thread-local storage.
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
Optional[str]: The session ID for the current agent.
|
|
135
|
+
"""
|
|
136
|
+
if is_langfuse_available():
|
|
137
|
+
return getattr(_local, 'agent_session_id', None)
|
|
138
|
+
return None
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def update_langfuse_trace(
|
|
142
|
+
session_id: Optional[str] = None,
|
|
143
|
+
user_id: Optional[str] = None,
|
|
144
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
145
|
+
tags: Optional[List[str]] = None,
|
|
146
|
+
) -> bool:
|
|
147
|
+
r"""Update the current Langfuse trace with session ID and metadata.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
session_id(Optional[str]): Optional session ID to use. If :obj:`None`
|
|
151
|
+
uses the current agent's session ID. (default: :obj:`None`)
|
|
152
|
+
user_id(Optional[str]): Optional user ID for the trace.
|
|
153
|
+
(default: :obj:`None`)
|
|
154
|
+
metadata(Optional[Dict[str, Any]]): Optional metadata dictionary.
|
|
155
|
+
(default: :obj:`None`)
|
|
156
|
+
tags(Optional[List[str]]): Optional list of tags.
|
|
157
|
+
(default: :obj:`None`)
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
bool: True if update was successful, False otherwise.
|
|
161
|
+
"""
|
|
162
|
+
if not is_langfuse_available():
|
|
163
|
+
return False
|
|
164
|
+
|
|
165
|
+
# Use provided session_id or get from thread-local storage
|
|
166
|
+
final_session_id = session_id or get_current_agent_session_id()
|
|
167
|
+
|
|
168
|
+
update_data: Dict[str, Any] = {}
|
|
169
|
+
if final_session_id:
|
|
170
|
+
update_data["session_id"] = final_session_id
|
|
171
|
+
if user_id:
|
|
172
|
+
update_data["user_id"] = user_id
|
|
173
|
+
if metadata:
|
|
174
|
+
update_data["metadata"] = metadata
|
|
175
|
+
if tags:
|
|
176
|
+
update_data["tags"] = tags
|
|
177
|
+
|
|
178
|
+
if update_data:
|
|
179
|
+
langfuse_context.update_current_trace(**update_data)
|
|
180
|
+
return True
|
|
181
|
+
|
|
182
|
+
return False
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def update_current_observation(
|
|
186
|
+
input: Optional[Dict[str, Any]] = None,
|
|
187
|
+
output: Optional[Dict[str, Any]] = None,
|
|
188
|
+
model: Optional[str] = None,
|
|
189
|
+
model_parameters: Optional[Dict[str, Any]] = None,
|
|
190
|
+
usage_details: Optional[Dict[str, Any]] = None,
|
|
191
|
+
**kwargs,
|
|
192
|
+
) -> None:
|
|
193
|
+
r"""Update the current Langfuse observation with input, output,
|
|
194
|
+
model, model_parameters, and usage_details.
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
input(Optional[Dict[str, Any]]): Optional input dictionary.
|
|
198
|
+
(default: :obj:`None`)
|
|
199
|
+
output(Optional[Dict[str, Any]]): Optional output dictionary.
|
|
200
|
+
(default: :obj:`None`)
|
|
201
|
+
model(Optional[str]): Optional model name. (default: :obj:`None`)
|
|
202
|
+
model_parameters(Optional[Dict[str, Any]]): Optional model parameters
|
|
203
|
+
dictionary. (default: :obj:`None`)
|
|
204
|
+
usage_details(Optional[Dict[str, Any]]): Optional usage details
|
|
205
|
+
dictionary. (default: :obj:`None`)
|
|
206
|
+
|
|
207
|
+
Returns:
|
|
208
|
+
None
|
|
209
|
+
"""
|
|
210
|
+
if not is_langfuse_available():
|
|
211
|
+
return
|
|
212
|
+
|
|
213
|
+
langfuse_context.update_current_observation(
|
|
214
|
+
input=input,
|
|
215
|
+
output=output,
|
|
216
|
+
model=model,
|
|
217
|
+
model_parameters=model_parameters,
|
|
218
|
+
usage_details=usage_details,
|
|
219
|
+
**kwargs,
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def get_langfuse_status() -> Dict[str, Any]:
|
|
224
|
+
r"""Get detailed Langfuse configuration status for debugging.
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
Dict[str, Any]: Status information including configuration state.
|
|
228
|
+
"""
|
|
229
|
+
env_enabled_str = os.environ.get("LANGFUSE_ENABLED")
|
|
230
|
+
env_enabled = (
|
|
231
|
+
env_enabled_str.lower() == "true" if env_enabled_str else None
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
status = {
|
|
235
|
+
"configured": _langfuse_configured,
|
|
236
|
+
"has_public_key": bool(os.environ.get("LANGFUSE_PUBLIC_KEY")),
|
|
237
|
+
"has_secret_key": bool(os.environ.get("LANGFUSE_SECRET_KEY")),
|
|
238
|
+
"env_enabled": env_enabled,
|
|
239
|
+
"host": os.environ.get("LANGFUSE_HOST", "https://cloud.langfuse.com"),
|
|
240
|
+
"debug": os.environ.get("LANGFUSE_DEBUG", "false").lower() == "true",
|
|
241
|
+
"current_session_id": get_current_agent_session_id(),
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if _langfuse_configured:
|
|
245
|
+
try:
|
|
246
|
+
# Try to get some context information
|
|
247
|
+
status["langfuse_context_available"] = True
|
|
248
|
+
except Exception as e:
|
|
249
|
+
status["langfuse_context_error"] = str(e)
|
|
250
|
+
|
|
251
|
+
return status
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def observe(*args, **kwargs):
|
|
255
|
+
def decorator(func):
|
|
256
|
+
return func
|
|
257
|
+
|
|
258
|
+
return decorator
|
camel/utils/mcp.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ========= Copyright 2023-
|
|
1
|
+
# ========= Copyright 2023-2025 @ 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,10 +10,124 @@
|
|
|
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-2025 @ CAMEL-AI.org. All Rights Reserved. =========
|
|
14
14
|
import functools
|
|
15
15
|
import inspect
|
|
16
|
-
|
|
16
|
+
import warnings
|
|
17
|
+
from typing import (
|
|
18
|
+
Any,
|
|
19
|
+
Callable,
|
|
20
|
+
List,
|
|
21
|
+
Optional,
|
|
22
|
+
Tuple,
|
|
23
|
+
Union,
|
|
24
|
+
get_args,
|
|
25
|
+
get_origin,
|
|
26
|
+
get_type_hints,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
from pydantic import create_model
|
|
30
|
+
from pydantic.errors import PydanticSchemaGenerationError
|
|
31
|
+
|
|
32
|
+
from camel.logger import get_logger
|
|
33
|
+
|
|
34
|
+
logger = get_logger(__name__)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _is_pydantic_serializable(type_annotation: Any) -> Tuple[bool, str]:
|
|
38
|
+
r"""Check if a type annotation is Pydantic serializable.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
type_annotation: The type annotation to check
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
Tuple[bool, str]: (is_serializable, error_message)
|
|
45
|
+
"""
|
|
46
|
+
# Handle None type
|
|
47
|
+
if type_annotation is type(None) or type_annotation is None:
|
|
48
|
+
return True, ""
|
|
49
|
+
|
|
50
|
+
# Handle generic types (List, Dict, Optional, etc.)
|
|
51
|
+
origin = get_origin(type_annotation)
|
|
52
|
+
if origin is not None:
|
|
53
|
+
args = get_args(type_annotation)
|
|
54
|
+
|
|
55
|
+
# For Union types (including Optional), check all args
|
|
56
|
+
if origin is Union:
|
|
57
|
+
for arg in args:
|
|
58
|
+
is_serializable, error_msg = _is_pydantic_serializable(arg)
|
|
59
|
+
if not is_serializable:
|
|
60
|
+
return False, error_msg
|
|
61
|
+
return True, ""
|
|
62
|
+
|
|
63
|
+
# For List, Set, Tuple, etc., check the contained types
|
|
64
|
+
if origin in (list, set, tuple, frozenset):
|
|
65
|
+
for arg in args:
|
|
66
|
+
is_serializable, error_msg = _is_pydantic_serializable(arg)
|
|
67
|
+
if not is_serializable:
|
|
68
|
+
return False, error_msg
|
|
69
|
+
return True, ""
|
|
70
|
+
|
|
71
|
+
# For Dict, check both key and value types
|
|
72
|
+
if origin is dict:
|
|
73
|
+
for arg in args:
|
|
74
|
+
is_serializable, error_msg = _is_pydantic_serializable(arg)
|
|
75
|
+
if not is_serializable:
|
|
76
|
+
return False, error_msg
|
|
77
|
+
return True, ""
|
|
78
|
+
|
|
79
|
+
# Try to create a simple pydantic model with this type
|
|
80
|
+
try:
|
|
81
|
+
create_model("TestModel", test_field=(type_annotation, ...))
|
|
82
|
+
# If model creation succeeds, the type is serializable
|
|
83
|
+
return True, ""
|
|
84
|
+
except (PydanticSchemaGenerationError, TypeError, ValueError) as e:
|
|
85
|
+
error_msg = (
|
|
86
|
+
f"Type '{type_annotation}' is not Pydantic serializable. "
|
|
87
|
+
f"Consider using a custom serializable type or converting "
|
|
88
|
+
f"to bytes/base64. Error: {e!s}"
|
|
89
|
+
)
|
|
90
|
+
return False, error_msg
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _validate_function_types(func: Callable[..., Any]) -> List[str]:
|
|
94
|
+
r"""Validate function parameter and return types are Pydantic serializable.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
func (Callable[..., Any]): The function to validate.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
List[str]: List of error messages for incompatible types.
|
|
101
|
+
"""
|
|
102
|
+
errors = []
|
|
103
|
+
|
|
104
|
+
try:
|
|
105
|
+
type_hints = get_type_hints(func)
|
|
106
|
+
except (NameError, AttributeError) as e:
|
|
107
|
+
# If we can't get type hints, skip validation
|
|
108
|
+
logger.warning(f"Could not get type hints for {func.__name__}: {e}")
|
|
109
|
+
return []
|
|
110
|
+
|
|
111
|
+
# Check return type
|
|
112
|
+
return_type = type_hints.get('return', Any)
|
|
113
|
+
if return_type != Any:
|
|
114
|
+
is_serializable, error_msg = _is_pydantic_serializable(return_type)
|
|
115
|
+
if not is_serializable:
|
|
116
|
+
errors.append(f"Return type: {error_msg}")
|
|
117
|
+
|
|
118
|
+
# Check parameter types
|
|
119
|
+
sig = inspect.signature(func)
|
|
120
|
+
for param_name, _param in sig.parameters.items():
|
|
121
|
+
if param_name == 'self':
|
|
122
|
+
continue
|
|
123
|
+
|
|
124
|
+
param_type = type_hints.get(param_name, Any)
|
|
125
|
+
if param_type != Any:
|
|
126
|
+
is_serializable, error_msg = _is_pydantic_serializable(param_type)
|
|
127
|
+
if not is_serializable:
|
|
128
|
+
errors.append(f"Parameter '{param_name}': {error_msg}")
|
|
129
|
+
|
|
130
|
+
return errors
|
|
17
131
|
|
|
18
132
|
|
|
19
133
|
class MCPServer:
|
|
@@ -55,7 +169,7 @@ class MCPServer:
|
|
|
55
169
|
|
|
56
170
|
def __init__(
|
|
57
171
|
self,
|
|
58
|
-
function_names: Optional[
|
|
172
|
+
function_names: Optional[List[str]] = None,
|
|
59
173
|
server_name: Optional[str] = None,
|
|
60
174
|
):
|
|
61
175
|
self.function_names = function_names
|
|
@@ -106,11 +220,11 @@ class MCPServer:
|
|
|
106
220
|
"""
|
|
107
221
|
from mcp.server.fastmcp import FastMCP
|
|
108
222
|
|
|
109
|
-
from camel.toolkits.base import BaseToolkit
|
|
110
|
-
|
|
111
223
|
original_init = cls.__init__
|
|
112
224
|
|
|
113
225
|
def new_init(instance, *args, **kwargs):
|
|
226
|
+
from camel.toolkits.base import BaseToolkit
|
|
227
|
+
|
|
114
228
|
original_init(instance, *args, **kwargs)
|
|
115
229
|
self.server_name = self.server_name or cls.__name__
|
|
116
230
|
instance.mcp = FastMCP(self.server_name)
|
|
@@ -135,6 +249,26 @@ class MCPServer:
|
|
|
135
249
|
f"Method {name} not found in class {cls.__name__} or "
|
|
136
250
|
"cannot be called."
|
|
137
251
|
)
|
|
252
|
+
|
|
253
|
+
# Validate function types for Pydantic compatibility
|
|
254
|
+
type_errors = _validate_function_types(func)
|
|
255
|
+
if type_errors:
|
|
256
|
+
error_message = (
|
|
257
|
+
f"Method '{name}' in class '{cls.__name__}' has "
|
|
258
|
+
f"non-Pydantic-serializable types:\n"
|
|
259
|
+
+ "\n".join(f" - {error}" for error in type_errors)
|
|
260
|
+
+ "\n\nSuggestions:"
|
|
261
|
+
+ "\n - Use standard Python types (str, int, float, bool, bytes)" # noqa: E501
|
|
262
|
+
+ "\n - Convert complex objects to JSON strings or bytes" # noqa: E501
|
|
263
|
+
+ "\n - Create custom Pydantic models for complex data" # noqa: E501
|
|
264
|
+
+ "\n - Use base64 encoding for binary data like images" # noqa: E501
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
# For now, issue a warning instead of raising an error
|
|
268
|
+
# This allows gradual migration while alerting developers
|
|
269
|
+
warnings.warn(error_message, UserWarning, stacklevel=3)
|
|
270
|
+
logger.warning(error_message)
|
|
271
|
+
|
|
138
272
|
wrapper = self.make_wrapper(func)
|
|
139
273
|
instance.mcp.tool(name=name)(wrapper)
|
|
140
274
|
|