camel-ai 0.2.65__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 +4835 -947
- 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 +23 -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/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 +31 -239
- 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 +16 -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 +212 -89
- 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 +16 -21
- camel/models/cometapi_model.py +83 -0
- camel/models/crynux_model.py +11 -18
- camel/models/deepseek_model.py +18 -58
- camel/models/fish_audio_model.py +8 -2
- camel/models/gemini_model.py +389 -26
- camel/models/groq_model.py +11 -19
- camel/models/internlm_model.py +11 -18
- camel/models/litellm_model.py +56 -34
- camel/models/lmstudio_model.py +17 -20
- camel/models/minimax_model.py +83 -0
- camel/models/mistral_model.py +18 -19
- camel/models/model_factory.py +37 -3
- camel/models/model_manager.py +26 -8
- 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 +188 -45
- camel/models/openai_model.py +216 -71
- 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 +21 -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 +48 -47
- camel/models/sglang_model.py +88 -40
- 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 +7 -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 +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 +143 -0
- camel/societies/workforce/prompts.py +258 -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 +5276 -355
- 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 +54 -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 +65 -7
- 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 +126 -18
- 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 +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 -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 +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 +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 +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 +5 -5
- 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 +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 +378 -39
- camel/types/mcp_registries.py +2 -2
- camel/types/openai_types.py +4 -4
- camel/types/unified_model_type.py +38 -6
- camel/utils/__init__.py +2 -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 +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 +2 -2
- 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.82.dist-info}/METADATA +327 -94
- camel_ai-0.2.82.dist-info/RECORD +507 -0
- {camel_ai-0.2.65.dist-info → camel_ai-0.2.82.dist-info}/WHEEL +1 -1
- {camel_ai-0.2.65.dist-info → camel_ai-0.2.82.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
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
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 os
|
|
15
15
|
import threading
|
|
16
16
|
from typing import Any, Dict, List, Optional
|
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
|
|
camel/utils/mcp_client.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
|
Unified MCP Client
|
|
16
16
|
|
|
@@ -113,7 +113,11 @@ class ServerConfig(BaseModel):
|
|
|
113
113
|
# Advanced options
|
|
114
114
|
sse_read_timeout: float = 300.0 # 5 minutes
|
|
115
115
|
terminate_on_close: bool = True
|
|
116
|
-
|
|
116
|
+
|
|
117
|
+
# New transport type parameter
|
|
118
|
+
type: Optional[str] = None
|
|
119
|
+
|
|
120
|
+
# Legacy parameter for backward compatibility
|
|
117
121
|
prefer_sse: bool = False
|
|
118
122
|
|
|
119
123
|
@model_validator(mode='after')
|
|
@@ -128,11 +132,43 @@ class ServerConfig(BaseModel):
|
|
|
128
132
|
if self.command and self.url:
|
|
129
133
|
raise ValueError("Cannot specify both 'command' and 'url'")
|
|
130
134
|
|
|
135
|
+
# Validate type if provided
|
|
136
|
+
if self.type is not None:
|
|
137
|
+
valid_types = {"stdio", "sse", "streamable_http", "websocket"}
|
|
138
|
+
if self.type not in valid_types:
|
|
139
|
+
raise ValueError(
|
|
140
|
+
f"Invalid type: "
|
|
141
|
+
f"'{self.type}'. "
|
|
142
|
+
f"Valid options: {valid_types}"
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
# Issue deprecation warning if prefer_sse is used
|
|
146
|
+
if self.prefer_sse and self.type is None:
|
|
147
|
+
import warnings
|
|
148
|
+
|
|
149
|
+
warnings.warn(
|
|
150
|
+
"The 'prefer_sse' parameter is deprecated. "
|
|
151
|
+
"Use 'type=\"sse\"' instead.",
|
|
152
|
+
DeprecationWarning,
|
|
153
|
+
stacklevel=2,
|
|
154
|
+
)
|
|
155
|
+
|
|
131
156
|
return self
|
|
132
157
|
|
|
133
158
|
@property
|
|
134
159
|
def transport_type(self) -> TransportType:
|
|
135
160
|
r"""Automatically detect transport type based on configuration."""
|
|
161
|
+
# Use explicit transport type if provided
|
|
162
|
+
if self.type is not None:
|
|
163
|
+
transport_map = {
|
|
164
|
+
"stdio": TransportType.STDIO,
|
|
165
|
+
"sse": TransportType.SSE,
|
|
166
|
+
"streamable_http": TransportType.STREAMABLE_HTTP,
|
|
167
|
+
"websocket": TransportType.WEBSOCKET,
|
|
168
|
+
}
|
|
169
|
+
return transport_map[self.type]
|
|
170
|
+
|
|
171
|
+
# If no type is provided, fall back to automatic detection
|
|
136
172
|
if self.command:
|
|
137
173
|
return TransportType.STDIO
|
|
138
174
|
elif self.url:
|
|
@@ -173,8 +209,6 @@ class MCPClient:
|
|
|
173
209
|
initialization. (default: :obj:`None`)
|
|
174
210
|
timeout (Optional[float], optional): Timeout for waiting for messages
|
|
175
211
|
from the server in seconds. (default: :obj:`10.0`)
|
|
176
|
-
strict (Optional[bool], optional): Strict mode for generating
|
|
177
|
-
FunctionTool objects. (default: :obj:`False`)
|
|
178
212
|
|
|
179
213
|
Examples:
|
|
180
214
|
STDIO server:
|
|
@@ -209,20 +243,6 @@ class MCPClient:
|
|
|
209
243
|
async with MCPClient({"url": "ws://localhost:8080/mcp"}) as client:
|
|
210
244
|
tools = client.get_tools()
|
|
211
245
|
|
|
212
|
-
With strict mode enabled:
|
|
213
|
-
|
|
214
|
-
.. code-block:: python
|
|
215
|
-
|
|
216
|
-
async with MCPClient({
|
|
217
|
-
"command": "npx",
|
|
218
|
-
"args": [
|
|
219
|
-
"-y",
|
|
220
|
-
"@modelcontextprotocol/server-filesystem",
|
|
221
|
-
"/path"
|
|
222
|
-
]
|
|
223
|
-
}, strict=True) as client:
|
|
224
|
-
tools = client.get_tools()
|
|
225
|
-
|
|
226
246
|
Attributes:
|
|
227
247
|
config (ServerConfig): The server configuration object.
|
|
228
248
|
client_info (Optional[types.Implementation]): Client implementation
|
|
@@ -235,14 +255,12 @@ class MCPClient:
|
|
|
235
255
|
config: Union[ServerConfig, Dict[str, Any]],
|
|
236
256
|
client_info: Optional[types.Implementation] = None,
|
|
237
257
|
timeout: Optional[float] = 10.0,
|
|
238
|
-
strict: Optional[bool] = False,
|
|
239
258
|
):
|
|
240
259
|
# Convert dict config to ServerConfig if needed
|
|
241
260
|
if isinstance(config, dict):
|
|
242
261
|
config = ServerConfig(**config)
|
|
243
262
|
|
|
244
263
|
self.config = config
|
|
245
|
-
self.strict = strict
|
|
246
264
|
|
|
247
265
|
# Validate transport type early (this will raise ValueError if invalid)
|
|
248
266
|
_ = self.config.transport_type
|
|
@@ -335,6 +353,14 @@ class MCPClient:
|
|
|
335
353
|
finally:
|
|
336
354
|
self._connection_context = None
|
|
337
355
|
|
|
356
|
+
# Add a small delay to allow subprocess cleanup on Windows
|
|
357
|
+
# This prevents "Event loop is closed" errors during shutdown
|
|
358
|
+
import asyncio
|
|
359
|
+
import sys
|
|
360
|
+
|
|
361
|
+
if sys.platform == "win32":
|
|
362
|
+
await asyncio.sleep(0.01)
|
|
363
|
+
|
|
338
364
|
finally:
|
|
339
365
|
# Ensure state is reset
|
|
340
366
|
self._tools = []
|
|
@@ -766,7 +792,6 @@ class MCPClient:
|
|
|
766
792
|
"name": mcp_tool.name,
|
|
767
793
|
"description": mcp_tool.description
|
|
768
794
|
or "No description provided.",
|
|
769
|
-
"strict": self.strict,
|
|
770
795
|
"parameters": parameters,
|
|
771
796
|
},
|
|
772
797
|
}
|
|
@@ -932,8 +957,7 @@ def create_mcp_client(
|
|
|
932
957
|
dictionary is provided, it will be automatically converted to
|
|
933
958
|
a :obj:`ServerConfig`.
|
|
934
959
|
**kwargs: Additional keyword arguments passed to the :obj:`MCPClient`
|
|
935
|
-
constructor, such as :obj:`client_info`, :obj:`timeout
|
|
936
|
-
:obj:`strict`.
|
|
960
|
+
constructor, such as :obj:`client_info`, :obj:`timeout`.
|
|
937
961
|
|
|
938
962
|
Returns:
|
|
939
963
|
MCPClient: A configured :obj:`MCPClient` instance ready for use as
|
|
@@ -972,20 +996,6 @@ def create_mcp_client(
|
|
|
972
996
|
"url": "ws://localhost:8080/mcp"
|
|
973
997
|
}) as client:
|
|
974
998
|
tools = client.get_tools()
|
|
975
|
-
|
|
976
|
-
With strict mode enabled:
|
|
977
|
-
|
|
978
|
-
.. code-block:: python
|
|
979
|
-
|
|
980
|
-
async with create_mcp_client({
|
|
981
|
-
"command": "npx",
|
|
982
|
-
"args": [
|
|
983
|
-
"-y",
|
|
984
|
-
"@modelcontextprotocol/server-filesystem",
|
|
985
|
-
"/path",
|
|
986
|
-
],
|
|
987
|
-
}, strict=True) as client:
|
|
988
|
-
tools = client.get_tools()
|
|
989
999
|
"""
|
|
990
1000
|
return MCPClient(config, **kwargs)
|
|
991
1001
|
|
|
@@ -0,0 +1,148 @@
|
|
|
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
|
+
from typing import List, Optional
|
|
15
|
+
|
|
16
|
+
from pydantic import BaseModel, Field
|
|
17
|
+
|
|
18
|
+
from camel.agents import ChatAgent
|
|
19
|
+
from camel.messages import BaseMessage
|
|
20
|
+
from camel.models import BaseModelBackend, ModelFactory
|
|
21
|
+
from camel.types import ModelPlatformType, ModelType
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class MessageSummary(BaseModel):
|
|
25
|
+
r"""Schema for structured message summaries.
|
|
26
|
+
|
|
27
|
+
Attributes:
|
|
28
|
+
summary (str): A brief, one-sentence summary of the conversation.
|
|
29
|
+
participants (List[str]): The roles of participants involved.
|
|
30
|
+
key_topics_and_entities (List[str]): Important topics, concepts, and
|
|
31
|
+
entities discussed.
|
|
32
|
+
decisions_and_outcomes (List[str]): Key decisions, conclusions, or
|
|
33
|
+
outcomes reached.
|
|
34
|
+
action_items (List[str]): A list of specific tasks or actions to be
|
|
35
|
+
taken, with assignees if mentioned.
|
|
36
|
+
progress_on_main_task (str): A summary of progress made on the
|
|
37
|
+
primary task.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
summary: str = Field(
|
|
41
|
+
description="A brief, one-sentence summary of the conversation."
|
|
42
|
+
)
|
|
43
|
+
participants: List[str] = Field(
|
|
44
|
+
description="The roles of participants involved."
|
|
45
|
+
)
|
|
46
|
+
key_topics_and_entities: List[str] = Field(
|
|
47
|
+
description="Important topics, concepts, and entities discussed."
|
|
48
|
+
)
|
|
49
|
+
decisions_and_outcomes: List[str] = Field(
|
|
50
|
+
description="Key decisions, conclusions, or outcomes reached."
|
|
51
|
+
)
|
|
52
|
+
action_items: List[str] = Field(
|
|
53
|
+
description=(
|
|
54
|
+
"A list of specific tasks or actions to be taken, with assignees "
|
|
55
|
+
"if mentioned."
|
|
56
|
+
)
|
|
57
|
+
)
|
|
58
|
+
progress_on_main_task: str = Field(
|
|
59
|
+
description="A summary of progress made on the primary task."
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class MessageSummarizer:
|
|
64
|
+
r"""Utility class for generating structured summaries of chat messages.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
model_backend (Optional[BaseModelBackend], optional):
|
|
68
|
+
The model backend to use for summarization.
|
|
69
|
+
If not provided, a default model backend will be created.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
def __init__(
|
|
73
|
+
self,
|
|
74
|
+
model_backend: Optional[BaseModelBackend] = None,
|
|
75
|
+
):
|
|
76
|
+
if model_backend is None:
|
|
77
|
+
self.model_backend = ModelFactory.create(
|
|
78
|
+
model_platform=ModelPlatformType.DEFAULT,
|
|
79
|
+
model_type=ModelType.GPT_4O_MINI,
|
|
80
|
+
)
|
|
81
|
+
else:
|
|
82
|
+
self.model_backend = model_backend
|
|
83
|
+
self.agent = ChatAgent(
|
|
84
|
+
BaseMessage.make_assistant_message(
|
|
85
|
+
role_name="Message Summarizer",
|
|
86
|
+
content=(
|
|
87
|
+
"You are an expert conversation summarizer. Your task is "
|
|
88
|
+
"to analyze chat messages and create a structured summary "
|
|
89
|
+
"in JSON format. The summary should capture:\n"
|
|
90
|
+
"- summary: A brief, one-sentence summary of the "
|
|
91
|
+
"conversation.\n"
|
|
92
|
+
"- participants: The roles of participants involved.\n"
|
|
93
|
+
"- key_topics_and_entities: Important topics, concepts, "
|
|
94
|
+
"and entities discussed.\n"
|
|
95
|
+
"- decisions_and_outcomes: Key decisions, conclusions, or "
|
|
96
|
+
"outcomes reached.\n"
|
|
97
|
+
"- action_items: A list of specific tasks or actions to "
|
|
98
|
+
"be taken, with assignees if mentioned.\n"
|
|
99
|
+
"- progress_on_main_task: A summary of progress made on "
|
|
100
|
+
"the primary task.\n\n"
|
|
101
|
+
"Your response must be a JSON object that strictly "
|
|
102
|
+
"adheres to this structure. Be concise and accurate."
|
|
103
|
+
),
|
|
104
|
+
),
|
|
105
|
+
model=self.model_backend,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
def summarize(self, messages: List[BaseMessage]) -> MessageSummary:
|
|
109
|
+
r"""Generate a structured summary of the provided messages.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
messages (List[BaseMessage]): List of messages to summarize.
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
MessageSummary: Structured summary of the conversation.
|
|
116
|
+
|
|
117
|
+
Raises:
|
|
118
|
+
ValueError: If the messages list is empty or if the model's
|
|
119
|
+
response cannot be parsed as valid JSON.
|
|
120
|
+
"""
|
|
121
|
+
if not messages:
|
|
122
|
+
raise ValueError("Cannot summarize an empty list of messages.")
|
|
123
|
+
|
|
124
|
+
# Construct prompt from messages
|
|
125
|
+
message_text = "\n".join(
|
|
126
|
+
f"{msg.role_name}: {msg.content}" for msg in messages
|
|
127
|
+
)
|
|
128
|
+
prompt = (
|
|
129
|
+
"Please analyze the following chat messages and generate a "
|
|
130
|
+
"structured summary.\n\n"
|
|
131
|
+
f"MESSAGES:\n\"\"\"\n{message_text}\n\"\"\"\n\n"
|
|
132
|
+
"Your response must be a JSON object that strictly adheres to the "
|
|
133
|
+
"required format."
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
# Get structured summary from model with forced JSON response
|
|
137
|
+
response = self.agent.step(prompt, response_format=MessageSummary)
|
|
138
|
+
|
|
139
|
+
if response.msg is None or response.msg.parsed is None:
|
|
140
|
+
raise ValueError(
|
|
141
|
+
"Failed to get a structured summary from the model."
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
summary = response.msg.parsed
|
|
145
|
+
if not isinstance(summary, MessageSummary):
|
|
146
|
+
raise ValueError("The parsed response is not a MessageSummary.")
|
|
147
|
+
|
|
148
|
+
return summary
|
camel/utils/response_format.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
|
from __future__ import annotations
|
|
16
16
|
|
camel/utils/token_counting.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
|
from __future__ import annotations
|
|
16
16
|
|
|
@@ -133,7 +133,11 @@ class OpenAITokenCounter(BaseTokenCounter):
|
|
|
133
133
|
self.tokens_per_message = 4
|
|
134
134
|
# If there's a name, the role is omitted
|
|
135
135
|
self.tokens_per_name = -1
|
|
136
|
-
elif (
|
|
136
|
+
elif (
|
|
137
|
+
("gpt-3.5-turbo" in self.model)
|
|
138
|
+
or ("gpt-4" in self.model)
|
|
139
|
+
or ("gpt-5" in self.model)
|
|
140
|
+
):
|
|
137
141
|
self.tokens_per_message = 3
|
|
138
142
|
self.tokens_per_name = 1
|
|
139
143
|
elif (
|
|
@@ -191,24 +195,32 @@ class OpenAITokenCounter(BaseTokenCounter):
|
|
|
191
195
|
image_str: str = item["image_url"]["url"]
|
|
192
196
|
detail = item["image_url"]["detail"]
|
|
193
197
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
#
|
|
198
|
-
|
|
199
|
-
|
|
198
|
+
# Only count tokens for base64 encoded images
|
|
199
|
+
# For URLs, we cannot reliably determine token count without fetching the image
|
|
200
|
+
if image_str.startswith("data:image"):
|
|
201
|
+
# Base64 encoded image
|
|
202
|
+
image_prefix_format = "data:image/{};base64,"
|
|
203
|
+
image_prefix: Optional[str] = None
|
|
204
|
+
for image_type in list(OpenAIImageType):
|
|
205
|
+
# Find the correct image format
|
|
206
|
+
image_prefix = image_prefix_format.format(
|
|
207
|
+
image_type.value
|
|
208
|
+
)
|
|
209
|
+
if image_prefix in image_str:
|
|
210
|
+
break
|
|
211
|
+
assert isinstance(image_prefix, str)
|
|
212
|
+
encoded_image = image_str.split(image_prefix)[
|
|
213
|
+
1
|
|
214
|
+
]
|
|
215
|
+
image_bytes = BytesIO(
|
|
216
|
+
base64.b64decode(encoded_image)
|
|
200
217
|
)
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
)
|
|
208
|
-
image = Image.open(image_bytes)
|
|
209
|
-
num_tokens += self._count_tokens_from_image(
|
|
210
|
-
image, OpenAIVisionDetailType(detail)
|
|
211
|
-
)
|
|
218
|
+
image = Image.open(image_bytes)
|
|
219
|
+
num_tokens += self._count_tokens_from_image(
|
|
220
|
+
image, OpenAIVisionDetailType(detail)
|
|
221
|
+
)
|
|
222
|
+
# Note: For regular URLs, token count cannot be determined without fetching the image
|
|
223
|
+
# The actual token usage will be reported by the API response
|
|
212
224
|
if key == "name":
|
|
213
225
|
num_tokens += self.tokens_per_name
|
|
214
226
|
|
|
@@ -280,15 +292,26 @@ class OpenAITokenCounter(BaseTokenCounter):
|
|
|
280
292
|
|
|
281
293
|
class AnthropicTokenCounter(BaseTokenCounter):
|
|
282
294
|
@dependencies_required('anthropic')
|
|
283
|
-
def __init__(
|
|
295
|
+
def __init__(
|
|
296
|
+
self,
|
|
297
|
+
model: str,
|
|
298
|
+
api_key: Optional[str] = None,
|
|
299
|
+
base_url: Optional[str] = None,
|
|
300
|
+
):
|
|
284
301
|
r"""Constructor for the token counter for Anthropic models.
|
|
285
302
|
|
|
286
303
|
Args:
|
|
287
304
|
model (str): The name of the Anthropic model being used.
|
|
305
|
+
api_key (Optional[str], optional): The API key for authenticating
|
|
306
|
+
with the Anthropic service. If not provided, it will use the
|
|
307
|
+
ANTHROPIC_API_KEY environment variable. (default: :obj:`None`)
|
|
308
|
+
base_url (Optional[str], optional): The URL of the Anthropic
|
|
309
|
+
service. If not provided, it will use the default Anthropic
|
|
310
|
+
URL. (default: :obj:`None`)
|
|
288
311
|
"""
|
|
289
312
|
from anthropic import Anthropic
|
|
290
313
|
|
|
291
|
-
self.client = Anthropic()
|
|
314
|
+
self.client = Anthropic(api_key=api_key, base_url=base_url)
|
|
292
315
|
self.model = model
|
|
293
316
|
|
|
294
317
|
@dependencies_required('anthropic')
|