# Camel > This documentation was extracted from the [CAMEL GitHub repository](https://github.com/camel-ai/camel). --- # CAMEL Documentation Source This documentation was extracted from the [CAMEL GitHub repository](https://github.com/camel-ai/camel). ## About CAMEL CAMEL (Communicative Agents for "Mind" Exploration of Large-Scale Language Model Society) is a multi-agent framework for exploring the scaling laws of agents. - **Repository**: https://github.com/camel-ai/camel - **Website**: https://www.camel-ai.org - **Documentation**: https://docs.camel-ai.org - **License**: Apache 2.0 ## Documentation Structure - `get_started/` - Getting started guides and installation instructions - `key_modules/` - Core module documentation (agents, models, prompts, etc.) - Reference files - API reference documentation (RST -> Markdown converted) ## Last Updated Documentation extracted on 2026-01-01 from the master branch. --- # camel.agents package ## Subpackages ::: {.toctree maxdepth="4"} camel.agents.tool_agents ::: ## Submodules ## camel.agents.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.agents.base ::: ## camel.agents.chat_agent module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.agents.chat_agent ::: ## camel.agents.critic_agent module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.agents.critic_agent ::: ## camel.agents.deductive_reasoner_agent module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.agents.deductive_reasoner_agent ::: ## camel.agents.embodied_agent module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.agents.embodied_agent ::: ## camel.agents.knowledge_graph_agent module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.agents.knowledge_graph_agent ::: ## camel.agents.role_assignment_agent module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.agents.role_assignment_agent ::: ## camel.agents.search_agent module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.agents.search_agent ::: ## camel.agents.task_agent module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.agents.task_agent ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.agents ::: --- # camel.agents.tool_agents package ## Submodules ## camel.agents.tool_agents.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.agents.tool_agents.base ::: ## camel.agents.tool_agents.hugging_face_tool_agent module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.agents.tool_agents.hugging_face_tool_agent ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.agents.tool_agents ::: --- # camel.benchmarks package ## Submodules ## camel.benchmarks.apibank module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.benchmarks.apibank ::: ## camel.benchmarks.apibench module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.benchmarks.apibench ::: ## camel.benchmarks.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.benchmarks.base ::: ## camel.benchmarks.gaia module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.benchmarks.gaia ::: ## camel.benchmarks.nexus module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.benchmarks.nexus ::: ## camel.benchmarks.ragbench module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.benchmarks.ragbench ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.benchmarks ::: --- # camel.bots.discord package ## Submodules ## camel.bots.discord.discord_app module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.bots.discord.discord_app ::: ## camel.bots.discord.discord_installation module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.bots.discord.discord_installation ::: ## camel.bots.discord.discord_store module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.bots.discord.discord_store ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.bots.discord ::: --- # camel.bots package ## Subpackages ::: {.toctree maxdepth="4"} camel.bots.discord camel.bots.slack ::: ## Submodules ## camel.bots.telegram_bot module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.bots.telegram_bot ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.bots ::: --- # camel.bots.slack package ## Submodules ## camel.bots.slack.models module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.bots.slack.models ::: ## camel.bots.slack.slack_app module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.bots.slack.slack_app ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.bots.slack ::: --- # camel.configs package ## Submodules ## camel.configs.anthropic_config module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.configs.anthropic_config ::: ## camel.configs.base_config module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.configs.base_config ::: ## camel.configs.cometapi_config module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.configs.cometapi_config ::: ## camel.configs.gemini_config module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.configs.gemini_config ::: ## camel.configs.groq_config module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.configs.groq_config ::: ## camel.configs.litellm_config module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.configs.litellm_config ::: ## camel.configs.mistral_config module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.configs.mistral_config ::: ## camel.configs.ollama_config module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.configs.ollama_config ::: ## camel.configs.openai_config module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.configs.openai_config ::: ## camel.configs.reka_config module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.configs.reka_config ::: ## camel.configs.samba_config module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.configs.samba_config ::: ## camel.configs.togetherai_config module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.configs.togetherai_config ::: ## camel.configs.vllm_config module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.configs.vllm_config ::: ## camel.configs.zhipuai_config module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.configs.zhipuai_config ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.configs ::: --- # camel.data_collector package ## Submodules ## camel.data_collector.alpaca_collector module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.data_collector.alpaca_collector ::: ## camel.data_collector.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.data_collector.base ::: ## camel.data_collector.sharegpt_collector module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.data_collector.sharegpt_collector ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.data_collector ::: --- # camel.datagen package ## Subpackages ::: {.toctree maxdepth="4"} camel.datagen.self_instruct camel.datagen.source2synth ::: ## Submodules ## camel.datagen.cot_datagen module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datagen.cot_datagen ::: ## camel.datagen.self_improving_cot module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datagen.self_improving_cot ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datagen ::: --- # camel.datagen.self_instruct.filter package ## Submodules ## camel.datagen.self_instruct.filter.filter_function module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datagen.self_instruct.filter.filter_function ::: ## camel.datagen.self_instruct.filter.filter_registry module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datagen.self_instruct.filter.filter_registry ::: ## camel.datagen.self_instruct.filter.instruction_filter module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datagen.self_instruct.filter.instruction_filter ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datagen.self_instruct.filter ::: --- # camel.datagen.self_instruct package ## Subpackages ::: {.toctree maxdepth="4"} camel.datagen.self_instruct.filter ::: ## Submodules ## camel.datagen.self_instruct.self_instruct module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datagen.self_instruct.self_instruct ::: ## camel.datagen.self_instruct.templates module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datagen.self_instruct.templates ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datagen.self_instruct ::: --- # camel.datagen.source2synth package ## Submodules ## camel.datagen.source2synth.data_processor module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datagen.source2synth.data_processor ::: ## camel.datagen.source2synth.models module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datagen.source2synth.models ::: ## camel.datagen.source2synth.user_data_processor_config module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datagen.source2synth.user_data_processor_config ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datagen.source2synth ::: --- # camel.datahubs package ## Submodules ## camel.datahubs.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datahubs.base ::: ## camel.datahubs.huggingface module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datahubs.huggingface ::: ## camel.datahubs.models module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datahubs.models ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datahubs ::: --- # camel.datasets package ## Submodules ## camel.datasets.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datasets.base ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.datasets ::: --- # camel.embeddings package ## Submodules ## camel.embeddings.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.embeddings.base ::: ## camel.embeddings.mistral_embedding module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.embeddings.mistral_embedding ::: ## camel.embeddings.openai_embedding module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.embeddings.openai_embedding ::: ## camel.embeddings.sentence_transformers_embeddings module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.embeddings.sentence_transformers_embeddings ::: ## camel.embeddings.vlm_embedding module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.embeddings.vlm_embedding ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.embeddings ::: --- # camel.environments package ## Submodules ## camel.environments.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.environments.base ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.environments ::: --- # camel.extractors package ## Submodules ## camel.extractors.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.extractors.base ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.extractors ::: --- # camel.interpreters package ## Submodules ## camel.interpreters.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.interpreters.base ::: ## camel.interpreters.docker_interpreter module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.interpreters.docker_interpreter ::: ## camel.interpreters.internal_python_interpreter module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.interpreters.internal_python_interpreter ::: ## camel.interpreters.interpreter_error module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.interpreters.interpreter_error ::: ## camel.interpreters.ipython_interpreter module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.interpreters.ipython_interpreter ::: ## camel.interpreters.subprocess_interpreter module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.interpreters.subprocess_interpreter ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.interpreters ::: --- # camel.loaders package ## Submodules ## camel.loaders.base_io module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.loaders.base_io ::: ## camel.loaders.firecrawl_reader module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.loaders.firecrawl_reader ::: ## camel.loaders.jina_url_reader module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.loaders.jina_url_reader ::: ## camel.loaders.unstructured_io module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.loaders.unstructured_io ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.loaders ::: --- # camel package ## Subpackages ::: {.toctree maxdepth="4"} camel.agents camel.configs camel.datagen camel.embeddings camel.interpreters camel.loaders camel.memories camel.messages camel.models camel.prompts camel.responses camel.retrievers camel.societies camel.storages camel.tasks camel.terminators camel.toolkits camel.types camel.utils ::: ## Submodules ## camel.generators module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.generators ::: ## camel.human module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.human ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel ::: --- # camel.memories.blocks package ## Submodules ## camel.memories.blocks.chat_history_block module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.memories.blocks.chat_history_block ::: ## camel.memories.blocks.vectordb_block module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.memories.blocks.vectordb_block ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.memories.blocks ::: --- # camel.memories.context_creators package ## Submodules ## camel.memories.context_creators.score_based module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.memories.context_creators.score_based ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.memories.context_creators ::: --- # camel.memories package ## Subpackages ::: {.toctree maxdepth="4"} camel.memories.blocks camel.memories.context_creators ::: ## Submodules ## camel.memories.agent_memories module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.memories.agent_memories ::: ## camel.memories.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.memories.base ::: ## camel.memories.records module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.memories.records ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.memories ::: --- # camel.messages.conversion package ## Subpackages ::: {.toctree maxdepth="4"} camel.messages.conversion.sharegpt ::: ## Submodules ## camel.messages.conversion.alpaca module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.messages.conversion.alpaca ::: ## camel.messages.conversion.conversation_models module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.messages.conversion.conversation_models ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.messages.conversion ::: --- # camel.messages.conversion.sharegpt.hermes package ## Submodules ## camel.messages.conversion.sharegpt.hermes.hermes_function_formatter module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.messages.conversion.sharegpt.hermes.hermes_function_formatter ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.messages.conversion.sharegpt.hermes ::: --- # camel.messages.conversion.sharegpt package ## Subpackages ::: {.toctree maxdepth="4"} camel.messages.conversion.sharegpt.hermes ::: ## Submodules ## camel.messages.conversion.sharegpt.function_call_formatter module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.messages.conversion.sharegpt.function_call_formatter ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.messages.conversion.sharegpt ::: --- # camel.messages package ## Submodules ## camel.messages.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.messages.base ::: ## camel.messages.func_message module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.messages.func_message ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.messages ::: --- # camel.models package ## Submodules ## camel.models.anthropic_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.anthropic_model ::: ## camel.models.azure_openai_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.azure_openai_model ::: ## camel.models.base_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.base_model ::: ## camel.models.cometapi_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.cometapi_model ::: ## camel.models.gemini_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.gemini_model ::: ## camel.models.groq_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.groq_model ::: ## camel.models.litellm_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.litellm_model ::: ## camel.models.mistral_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.mistral_model ::: ## camel.models.model_factory module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.model_factory ::: ## camel.models.nemotron_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.nemotron_model ::: ## camel.models.ollama_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.ollama_model ::: ## camel.models.open_source_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.openai_audio_models ::: ## camel.models.openai_compatible_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.openai_compatible_model ::: ## camel.models.openai_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.openai_model ::: ## camel.models.reka_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.reka_model ::: ## camel.models.samba_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.samba_model ::: ## camel.models.stub_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.stub_model ::: ## camel.models.togetherai_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.togetherai_model ::: ## camel.models.vllm_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.vllm_model ::: ## camel.models.zhipuai_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.zhipuai_model ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models ::: --- # camel.models.reward package ## Submodules ## camel.models.reward.base_reward_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.reward.base_reward_model ::: ## camel.models.reward.evaluator module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.reward.evaluator ::: ## camel.models.reward.nemotron_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.reward.nemotron_model ::: ## camel.models.reward.skywork_model module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.reward.skywork_model ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.models.reward ::: --- # camel.personas package ## Submodules ## camel.personas.persona module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.personas.persona ::: ## camel.personas.persona_hub module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.personas.persona_hub ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.personas ::: --- # camel.prompts package ## Submodules ## camel.prompts.ai_society module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.prompts.ai_society ::: ## camel.prompts.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.prompts.base ::: ## camel.prompts.code module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.prompts.code ::: ## camel.prompts.evaluation module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.prompts.evaluation ::: ## camel.prompts.generate_text_embedding_data module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.prompts.generate_text_embedding_data ::: ## camel.prompts.image_craft module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.prompts.image_craft ::: ## camel.prompts.misalignment module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.prompts.misalignment ::: ## camel.prompts.multi_condition_image_craft module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.prompts.multi_condition_image_craft ::: ## camel.prompts.object_recognition module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.prompts.object_recognition ::: ## camel.prompts.prompt_templates module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.prompts.prompt_templates ::: ## camel.prompts.role_description_prompt_template module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.prompts.role_description_prompt_template ::: ## camel.prompts.solution_extraction module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.prompts.solution_extraction ::: ## camel.prompts.task_prompt_template module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.prompts.task_prompt_template ::: ## camel.prompts.translation module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.prompts.translation ::: ## camel.prompts.video_description_prompt module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.prompts.video_description_prompt ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.prompts ::: --- # camel.responses package ## Submodules ## camel.responses.agent_responses module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.responses.agent_responses ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.responses ::: --- # camel.retrievers package ## Submodules ## camel.retrievers.auto_retriever module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.retrievers.auto_retriever ::: ## camel.retrievers.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.retrievers.base ::: ## camel.retrievers.bm25_retriever module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.retrievers.bm25_retriever ::: ## camel.retrievers.cohere_rerank_retriever module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.retrievers.cohere_rerank_retriever ::: ## camel.retrievers.vector_retriever module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.retrievers.vector_retriever ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.retrievers ::: --- # camel.runtime package ## Subpackages ::: {.toctree maxdepth="4"} camel.runtime.utils ::: ## Submodules ## camel.runtime.api module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.runtime.api ::: ## camel.runtime.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.runtime.base ::: ## camel.runtime.configs module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.runtime.configs ::: ## camel.runtime.docker_runtime module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.runtime.docker_runtime ::: ## camel.runtime.llm_guard_runtime module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.runtime.llm_guard_runtime ::: ## camel.runtime.remote_http_runtime module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.runtime.remote_http_runtime ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.runtime ::: --- # camel.runtime.utils package ## Submodules ## camel.runtime.utils.function_risk_toolkit module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.runtime.utils.function_risk_toolkit ::: ## camel.runtime.utils.ignore_risk_toolkit module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.runtime.utils.ignore_risk_toolkit ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.runtime.utils ::: --- # camel.schemas package ## Submodules ## camel.schemas.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.schemas.base ::: ## camel.schemas.openai_converter module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.schemas.openai_converter ::: ## camel.schemas.outlines_converter module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.schemas.outlines_converter ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.schemas ::: --- # camel.societies package ## Submodules ## camel.societies.babyagi_playing module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.societies.babyagi_playing ::: ## camel.societies.role_playing module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.societies.role_playing ::: ## Subpackages ::: {.toctree maxdepth="4"} camel.societies.workforce ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.societies ::: --- camel.societies.workforce package ======================= # Submodules camel.societies.workforce.base module \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-- ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.societies.workforce.base ::: camel.societies.workforce.prompts module \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-- ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.societies.workforce.prompts ::: camel.societies.workforce.role_playing_worker module \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-- ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.societies.workforce.role_playing_worker ::: camel.societies.workforce.single_agent_worker module \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-- ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.societies.workforce.single_agent_worker ::: camel.societies.workforce.task_channel module \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-- ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.societies.workforce.task_channel ::: camel.societies.workforce.utils module \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-- ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.societies.workforce.utils ::: camel.societies.workforce.worker module \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-- ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.societies.workforce.worker ::: camel.societies.workforce.workforce module \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-- ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.societies.workforce.workforce ::: # Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.societies.workforce ::: --- # camel.storages.graph_storages package ## Submodules ## camel.storages.graph_storages.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.graph_storages.base ::: ## camel.storages.graph_storages.graph_element module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.graph_storages.graph_element ::: ## camel.storages.graph_storages.neo4j_graph module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.graph_storages.neo4j_graph ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.graph_storages ::: --- # camel.storages.key_value_storages package ## Submodules ## camel.storages.key_value_storages.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.key_value_storages.base ::: ## camel.storages.key_value_storages.in_memory module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.key_value_storages.in_memory ::: ## camel.storages.key_value_storages.json module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.key_value_storages.json ::: ## camel.storages.key_value_storages.redis module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.key_value_storages.redis ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.key_value_storages ::: --- # camel.storages package ## Subpackages ::: {.toctree maxdepth="4"} camel.storages.graph_storages camel.storages.key_value_storages camel.storages.object_storages camel.storages.vectordb_storages ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages ::: --- # camel.storages.object_storages package ## Submodules ## camel.storages.object_storages.amazon_s3 module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.object_storages.amazon_s3 ::: ## camel.storages.object_storages.azure_blob module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.object_storages.azure_blob ::: ## camel.storages.object_storages.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.object_storages.base ::: ## camel.storages.object_storages.google_cloud module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.object_storages.google_cloud ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.object_storages ::: --- # camel.storages.vectordb_storages package ## Submodules ## camel.storages.vectordb_storages.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.vectordb_storages.base ::: ## camel.storages.vectordb_storages.milvus module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.vectordb_storages.milvus ::: ## camel.storages.vectordb_storages.qdrant module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.vectordb_storages.tidb ::: ## camel.storages.vectordb_storages.tidb module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.vectordb_storages.qdrant ::: ## camel.storages.vectordb_storages.faiss module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.vectordb_storages.faiss ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.storages.vectordb_storages ::: --- # camel.tasks package ## Submodules ## camel.tasks.task module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.tasks.task ::: ## camel.tasks.task_prompt module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.tasks.task_prompt ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.tasks ::: --- # camel.terminators package ## Submodules ## camel.terminators.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.terminators.base ::: ## camel.terminators.response_terminator module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.terminators.response_terminator ::: ## camel.terminators.token_limit_terminator module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.terminators.token_limit_terminator ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.terminators ::: --- # camel.toolkits package ## Submodules ## camel.toolkits.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.toolkits.base ::: ## camel.toolkits.code_execution module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.toolkits.code_execution ::: ## camel.toolkits.dalle_toolkit module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.toolkits.dalle_toolkit ::: ## camel.toolkits.github_toolkit module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.toolkits.github_toolkit ::: ## camel.toolkits.google_maps_toolkit module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.toolkits.google_maps_toolkit ::: ## camel.toolkits.linkedin_toolkit module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.toolkits.linkedin_toolkit ::: ## camel.toolkits.math_toolkit module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.toolkits.math_toolkit ::: ## camel.toolkits.open_api_toolkit module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.toolkits.open_api_toolkit ::: ## camel.toolkits.openai_function module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.toolkits.function_tool ::: ## camel.toolkits.reddit_toolkit module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.toolkits.reddit_toolkit ::: ## camel.toolkits.retrieval_toolkit module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.toolkits.retrieval_toolkit ::: ## camel.toolkits.search_toolkit module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.toolkits.search_toolkit ::: ## camel.toolkits.slack_toolkit module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.toolkits.slack_toolkit ::: ## camel.toolkits.twitter_toolkit module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.toolkits.twitter_toolkit ::: ## camel.toolkits.weather_toolkit module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.toolkits.weather_toolkit ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.toolkits ::: --- # camel.types.agents package ## Submodules ## camel.types.agents.tool_calling_record module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.types.agents.tool_calling_record ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.types.agents ::: --- # camel.types package ## Submodules ## camel.types.enums module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.types.enums ::: ## camel.types.openai_types module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.types.openai_types ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.types ::: --- # camel.utils package ## Submodules ## camel.utils.async_func module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.utils.async_func ::: ## camel.utils.commons module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.utils.commons ::: ## camel.utils.constants module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.utils.constants ::: ## camel.utils.token_counting module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.utils.token_counting ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.utils ::: --- # camel.verifiers package ## Submodules ## camel.verifiers.base module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.verifiers.base ::: ## camel.verifiers.models module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.verifiers.models ::: ## camel.verifiers.python_verifier module ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.verifiers.python_verifier ::: ## Module contents ::: {.automodule members="" undoc-members="" show-inheritance=""} camel.verifiers ::: --- Advanced Features ================ ```{=html}
← Multi-agent Society Data Processing →
``` ::: {.toctree maxdepth="1"} agents_with_tools agents_with_tools_from_ACI agents_with_tools_from_Composio agents_with_human_in_loop_and_tool_approval agents_with_memory agents_with_rag agents_with_graph_rag agents_with_MCP agents_tracking critic_agents_and_tree_search embodied_agents agent_generate_structured_output ::: --- ```{=html}
← Basic Concepts Model Training →
``` # Applications ::: {.toctree maxdepth="1"} roleplaying_scraper dynamic_travel_planner customer_service_Discord_bot_with_agentic_RAG customer_service_Discord_bot_using_SambaNova_with_agentic_RAG customer_service_Discord_bot_using_local_model_with_agentic_RAG finance_discord_bot pptx_toolkit ::: --- Basic Concepts ============= ```{=html}
Applications →
``` ::: {.toctree maxdepth="1"} create_your_first_agent create_your_first_agents_society agents_message agents_prompting ::: --- # Agentic Data Generation ```{=html}
← Applications Data Processing →
``` ::: {.toctree maxdepth="1"} sft_data_generation_and_unsloth_finetuning_mistral_7b_instruct sft_data_generation_and_unsloth_finetuning_Qwen2_5_7B sft_data_generation_and_unsloth_finetuning_tinyllama data_gen_with_real_function_calls_and_hermes_format self_instruct_data_generation cot_data_gen_sft_qwen_unsolth_upload_huggingface synthetic_dataevaluation&filter_with_reward_model data_model_generation_and_structured_output_with_qwen distill_math_reasoning_data_from_deepseek_r1 self_improving_math_reasoning_data_distillation_from_deepSeek_r1 self_improving_cot_generation ::: --- # Deep Dive into CAMEL’s Practices for Self-Improving CoT Generation 🚀 The field of AI is rapidly evolving, with reasoning models playing a crucial role in enhancing the problem-solving capabilities of large language models (LLMs). Recent developments, such as DeepSeek's R1 and OpenAI's o3-mini, demonstrate the industry's commitment to advancing reasoning through innovative approaches. DeepSeek's R1 model, introduced in January 2025, has shown remarkable proficiency in tasks that require complex reasoning and code generation. Its exceptional performance in areas like mathematics, science, and programming is particularly noteworthy. By distilling Chain-of-Thought (CoT) data from reasoning models, we can generate high-quality reasoning traces that are more accurate in solving complex problems. These generated data can be used to further fine-tune another LLM with less parameters, thereby enhancing its reasoning ability. CAMEL developed an approach leverages iterative refinement, self-assessment, and efficient batch processing to enable the continuous improvement of reasoning traces. In this blog, we will delve into how CAMEL implements its self-improving CoT pipeline. --- ## 1. Overview of the End-to-End Pipeline 🔍 ### 1.1 Why an Iterative CoT Pipeline? One-time CoT generation often leads to incomplete or suboptimal solutions. CAMEL addresses this challenge by employing a multi-step, iterative approach: 1. **Generate** an initial reasoning trace. 2. **Evaluate** the trace through either a dedicated evaluation agent or a specialized reward model. 3. **Refine** the trace based on the feedback provided. This self-improving methodology ensures that the reasoning process improves progressively, meeting specific thresholds for correctness, clarity, and completeness. Each iteration enhances the model's ability to solve the problem by learning from the previous outputs and evaluations. ### 1.2 Core Components The self-improving pipeline consists of three key components: 1. **`reason_agent`:** This agent is responsible for generating or improving reasoning traces. 2. **`evaluate_agent`:** An optional agent that evaluates the quality of the reasoning trace. This can be replaced by a reward model if needed. 3. **`reward_model`:** An optional model that provides numerical feedback on the trace, evaluating dimensions such as correctness, coherence, complexity, and verbosity. Here's a high-level diagram of the pipeline: ![Self-Improving CoT Pipeline](https://i.postimg.cc/DygTcWd6/download.png) --- ## 2. Generation of CoT Data: The Heart of the Pipeline 🤖 Generating CoT data is at the core of the pipeline. Below, we outline the process in detail. ### 2.1 Initial Trace Generation 🐣 The first step in the process is the generation of an initial reasoning trace. The **`reason_agent`** plays a central role here, creating a coherent and logical explanation of how to solve a given problem. The agent breaks down the problem into smaller steps, illustrating the thought process at each stage. We also support the use of non-reasoning LLMs to generate traces through prompt engineering. The generation could also guided by **few-shot examples**, which provide context and help the agent understand the desired reasoning style. Here’s how this is accomplished: - **Input**: The problem statement is provided to the **`reason_agent`**, we can optionally provide the ground truth to guide the reasoning process. - **Output**: The agent generates a sequence of reasoning content. This initial generation serves as a foundational reasoning process that can be directly useful or further refined. ### 2.2 Evaluation of the Initial Trace 📒 Once the reasoning trace is generated, it is evaluated for its quality. This evaluation serves two purposes: - **Detecting weaknesses**: The evaluation identifies areas where the reasoning trace could be further improved. - **Providing feedback**: The evaluation produces feedback that guides the agent in refining the reasoning trace. This feedback can come from either the **`evaluate_agent`** or a **`reward_model`**. #### 2.2.1 Agent-Based Evaluation If an **`evaluate_agent`** is available, it examines the reasoning trace for: 1. **Correctness**: Does the trace logically solve the problem? 2. **Clarity**: Is the reasoning easy to follow and well-structured? 3. **Completeness**: Are all necessary steps included in the reasoning? The feedback from the agent provides insights into areas for improvement, such as unclear reasoning or incorrect answers, offering a more generalized approach compared to rule-based matching. #### 2.2.2 Reward Model Evaluation Alternatively, the pipeline supports using a **reward model** to evaluate the trace. The reward model outputs scores based on predefined dimensions such as correctness, coherence, complexity, and verbosity. --- ### 2.3 Iterative Refinement: The Self-Improving Cycle 🔁 The key to CAMEL's success in CoT generation is its **self-improving loop**. After the initial trace is generated and evaluated, the model refines the trace based on the evaluation feedback. This process is repeated in a loop. #### How does this iterative refinement work? 1. **Feedback Integration**: The feedback from the evaluation phase is used to refine the reasoning. This could involve rewording unclear parts, adding missing steps, or adjusting the logic to make it more correct or complete. 2. **Improvement through Reasoning**: After receiving feedback, the **`reason_agent`** is used again to generate an improved version of the reasoning trace. This trace incorporates the feedback provided, refining the earlier steps and enhancing the overall reasoning. 3. **Re-evaluation**: Once the trace is improved, the new version is evaluated again using the same process (either agent-based evaluation or reward model). This new trace is assessed against the same criteria to ensure the improvements have been made. 4. **Threshold Check**: The iterative process continues until the desired quality thresholds are met or reached the maximum number of iterations. --- ## 3. Pipeline Setup in Code 💻 Below is a truncated version of our pipeline initialization. We encapsulate logic in a class called `SelfImprovingCoTPipeline`: ```python class SelfImprovingCoTPipeline: def __init__( self, reason_agent: ChatAgent, problems: List[Dict], max_iterations: int = 3, score_threshold: Union[float, Dict[str, float]] = 0.7, evaluate_agent: Optional[ChatAgent] = None, reward_model: Optional[BaseRewardModel] = None, output_path: Optional[str] = None, few_shot_examples: Optional[str] = None, batch_size: Optional[int] = None, max_workers: Optional[int] = None, solution_pattern: str = r'\\boxed{(.*?)}', trace_pattern: Optional[str] = None, ): r"""Initialize the STaR pipeline. Args: reason_agent (ChatAgent): The chat agent used for generating and improving reasoning traces. problems (List[Dict]): List of problem dictionaries to process. max_iterations (int, optional): Maximum number of improvement iterations. If set to `0`, the pipeline will generate an initial trace without any improvement iterations. (default: :obj:`3`) score_threshold (Union[float, Dict[str, float]], optional): Quality threshold. Can be either a single float value applied to average score, or a dictionary mapping score dimensions to their thresholds. For example: {"correctness": 0.8, "coherence": 0.7}. If using reward model and threshold for a dimension is not specified, will use the default value 0.7. (default: :obj:`0.7`) evaluate_agent (Optional[ChatAgent]): The chat agent used for evaluating reasoning traces. (default: :obj:`None`) reward_model (BaseRewardModel, optional): Model used to evaluate reasoning traces. If `None`, uses Agent self-evaluation. (default: :obj:`None`) output_path (str, optional): Output path for saving traces. If `None`, results will only be returned without saving to file. (default: :obj:`None`) few_shot_examples (str, optional): Examples to use for few-shot generation. (default: :obj:`None`) batch_size (int, optional): Batch size for parallel processing. (default: :obj:`None`) max_workers (int, optional): Maximum number of worker threads. (default: :obj:`None`) solution_pattern (str, optional): Regular expression pattern with one capture group to extract answers from solution text. (default: :obj:`r'\\boxed{(.*?)}'`) trace_pattern (str, optional): Regular expression pattern with one capture group to extract answers from trace text. If `None`, uses the same pattern as solution_pattern. (default: :obj:`None`) """ ... ``` **Example usage:** ```python from camel.agents import ChatAgent from camel.datagen import SelfImprovingCoTPipeline # Initialize agents reason_agent = ChatAgent( """Answer my question and give your final answer within \\boxed{}.""" ) evaluate_agent = ChatAgent( "You are a highly critical teacher who evaluates the student's answers " "with a meticulous and demanding approach." ) # Prepare your problems problems = [ {"problem": "Your problem text here"}, # Add more problems... ] # Create and run the pipeline pipeline = SelfImprovingCoTPipeline( reason_agent=reason_agent, evaluate_agent=evaluate_agent, problems=problems, max_iterations=3, output_path="star_output.json" ) results = pipeline.generate() ``` --- ## 4. Batch Processing & API Request Handling 📦 ### 4.1 The Need for Batch Processing ⏰ Early on, we tried generating CoT reasoning for each problem one by one. This approach quickly revealed two major issues: 1. **Time consumption**: Sequential processing doesn't scale to large problem sets. 2. **API request bottlenecks**: Slowdowns or occasional disconnections occurred when handling numerous calls. Hence, we introduced a parallel **`BatchProcessor`** to: - Split the tasks into manageable batches. - Dynamically adjust batch size (`batch_size`) based on the success/failure rates and system resource usage (CPU/memory). - Retry on transient errors or API timeouts to maintain a stable flow. Below shows how we batch-process multiple problems: ```python async def _batch_process_problems( self, problems: List[Dict], rationalization: bool ) -> List[ProblemResult]: results = [] total_problems = len(problems) processed = 0 while processed < total_problems: batch_size = self.batch_processor.batch_size batch = problems[processed : processed + batch_size] batch_start_time = time.time() with ThreadPoolExecutor(max_workers=self.batch_processor.max_workers) as executor: futures = [ executor.submit( self.process_problem, problem=problem, rationalization=rationalization, ) for problem in batch ] ... processed += len(batch) ... # Log progress & performance ``` ### 4.2 Handling API Instability 🚨 Even with batching, API requests for LLMs can fail due to network fluctuations or remote server instability. We implemented a `retry_on_error` decorator: ```python def retry_on_error( max_retries: int = 3, initial_delay: float = 1.0 ) -> Callable: def decorator(func: Callable) -> Callable: @functools.wraps(func) def wrapper(*args, **kwargs): delay = initial_delay for attempt in range(max_retries + 1): try: return func(*args, **kwargs) except Exception as e: if attempt == max_retries: raise time.sleep(delay) delay *= 2 raise return wrapper return decorator ``` Whenever we invoke LLM calls for generation, evaluation, or improvement, these decorated methods gracefully handle transient errors by retrying with exponential backoff (doubling the wait time after each failed attempt). --- ## 5. Model Switching & Dynamic File Writing 📝 ### 5.1 Flexible Model Scheduling 🕒 In CAMEL's CoT pipeline, adding models to the `ChatAgent` is useful for handling errors and ensuring smooth operation. This setup allows the system to switch between models as needed, maintaining reasoning continuity. To add models to a `ChatAgent`, you can create instances of models and include them in the agent's model list: ```python model1 = ModelFactory.create( model_platform=ModelPlatformType.DEEPSEEK, model_type="deepseek-reasoner", ... ) model2 = ModelFactory.create( model_platform=ModelPlatformType.TOGETHER, model_type="deepseek-reasoner", ... ) agent = ChatAgent( system_message, model=[model1, model2] ) ``` By incorporating multiple models, CAMEL can effectively manage model availability and ensure robust error handling. ### 5.2 Real-Time JSON Updates 🔄 As soon as a problem’s results are ready, we lock the file (`output_path`) and update it in-place—rather than saving everything at the very end. This ensures data integrity if the process is interrupted partway through. ```python def safe_write_json(self, file_path, data): temp_path = file_path + ".tmp" with open(temp_path, "w") as f: json.dump(data, f, indent=2) os.replace(temp_path, file_path) ``` This two-step write (to a `.tmp` file then replace) prevents partial writes from corrupting the output file. --- ## 6. CAMEL’s Next Steps in CoT Data Generation 🚀 1. **Real-Time Monitoring Dashboard**: Visualize throughput, error rates, running cost, data quality, etc. for smooth operational oversight. 2. **Performance Enhancements**: Further improve performance and add more error handling to make the system more robust. 3. **Cutting-Edge Research Solutions**: Integrate more cutting-edge research solutions for synthetic data generation. 4. **Rejection Sampling**: Integrate rejection sampling method to the SelfImprovingCoT pipeline. --- ## Conclusion 📚 CAMEL’s self-improving pipeline exemplifies a comprehensive approach to Chain-of-Thought data generation: - **Flexible Evaluation**: Utilizing agent-based or reward-model-based evaluation provides adaptable scoring and feedback loops. - **Continuous Improvement**: Iterative refinement ensures each reasoning trace is enhanced until it meets the desired quality. - **Efficient Processing**: Batched concurrency increases throughput while maintaining system balance. - **Robust Stability**: Error-tolerant mechanisms with retries enhance system reliability. - **Consistent Output**: Dynamic file writing ensures partial results are consistently preserved and valid. Looking ahead, CAMEL’s roadmap is dedicated to pioneering advanced synthetic data generation methods, integrating cutting-edge research and technology. _Stay tuned for more updates on CAMEL's journey in advancing agentic synthetic data generation!_ --- **Further Reading & Resources** - **CAMEL GitHub**: Explore our open-source projects on [GitHub](https://github.com/camel-ai/camel) and give us a 🌟star. **Data Generation Cookbooks** - [Self-Improving Math Reasoning Data Distillation](https://docs.camel-ai.org/cookbooks/data_generation/self_improving_math_reasoning_data_distillation_from_deepSeek_r1.html) - [Generating High-Quality SFT Data with CAMEL](https://docs.camel-ai.org/cookbooks/data_generation/sft_data_generation_and_unsloth_finetuning_Qwen2_5_7B.html) - [Function Call Data Generation and Evaluation](https://docs.camel-ai.org/cookbooks/data_generation/data_gen_with_real_function_calls_and_hermes_format.html) - [Agentic Data Generation, Evaluation & Filtering with Reward Models](https://docs.camel-ai.org/cookbooks/data_generation/synthetic_dataevaluation%26filter_with_reward_model.html) --- Data Processing and Analysis =========================== ```{=html}
← Advanced Features Multi-agent Society →
``` ::: {.toctree maxdepth="1"} video_analysis agent_with_chunkr_for_pdf_parsing summarisation_agent_with_mistral_ocr ingest_data_from_websites_with_Firecrawl ::: --- --- title: "Create Document Summarization Agents with Mistral OCR & CAMEL-AI 🐫" --- You can also check this cookbook in Colab [here](https://colab.research.google.com/drive/1ZwVmqa5vjpZ0C3H7k1XIseFfbCR4mq17?usp=sharing) In this cookbook, we’ll explore [**Mistral OCR**](https://mistral.ai/news/mistral-ocr)—a state-of-the-art Optical Character Recognition API that understands complex document layouts and extracts text, tables, images, and equations with unprecedented accuracy. We’ll show you how to: - Use the Mistral OCR API to convert scanned or image-based PDFs into structured Markdown - Leverage a Mistral LLM agent within CAMEL to summarize and analyze the extracted content - Build a seamless, end-to-end pipeline for retrieval-augmented generation (RAG), research, or business automation ## Table of Contents 1. 🧑🏻‍💻 Introduction 2. ⚡️ Step-by-step Guide: Mistral OCR Extraction 3. 💫 Quick Demo with Mistral Agent 4. 🧑🏻‍💻 Conclusion
CAMEL Homepage Join Discord
⭐ *Star us on [GitHub](https://github.com/camel-ai/camel), join our [Discord](https://discord.camel-ai.org), or follow us on [X](https://x.com/camelaiorg)* --- ![Slide 16_9 - 33.png](./images/summarisation_agent_with_mistral_ocr_1.png) ## **Introduction to Mistral OCR** Throughout history, advancements in information abstraction and retrieval have driven human progress—from hieroglyphs to digitization. Today, over 90% of organizational data lives in documents, often locked in complex layouts and multiple languages. **Mistral OCR** ushers in the next leap in document understanding: a multimodal API that comprehends every element—text, images, tables, equations—and outputs ordered, structured Markdown with embedded media references. #### **Key Features of Mistral OCR:** 1. **State-of-the-art complex document understanding** - Extracts interleaved text, figures, tables, and mathematical expressions with high fidelity. 2. **Natively multilingual & multimodal** - Parses scripts and fonts from across the globe, handling right-to-left layouts and non-Latin characters seamlessly. 3. **Doc-as-prompt, structured output** - Returns ordered Markdown, embedding images and bounding-box metadata ready for RAG and downstream AI workflows. 4. **Top-tier benchmarks & speed** - Outperforms leading OCR systems in accuracy—especially in math, tables, and multilingual tests—while delivering fast batch inference (∼2000 pages/min). 5. **Scalable & flexible deployment** - Available via `mistral-ocr-latest` on Mistral’s developer suite, cloud partners, and on-premises self-hosting for sensitive data. Ready to unlock your documents? Let’s dive into the extraction guide. First, install the CAMEL package with all its dependencies. ```python !pip install "camel-ai[all]==0.2.61" ``` ## ⚡️ Step-by-step Guide: Mistral OCR Loader **Step 1: Set up your Mistral API key** If you don’t have a Mistral API key, you can obtain one by following these steps: 1. **Create an account:** Go to [Mistral Console](https://console.mistral.ai/home) and sign up for an organization account. 2. **Get your API key:** Once logged in, navigate to **Organization** → **API Keys**, generate a new key, copy it, and store it securely. ```python import os from getpass import getpass mistral_api_key = getpass('Enter your Mistral API key: ') os.environ['MISTRAL_API_KEY'] = mistral_api_key ``` **Step 2: Upload your PDF or image file for OCR** In a Colab or Jupyter environment, you can upload any PDF file directly: ```python # Colab file upload from google.colab import files uploaded = files.upload() # Grab the first uploaded filename file_path = next(iter(uploaded)) ``` **Step 3: Import and initialize the Mistral OCR loader** ```python # Importing the MistralReader class from the camel.loaders module # This class handles document processing using Mistral OCR capabilities from camel.loaders import MistralReader # Initializing an instance of MistralReader # This object will be used to submit tasks and manage OCR processing mistral_reader = MistralReader() ``` ## Step 4: Obtain OCR output from Mistral Once the task completes, retrieve its output using the returned `task.id`. The output of **Mistral OCR** is a structured object: ```python # Retrieve the OCR output # CORRECT: Just use extract_text for local files or URLs ocr_response = mistral_reader.extract_text(file_path) print(ocr_response) ``` ## 💫 Quick Demo with CAMEL Agent Here we choose Mistral model for our demo. If you'd like to explore different models or tools to suit your needs, feel free to visit the [CAMEL documentation page](https://docs.camel-ai.org/), where you'll find guides and tutorials. If you don't have a Mistral API key, you can obtain one by following these steps: 1. Visit the Mistral Console (https://console.mistral.ai/) 2. In the left panel, click on API keys under API section 3. Choose your plan For more details, you can also check the Mistral documentation: https://docs.mistral.ai/getting-started/quickstart/ ```python from camel.configs import MistralConfig from camel.models import ModelFactory from camel.types import ModelPlatformType, ModelType mistral_model = ModelFactory.create( model_platform=ModelPlatformType.MISTRAL, model_type=ModelType.MISTRAL_LARGE, model_config_dict=MistralConfig(temperature=0.0).as_dict(), ) # Use Mistral model model = mistral_model ``` ```python from camel.agents import ChatAgent # Initialize a ChatAgent agent = ChatAgent( system_message="You are a helpful document assistant.", # Define the agent's role model=mistral_model ) # Use the ChatAgent to generate insights based on the OCR output response = agent.step( f"Based on the following OCR-extracted content, give me a concise conclusion of the document:\n{ocr_response}" ) print(response.msgs[0].content) ``` **For advanced usage of RAG capabilities with large files, please refer to our [RAG cookbook](https://docs.camel-ai.org/cookbooks/advanced_features/agents_with_rag#rag-cookbook).** ## 🧑🏻‍💻 Conclusion In conclusion, integrating **Mistral OCR** within CAMEL-AI revolutionizes the process of document data extraction and preparation, enhancing your capabilities for AI-driven applications. With Mistral OCR’s robust features—state-of-the-art complex document understanding, natively multilingual & multimodal parsing, and doc-as-prompt structured Markdown output—you can seamlessly process complex PDFs and images into machine-readable formats optimized for LLMs, directly feeding into CAMEL-AI’s multi-agent workflows. This integration not only simplifies data preparation but also empowers intelligent and accurate analytics at scale. With these tools at your disposal, you’re equipped to transform raw document data into actionable insights, unlocking new possibilities in automation and AI-powered decision-making. That's everything: Got questions about 🐫 CAMEL-AI? Join us on [Discord](https://discord.camel-ai.org)! Whether you want to share feedback, explore the latest in multi-agent systems, get support, or connect with others on exciting projects, we’d love to have you in the community! 🤝 Check out some of our other work: 1. 🐫 Creating Your First CAMEL Agent [free Colab](https://colab.research.google.com/drive/1cmWPxXEsyMbmjPhD2bWfHuhd_Uz6FaJQ?usp=sharing) 2. Graph RAG Cookbook [free Colab](https://colab.research.google.com/drive/1uZKQSuu0qW6ukkuSv9TukLB9bVaS1H0U?usp=sharing) 3. 🧑‍⚖️ Create A Hackathon Judge Committee with Workforce [free Colab](https://colab.research.google.com/drive/18ajYUMfwDx3WyrjHow3EvUMpKQDcrLtr?usp=sharing) 4. 🔥 3 ways to ingest data from websites with Firecrawl & CAMEL [free Colab](https://colab.research.google.com/drive/1lOmM3VmgR1hLwDKdeLGFve_75RFW0R9I?usp=sharing) 5. 🦥 Agentic SFT Data Generation with CAMEL and Mistral Models, Fine-Tuned with Unsloth [free Colab](https://colab.research.google.com/drive/1lYgArBw7ARVPSpdwgKLYnp_NEXiNDOd-?usp=sharingg) Thanks from everyone at 🐫 CAMEL-AI
CAMEL Homepage Join Discord
⭐ *Star us on [GitHub](https://github.com/camel-ai/camel), join our [Discord](https://discord.camel-ai.org), or follow us on [X](https://x.com/camelaiorg)* --- # Loong Cookbooks {#cookbooks_loong} ::: {.toctree maxdepth="1" caption="Loong Cookbooks"} batched_single_step_env.ipynb multi_step_rl.ipynb single_step_env.ipynb ::: --- # MCP Cookbooks {#cookbooks_mcp} ::: {.toctree maxdepth="1" caption="MCP Cookbooks"} agents_with_sql_mcp.ipynb camel_aci_mcp_cookbook.ipynb agent_to_mcp_with_faiss.ipynb ::: --- --- title: "🍳 CAMEL Cookbook: Building a Collaborative AI Research Society" --- ## Claude 4 + Azure OpenAI Collaboration for ARENA AI Alignment Research
CAMEL Homepage Join Discord
⭐ *Star us on [GitHub](https://github.com/camel-ai/camel), join our [Discord](https://discord.camel-ai.org), or follow us on [X](https://x.com/camelaiorg)* --- ## 📋 Overview This cookbook demonstrates how to create a collaborative multi-agent society using CAMEL-AI, bringing together Claude 4 and Azure OpenAI models to research AI alignment topics from the ARENA curriculum. Our society consists of 4 specialized AI researchers with distinct personas and expertise areas. ## So, Let's catapault our way right in 🧚 ## 🛠️ Dependencies and Setup First, let's install the required dependencies and handle the notebook environment: ```python !pip install camel-ai['0.2.64'] anthropic ``` ```python import textwrap import os from getpass import getpass from typing import Dict, Any from camel.agents import ChatAgent from camel.messages import BaseMessage from camel.models import ModelFactory from camel.models.azure_openai_model import AzureOpenAIModel from camel.tasks import Task from camel.toolkits import FunctionTool, SearchToolkit from camel.types import ModelPlatformType, ModelType from camel.societies.workforce import Workforce ``` Prepare API keys: Azure OpenAI, Claude (Anthropic), and optionally Google Search ```python # Ensuring API Keys are set if not os.getenv("AZURE_OPENAI_API_KEY"): print("AZURE OPENAI API KEY is required to proceed.") azure_openai_api_key = getpass("Enter your Azure OpenAI API Key: ") os.environ["AZURE_OPENAI_API_KEY"] = azure_openai_api_key if not os.getenv("AZURE_OPENAI_ENDPOINT"): print("Azure OpenAI Endpoint is required to proceed.") azure_openai_endpoint = input("Enter your Azure OpenAI Endpoint: ") os.environ["AZURE_OPENAI_ENDPOINT"] = azure_openai_endpoint if not os.getenv("ANTHROPIC_API_KEY"): print("ANTHROPIC API KEY is required to proceed.") anthropic_api_key = getpass("Enter your Anthropic API Key: ") os.environ["ANTHROPIC_API_KEY"] = anthropic_api_key optional_keys_setup = input("Setup optional API Keys for Google search functionality?(y/n): ").lower() if "y" in optional_keys_setup: if not os.getenv("GOOGLE_API_KEY"): print("[OPTIONAL] Provide a GOOGLE CLOUD API KEY for google search.") google_api_key = getpass("Enter your Google API KEY: ") os.environ["GOOGLE_API_KEY"] = google_api_key if not os.getenv("SEARCH_ENGINE_ID"): print("[OPTIONAL] Provide a search engine ID for google search.") search_engine_id = getpass("Enter your Search Engine ID: ") os.environ["SEARCH_ENGINE_ID"] = search_engine_id ``` ### What this does: - Imports all necessary CAMEL-AI components - Handles async operations for notebook environments - Sets up typing hints for better code clarity ## 🏗️ Core Society Class Structure Let's define our main research society class: ```python class ARENAResearchSociety: """ A collaborative CAMEL society between Claude 4 and Azure OpenAI for researching the ARENA AI alignment curriculum. """ def __init__(self): self.workforce = None self.setup_api_keys() ``` ### What this does: - Creates the main class that will orchestrate our AI research society - Initializes with API key setup to ensure proper authentication - Prepares the workforce variable for later agent assignment ## 🔑 API Configuration Management Configure all necessary API keys and endpoints: ```python def setup_api_keys(self): """Setup API keys for Azure OpenAI and Claude""" print("🔧 Setting up API keys...") # Azure OpenAI configuration if not os.getenv("AZURE_OPENAI_API_KEY"): azure_api_key = getpass("Please input your Azure OpenAI API key: ") os.environ["AZURE_OPENAI_API_KEY"] = azure_api_key if not os.getenv("AZURE_OPENAI_ENDPOINT"): azure_endpoint = getpass("Please input your Azure OpenAI endpoint: ") os.environ["AZURE_OPENAI_ENDPOINT"] = azure_endpoint if not os.getenv("AZURE_DEPLOYMENT_NAME"): deployment_name = getpass("Please input your Azure deployment name (e.g., div-o4-mini): ") os.environ["AZURE_DEPLOYMENT_NAME"] = deployment_name # Set OPENAI_API_KEY for compatibility (use Azure key) os.environ["OPENAI_API_KEY"] = os.getenv("AZURE_OPENAI_API_KEY") # Claude API configuration if not os.getenv("ANTHROPIC_API_KEY"): claude_api_key = getpass("Please input your Claude API key: ") os.environ["ANTHROPIC_API_KEY"] = claude_api_key # Optional: Google Search for research capabilities if not os.getenv("GOOGLE_API_KEY"): try: google_api_key = getpass("Please input your Google API key (optional, press Enter to skip): ") if google_api_key: os.environ["GOOGLE_API_KEY"] = google_api_key search_engine_id = getpass("Please input your Search Engine ID: ") if search_engine_id: # Only set if provided os.environ["SEARCH_ENGINE_ID"] = search_engine_id else: print("⚠️ Search Engine ID not provided. Search functionality will be disabled.") except KeyboardInterrupt: print("Skipping Google Search setup...") print("✅ API keys configured!") ARENAResearchSociety.setup_api_keys = setup_api_keys ``` ### What this does: - Securely collects API credentials using getpass (hidden input) - Supports Azure OpenAI, Claude (Anthropic), and optional Google Search - Sets environment variables for seamless integration - Provides graceful fallbacks for optional components ## 🤖 Azure OpenAI Agent Creation Create specialized Azure OpenAI agents with custom personas: ```python def create_azure_agent(self, role_name: str, persona: str, specialization: str) -> ChatAgent: """Create an Azure OpenAI agent with specific role and persona""" msg_content = textwrap.dedent(f""" You are {role_name}, a researcher specializing in AI alignment and safety. Your persona: {persona} Your specialization: {specialization} You are part of a collaborative research team studying the ARENA AI alignment curriculum. ARENA focuses on practical AI safety skills including: - Mechanistic interpretability - Reinforcement learning from human feedback (RLHF) - AI governance and policy - Robustness and adversarial examples When collaborating: 1. Provide detailed, technical analysis 2. Reference specific ARENA modules when relevant 3. Build upon other agents' findings 4. Maintain academic rigor while being accessible 5. Always cite sources and provide evidence for claims """).strip() sys_msg = BaseMessage.make_assistant_message( role_name=role_name, content=msg_content, ) # Configure Azure OpenAI model with correct API version for o4-mini model = AzureOpenAIModel( model_type=ModelType.GPT_4O_MINI, api_key=os.getenv("AZURE_OPENAI_API_KEY"), url=os.getenv("AZURE_OPENAI_ENDPOINT"), api_version="2025-01-01-preview", # Updated to support o4-mini azure_deployment_name=os.getenv("AZURE_DEPLOYMENT_NAME") or "div-o4-mini" ) return ChatAgent( system_message=sys_msg, model=model, ) ARENAResearchSociety.create_azure_agent = create_azure_agent ``` ### What this does: - Creates customizable Azure OpenAI agents with specific roles and expertise - Embeds ARENA curriculum knowledge into each agent's system prompt - Uses the latest API version compatible with o4-mini model - Returns a fully configured ChatAgent ready for collaboration ## 🧠 Claude Agent Creation Create Claude agents with complementary capabilities: ```python def create_claude_agent(self, role_name: str, persona: str, specialization: str, tools=None) -> ChatAgent: """Create a Claude agent with specific role and persona""" msg_content = textwrap.dedent(f""" You are {role_name}, a researcher specializing in AI alignment and safety. Your persona: {persona} Your specialization: {specialization} You are part of a collaborative research team studying the ARENA AI alignment curriculum. ARENA focuses on practical AI safety skills including: - Mechanistic interpretability - Reinforcement learning from human feedback (RLHF) - AI governance and policy - Robustness and adversarial examples When collaborating: 1. Provide thorough, nuanced analysis 2. Consider ethical implications and long-term consequences 3. Synthesize information from multiple perspectives 4. Ask probing questions to deepen understanding 5. Connect concepts across different AI safety domains """).strip() # Remove trailing whitespace sys_msg = BaseMessage.make_assistant_message( role_name=role_name, content=msg_content, ) # Configure Claude model model = ModelFactory.create( model_platform=ModelPlatformType.ANTHROPIC, model_type=ModelType.CLAUDE_3_5_SONNET, ) agent = ChatAgent( system_message=sys_msg, model=model, tools=tools or [], ) return agent ARENAResearchSociety.create_claude_agent = create_claude_agent ``` ### What this does: - Creates Claude agents with nuanced, philosophical thinking capabilities - Emphasizes ethical considerations and long-term thinking - Supports optional tool integration (like search capabilities) - Uses Claude 3.5 Sonnet for advanced reasoning ## 👥 Workforce Assembly Bring together all agents into a collaborative workforce: ```python def create_research_workforce(self): """Create the collaborative research workforce""" print("🏗️ Creating ARENA Research Society...") # Setup search tools for the lead researcher (only if properly configured) search_tools = [] if os.getenv("GOOGLE_API_KEY") and os.getenv("SEARCH_ENGINE_ID"): try: search_toolkit = SearchToolkit() search_tools = [ FunctionTool(search_toolkit.search_google), ] print("🔍 Search tools enabled for lead researcher") except Exception as e: print(f"⚠️ Search tools disabled due to configuration issue: {e}") search_tools = [] else: print("🔍 Search tools disabled - missing API keys") # Create Claude agents claude_lead = self.create_claude_agent( role_name="Dr. Claude Alignment", persona="A thoughtful, methodical researcher who excels at synthesizing complex information and identifying key insights. Known for asking the right questions and seeing the bigger picture. Works with existing knowledge when search tools are unavailable.", specialization="AI safety frameworks, mechanistic interpretability, and curriculum analysis", tools=search_tools ) claude_ethicist = self.create_claude_agent( role_name="Prof. Claude Ethics", persona="A philosophical thinker who deeply considers the ethical implications and long-term consequences of AI development. Bridges technical concepts with societal impact.", specialization="AI governance, policy implications, and ethical frameworks in AI alignment" ) # Create Azure OpenAI agents azure_technical = self.create_azure_agent( role_name="Dr. Azure Technical", persona="A detail-oriented technical expert who dives deep into implementation specifics and mathematical foundations. Excellent at breaking down complex algorithms.", specialization="RLHF implementation, robustness techniques, and technical deep-dives" ) azure_practical = self.create_azure_agent( role_name="Dr. Azure Practical", persona="A pragmatic researcher focused on real-world applications and practical implementation. Bridges theory with practice.", specialization="Practical AI safety applications, training methodologies, and hands-on exercises" ) # Configure coordinator and task agents to use Azure OpenAI with correct API version coordinator_agent_kwargs = { 'model': AzureOpenAIModel( model_type=ModelType.GPT_4O_MINI, api_key=os.getenv("AZURE_OPENAI_API_KEY"), url=os.getenv("AZURE_OPENAI_ENDPOINT"), api_version="2025-01-01-preview", azure_deployment_name=os.getenv("AZURE_DEPLOYMENT_NAME") or "div-o4-mini" ), 'token_limit': 8000 } task_agent_kwargs = { 'model': AzureOpenAIModel( model_type=ModelType.GPT_4O_MINI, api_key=os.getenv("AZURE_OPENAI_API_KEY"), url=os.getenv("AZURE_OPENAI_ENDPOINT"), api_version="2025-01-01-preview", azure_deployment_name=os.getenv("AZURE_DEPLOYMENT_NAME") or "div-o4-mini" ), 'token_limit': 16000 } # Create the workforce with proper configuration self.workforce = Workforce( 'ARENA AI Alignment Research Society', coordinator_agent_kwargs=coordinator_agent_kwargs, task_agent_kwargs=task_agent_kwargs ) # Add agents with descriptive roles self.workforce.add_single_agent_worker( 'Dr. Claude Alignment (Lead Researcher) - Synthesizes information, leads research direction, and provides comprehensive analysis based on existing knowledge', worker=claude_lead, ).add_single_agent_worker( 'Prof. Claude Ethics (Ethics & Policy Specialist) - Analyzes ethical implications, policy considerations, and societal impact of AI alignment research', worker=claude_ethicist, ).add_single_agent_worker( 'Dr. Azure Technical (Technical Deep-Dive Specialist) - Provides detailed technical analysis, mathematical foundations, and implementation specifics', worker=azure_technical, ).add_single_agent_worker( 'Dr. Azure Practical (Applied Research Specialist) - Focuses on practical applications, training methodologies, and hands-on implementation guidance', worker=azure_practical, ) print("✅ ARENA Research Society created with 4 specialized agents!") return self.workforce ARENAResearchSociety.create_research_workforce = create_research_workforce ``` ### What this does: - Creates 4 specialized researchers: 2 Claude agents + 2 Azure OpenAI agents - Each agent has distinct personalities and expertise areas - Configures search tools for the lead researcher (when available) - Sets up proper workforce coordination using Azure OpenAI models - Creates a balanced team covering technical, practical, and ethical perspectives ## 📋 Research Task Creation Define structured research tasks for the collaborative team: ```python def create_research_task(self, research_topic: str, specific_questions: str = None) -> Task: """Create a research task for the ARENA curriculum""" arena_context = { "curriculum_info": "ARENA (AI Research and Education Nexus for Alignment) is a comprehensive AI safety curriculum", "focus_areas": [ "Mechanistic Interpretability - Understanding how neural networks work internally", "Reinforcement Learning from Human Feedback (RLHF) - Training AI systems to be helpful and harmless", "AI Governance - Policy, regulation, and coordination for AI safety", "Robustness & Adversarial Examples - Making AI systems robust to attacks and edge cases" ], "emphasis": "practical skills, hands-on exercises, and real-world applications", "website": "https://www.arena.education/curriculum" } # Check if search tools are available has_search = bool(os.getenv("GOOGLE_API_KEY") and os.getenv("SEARCH_ENGINE_ID")) base_content = f""" Research Topic: {research_topic} Please conduct a comprehensive collaborative research analysis on this topic in relation to the ARENA AI alignment curriculum. {'Note: Search tools are available for gathering latest information.' if has_search else 'Note: Analysis will be based on existing knowledge as search tools are not available.'} Research Process: 1. **Information Gathering** - {'Collect relevant information about the topic, including latest developments' if has_search else 'Analyze the topic based on existing knowledge and understanding'} 2. **Technical Analysis** - Provide detailed technical breakdown and mathematical foundations 3. **Practical Applications** - Explore how this relates to hands-on ARENA exercises and real-world implementation 4. **Ethical Considerations** - Analyze policy implications and ethical frameworks 5. **Synthesis** - Combine all perspectives into actionable insights and recommendations Expected Deliverables: - Comprehensive analysis from each specialist perspective - Identification of key concepts and their relationships - Practical implementation guidance - Policy and ethical considerations - Recommendations for further research or curriculum development """ if specific_questions: base_content += f"\n\nSpecific Research Questions:\n{specific_questions}" return Task( content=base_content.strip(), additional_info=arena_context, id="arena_research_001", ) ARENAResearchSociety.create_research_task = create_research_task ``` ### What this does: - Creates structured research tasks with clear objectives and deliverables - Adapts task content based on available tools (search vs. knowledge-based) - Includes ARENA curriculum context for focused analysis - Supports custom research questions for specialized investigations ## 🔬 Research Execution Execute collaborative research sessions: ```python def run_research(self, research_topic: str, specific_questions: str = None): """Run a collaborative research session""" if not self.workforce: self.create_research_workforce() print(f"🔬 Starting collaborative research on: {research_topic}") print("=" * 60) task = self.create_research_task(research_topic, specific_questions) processed_task = self.workforce.process_task(task) print("\n" + "=" * 60) print("📊 RESEARCH RESULTS") print("=" * 60) print(processed_task.result) return processed_task.result ARENAResearchSociety.run_research = run_research ``` ## What this does: - Orchestrates the entire research process - Creates the workforce if not already initialized - Processes tasks through the collaborative agent network - Returns formatted research results ## 🎯 Interactive Demo Interface Create an interactive interface for easy topic selection: ```python """Demonstrating the ARENA Research Society""" society = ARENAResearchSociety() # Example research topics related to ARENA curriculum sample_topics = { 1: { "topic": "Mechanistic Interpretability in Large Language Models", "questions": """ - How do the latest mechanistic interpretability techniques apply to understanding LLM behavior? - What are the most effective methods for interpreting attention patterns and residual streams? - How can mechanistic interpretability inform AI alignment strategies? - What are the current limitations and future directions in this field? """ }, 2: { "topic": "RLHF Implementation Challenges and Best Practices", "questions": """ - What are the main technical challenges in implementing RLHF at scale? - How do different reward modeling approaches compare in effectiveness? - What are the alignment implications of various RLHF techniques? - How can we address issues like reward hacking and distributional shift? """ }, 3: { "topic": "AI Governance Frameworks for Emerging Technologies", "questions": """ - What governance frameworks are most suitable for rapidly advancing AI capabilities? - How can policy makers balance innovation with safety considerations? - What role should technical AI safety research play in policy development? - How can international coordination on AI governance be improved? """ } } print("🎯 ARENA AI Alignment Research Society") print("Choose a research topic or provide your own:") print() for num, info in sample_topics.items(): print(f"{num}. {info['topic']}") print("4. Custom research topic") print() try: choice = input("Enter your choice (1-4): ").strip() if choice in ['1', '2', '3']: topic_info = sample_topics[int(choice)] result = society.run_research( topic_info["topic"], topic_info["questions"] ) elif choice == '4': custom_topic = input("Enter your research topic: ").strip() custom_questions = input("Enter specific questions (optional): ").strip() result = society.run_research( custom_topic, custom_questions if custom_questions else None ) else: print("Invalid choice. Running default research...") result = society.run_research(sample_topics[1]["topic"], sample_topics[1]["questions"]) except KeyboardInterrupt: print("\n👋 Research session interrupted.") except Exception as e: print(f"❌ Error during research: {e}") ``` ## What this does: - Provides pre-defined research topics relevant to ARENA curriculum - Offers custom topic input for flexible research - Handles user interaction gracefully with error handling - Demonstrates the full capabilities of the collaborative AI society ## 🚀 Running the Cookbook To run this collaborative AI research society: Execute Individual cells. Follow prompts: Enter your API credentials and select research topics The system will create a collaborative research environment where Claude and Azure OpenAI agents work together to produce comprehensive analysis on AI alignment topics! ## 🎯 Conclusion The future of AI collaboration is here, and this CAMEL-powered society demonstrates the incredible potential of multi-agent systems working across different AI platforms. In this cookbook, you've learned how to: - Build cross-platform AI collaboration between Claude 4 and Azure OpenAI models - Create specialized AI researchers with distinct personas and expertise areas - Implement robust workforce management using CAMEL's advanced orchestration - Handle complex API configurations for multiple AI providers seamlessly - Design structured research workflows for AI alignment and safety topics - Create scalable agent societies that can tackle complex, multi-faceted problems This collaborative approach showcases how different AI models can complement each other - Claude's nuanced reasoning and ethical considerations paired with Azure OpenAI's technical precision creates a powerful research dynamic. The ARENA AI alignment focus demonstrates how these societies can be specialized for cutting-edge domains like mechanistic interpretability, RLHF, and AI governance. As the field of multi-agent AI systems continues to evolve, frameworks like CAMEL are paving the way for increasingly sophisticated collaborations. Whether you're researching AI safety, exploring complex technical topics, or building specialized knowledge teams, the patterns and techniques in this cookbook provide a solid foundation for the next generation of AI-powered research. The possibilities are endless when AI agents work together. Keep experimenting, keep collaborating, and keep pushing the boundaries of what's possible. Happy researching! 🔬✨ That's everything: Got questions about 🐫 CAMEL-AI? Join us on [Discord](https://discord.camel-ai.org)! Whether you want to share feedback, explore the latest in multi-agent systems, get support, or connect with others on exciting projects, we’d love to have you in the community! 🤝 Check out some of our other work: 1. 🐫 Creating Your First CAMEL Agent [free Colab](https://docs.camel-ai.org/cookbooks/create_your_first_agent.html) 2. Graph RAG Cookbook [free Colab](https://colab.research.google.com/drive/1uZKQSuu0qW6ukkuSv9TukLB9bVaS1H0U?usp=sharing) 3. 🧑‍⚖️ Create A Hackathon Judge Committee with Workforce [free Colab](https://colab.research.google.com/drive/18ajYUMfwDx3WyrjHow3EvUMpKQDcrLtr?usp=sharing) 4. 🔥 3 ways to ingest data from websites with Firecrawl & CAMEL [free Colab](https://colab.research.google.com/drive/1lOmM3VmgR1hLwDKdeLGFve_75RFW0R9I?usp=sharing) 5. 🦥 Agentic SFT Data Generation with CAMEL and Mistral Models, Fine-Tuned with Unsloth [free Colab](https://colab.research.google.com/drive/1lYgArBw7ARVPSpdwgKLYnp_NEXiNDOd-?usp=sharingg) Thanks from everyone at 🐫 CAMEL-AI
CAMEL Homepage Join Discord
⭐ *Star us on [GitHub](https://github.com/camel-ai/camel), join our [Discord](https://discord.camel-ai.org), or follow us on [X](https://x.com/camelaiorg)* --- --- # Multi-agent Society ```{=html}
← Data Processing Advanced Features →
``` ::: {.toctree maxdepth="1"} agents_society workforce_judge_committee task_generation azure_openai_claude_society ::: --- --- title: Installation description: Get started with CAMEL-AI - Install, configure, and build your first multi-agent system icon: wrench --- ## Tutorial **Python Version Requirements** CAMEL-AI requires `Python >=3.10 and <=3.14`. Here's how to check your version: ```bash python3 --version ``` If you need to update Python, visit [python.org/downloads](https://python.org/downloads) CAMEL-AI supports multiple installation methods to suit different development workflows. Choose the method that best fits your needs. - **Basic Installation:** Install the core CAMEL library: ```shell pip install camel-ai ``` - **Full Installation (Recommended):** Install CAMEL with all features and dependencies: ```shell pip install 'camel-ai[all]' ``` Some features may not work without their required dependencies. Install `camel-ai[all]` to ensure all dependencies are available, or install specific extras based on the features you need. - **Custom Installation:** Available extras for specific use cases: - `all`: Includes all features below - `model_platforms`: OpenAI, Google, Mistral, Anthropic Claude, Cohere etc. - `huggingface`: Transformers, Diffusers, Accelerate, Datasets, PyTorch etc. - `rag`: Sentence Transformers, Qdrant, Milvus, TiDB, BM25, OceanBase, Weaviate, chroma etc. - `storage`: Neo4j, Redis, Azure Blob, Google Cloud Storage, AWS S3 etc, Pgvector. - `web_tools`: DuckDuckGo, Wikipedia, WolframAlpha, Google Maps, Weather API etc. - `document_tools`: PDF, Word, OpenAPI, BeautifulSoup, Unstructured etc. - `media_tools`: Image Processing, Audio Processing, YouTube Download, FFmpeg etc. - `communication_tools`: Slack, Discord, Telegram, GitHub, Reddit, Notion etc. - `data_tools`: Pandas, TextBlob, DataCommons, OpenBB, Stripe etc. - `research_tools`: arXiv, Google Scholar etc. - `dev_tools`: Docker, Jupyter, Tree-sitter, Code Interpreter etc. Multiple extras can be combined: ```shell pip install 'camel-ai[rag,web_tools,document_tools]' # Example: RAG system with web search and document processing ``` - To verify that `camel-ai` is installed, run: ```shell pip show camel-ai ``` Installation successful! You're ready to create your first multi-agent system! 🎉 # Creating a CAMEL-AI Project We recommend starting with a simple role-playing scenario to understand CAMEL's multi-agent capabilities. Here's how to get started: - Create a new project directory: ```shell mkdir my_camel_project cd my_camel_project ``` - Create a `.env` file with your API keys: ```bash OPENAI_API_KEY= OPENAI_API_BASE_URL= # Optional: for proxy services ANTHROPIC_API_KEY= GOOGLE_API_KEY= ``` - Create a `requirements.txt` file: ```txt camel-ai[all] python-dotenv ``` - Install project dependencies: ```bash pip install -r requirements.txt ``` - Set up your environment variables by loading the `.env` file: ```python from dotenv import load_dotenv load_dotenv() ``` - Run your first multi-agent example: ```bash python examples/role_playing.py ``` Want to see multi-agent collaboration at scale? Try running the workforce example: python examples/workforce/multiple_single_agents.py ## Alternative Installation Methods CAMEL-AI offers multiple installation approaches for different development needs: ### From Docker - Containerized deployment with pre-configured environment - Detailed guidance available at [CAMEL Docker Guide](https://github.com/camel-ai/camel/blob/master/.container/README.md) ### From Source with UV - Development installation with full source access - Supports Python 3.10, 3.11, 3.12, 3.13, 3.14 - Includes development tools and testing capabilities **Python 3.13+ Compatibility Notes:** - `unstructured` and `pyobvector` packages are not available on Python 3.13+ - These packages require NumPy < 2.0, which is incompatible with Python 3.13+ - If you need these features, use Python 3.10-3.12 - All other features work normally on Python 3.13+ ```bash # Clone the repository git clone https://github.com/camel-ai/camel.git cd camel # Install UV package manager pip install uv # Create virtual environment uv venv .venv --python=3.10 # Activate environment (macOS/Linux) source .venv/bin/activate # For Windows: .venv\Scripts\activate # Install CAMEL with all dependencies uv pip install -e ".[all, dev, docs]" ``` Learn about contributing to CAMEL-AI and development best practices ## Configuration Options Configure default model platform and type using environment variables: ```bash export DEFAULT_MODEL_PLATFORM_TYPE=openai # e.g., openai, anthropic, etc. export DEFAULT_MODEL_TYPE=gpt-4o-mini # e.g., gpt-3.5-turbo, gpt-4o-mini, etc. ``` By default, CAMEL uses: ```bash ModelPlatformType.DEFAULT = "openai" ModelType.DEFAULT = "gpt-4o-mini" ``` **For Bash shell (Linux, macOS, Git Bash on Windows):** ```bash export OPENAI_API_KEY= export OPENAI_API_BASE_URL= # Optional ``` **For Windows Command Prompt:** ```cmd set OPENAI_API_KEY= set OPENAI_API_BASE_URL= ``` **For Windows PowerShell:** ```powershell $env:OPENAI_API_KEY="" $env:OPENAI_API_BASE_URL="" ``` **Using .env File (Recommended):** ```bash OPENAI_API_KEY= ANTHROPIC_API_KEY= GOOGLE_API_KEY= ``` Load in Python: ```python from dotenv import load_dotenv load_dotenv() # Use load_dotenv(override=True) to overwrite existing variables ``` ## Running Examples After setting up your API keys, explore CAMEL's capabilities: ```bash # Two agents role-playing and collaborating python examples/ai_society/role_playing.py # Agent utilizing code execution tools python examples/toolkits/code_execution_toolkit.py # Generating knowledge graphs with agents python examples/knowledge_graph/knowledge_graph_agent_example.py # Multiple agents collaborating on complex tasks python examples/workforce/multiple_single_agents.py # Creative image generation with agents python examples/vision/image_crafting.py ``` ## Testing Your Installation Run the test suite to ensure everything is working: ```bash # Activate virtual environment first source .venv/bin/activate # macOS/Linux # .venv\Scripts\activate # Windows # Run all tests pytest --fast-test-mode test/ # Run specific test categories pytest -v apps/ pytest -v examples/ ``` ## Next Steps Follow our quickstart guide to create role-playing agents and see CAMEL in action. Discover RAG systems, tool integration, and complex multi-agent cookbooks. Connect with other developers, contribute, and share your CAMEL experiences. Dive deep into CAMEL's API and advanced configuration options. For additional feature examples and use cases, explore the [`examples`](https://github.com/camel-ai/camel/tree/master/examples) directory in the CAMEL repository. --- --- title: "Introduction" icon: rocket description: | CAMEL-AI is an open-source community for finding the scaling laws of agents for data generation, world simulation, and task automation. --- ## What is CAMEL-AI? **CAMEL‑AI is an open‑source, modular framework for building intelligent multi‑agent systems.** It provides the primitives to: - Create **Agents** that reason, plan, and act - Compose **Societies** of agents with defined roles - Integrate **Interpreters** for code execution and analysis - Manage **Memory** for long‑horizon context and learning - Orchestrate **Retrieval‑Augmented Generation (RAG)** pipelines - Generate **Synthetic Data** at scale with self‑instruct and verifier loops - Simulate **Worlds** and agent interactions in environments like social networks ## Core Components - **Agents**: Atomic reasoning units driven by LLMs, capable of tool calls and decision‑making - **Societies**: Coordinator layers that assign roles, delegate tasks, and manage collaboration - **Interpreters**: Execution backends (Python, shell, browsers) for live code evaluation and automation - **Memory & Storage**: Persistent context layers for chat history, tool outputs, and learned knowledge - **RAG Pipelines**: Combine chunking, retrieval, and generation for grounded, accurate responses - **Synthetic Data Engines**: Self‑instruct, Chain‑of‑Thought, and Source2Synth pipelines with verifiers - **World Simulation**: Platforms like Oasis for large‑scale multi‑agent social simulations - **Task Automation**: Benchmarks like CRAB for real‑world multi‑step software workflows ## Ecosystem Highlights Large‑scale social simulation environment: model Reddit, Twitter, and user interactions Cross‑environment agent automation tasks across Ubuntu and Android platforms Verifier‑driven synthetic data generation for domain‑specific QA at scale OWL (Optimized Workforce Learning) is a multi-agent automation framework for real-world tasks. Built on CAMEL-AI, it enables dynamic agent collaboration using tools like browsers, code interpreters, and multimodal models. ## Ready to Get Started? Spin up your first agent in under 5 minutes pip install camel-ai[all] – all toolkits and interpreters included Hands‑on examples: data gen, RAG, simulations, and more --- --- title: "Setup" icon: gear description: "Configure API credentials and select a model provider" --- CAMEL-AI supports multiple model backends. Choose one below and configure your environment variables. ## 1. OpenAI API Obtain your `OPENAI_API_KEY` from [OpenAI Dashboard](https://platform.openai.com/account/api-keys). ```bash echo 'export OPENAI_API_KEY=""' >> ~/.zshrc source ~/.zshrc ``` _Replace `~/.zshrc` with `~/.bashrc` if using bash._ ```powershell setx OPENAI_API_KEY "" /M ``` _You may need to restart your terminal for changes to apply._ Create a `.env` file in your project root: ```dotenv OPENAI_API_KEY= ``` Load in Python: ```python from dotenv import load_dotenv load_dotenv() import os print(os.getenv("OPENAI_API_KEY")) ``` To configure an `API_BASE_URL` (e.g., Azure), also set: ```bash export OPENAI_API_BASE_URL="" ``` ## 2. Other Hosted APIs For non-OpenAI providers, see [Using Models by API Calling](../key_modules/models). ## 3. Local Models To run fully on-device with open-source models, refer to [Local Models Guide](../key_modules/models) --- # Welcome to CAMEL\'s documentation! | **Finding the Scaling Law of Agents: The First and the Best Multi-Agent Framework.** | **CAMEL** emerges as the earliest [LLM-based multi-agent framework](https://arxiv.org/pdf/2303.17760.pdf), and is now a generic framework to build and use LLM-based agents for real-world task solving. We believe that studying these agents on a large scale offers valuable insights into their behaviors, capabilities, and potential risks. To facilitate research in this field, we implement and support various types of agents, tasks, prompts, models, and simulated environments. ## Main Documentation ::: {#getting_started .toctree maxdepth="1" caption="Get Started"} get_started/installation.md get_started/setup.md ::: ::: {#agents .toctree maxdepth="1" caption="Agents"} cookbooks/create_your_first_agent.ipynb cookbooks/create_your_first_agents_society.ipynb cookbooks/embodied_agents.ipynb cookbooks/critic_agents_and_tree_search.ipynb ::: ::: {#key_modules .toctree maxdepth="1" caption="Key Modules"} key_modules/agents.md key_modules/datagen.md key_modules/models.md key_modules/messages.md key_modules/memory.md key_modules/tools.md key_modules/prompts.md key_modules/runtimes.md key_modules/tasks.md key_modules/loaders.md key_modules/storages.md key_modules/society.md key_modules/embeddings.md key_modules/retrievers.md key_modules/workforce.md key_modules/benchmark.md ::: ::: {#cookbooks .toctree maxdepth="2" caption="Cookbooks"} cookbooks/basic_concepts/index cookbooks/advanced_features/index cookbooks/multi_agent_society/index cookbooks/data_generation/index cookbooks/applications/index cookbooks/data_processing/index cookbooks/loong/index cookbooks/mcp/index ::: ::: {#api_references .toctree maxdepth="1" caption="API References"} modules ::: ## Indices and tables - `genindex`{.interpreted-text role="ref"} - `modindex`{.interpreted-text role="ref"} - `search`{.interpreted-text role="ref"} ## Get Involved We are always happy to work with friends to continuously move forward with our own competitive edges. **For Research Aficionados**: New, rigorous and in-depth research takes time and resources. With access to almost unlimited usage of advanced GPU computes and a team of amazing researchers and engineers, we are bold enough to explore the frontier with patience. Whether you would like to join in our on-going project or have new idea to test, feel free to talk to us and see how we may work together. **For Coding Enthusiasts**: Whether you want to introduce new features, enhance the infrastructure, improve documentation, asking issues, add more examples, implement state-of-the-art research ideas, or fix bugs, we appreciate each and every commit. Get started by checking out the [Contributing Guidelines](https://github.com/camel-ai/camel/wiki/Contributing-Guidlines) on GitHub. **For Interested Humans**: Connect with us on [Discord](https://discord.camel-ai.org), [WeChat](https://ghli.org/camel/wechat.png), or [Slack](https://join.slack.com/t/camel-ai/shared_invite/zt-2g7xc41gy-_7rcrNNAArIP6sLQqldkqQ). --- --- title: "BenchMarks" description: "Learn about CAMEL's Benchmark module." --- ## Overview The **Benchmark** module in CAMEL provides a framework for evaluating AI agents and language models across various tasks and domains. It includes implementations of multiple benchmarks and provides a interface for running evaluations, measuring performance, and generating detailed reports. The module supports benchmarks for: - **API calling and tool use** (APIBank, APIBench, Nexus) - **General AI assistance** (GAIA) - **Browser-based comprehension** (BrowseComp) - **Retrieval-Augmented Generation** (RAGBench) ## Architecture ### Base Class: `BaseBenchmark` All benchmarks inherit from the `BaseBenchmark` abstract class, which provides a common interface for downloading data, loading datasets, running evaluations, and accessing results. #### BaseBenchmark Methods | Method | Description | Parameters | | ------------ | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `__init__()` | Initialize the benchmark | `name`: Benchmark name
`data_dir`: Data directory path
`save_to`: Results save path
`processes`: Number of parallel processes | | `download()` | Download benchmark data | None | | `load()` | Load benchmark data | `force_download`: Force re-download | | `run()` | Run the benchmark evaluation | `agent`: ChatAgent to evaluate
`on`: Data split ("train", "valid", "test")
`randomize`: Shuffle data
`subset`: Limit number of examples | | `train` | Get training data | None | | `valid` | Get validation data | None | | `test` | Get test data | None | | `results` | Get evaluation results | None | ## Available Benchmarks ### 1. GAIA Benchmark **GAIA (General AI Assistants)** is a benchmark for evaluating general-purpose AI assistants on real-world tasks requiring multiple steps, tool use, and reasoning. ### 2. APIBank Benchmark **APIBank** evaluates the ability of LLMs to make correct API calls and generate appropriate responses in multi-turn conversations. ### 3. APIBench Benchmark **APIBench (Gorilla)** tests the ability to generate correct API calls for various machine learning frameworks (HuggingFace, TensorFlow Hub, Torch Hub). ### 4. Nexus Benchmark **Nexus** evaluates function calling capabilities across multiple domains including security APIs, location services, and climate data. #### Available Tasks | Task | Description | | ---------------------------- | ----------------------------- | | `"NVDLibrary"` | CVE and CPE API calls | | `"VirusTotal"` | Malware and security analysis | | `"OTX"` | Open Threat Exchange API | | `"PlacesAPI"` | Location and mapping services | | `"ClimateAPI"` | Weather and climate data | | `"VirusTotal-ParallelCalls"` | Multiple parallel API calls | | `"VirusTotal-NestedCalls"` | Nested API calls | | `"NVDLibrary-NestedCalls"` | Nested CVE/CPE calls | ### 5. BrowseComp Benchmark **BrowseComp** evaluates browser-based comprehension by testing agents on questions that require understanding web content. ### 6. RAGBench Benchmark **RAGBench** evaluates Retrieval-Augmented Generation systems using context relevancy and faithfulness metrics. #### Available Subsets | Subset | Description | | ------------ | -------------------------------------------------- | | `"hotpotqa"` | Multi-hop question answering | | `"covidqa"` | COVID-19 related questions | | `"finqa"` | Financial question answering | | `"cuad"` | Contract understanding | | `"msmarco"` | Microsoft Machine Reading Comprehension | | `"pubmedqa"` | Biomedical questions | | `"expertqa"` | Expert-level questions | | `"techqa"` | Technical questions | | Others | `"emanual"`, `"delucionqa"`, `"hagrid"`, `"tatqa"` | ## Common Usage Pattern All benchmarks follow a similar pattern: ```python from camel.benchmarks import from camel.agents import ChatAgent # 1. Initialize benchmark = ( data_dir="./data", save_to="./results.json", processes=4 ) # 2. Load data benchmark.load(force_download=False) # 3. Create agent agent = ChatAgent(...) # 4. Run evaluation results = benchmark.run( agent=agent, # benchmark-specific parameters randomize=False, subset=None # or number of examples ) # 5. Access results print(results) # Summary metrics print(benchmark.results) # Detailed per-example results ``` ## Implementing Custom Benchmarks To create a custom benchmark, inherit from `BaseBenchmark` and implement: 1. `download()`: Download benchmark data 2. `load()`: Load data into `self._data` dictionary 3. `run()`: Execute benchmark and populate `self._results` 4. Optional: Override `train`, `valid`, `test` properties ## References - **GAIA**: https://huggingface.co/datasets/gaia-benchmark/GAIA - **APIBank**: https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/api-bank - **APIBench (Gorilla)**: https://huggingface.co/datasets/gorilla-llm/APIBench - **Nexus**: https://huggingface.co/collections/Nexusflow/nexusraven-v2 - **BrowseComp**: https://openai.com/index/browsecomp/ - **RAGBench**: https://arxiv.org/abs/2407.11005 ## Other Resources - Explore the [Agents](./agents.md) module for creating custom agents --- --- title: "Agents" description: "Learn about CAMEL's agent types, with a focus on ChatAgent and advanced agent architectures for AI-powered automation." icon: user-helmet-safety --- ## Concept Agents in CAMEL are autonomous entities capable of performing specific tasks through interaction with language models and other components. Each agent is designed with a particular role and capability, allowing them to work independently or collaboratively to achieve complex goals. Think of an agent as an AI-powered teammate one that brings a defined role, memory, and tool-using abilities to every workflow. CAMEL’s agents are composable, robust, and can be extended with custom logic. ## Base Agent Architecture All CAMEL agents inherit from the BaseAgent abstract class, which defines two essential methods: | Method | Purpose | Description | |-------------|---------------------|----------------------------------------------| | reset() | State Management | Resets the agent to its initial state | | step() | Task Execution | Performs a single step of the agent's operation | ## Types ### ChatAgent The `ChatAgent` is the primary implementation that handles conversations with language models. It supports: - System message configuration for role definition - Memory management for conversation history - Tool/function calling capabilities - Response formatting and structured outputs - Multiple model backend support with scheduling strategies - Async operation support **`CriticAgent`** Specialized agent for evaluating and critiquing responses or solutions. Used in scenarios requiring quality assessment or validation. **`DeductiveReasonerAgent`** Focused on logical reasoning and deduction. Breaks down complex problems into smaller, manageable steps. **`EmbodiedAgent`** Designed for embodied AI scenarios, capable of understanding and responding to physical world contexts. **`KnowledgeGraphAgent`** Specialized in building and utilizing knowledge graphs for enhanced reasoning and information management. **`MultiHopGeneratorAgent`** Handles multi-hop reasoning tasks, generating intermediate steps to reach conclusions. **`SearchAgent`** Focused on information retrieval and search tasks across various data sources. **`TaskAgent`** Handles task decomposition and management, breaking down complex tasks into manageable subtasks. ## Usage ### Basic ChatAgent Usage ```python from camel.agents import ChatAgent # Create a chat agent with a system message agent = ChatAgent(system_message="You are a helpful assistant.") # Step through a conversation response = agent.step("Hello, can you help me?") ``` ### Simplified Agent Creation The `ChatAgent` supports multiple ways to specify the model: ```python from camel.agents import ChatAgent from camel.models import ModelFactory from camel.types import ModelPlatformType, ModelType # Method 1: Using just a string for the model name (default model platform is used) agent_1 = ChatAgent("You are a helpful assistant.", model="gpt-4o-mini") # Method 2: Using a ModelType enum (default model platform is used) agent_2 = ChatAgent("You are a helpful assistant.", model=ModelType.GPT_4O_MINI) # Method 3: Using a tuple of strings (platform, model) agent_3 = ChatAgent("You are a helpful assistant.", model=("openai", "gpt-4o-mini")) # Method 4: Using a tuple of enums agent_4 = ChatAgent( "You are a helpful assistant.", model=(ModelPlatformType.ANTHROPIC, ModelType.CLAUDE_3_5_SONNET), ) # Method 5: Using default model platform and default model type when none is specified agent_5 = ChatAgent("You are a helpful assistant.") # Method 6: Using a pre-created model with ModelFactory (original approach) model = ModelFactory.create( model_platform=ModelPlatformType.OPENAI, # Using enum model_type=ModelType.GPT_4O_MINI, # Using enum ) agent_6 = ChatAgent("You are a helpful assistant.", model=model) # Method 7: Using ModelFactory with string parameters model = ModelFactory.create( model_platform="openai", # Using string model_type="gpt-4o-mini", # Using string ) agent_7 = ChatAgent("You are a helpful assistant.", model=model) ``` ### Using Tools with Chat Agent ```python from camel.agents import ChatAgent from camel.toolkits import FunctionTool # Define a tool def calculator(a: int, b: int) -> int: return a + b # Create agent with tool agent = ChatAgent(tools=[calculator]) # The agent can now use the calculator tool in conversations response = agent.step("What is 5 + 3?") ``` ### Structured Output CAMEL's `ChatAgent` can produce structured output by leveraging Pydantic models. This feature is especially useful when you need the agent to return data in a specific format, such as JSON. By defining a Pydantic model, you can ensure that the agent's output is predictable and easy to parse. Here's how you can get a structured response from a `ChatAgent`. First, define a `BaseModel` that specifies the desired output fields. You can add descriptions to each field to guide the model. ```python from pydantic import BaseModel, Field from typing import List class JokeResponse(BaseModel): joke: str = Field(description="A joke") funny_level: int = Field(description="Funny level, from 1 to 10") # Create agent with structured output agent = ChatAgent(model="gpt-4o-mini") response = agent.step("Tell me a joke.", response_format=JokeResponse) # The response content is a JSON string print(response.msgs[0].content) # '{"joke": "Why don't scientists trust atoms? Because they make up everything!", "funny_level": 8}' # Access the parsed Pydantic object parsed_response = response.msgs[0].parsed print(parsed_response.joke) # "Why don't scientists trust atoms? Because they make up everything!" print(parsed_response.funny_level) # 8 ``` You can also use nested Pydantic models and lists to define more complex structures. In this example, we define a `StudentList` that contains a list of `Student` objects. ```python from pydantic import BaseModel from typing import List class Student(BaseModel): name: str age: str email: str class StudentList(BaseModel): students: List[Student] # Create agent with structured output agent = ChatAgent(model="gpt-4o-mini") response = agent.step( "Create a list of two students with their names, ages, and email addresses.", response_format=StudentList, ) # Access the parsed Pydantic object parsed_response = response.msgs[0].parsed for student in parsed_response.students: print(f"Name: {student.name}, Age: {student.age}, Email: {student.email}") # Name: Alex, Age: 22, Email: alex@example.com # Name: Beth, Age: 25, Email: beth@example.com ``` ## Best Practices
  • Use appropriate window sizes to manage conversation history
  • Consider token limits when dealing with long conversations
  • Utilize the memory system for maintaining context
  • Keep tool functions focused and well-documented
  • Handle tool errors gracefully
  • Use external tools for operations that should be handled by the user
  • Implement appropriate response terminators for conversation control
  • Use structured outputs when specific response formats are needed
  • Handle async operations properly when dealing with long-running tasks
  • Use the simplified model specification methods for cleaner code
  • For default platform models, just specify the model name as a string
  • For specific platforms, use the tuple format (platform, model)
  • Use enums for better type safety and IDE support
## Advanced Features You can dynamically select which model an agent uses for each step by adding your own scheduling strategy. ```python title="Custom Model Scheduling" def custom_strategy(models): # Custom model selection logic return models[0] agent.add_model_scheduling_strategy("custom", custom_strategy) ``` Agents can respond in any language. Set the output language on-the-fly during conversations. ```python title="Set Output Language" agent.set_output_language("Spanish") ``` --- --- title: "Browser Toolkit" icon: "globe" --- The Browser Toolkit provides a powerful set of tools to automate and interact with web browsers. It allows CAMEL agents to perform complex web-based tasks, from simple page navigation to intricate form submissions and data extraction. Uses a sophisticated two-agent system: a `planning_agent` to create and refine high-level plans, and a `web_agent` to observe the screen and execute low-level actions. The `web_agent` can analyze "Set-of-Marks" (SoM) screenshots, which are visual representations of the page with interactive elements highlighted, enabling it to perform complex visual reasoning. Supports persistent browser sessions by saving and loading cookies and user data, allowing the agent to stay logged into websites across multiple sessions. Can analyze videos on the current page (e.g., YouTube) to answer questions about their content, leveraging the `VideoAnalysisToolkit`. ## Initialization To get started, initialize the `BrowserToolkit`. You can configure the underlying models for the planning and web agents. ```python from camel.toolkits import BrowserToolkit # Initialize with default models browser_toolkit = BrowserToolkit() ``` ```python from camel.toolkits import BrowserToolkit from camel.models import ModelFactory from camel.types import ModelPlatformType, ModelType # Define custom models for the agents (use latest OpenAI models) web_agent_model = ModelFactory.create( model_platform=ModelPlatformType.OPENAI, model_type=ModelType.GPT_5_MINI, ) planning_agent_model = ModelFactory.create( model_platform=ModelPlatformType.OPENAI, model_type=ModelType.O4_MINI, ) browser_toolkit = BrowserToolkit( web_agent_model=web_agent_model, planning_agent_model=planning_agent_model, ) ``` ## Core Functionality: `browse_url` The main entry point for the toolkit is the `browse_url` function. It takes a high-level task and a starting URL, and then autonomously navigates the web to complete the task. ```python task_prompt = "Find the main contributions of the paper 'Sparks of AGI' by Microsoft Research." start_url = "https://www.google.com" # The agent will navigate from Google, find the paper, and extract the information. result = browser_toolkit.browse_url( task_prompt=task_prompt, start_url=start_url, ) print(result) ``` ## How It Works: The Two-Agent System The `browse_url` function orchestrates a loop between the `planning_agent` and the `web_agent`. The `planning_agent` creates a high-level plan to accomplish the task. The `web_agent` observes the current page by taking a "Set-of-Marks" (SoM) screenshot. Based on the observation and the plan, the `web_agent` decides on the next action to take (e.g., click, type, scroll). The toolkit executes the action and the loop repeats. If the `web_agent` gets stuck, the `planning_agent` can re-evaluate the situation and create a new plan. ## Advanced Usage ### Persistent Sessions You can maintain login sessions across runs by providing a path to a `cookies.json` file or a `user_data_dir`. ```python # The toolkit will save cookies and local storage to this file cookie_path = "./my_browser_session.json" # First run: Log in to a website # browser_toolkit = BrowserToolkit(cookie_json_path=cookie_path) # browser_toolkit.browse_url(task_prompt="Log in to my account...", start_url="...") # Subsequent runs: The agent will be logged in automatically browser_toolkit_loggedin = BrowserToolkit(cookie_json_path=cookie_path) ``` ### Video Analysis The toolkit can answer questions about videos on a webpage. ```python # First, navigate to the video browser_toolkit.browse_url(task_prompt="Navigate to a specific YouTube video", start_url="...") # Then, ask a question about it # Note: This is an example of how you might use the underlying BaseBrowser. # The browse_url function would orchestrate this automatically. question = "What is the main topic of this video?" answer = browser_toolkit.browser.ask_question_about_video(question=question) print(answer) ``` --- --- title: "Datagen" description: "CAMEL’s data generation modules for high-quality, instruction-tuned, and reasoning-rich datasets." icon: arrow-progress --- This page introduces CAMEL's **data generation modules** for creating high-quality training data with explicit reasoning, diverse instructions, and advanced automated refinement. - **Chain of Thought (CoT):** Generates explicit reasoning paths - **Self-Instruct:** Produces instruction-following data from both humans and machines - **Source2Synth:** Synthesizes multi-hop QA from source text or code - **Self-Improving CoT:** Iteratively improves reasoning through agent self-critique ## Chain of Thought (CoT) Data Generation Chain of Thought (CoT) data generation creates step-by-step reasoning paths for problem solving, leveraging dual agents and advanced search/verification logic. - Monte Carlo Tree Search (MCTS) for solution exploration - Binary Search Error Detection for precise error localization - Dual-Agent Verification System for quality assurance - Solution Tree Management for tracking reasoning paths **CoTDataGenerator Class** The main class that implements the CoT generation system with the following capabilities: - **Dual-Agent Architecture**: Supports both single-agent (legacy) and dual-agent modes - **Answer Generation**: Sophisticated answer generation with MCTS - **Answer Verification**: Robust verification system using golden answers - **Error Detection**: Binary search-based error detection in solutions - **Solution Management**: Comprehensive solution tree management and export Spin up chain-of-thought data generation with dual agents, golden answers, and CoT solution generation: ```python from camel.agents import ChatAgent from camel.datagen import CoTDataGenerator # Initialize agents generator_agent = ChatAgent("Generator agent for simple math computation.") verifier_agent = ChatAgent("Verified agent for simple math computation.") # Define golden answers question = "What's the answer of 1 + 2?" golden_answers = { question: "3", } # Create generator cot_generator = CoTDataGenerator( generator_agent=generator_agent, verifier_agent=verifier_agent, golden_answers=golden_answers, search_limit=3, ) # Generate solution solution = cot_generator.solve(question) ``` Easily import question-answer pairs or export generated solutions for further use: ```python # Import QA pairs from JSON cot_generator.import_qa_from_json("qa_pairs.json") # Export solutions cot_generator.export_solutions("solutions.json") ``` First, the agent attempts to solve the problem directly and checks the result against the golden answer for correctness. If the direct attempt fails, a Monte Carlo Tree Search (MCTS) explores alternative reasoning paths, building a solution tree from previous attempts. Binary search is used to efficiently pinpoint and isolate errors in the solution. New solutions are then generated, reusing verified-correct parts. All candidate solutions are strictly verified using a dual-agent system or comparison against golden answers to ensure high quality and accuracy.
  • search_limit: Maximum number of search iterations (default: 100)
  • generator_agent: Specialized agent for answer generation
  • verifier_agent: Specialized agent for answer verification
  • golden_answers: Pre-defined correct answers for validation
The solution tree is exported in JSON format containing:
  • Solutions with intermediate steps
  • Golden answers used for verification
  • Export timestamp
--- ## Self-Instruct: Instruction Generation Self-Instruct is a pipeline for generating high-quality, diverse instructions by combining human-written seed tasks and machine-generated prompts, all filtered for quality and diversity.
  • Combines human-written and machine-generated instructions using configurable ratios
  • Supports both classification and non-classification task types
  • Built-in instruction filtering and validation
  • Automatic instance generation for tasks
  • JSON-based data input/output
SelfInstructPipeline – Orchestrates the end-to-end instruction generation, mixing seeds and machine prompts, filtering, and outputting results.

InstructionFilter – Handles validation and filtering of all generated instructions:
  • Length-based, keyword, and punctuation checks
  • Non-English text detection
  • ROUGE similarity filtering for deduplication
  • Extensible registry for custom filters
Quickly set up an instruction generation pipeline with both human and machine prompts: ```python from camel.agents import ChatAgent from camel.datagen.self_instruct import SelfInstructPipeline # Initialize agent agent = ChatAgent() # Create pipeline with default settings pipeline = SelfInstructPipeline( agent=agent, seed='seed_tasks.jsonl', # Path to human-written seed tasks num_machine_instructions=5, data_output_path='./data_output.json', human_to_machine_ratio=(6, 2) ) # Generate instructions pipeline.generate() ``` Use custom filters to refine and deduplicate instructions as needed: ```python from camel.datagen.self_instruct import SelfInstructPipeline from camel.datagen.self_instruct.filter import InstructionFilter # Configure filters filter_config = { "length": {}, "keyword": {}, "punctuation": {}, "non_english": {}, "rouge_similarity": { "threshold": 0.7, "metric": "rouge-l" } } pipeline = SelfInstructPipeline( agent=agent, seed='seed_tasks.jsonl', instruction_filter=InstructionFilter(filter_config), num_machine_instructions=5 ) ``` Load and validate human-written instructions from JSONL file; initialize task storage. Sample both human and machine tasks based on your chosen ratio, then generate new instructions with ChatAgent and apply filters. Automatically determine if tasks are classification or not, and generate the right prompts for each type. Generate input-output pairs, format and parse instances, and apply quality filters. Save all generated instructions and their instances to JSON, with metadata and configuration details.
  • agent: ChatAgent instance for generating instructions
  • seed: Path to human-written seed tasks in JSONL format
  • num_machine_instructions: Number of machine-generated instructions (default: 5)
  • data_output_path: Path for saving generated data (default: ./data_output.json)
  • human_to_machine_ratio: Ratio of human to machine tasks (default: (6, 2))
  • instruction_filter: Custom InstructionFilter instance (optional)
  • filter_config: Configuration dictionary for default filters (optional)
The default filter configuration supports:
  • length: Configure length constraints for instructions
  • keyword: Set up keyword-based filtering rules
  • punctuation: Define punctuation validation rules
  • non_english: Non-English text detection
  • rouge_similarity: Set ROUGE similarity thresholds for deduplication
Seed Tasks (Input): ```json {"instruction": "Classify the sentiment of this text as positive or negative."} {"instruction": "Generate a summary of the given paragraph."} ``` Generated Data (Output): ```json { "machine_instructions": [ { "instruction": "...", "is_classification": true, "instances": [ { "input": "...", "output": "..." } ] } ] } ```
--- ## Source2Synth: Multi-hop Question-Answer Generation Source2Synth generates complex multi-hop QA pairs from source text (or code) via an orchestrated pipeline of AI-driven and rule-based steps, with curation and complexity control. UserDataProcessor: Orchestrates the full pipeline, from raw text through QA generation and curation.

ExampleConstructor: Builds multi-hop QA examples, extracting premise, intermediate steps, and conclusions.

DataCurator: Filters, deduplicates, and samples the final dataset to match quality and complexity requirements.
  • Batch or single text processing
  • Switchable AI or rule-based question generation
  • Multi-hop QA and complexity scoring
  • Integrated curation, deduplication, and reproducible sampling
  • Seamless MultiHopGeneratorAgent integration
Rapidly generate a multi-hop QA dataset from your own text or source files: ```python from camel.datagen.source2synth import ( UserDataProcessor, ProcessorConfig ) # Create configuration config = ProcessorConfig( seed=42, min_length=50, max_length=1000, complexity_threshold=0.5, dataset_size=10, use_ai_model=True, ) # Initialize processor processor = UserDataProcessor(config) # Process a single text result = processor.process_text( "Your source text here", source="example_source" ) # Process multiple texts texts = ["Text 1", "Text 2", "Text 3"] sources = ["source1", "source2", "source3"] batch_results = processor.process_batch(texts, sources) ```
  • seed: Random seed for reproducibility
  • min_length: Minimum text length for processing
  • max_length: Maximum text length for processing
  • complexity_threshold: Minimum complexity score (0.0–1.0)
  • dataset_size: Target size for the final dataset
  • use_ai_model: Toggle between AI model and rule-based generation
  • hop_generating_agent: Custom MultiHopGeneratorAgent (optional)
Validate text length and quality; standardize for processing. Identify premises, extract intermediate facts, and form conclusions. Generate multi-hop questions, validate answers, and score for complexity. Filter for quality, enforce complexity thresholds, deduplicate, and sample to target size.
--- ## Self-Improving CoT Data Generation This pipeline implements self-taught reasoning—an iterative process where an AI agent refines its own reasoning traces via self-evaluation, feedback, and reward models for continual improvement. SelfImprovingCoTPipeline: Implements the STaR (Self-Taught Reasoning) methodology, supporting both agent-based and external reward model evaluation, iterative feedback loops, and flexible output formats.

- Customizable reasoning and evaluation agents
- Support for reward models and custom thresholds
- Few-shot learning and rich output options
The pipeline generates an initial reasoning path for each problem using the designated agent. An evaluator agent (or reward model) critically reviews each reasoning trace for quality, clarity, and correctness. The system refines and re-generates reasoning steps using the evaluation feedback. This evaluation-feedback loop is repeated for a configurable number of iterations to reach optimal performance.
Launch a self-improving reasoning workflow with just a few lines: ```python from camel.agents import ChatAgent from camel.datagen import SelfImprovingCoTPipeline # Initialize agents reason_agent = ChatAgent( """Answer my question and give your final answer within \\boxed{}.""" ) evaluate_agent = ChatAgent( "You are a highly critical teacher who evaluates the student's answers " "with a meticulous and demanding approach." ) # Prepare your problems problems = [ {"problem": "Your problem text here"}, # Add more problems... ] # Create and run the pipeline pipeline = SelfImprovingCoTPipeline( reason_agent=reason_agent, evaluate_agent=evaluate_agent, problems=problems, max_iterations=3, output_path="star_output.json" ) results = pipeline.generate() ``` Evaluate and guide reasoning traces with an external reward model, such as Nemotron: ```python from camel.models.reward import NemotronRewardModel # Initialize reward model reward_model = NemotronRewardModel( model_type=ModelType.NVIDIA_NEMOTRON_340B_REWARD, url="https://integrate.api.nvidia.com/v1", api_key="your_api_key" ) # Create pipeline with reward model pipeline = SelfImprovingCoTPipeline( reason_agent=reason_agent, evaluate_agent=evaluate_agent, problems=problems, reward_model=reward_model, score_threshold={ "correctness": 0.8, "clarity": 0.7, "completeness": 0.7 } ) ``` Input Format (JSON): ```json { "problems": [ { "problem": "Problem text here", "solution": "Optional solution text" } ] } ``` Output Format (JSON):
  • Original problem
  • Final reasoning trace
  • Improvement history with iterations
  • Evaluation scores and feedback per iteration
  • max_iterations: Maximum number of improvement iterations (default: 3)
  • score_threshold: Minimum quality thresholds for evaluation dimensions (default: 0.7)
  • few_shot_examples: (Optional) Examples for few-shot learning
  • output_path: (Optional) Path for saving generated results
--- --- title: "Embeddings" icon: vector-square --- Embeddings transform text, images, and other media into dense numeric vectors that capture their underlying meaning. This makes it possible for machines to perform semantic search, similarity, recommendations, clustering, RAG, and more. Text embeddings turn sentences or documents into high-dimensional vectors that capture meaning. Example:
  • “A young boy is playing soccer in a park.”
  • “A child is kicking a football on a playground.”
These sentences get mapped to similar vectors, letting your AI recognize their meaning, regardless of wording. Image embeddings use neural networks (like CNNs) or vision-language models to turn images into numeric vectors, capturing shapes, colors, and features. For example: A cat image → vector that is “close” to other cats and “far” from cars in vector space.
## Supported Embedding Types Use OpenAI’s API to generate text embeddings.
Requires: OpenAI API Key.
Use Mistral’s API for text embeddings.
Requires: Mistral API Key.
Local, open-source transformer models from the{" "} Sentence Transformers {" "} library. OpenAI’s vision models for image embeddings.
Requires: OpenAI API Key.
Text embeddings from OpenAI models on Azure.
Requires: Azure OpenAI API Key.
Together AI’s hosted models for text embeddings.
Requires: Together AI API Key.
## Usage Examples Make sure you have the right API key set (OpenAI, Mistral, Azure, or Together) for the embedding backend you want to use. ```python openai_embed.py from camel.embeddings import OpenAIEmbedding from camel.types import EmbeddingModelType openai_embedding = OpenAIEmbedding(model_type=EmbeddingModelType.TEXT_EMBEDDING_3_SMALL) embeddings = openai_embedding.embed_list(["Hello, world!", "Another example"]) ```` ```python mistral_embed.py from camel.embeddings import MistralEmbedding from camel.types import EmbeddingModelType mistral_embedding = MistralEmbedding(model_type=EmbeddingModelType.MISTRAL_EMBED) embeddings = mistral_embedding.embed_list(["Hello, world!", "Another example"]) ```` ```python sentence_transformer_embed.py from camel.embeddings import SentenceTransformerEncoder sentence_encoder = SentenceTransformerEncoder(model_name='intfloat/e5-large-v2') embeddings = sentence_encoder.embed_list(["Hello, world!", "Another example"]) ```` ```python image_embed.py from camel.embeddings import VisionLanguageEmbedding from PIL import Image import requests vlm_embedding = VisionLanguageEmbedding() url = "http://images.cocodataset.org/val2017/000000039769.jpg" image = Image.open(requests.get(url, stream=True).raw) test_images = [image, image] embeddings = vlm_embedding.embed_list(test_images) ```` ```python azure_embed.py from camel.embeddings import AzureEmbedding from camel.types import EmbeddingModelType azure_openai_embedding = AzureEmbedding(model_type=EmbeddingModelType.TEXT_EMBEDDING_ADA_2) embeddings = azure_openai_embedding.embed_list(["Hello, world!", "Another example"]) ```` ```python together_embed.py from camel.embeddings import TogetherEmbedding together_embedding = TogetherEmbedding(model_type="togethercomputer/m2-bert-80M-8k-retrieval") embeddings = together_embedding.embed_list(["Hello, world!", "Another example"]) ```` Pick a text embedding that matches your language, latency, and privacy needs. For multimodal use cases, use image or vision-language embeddings. Explore retrieval-augmented generation (RAG) and search recipes using embeddings. Full API docs and all configuration options. --- --- title: "Interpreters" description: "Execute code safely and flexibly with CAMEL’s suite of interpreters: local, isolated, and cloud-based execution environments." icon: terminal --- Interpreters allow CAMEL agents to **execute code snippets** in various secure and flexible environments—from local safe execution to isolated Docker containers and managed cloud sandboxes. ## What are Interpreters? Interpreters empower agents to run code dynamically—enabling evaluation, testing, task automation, and rich feedback loops. Choose your interpreter based on trust, isolation, and supported languages.
{" "} Fast, local, safe execution for trusted Python code within the agent process.
Best for: Trusted code, quick Python evaluation.
{" "} Isolated execution in a subprocess. Supports Bash, Python, shell scripts.
Best for: Shell commands, scripts, process isolation.
{" "} Fully sandboxed in Docker containers.
Best for: Untrusted code, dependency isolation, safe experimentation.
Install Docker
{" "} Interactive, stateful execution via Jupyter/IPython kernel.
Best for: Multi-step reasoning, persistent variables, rich outputs.
{" "} Cloud-based sandboxing for scalable, secure remote execution.
Best for: Managed, scalable tasks. No local setup needed.
E2B Docs
--- Fast, local, and safe—executes trusted Python code directly within the CAMEL agent process.
Note: Only expressions (not statements) are allowed in strict safe mode; for output, your code should evaluate to a string.

```python from camel.interpreters import InternalPythonInterpreter # Initialize the interpreter interpreter = InternalPythonInterpreter() # Code to execute (should evaluate to a string) python_code = "'Hello from InternalPythonInterpreter!'" # Run code result_str = interpreter.run(code=python_code, code_type="python") print(f"Result: {result_str}") ````
Execute shell commands or scripts in a separate process for isolation and flexibility.
Supports multiple languages, including Bash and Python.

```python from camel.interpreters import SubprocessInterpreter interpreter = SubprocessInterpreter() shell_command = "echo 'Hello from SubprocessInterpreter!'" result_str = interpreter.run(code=shell_command, code_type="bash") print(f"Result: {result_str.strip()}") ````
Provides full isolation—code runs in a Docker container, protecting your host system and supporting any dependencies.
Requires Docker installed.
Install Docker

```python from camel.interpreters import DockerInterpreter interpreter = DockerInterpreter() python_code_in_docker = "print('Hello from DockerInterpreter!')" result_str = interpreter.run(code=python_code_in_docker, code_type="python") print(f"Result: {result_str.strip()}") ````
Interactive, stateful execution in a Jupyter-like Python kernel—maintains session state and supports rich outputs.

```python from camel.interpreters import JupyterKernelInterpreter interpreter = JupyterKernelInterpreter( require_confirm=False, print_stdout=True, print_stderr=True ) python_code_in_jupyter_kernel = "print('Hello from JupyterKernelInterpreter!')" result = interpreter.run(code=python_code_in_jupyter_kernel, code_type="python") print(result) ````
Run code in a secure, scalable, cloud-based environment—no local setup needed, great for running untrusted or complex code.
E2B Documentation

```python from camel.interpreters import E2BInterpreter interpreter = E2BInterpreter() python_code_in_e2b = "print('Hello from E2BInterpreter!')" result = interpreter.run(code=python_code_in_e2b, code_type="python") print(result) ```
  • Use InternalPythonInterpreter only for trusted and simple Python code.
  • Subprocess and Docker interpreters are better for code isolation and dependency management.
  • Prefer Docker for any untrusted code or when extra libraries are needed.
  • E2B Interpreter is ideal for scalable, managed, and safe cloud execution—no local risk.
  • For interactive, multi-step logic, leverage JupyterKernelInterpreter for persistent session state.
  • Always validate and sanitize user inputs if agents dynamically construct code for execution.
  • If Docker isn’t working, verify your Docker daemon is running and you have the correct permissions.
  • For E2B, check API key and account limits if code doesn’t execute.
  • Long-running scripts are best managed in Subprocess or Docker interpreters with timeout controls.
  • Use session resets (where supported) to avoid cross-task state bleed in Jupyter/IPython interpreters.
``` --- --- title: "Loaders" icon: loader --- CAMEL’s Loaders provide flexible ways to ingest and process all kinds of data structured files, unstructured text, web content, and even OCR from images. They power your agent’s ability to interact with the outside world. itionally, several data readers were added, including `Apify Reader`, `Chunkr Reader`, `Firecrawl Reader`, `Jina_url Reader`, and `Mistral Reader`, which enable retrieval of external data for improved data integration and analysis. ## Types {" "} Handles core file input/output for formats like PDF, DOCX, HTML, and more.

Lets you represent, read, and process structured files.
{" "} Powerful ETL for parsing, cleaning, extracting, chunking, and staging unstructured data.

Perfect for RAG pipelines and pre-processing.
{" "} Integrates with Apify to automate web workflows and scraping.

Supports authentication, actor management, and dataset operations via API.
{" "} Connects to the Chunkr API for document chunking, segmentation, and OCR.

Handles everything from simple docs to scanned PDFs.
{" "} Converts entire websites into LLM-ready markdown using the Firecrawl API.

Useful for quickly ingesting web content as clean text.
{" "} Uses Jina AI’s URL reading service to cleanly extract web content.

Designed for LLM-friendly extraction from any URL.
{" "} Lightweight tool to convert files (HTML, DOCX, PDF, etc.) into Markdown.

Ideal for prepping documents for LLM ingestion or analysis.
{" "} Integrates Mistral AI’s OCR service for extracting text from images and PDFs.

Supports both local and remote file processing for various formats.
## Get Started This module is designed to read files of various formats, extract their contents, and represent them as `File` objects, each tailored to handle a specific file type. ```python base_io_example.py from io import BytesIO from camel.loaders import create_file_from_raw_bytes # Read a pdf file from disk with open("test.pdf", "rb") as file: file_content = file.read() # Use the create_file function to create an object based on the file extension file_obj = create_file_from_raw_bytes(file_content, "test.pdf") # Once you have the File object, you can access its content print(file_obj.docs[0]["page_content"]) ```` --- To get started with the Unstructured IO module, just import and initialize it. You can parse, clean, extract, chunk, and stage data from files or URLs. Here’s how you use it step by step:
1. Parse unstructured data from a file or URL: ```python unstructured_io_parse.py from camel.loaders import UnstructuredIO uio = UnstructuredIO() example_url = ( "https://www.cnn.com/2023/01/30/sport/empire-state-building-green-" "philadelphia-eagles-spt-intl/index.html" ) elements = uio.parse_file_or_url(example_url) print(("\n\n".join([str(el) for el in elements]))) ```` ```markdown parsed_elements.md > > > The Empire State Building was lit in green and white to celebrate the Philadelphia Eagles’ victory in the NFC Championship game on Sunday – a decision that’s sparked a bit of a backlash in the Big Apple. > > > The Eagles advanced to the Super Bowl for the first time since 2018 after defeating the San Francisco 49ers 31-7, and the Empire State Building later tweeted how it was marking the occasion. > > > Fly @Eagles Fly! We’re going Green and White in honor of the Eagles NFC Championship Victory. pic.twitter.com/RNiwbCIkt7— Empire State Building (@EmpireStateBldg) > > > January 29, 2023... ```
2. Clean unstructured text data: ```python unstructured_io_clean.py example_dirty_text = ("\x93Some dirty text ’ with extra spaces and – dashes.") options = [ ('replace_unicode_quotes',{" "} {}), ('clean_dashes', {}), ('clean_non_ascii_chars', {}), ('clean_extra_whitespace', {}), ] cleaned_text = uio.clean_text_data(text=example_dirty_text, clean_options=options) print(cleaned_text) ``` ```markdown cleaned_text.md >>> Some dirty text with extra spaces and dashes. ```
3. Extract data from text (for example, emails): ```python unstructured_io_extract.py example_email_text = "Contact me at example@email.com." extracted_text = uio.extract_data_from_text( text=example_email_text, extract_type="extract_email_address" ) print(extracted_text) ```` ```markdown extracted_email.md >>> ['example@email.com'] ````
4. Chunk content by title: ```python unstructured_io_chunk.py chunks = uio.chunk_elements(elements=elements, chunk_type="chunk_by_title") for chunk in chunks: print(chunk) print("\n" + "-" \* 80) ```` ```markdown chunked_content.md >>> The Empire State Building was lit in green and white to celebrate the Philadelphia Eagles’ victory in the NFC Championship game on Sunday – a decision that’s sparked a bit of a backlash in the Big Apple. >>> -------------------------------------------------------------------------------- >>> Fly @Eagles Fly! We’re going Green and White in honor of the Eagles NFC Championship Victory. pic.twitter.com/RNiwbCIkt7— Empire State Building (@EmpireStateBldg) >>> -------------------------------------------------------------------------------- >>> January 29, 2023 ````
5. Stage elements for use with other platforms: ```python unstructured_io_stage.py staged_element = uio.stage_elements(elements=elements, stage_type="stage_for_baseplate") print(staged_element) ``` ```markdown staged_elements.md >>> {'rows': [{'data': {'type': 'UncategorizedText', 'element_id': 'e78902d05b0cb1e4c38fc7a79db450d5', 'text': 'CNN\n \xa0—'}, 'metadata': {'filetype': 'text/html', 'languages': ['eng'], 'page_number': 1, 'url': 'https://www.cnn.com/2023/01/30/sport/empire-state-building-green-philadelphia-eagles-spt-intl/index.html', 'emphasized_text_contents': ['CNN'], 'emphasized_text_tags': ['span']}}, ... ```
This guide gets you started with Unstructured IO. For more, see the Unstructured IO Documentation.
--- Initialize the Apify client, set up the required actors and parameters, and run the actor. ```python apify_reader.py from camel.loaders import Apify apify = Apify() run_input = { "startUrls": [{"url": "https://www.camel-ai.org/"}], "maxCrawlDepth": 0, "maxCrawlPages": 1, } actor_result = apify.run_actor( actor_id="apify/website-content-crawler", run_input=run_input ) dataset_result = apify.get_dataset_items( dataset_id=actor_result["defaultDatasetId"] ) print(dataset_result) ```` ```markdown apify_output.md >>>[{'url': 'https://www.camel-ai.org/', 'crawl': {'loadedUrl': 'https://www.camel-ai.org/', ...}, 'metadata': {'canonicalUrl': 'https://www.camel-ai.org/', ...}, ... }] ```` --- Firecrawl Reader provides a simple way to turn any website into LLM-ready markdown format. Here’s how you can use it step by step: First, create a Firecrawl client and crawl a specific URL. ```python firecrawl_crawl.py from camel.loaders import Firecrawl firecrawl = Firecrawl() response = firecrawl.crawl(url="https://www.camel-ai.org/about") print(response["status"]) # Should print "completed" when done ``` ```markdown crawl_status.md >>>completed ``` When the status is "completed", the content extraction is done and you can retrieve the results. Once finished, access the LLM-ready markdown directly from the response: ```python firecrawl_markdown.py print(response["data"][0]["markdown"]) ``` ```markdown extracted_markdown.md >>>Camel-AI Team We are finding the scaling law of agent 🐫 CAMEL is an open-source library designed for the study of autonomous and communicative agents. We believe that studying these agents on a large scale offers valuable insights into their behaviors, capabilities, and potential risks. To facilitate research in this field, we implement and support various types of agents, tasks, prompts, models, and simulated environments. **We are** always looking for more **contributors** and **collaborators**. Contact us to join forces via [Slack](https://join.slack.com/t/camel-kwr1314/ shared_invite/zt-1vy8u9lbo-ZQmhIAyWSEfSwLCl2r2eKA) or [Discord](https://discord.gg/CNcNpquyDc)... ```
That’s it. With just a couple of lines, you can turn any website into clean markdown, ready for LLM pipelines or further processing.
--- Chunkr Reader allows you to process PDFs (and other docs) in chunks, with built-in OCR and format control. Below is a basic usage pattern: Initialize the `ChunkrReader` and `ChunkrReaderConfig`, set the file path and chunking options, then submit your task and fetch results: ```python import asyncio from camel.loaders import ChunkrReader, ChunkrReaderConfig async def main(): chunkr = ChunkrReader() config = ChunkrReaderConfig( chunk_processing=512, # Example: target chunk length ocr_strategy="Auto", # Example: OCR strategy high_resolution=False # False for faster processing (old "Fast" model) ) # Replace with your actual file path. file_path = "/path/to/your/document.pdf" try: task_id = await chunkr.submit_task( file_path=file_path, chunkr_config=config, ) print(f"Task ID: {task_id}") # Poll and fetch the output. if task_id: task_output_json_str = await chunkr.get_task_output(task_id=task_id) if task_output_json_str: print("Task Output:") print(task_output_json_str) else: print(f"Failed to get output for task {task_id}, or task did not succeed/was cancelled.") except ValueError as e: print(f"An error occurred during task submission or retrieval: {e}") except FileNotFoundError: print(f"Error: File not found at {file_path}. Please check the path.") except Exception as e: print(f"An unexpected error occurred: {e}") if __name__ == "__main__": print("To run this example, replace '/path/to/your/document.pdf' with a real file path, ensure CHUNKR_API_KEY is set, and uncomment 'asyncio.run(main())'.") # asyncio.run(main()) # Uncomment to run the example ``` A successful task returns a chunked structure like this: ```markdown > > > Task ID: 7becf001-6f07-4f63-bddf-5633df363bbb > > > Task Output: > > > { "task_id": "7becf001-6f07-4f63-bddf-5633df363bbb", "status": "Succeeded", "created_at": "2024-11-08T12:45:04.260765Z", "finished_at": "2024-11-08T12:45:48.942365Z", "expires_at": null, "message": "Task succeeded", "output": { "chunks": [ { "segments": [ { "segment_id": "d53ec931-3779-41be-a220-3fe4da2770c5", "bbox": { "left": 224.16666, "top": 370.0, "width": 2101.6665, "height": 64.166664 }, "page_number": 1, "page_width": 2550.0, "page_height": 3300.0, "content": "Large Language Model based Multi-Agents: A Survey of Progress and Challenges", "segment_type": "Title", "ocr": null, "image": "https://chunkmydocs-bucket-prod.storage.googleapis.com/.../d53ec931-3779-41be-a220-3fe4da2770c5.jpg?...", "html": "

Large Language Model based Multi-Agents: A Survey of Progress and Challenges

", "markdown": "# Large Language Model based Multi-Agents: A Survey of Progress and Challenges\n\n" } ], "chunk_length": 11 }, { "segments": [ { "segment_id": "7bb38fc7-c1b3-4153-a3cc-116c0b9caa0a", "bbox": { "left": 432.49997, "top": 474.16666, "width": 1659.9999, "height": 122.49999 }, "page_number": 1, "page_width": 2550.0, "page_height": 3300.0, "content": "Taicheng Guo 1 , Xiuying Chen 2 , Yaqi Wang 3 \u2217 , Ruidi Chang , Shichao Pei 4 , Nitesh V. Chawla 1 , Olaf Wiest 1 , Xiangliang Zhang 1 \u2020", "segment_type": "Text", "ocr": null, "image": "https://chunkmydocs-bucket-prod.storage.googleapis.com/.../7bb38fc7-c1b3-4153-a3cc-116c0b9caa0a.jpg?...", "html": "

Taicheng Guo 1 , Xiuying Chen 2 , Yaqi Wang 3 \u2217 , Ruidi Chang , Shichao Pei 4 , Nitesh V. Chawla 1 , Olaf Wiest 1 , Xiangliang Zhang 1 \u2020

", "markdown": "Taicheng Guo 1 , Xiuying Chen 2 , Yaqi Wang 3 \u2217 , Ruidi Chang , Shichao Pei 4 , Nitesh V. Chawla 1 , Olaf Wiest 1 , Xiangliang Zhang 1 \u2020\n\n" } ], "chunk_length": 100 } ] } } ```
--- Jina Reader provides a convenient interface to extract clean, LLM-friendly content from any URL in a chosen format (like markdown): ```python from camel.loaders import JinaURLReader from camel.types.enums import JinaReturnFormat jina_reader = JinaURLReader(return_format=JinaReturnFormat.MARKDOWN) response = jina_reader.read_content("https://docs.camel-ai.org/") print(response) ``` --- MarkitDown Reader lets you convert files (like HTML or docs) into LLM-ready markdown with a single line. ```python from camel.loaders import MarkItDownLoader loader = MarkItDownLoader() response = loader.convert_file("demo.html") print(response) ``` Example output: ```markdown > > > Welcome to CAMEL’s documentation! — CAMEL 0.2.61 documentation [Skip to main content](https://docs.camel-ai.org/#main-content) ... ``` --- Mistral Reader offers OCR and text extraction from both PDFs and images, whether local or remote. Just specify the file path or URL: ```python from camel.loaders import MistralReader mistral_reader = MistralReader() # Extract text from a PDF URL url_ocr_response = mistral_reader.extract_text( file_path="https://arxiv.org/pdf/2201.04234", pages=[5] ) print(url_ocr_response) ``` You can also extract from images or local files: ```python # Extract text from an image URL image_ocr_response = mistral_reader.extract_text( file_path="https://raw.githubusercontent.com/mistralai/cookbook/refs/heads/main/mistral/ocr/receipt.png", is_image=True, ) print(image_ocr_response) ``` ```python # Extract text from a local PDF file local_ocr_response = mistral_reader.extract_text("path/to/your/document.pdf") print(local_ocr_response) ``` Response includes structured page data, markdown content, and usage details. ```markdown > > > pages=[OCRPageObject(index=5, markdown='![img-0.jpeg](./images/img-0.jpeg)\n\nFigure 2: Scatter plot of predicted accuracy versus (true) OOD accuracy. Each point denotes a dif...', > > > images=[OCRImageObject(id='img-0.jpeg', ...)], dimensions=OCRPageDimensions(...))] model='mistral-ocr-2505-completion' usage_info=... ``` --- --- title: "Memory" icon: memory --- The CAMEL Memory module gives your AI agents a flexible, persistent way to **store, retrieve, and manage information**, across any conversation or task. With memory, agents can maintain context, recall key details from previous chats, and deliver much more coherent, context-aware responses. Memory is what transforms a “chatbot” into a smart, adaptable assistant. This is the fastest way to enable true memory for your agents: store, retrieve, and leverage context across interactions. ```python from camel.memories import ( ChatHistoryBlock, LongtermAgentMemory, MemoryRecord, ScoreBasedContextCreator, VectorDBBlock, ) from camel.messages import BaseMessage from camel.types import ModelType, OpenAIBackendRole from camel.utils import OpenAITokenCounter # Initialize the memory memory = LongtermAgentMemory( context_creator=ScoreBasedContextCreator( token_counter=OpenAITokenCounter(ModelType.GPT_4O_MINI), token_limit=1024, ), chat_history_block=ChatHistoryBlock(), vector_db_block=VectorDBBlock(), ) # Create and write new records records = [ MemoryRecord( message=BaseMessage.make_user_message( role_name="User", meta_dict=None, content="What is CAMEL AI?", ), role_at_backend=OpenAIBackendRole.USER, ), MemoryRecord( message=BaseMessage.make_assistant_message( role_name="Agent", meta_dict=None, content="CAMEL-AI.org is the 1st LLM multi-agent framework and " "an open-source community dedicated to finding the scaling law " "of agents.", ), role_at_backend=OpenAIBackendRole.ASSISTANT, ), ] memory.write_records(records) # Get context for the agent context, token_count = memory.get_context() print(context) print(f"Retrieved context (token count: {token_count}):") for message in context: print(f"{message}") ``` ```markdown >>> Retrieved context (token count: 49): {'role': 'user', 'content': 'What is AI?'} {'role': 'assistant', 'content': 'AI refers to systems that mimic human intelligence.'} ``` Assign memory to any agent and watch your AI recall and reason like a pro. ```python from camel.agents import ChatAgent # Define system message for the agent sys_msg = BaseMessage.make_assistant_message( role_name='Agent', content='You are a curious agent wondering about the universe.', ) # Initialize agent agent = ChatAgent(system_message=sys_msg) # Set memory to the agent agent.memory = memory # Define a user message usr_msg = BaseMessage.make_user_message( role_name='User', content="Tell me which is the 1st LLM multi-agent framework based on what we have discussed", ) # Sending the message to the agent response = agent.step(usr_msg) # Check the response (just for illustrative purpose) print(response.msgs[0].content) ``` ```markdown >>> CAMEL AI is recognized as the first LLM (Large Language Model) multi-agent framework. It is an open-source community initiative focused on exploring the scaling laws of agents, enabling the development and interaction of multiple AI agents in a collaborative environment. This framework allows researchers and developers to experiment with various configurations and interactions among agents, facilitating advancements in AI capabilities and understanding. ``` **What it is:** The basic data unit in CAMEL’s memory system—everything stored/retrieved flows through this structure. **Attributes:** - **message**: The content, as a `BaseMessage` - **role_at_backend**: Backend role (`OpenAIBackendRole`) - **uuid**: Unique identifier for the record - **extra_info**: Optional metadata (key-value pairs) **Key methods:** - `from_dict()`: Build from a Python dict - `to_dict()`: Convert to dict for saving/serialization - `to_openai_message()`: Transform into an OpenAI message object **What it is:** Result of memory retrieval from `AgentMemory`, scored for context relevance. **Attributes:** - **memory_record**: The original `MemoryRecord` - **score**: How important/relevant this record is (float) **What it is:** The core “building block” for agent memory, following the Composite design pattern (supports tree structures). **Key methods:** - `write_records()`: Store multiple records - `write_record()`: Store a single record - `clear()`: Remove all stored records **What it is:** Defines strategies for generating agent context when data exceeds model limits. **Key methods/properties:** - `token_counter`: Counts message tokens - `token_limit`: Max allowed tokens in the context - `create_context()`: Algorithm for building context from chat history **What it is:** Specialized `MemoryBlock` for direct agent use. **Key methods:** - `retrieve()`: Get `ContextRecord` list - `get_context_creator()`: Return the associated context creator - `get_context()`: Return properly sized chat context **What it does:** Stores and retrieves recent chat history (like a conversation timeline). **Initialization:** - `storage`: Optional (default `InMemoryKeyValueStorage`) - `keep_rate`: Historical message score weighting (default `0.9`) **Methods:** - `retrieve()`: Get recent chats (windowed) - `write_records()`: Add new records - `clear()`: Remove all chat history **Use Case:** Best for maintaining the most recent conversation flow/context. **What it does:** Uses vector embeddings for storing and retrieving information based on semantic similarity. **Initialization:** - `storage`: Optional vector DB (`QdrantStorage` by default) - `embedding`: Embedding model (default: `OpenAIEmbedding`) **Methods:** - `retrieve()`: Get similar records based on query/keyword - `write_records()`: Add new records (converted to vectors) - `clear()`: Remove all vector records **Use Case:** Ideal for large histories or when semantic search is needed. **Key Differences:** - **Storage:** ChatHistoryBlock uses key-value storage. VectorDBBlock uses vector DBs. - **Retrieval:** ChatHistoryBlock retrieves by recency. VectorDBBlock retrieves by similarity. - **Data:** ChatHistoryBlock stores raw messages. VectorDBBlock stores embeddings. **What is it?** An **AgentMemory** implementation that wraps `ChatHistoryBlock`. **Best for:** Sequential, recent chat context (simple conversation memory). **Initialization:** - `context_creator`: `BaseContextCreator` - `storage`: Optional `BaseKeyValueStorage` - `window_size`: Optional `int` (retrieval window) **Methods:** - `retrieve()`: Get recent chat messages - `write_records()`: Write new records to chat history - `get_context_creator()`: Get the context creator - `clear()`: Remove all chat messages **What is it?** An **AgentMemory** implementation that wraps `VectorDBBlock`. **Best for:** Semantic search—find relevant messages by meaning, not just recency. **Initialization:** - `context_creator`: `BaseContextCreator` - `storage`: Optional `BaseVectorStorage` - `retrieve_limit`: `int` (default `3`) **Methods:** - `retrieve()`: Get relevant messages from the vector DB - `write_records()`: Write new records and update topic - `get_context_creator()`: Get the context creator **What is it?** Combines **ChatHistoryMemory** and **VectorDBMemory** for hybrid memory. **Best for:** Production bots that need both recency & semantic search. **Initialization:** - `context_creator`: `BaseContextCreator` - `chat_history_block`: Optional `ChatHistoryBlock` - `vector_db_block`: Optional `VectorDBBlock` - `retrieve_limit`: `int` (default `3`) **Methods:** - `retrieve()`: Get context from both history & vector DB - `write_records()`: Write to both chat history & vector DB - `get_context_creator()`: Get the context creator - `clear()`: Remove all records from both memory blocks Add [Mem0](https://mem0.ai/) for cloud-based memory with automatic sync. **Initialization Params:** - `api_key`: (optional) Mem0 API authentication - `agent_id`: (optional) Agent association - `user_id`: (optional) User association - `metadata`: (optional) Dict of metadata for all memories ```python from camel.memories import ChatHistoryMemory, ScoreBasedContextCreator from camel.storages import Mem0Storage from camel.types import ModelType from camel.utils import OpenAITokenCounter memory = ChatHistoryMemory( context_creator=ScoreBasedContextCreator( token_counter=OpenAITokenCounter(ModelType.GPT_4O_MINI), token_limit=1024, ), storage=Mem0Storage( api_key="your_mem0_api_key", # Or set MEM0_API_KEY env var agent_id="agent123" ), agent_id="agent123" ) # ...write and retrieve as usual... ``` ```markdown >>> Retrieved context (token count: 49): {'role': 'user', 'content': 'What is CAMEL AI?'} {'role': 'assistant', 'content': 'CAMEL-AI.org is the 1st LLM multi-agent framework and an open-source community dedicated to finding the scaling law of agents.'} ``` **Why use this?** - Cloud persistence of chat history - Simple setup and config - Sequential retrieval—conversation order preserved - Syncs across sessions automatically **Use when:** you need reliable, persistent chat history in the cloud (not advanced semantic search). You can subclass `BaseContextCreator` for advanced control. ```python from camel.memories import BaseContextCreator class MyCustomContextCreator(BaseContextCreator): @property def token_counter(self): # Implement your token counting logic return @property def token_limit(self): return 1000 def create_context(self, records): # Implement your context creation logic pass ``` You can use custom embeddings or vector DBs. ```python from camel.embeddings import OpenAIEmbedding from camel.memories import VectorDBBlock from camel.storages import QdrantStorage vector_db = VectorDBBlock( embedding=OpenAIEmbedding(), storage=QdrantStorage(vector_dim=OpenAIEmbedding().get_output_dim()), ) ``` - For production, use persistent storage (not just in-memory). - Optimize your context creator for both relevance and token count. --- --- title: "Messages" icon: messages --- The BaseMessage class is the backbone for all message objects in the CAMEL chat system. It offers a consistent structure for agent communication and easy conversion between message types. Explore and run every code sample directly in this Colab notebook. --- ## Get Started To create a BaseMessage instance, supply these arguments:
  • role_name: Name of the user or assistant
  • role_type: RoleType.ASSISTANT or RoleType.USER
  • content: The actual message text
  • meta_dict (optional): Additional metadata
  • video_bytes (optional): Attach video bytes
  • image_list (optional): List of PIL Image objects
  • image_detail (optional): Level of image detail (default: "auto")
  • video_detail (optional): Level of video detail (default: "low")
Example: ```python from camel.messages import BaseMessage from camel.types import RoleType message = BaseMessage( role_name="test_user", role_type=RoleType.USER, content="test content" ) ````
Easily create messages for user or assistant agents: ```python user_message = BaseMessage.make_user_message( role_name="user_name", content="test content for user", ) assistant_message = BaseMessage.make_assistant_message( role_name="assistant_name", content="test content for assistant", ) ```` --- ## Methods in the `BaseMessage` Class The BaseMessage class lets you:
  • Create a new instance with updated content:
    new_message = message.create_new_instance("new test content")
  • Convert to OpenAI message formats:
    openai_message = message.to_openai_message(role_at_backend=OpenAIBackendRole.USER)
    openai_system_message = message.to_openai_system_message()
    openai_user_message = message.to_openai_user_message()
    openai_assistant_message = message.to_openai_assistant_message()
  • Convert to a Python dictionary:
    message_dict = message.to_dict()
These methods allow you to transform a BaseMessage into the right format for different LLM APIs and agent flows.
--- ## Using `BaseMessage` with `ChatAgent` You can send multimodal messages (including images) to your agents: ```python from io import BytesIO import requests from PIL import Image from camel.agents import ChatAgent from camel.messages import BaseMessage # Download an image url = "https://raw.githubusercontent.com/camel-ai/camel/master/misc/logo_light.png" img = Image.open(BytesIO(requests.get(url).content)) # Build system and user messages sys_msg = BaseMessage.make_assistant_message( role_name="Assistant", content="You are a helpful assistant.", ) user_msg = BaseMessage.make_user_message( role_name="User", content="what's in the image?", image_list=[img] ) # Create agent and send message camel_agent = ChatAgent(system_message=sys_msg) response = camel_agent.step(user_msg) print(response.msgs[0].content) ``` The image features a logo for "CAMEL-AI." It includes a stylized purple camel graphic alongside the text "CAMEL-AI," which is also in purple. The design appears modern and is likely related to artificial intelligence. --- ## Conclusion The BaseMessage class is essential for structured, clear, and flexible communication in the CAMEL-AI ecosystem—making it simple to create, convert, and handle messages across any workflow. For further details, check out the key modules documentation. --- --- title: "Models" description: "CAMEL-AI: Flexible integration and deployment of top LLMs and multimodal models like [OpenAI](https://openai.com/), [Mistral](https://mistral.ai/), [Gemini](https://ai.google.dev/gemini-api/docs/models), [Llama](https://www.llama.com/), [Nebius](https://nebius.com/), and more." icon: gear-code --- In CAMEL, every model refers specifically to a Large Language Model (LLM) the intelligent core powering your agent's understanding, reasoning, and conversational capabilities. Play with different models in our [interactive Colab Notebook](https://colab.research.google.com/drive/18hQLpte6WW2Ja3Yfj09NRiVY-6S2MFu7?usp=sharing). LLMs are sophisticated AI systems trained on vast datasets to understand and generate human-like text. They reason, summarize, create content, and drive conversations effortlessly. CAMEL allows quick integration and swapping of leading LLMs from providers like OpenAI, Gemini, Llama, Anthropic, Nebius, and more, helping you match the best model to your task. Customize performance parameters such as temperature, token limits, and response structures easily, balancing creativity, accuracy, and efficiency. Experiment freely, CAMEL’s modular design lets you seamlessly compare and benchmark different LLMs, adapting swiftly as your project needs evolve. ## Supported Model Platforms in CAMEL CAMEL supports a wide range of models, including [OpenAI’s GPT series](https://platform.openai.com/docs/models), [Meta’s Llama models](https://www.llama.com/), [DeepSeek models](https://www.deepseek.com/) (R1 and other variants), and more. ### Direct Integrations | Model Provider | Model Type(s) | | :-------------- | :------------ | | **OpenAI** | gpt-4.5-preview
gpt-4o, gpt-4o-mini
o1, o1-preview, o1-mini
o3-mini, o3-pro, o3
o4-mini
gpt-4.1, gpt-4.1-mini, gpt-4.1-nano
gpt-5, gpt-5-mini, gpt-5-nano
gpt-4-turbo, gpt-4, gpt-3.5-turbo | | **Azure OpenAI** | gpt-4o, gpt-4-turbo
gpt-4, gpt-3.5-turbo | | **Mistral AI** | mistral-large-latest, pixtral-12b-2409
ministral-8b-latest, ministral-3b-latest
open-mistral-nemo, codestral-latest
open-mistral-7b, open-mixtral-8x7b
open-mixtral-8x22b, open-codestral-mamba
mistral-small-2506, mistral-medium-2508
magistral-small-1.2, magistral-medium-1.2 | | **Moonshot** | moonshot-v1-8k
moonshot-v1-32k
moonshot-v1-128k | | **Anthropic** | claude-2.1, claude-2.0, claude-instant-1.2
claude-3-opus-latest, claude-3-sonnet-20240229, claude-3-haiku-20240307
claude-3-5-sonnet-latest, claude-3-5-haiku-latest, claude-3-7-sonnet-latest
claude-sonnet-4-5, claude-sonnet-4-20250514, claude-opus-4-20250514, claude-opus-4-1-20250805 | | **Gemini** | gemini-2.5-pro, gemini-2.5-flash
gemini-2.0-flash, gemini-2.0-flash-thinking-exp
gemini-2.0-flash-lite| | **Lingyiwanwu** | yi-lightning, yi-large, yi-medium
yi-large-turbo, yi-vision, yi-medium-200k
yi-spark, yi-large-rag, yi-large-fc | | **Qwen** | qwen3-coder-plus, qwq-32b-preview, qwq-plus, qvq-72b-preview, qwen-max, qwen-plus, qwen-turbo, qwen-long
qwen-plus-latest, qwen-plus-2025-04-28, qwen-turbo-latest, qwen-turbo-2025-04-28
qwen-vl-max, qwen-vl-plus, qwen-vl-72b-instruct, qwen-math-plus, qwen-math-turbo, qwen-coder-turbo
qwen2.5-coder-32b-instruct, qwen2.5-72b-instruct, qwen2.5-32b-instruct, qwen2.5-14b-instruct | | **DeepSeek** | deepseek-chat
deepseek-reasoner | | **CometAPI** | **All models available on [CometAPI](https://api.cometapi.com/pricing)**
Including: gpt-5-chat-latest, gpt-5, gpt-5-mini, gpt-5-nano
claude-opus-4-1-20250805, claude-sonnet-4-20250514, claude-3-7-sonnet-latest
gemini-2.5-pro, gemini-2.5-flash, grok-4-0709, grok-3
deepseek-v3.1, deepseek-v3, deepseek-r1-0528, qwen3-30b-a3b | | **Nebius** | **All models available on [Nebius AI Studio](https://studio.nebius.com/)**
Including: gpt-oss-120b, gpt-oss-20b, GLM-4.5
DeepSeek V3 & R1, LLaMA, Mistral, and more | | **ZhipuAI** | glm-4, glm-4v, glm-4v-flash
glm-4v-plus-0111, glm-4-plus, glm-4-air
glm-4-air-0111, glm-4-airx, glm-4-long
glm-4-flashx, glm-zero-preview, glm-4-flash, glm-3-turbo | | **InternLM** | internlm3-latest, internlm3-8b-instruct
internlm2.5-latest, internlm2-pro-chat | | **Reka** | reka-core, reka-flash, reka-edge | | **COHERE** | command-r-plus, command-r, command-light, command, command-nightly | | **ERNIE** | ernie-x1-turbo-32k, ernie-x1-32k, ernie-x1-32k-preview
ernie-4.5-turbo-128k, ernie-4.5-turbo-32k
deepseek-v3, deepseek-r1, qwen3-235b-a22b | | **MiniMax** | MiniMax-M2, MiniMax-M2-Stable | ### API & Connector Platforms | Model Platform | Supported via API/Connector | | :-------------- | :-------------------------- | | **GROQ** | [supported models](https://console.groq.com/docs/models) | | **TOGETHER AI** | [supported models](https://docs.together.ai/docs/dedicated-models) | | **SambaNova** | [supported models](https://docs.sambanova.ai/cloud/docs/get-started/supported-models) | | **Ollama** | [supported models](https://ollama.com/library) | | **OpenRouter** | [supported models](https://openrouter.ai/models) | | **PPIO** | [supported models](https://ppio.com/model-api/console) | | **LiteLLM** | [supported models](https://docs.litellm.ai/docs/providers) | | **LMStudio** | [supported models](https://lmstudio.ai/models) | | **vLLM** | [supported models](https://docs.vllm.ai/en/latest/models/supported_models.html) | | **SGLANG** | [supported models](https://docs.sglang.ai/supported_models/generative_models.html ) | | **NetMind** | [supported models](https://www.netmind.ai/modelsLibrary) | | **NOVITA** | [supported models](https://novita.ai/models?utm_source=github_owl&utm_medium=github_readme&utm_campaign=github_link) | | **NVIDIA** | [supported models](https://docs.api.nvidia.com/nim/reference/llm-apis) | | **AIML** | [supported models](https://docs.aimlapi.com/api-overview/model-database/text-models) | | **ModelScope** | [supported models](https://www.modelscope.cn/docs/model-service/API-Inference/intro) | | **AWS Bedrock** | [supported models](https://us-west-2.console.aws.amazon.com/bedrock/home?region=us-west-2#/) | | **IBM WatsonX** | [supported models](https://jp-tok.dataplatform.cloud.ibm.com/samples?context=wx&tab=foundation-model) | | **Crynux** | [supported models](https://docs.crynux.ai/application-development/how-to-run-llm-using-crynux-network/supported-models) | | **SiliconFlow** | [supported models](https://cloud.siliconflow.cn/me/models) | | **AMD** | dvue-aoai-001-gpt-4.1 | | **Volcano** | [supported models](https://console.volcengine.com/ark) | | **Qianfan** | [supported models](https://cloud.baidu.com/doc/qianfan/s/rmh4stp0j) | ## How to Use Models via API Calls Integrate your favorite models into CAMEL-AI with straightforward Python calls. Choose a provider below to see how it’s done: Here's how you use OpenAI models such as GPT-4o-mini with CAMEL: ```python from camel.models import ModelFactory from camel.types import ModelPlatformType, ModelType from camel.configs import ChatGPTConfig from camel.agents import ChatAgent model = ModelFactory.create( model_platform=ModelPlatformType.OPENAI, model_type=ModelType.GPT_4O_MINI, model_config_dict=ChatGPTConfig(temperature=0.2).as_dict(), ) agent = ChatAgent( system_message="You are a helpful assistant.", model=model ) response = agent.step("Say hi to CAMEL AI community.") print(response.msg.content) ``` Using Google's Gemini models in CAMEL: - **Google AI Studio** ([Quick Start](https://aistudio.google.com/)): Try models quickly in a no-code environment. - **API Key Setup** ([Generate Key](https://aistudio.google.com/app/apikey)): Obtain your Gemini API key to start integration. - **Gemini API Docs** ([Deep Dive](https://ai.google.dev/gemini-api/docs)): Explore detailed Gemini API capabilities. ```python from camel.models import ModelFactory from camel.types import ModelPlatformType, ModelType from camel.configs import GeminiConfig from camel.agents import ChatAgent model = ModelFactory.create( model_platform=ModelPlatformType.GEMINI, model_type=ModelType.GEMINI_2_5_PRO, model_config_dict=GeminiConfig(temperature=0.2).as_dict(), ) agent = ChatAgent( system_message="You are a helpful assistant.", model=model ) response = agent.step("Say hi to CAMEL AI community.") print(response.msgs[0].content) ``` Integrate Mistral AI models like Mistral Medium into CAMEL: ```python from camel.models import ModelFactory from camel.types import ModelPlatformType, ModelType from camel.configs import MistralConfig from camel.agents import ChatAgent model = ModelFactory.create( model_platform=ModelPlatformType.MISTRAL, model_type=ModelType.MAGISTRAL_MEDIUM_1_2, model_config_dict=MistralConfig(temperature=0.0).as_dict(), ) agent = ChatAgent( system_message="You are a helpful assistant.", model=model ) response = agent.step("Say hi to CAMEL AI community.") print(response.msgs[0].content) ``` Leveraging Anthropic's Claude models within CAMEL: ```python from camel.models import ModelFactory from camel.types import ModelPlatformType, ModelType from camel.configs import AnthropicConfig from camel.agents import ChatAgent model = ModelFactory.create( model_platform=ModelPlatformType.ANTHROPIC, model_type=ModelType.CLAUDE_3_5_SONNET, model_config_dict=AnthropicConfig(temperature=0.2).as_dict(), ) agent = ChatAgent( system_message="You are a helpful assistant.", model=model ) response = agent.step("Say hi to CAMEL AI community.") print(response.msgs[0].content) ``` Leverage [CometAPI](https://api.cometapi.com/)'s unified access to multiple frontier AI models: - **CometAPI Platform** ([CometAPI](https://www.cometapi.com/?utm_source=camel-ai&utm_campaign=integration&utm_medium=integration&utm_content=integration)): - **API Key Setup**: Obtain your CometAPI key to start integration. - **OpenAI Compatible**: Use familiar OpenAI API patterns with advanced frontier models. ```python from camel.models import ModelFactory from camel.types import ModelPlatformType, ModelType from camel.configs import CometAPIConfig from camel.agents import ChatAgent model = ModelFactory.create( model_platform=ModelPlatformType.COMETAPI, model_type=ModelType.COMETAPI_GPT_5_CHAT_LATEST, model_config_dict=CometAPIConfig(temperature=0.2).as_dict(), ) agent = ChatAgent( system_message="You are a helpful assistant.", model=model ) response = agent.step("Say hi to CAMEL AI community.") print(response.msgs[0].content) ``` **Flexible Model Access:** You can use any model available on CometAPI by passing the model name as a string to `model_type`, even if it's not in the predefined enums. **Environment Variables:** ```bash export COMETAPI_KEY="your_cometapi_key_here" export COMETAPI_API_BASE_URL="https://api.cometapi.com/v1/" # Optional ``` **Model Support:** - **Complete Access:** All models available on [CometAPI](https://api.cometapi.com/) are supported - **Predefined Enums:** Common models like `COMETAPI_GPT_5_CHAT_LATEST`, `COMETAPI_CLAUDE_OPUS_4_1_20250805`, etc. - **String-based Access:** Use any model name directly as a string for maximum flexibility **Example with different models:** ```python # Access multiple frontier models through CometAPI models_to_try = [ ModelType.COMETAPI_GPT_5_CHAT_LATEST, ModelType.COMETAPI_GPT_5, ModelType.COMETAPI_GPT_5_MINI, ModelType.COMETAPI_CLAUDE_OPUS_4_1_20250805, ModelType.COMETAPI_CLAUDE_SONNET_4_20250514, ModelType.COMETAPI_CLAUDE_3_7_SONNET_LATEST, ModelType.COMETAPI_GEMINI_2_5_PRO, ModelType.COMETAPI_GEMINI_2_5_FLASH, ModelType.COMETAPI_GROK_4_0709, ModelType.COMETAPI_GROK_3, ModelType.COMETAPI_DEEPSEEK_V3_1, ModelType.COMETAPI_DEEPSEEK_V3, ModelType.COMETAPI_QWEN3_30B_A3B, ModelType.COMETAPI_QWEN3_CODER_PLUS_2025_07_22 ] for model_type in models_to_try: model = ModelFactory.create( model_platform=ModelPlatformType.COMETAPI, model_type=model_type ) # Use the model... ``` Leverage [Nebius AI Studio](https://nebius.com/)'s high-performance GPU cloud with OpenAI-compatible models: - **Nebius AI Studio** ([Platform](https://studio.nebius.com/)): Access powerful models through their cloud infrastructure. - **API Key Setup** ([Generate Key](https://studio.nebius.ai/settings/api-keys)): Obtain your Nebius API key to start integration. - **Nebius Docs** ([Documentation](https://nebius.com/docs/)): Explore detailed Nebius API capabilities. ```python from camel.models import ModelFactory from camel.types import ModelPlatformType, ModelType from camel.configs import NebiusConfig from camel.agents import ChatAgent model = ModelFactory.create( model_platform=ModelPlatformType.NEBIUS, model_type=ModelType.NEBIUS_GPT_OSS_120B, model_config_dict=NebiusConfig(temperature=0.2).as_dict(), ) agent = ChatAgent( system_message="You are a helpful assistant.", model=model ) response = agent.step("Say hi to CAMEL AI community.") print(response.msgs[0].content) ``` **Flexible Model Access:** You can use any model available on Nebius by passing the model name as a string to `model_type`, even if it's not in the predefined enums. **Environment Variables:** ```bash export NEBIUS_API_KEY="your_nebius_api_key" export NEBIUS_API_BASE_URL="https://api.studio.nebius.com/v1" # Optional ``` **Model Support:** - **Complete Access:** All models available on [Nebius AI Studio](https://studio.nebius.com/) are supported - **Predefined Enums:** Common models like `NEBIUS_GPT_OSS_120B`, `NEBIUS_DEEPSEEK_V3`, etc. - **String-based Access:** Use any model name directly as a string for maximum flexibility **Example with any model:** ```python # Use any model available on Nebius model = ModelFactory.create( model_platform=ModelPlatformType.NEBIUS, model_type="your-custom-model-name" # Any Nebius model ) ``` Leverage [Qwen](https://qwenlm.github.io/)'s state-of-the-art models for coding and reasoning: ```python from camel.models import ModelFactory from camel.types import ModelPlatformType, ModelType from camel.configs import QwenConfig from camel.agents import ChatAgent model = ModelFactory.create( model_platform=ModelPlatformType.QWEN, model_type=ModelType.QWEN_2_5_CODER_32B, model_config_dict=QwenConfig(temperature=0.2).as_dict(), ) agent = ChatAgent(system_message="You are a helpful assistant.", model=model) response = agent.step("Give me Python code to develop a trading bot.") print(response.msgs[0].content) ``` Access a wide variety of models through [OpenRouter](https://openrouter.ai/)'s unified API: **Setup:** Set your OpenRouter API key as an environment variable: ```bash export OPENROUTER_API_KEY="your-api-key-here" ``` ```python from camel.models import ModelFactory from camel.types import ModelPlatformType, ModelType from camel.configs import OpenRouterConfig from camel.agents import ChatAgent # Using predefined OpenRouter models model = ModelFactory.create( model_platform=ModelPlatformType.OPENROUTER, model_type=ModelType.OPENROUTER_LLAMA_3_1_70B, model_config_dict=OpenRouterConfig(temperature=0.2).as_dict(), ) agent = ChatAgent( system_message="You are a helpful assistant.", model=model ) response = agent.step("Say hi to CAMEL AI community.") print(response.msgs[0].content) ``` CAMEL supports several predefined OpenRouter models including: - `OPENROUTER_LLAMA_3_1_405B` - Meta's Llama 3.1 405B model - `OPENROUTER_LLAMA_3_1_70B` - Meta's Llama 3.1 70B model - `OPENROUTER_LLAMA_4_MAVERICK` - Meta's Llama 4 Maverick model - `OPENROUTER_LLAMA_4_SCOUT` - Meta's Llama 4 Scout model - `OPENROUTER_OLYMPICODER_7B` - Open R1's OlympicCoder 7B model - `OPENROUTER_HORIZON_ALPHA` - Horizon Alpha model Free versions are also available for some models (e.g., `OPENROUTER_LLAMA_4_MAVERICK_FREE`). You can also use any OpenRouter model via the OpenAI-compatible interface: ```python import os from camel.models import ModelFactory from camel.types import ModelPlatformType # Use any model available on OpenRouter model = ModelFactory.create( model_platform=ModelPlatformType.OPENAI_COMPATIBLE_MODEL, model_type="anthropic/claude-3.5-sonnet", # Any OpenRouter model url="https://openrouter.ai/api/v1", api_key=os.getenv("OPENROUTER_API_KEY"), model_config_dict={"temperature": 0.2}, ) agent = ChatAgent( system_message="You are a helpful assistant.", model=model ) response = agent.step("Explain quantum computing in simple terms.") print(response.msgs[0].content) ``` **Available Models:** View the full list of models available through OpenRouter at [openrouter.ai/models](https://openrouter.ai/models). Using [Groq](https://groq.com/)'s powerful models (e.g., Llama 3.3-70B): ```python from camel.models import ModelFactory from camel.types import ModelPlatformType, ModelType from camel.configs import GroqConfig from camel.agents import ChatAgent model = ModelFactory.create( model_platform=ModelPlatformType.GROQ, model_type=ModelType.GROQ_LLAMA_3_3_70B, model_config_dict=GroqConfig(temperature=0.2).as_dict(), ) agent = ChatAgent( system_message="You are a helpful assistant.", model=model ) response = agent.step("Say hi to CAMEL AI community.") print(response.msgs[0].content) ``` ## Using On-Device Open Source Models Unlock true flexibility: CAMEL-AI supports running popular LLMs right on your own machine. Use Ollama, vLLM, or SGLang to experiment, prototype, or deploy privately (no cloud required). CAMEL-AI makes it easy to integrate local open-source models as part of your agent workflows. Here’s how you can get started with the most popular runtimes: Download Ollama and follow the installation steps for your OS. ```bash ollama pull llama3 ``` Create a file named Llama3ModelFile: ``` FROM llama3 PARAMETER temperature 0.8 PARAMETER stop Result SYSTEM """ """ ``` You can also create a shell script setup_llama3.sh: ```bash #!/bin/zsh model_name="llama3" custom_model_name="camel-llama3" ollama pull $model_name ollama create $custom_model_name -f ./Llama3ModelFile chmod +x setup_llama3.sh ./setup_llama3.sh ``` ```python from camel.agents import ChatAgent from camel.models import ModelFactory from camel.types import ModelPlatformType ollama_model = ModelFactory.create( model_platform=ModelPlatformType.OLLAMA, model_type="llama3", url="http://localhost:11434/v1", model_config_dict={"temperature": 0.4}, ) agent = ChatAgent("You are a helpful assistant.", model=ollama_model) response = agent.step("Say hi to CAMEL") print(response.msg.content) ``` Follow the vLLM installation guide for your environment. ```bash python -m vllm.entrypoints.openai.api_server \ --model microsoft/Phi-3-mini-4k-instruct \ --api-key vllm --dtype bfloat16 ``` ```python from camel.agents import ChatAgent from camel.models import ModelFactory from camel.types import ModelPlatformType vllm_model = ModelFactory.create( model_platform=ModelPlatformType.VLLM, model_type="microsoft/Phi-3-mini-4k-instruct", url="http://localhost:8000/v1", model_config_dict={"temperature": 0.0}, ) agent = ChatAgent("You are a helpful assistant.", model=vllm_model) response = agent.step("Say hi to CAMEL AI") print(response.msg.content) ``` Follow the SGLang install instructions for your platform. ```python from camel.agents import ChatAgent from camel.models import ModelFactory from camel.types import ModelPlatformType sglang_model = ModelFactory.create( model_platform=ModelPlatformType.SGLANG, model_type="meta-llama/Llama-3.2-1B-Instruct", model_config_dict={"temperature": 0.0}, api_key="sglang", ) agent = ChatAgent("You are a helpful assistant.", model=sglang_model) response = agent.step("Say hi to CAMEL AI") print(response.msg.content) ``` Explore the full CAMEL-AI Examples library for advanced workflows, tool integrations, and multi-agent demos. ## Next Steps You’ve now seen how to connect, configure, and optimize models with CAMEL-AI. Learn how to create, format, and convert BaseMessage objects—the backbone of agent conversations in CAMEL-AI. --- --- title: "Prompts" icon: message-pen --- The prompt module in CAMEL guides AI models to produce accurate, relevant, and personalized outputs. It provides a library of templates and dictionaries for diverse tasks — like role description, code generation, evaluation, embeddings, and even object recognition.

You can also craft your own prompts to precisely shape your agent’s behavior.
## Using Prompt Templates CAMEL provides many ready-to-use prompt templates for quickly spinning up task-specific agents. ```python prompt_template.py from camel.agents import TaskSpecifyAgent from camel.configs import ChatGPTConfig from camel.models import ModelFactory from camel.types import ModelPlatformType, ModelType, TaskType model = ModelFactory.create( model_platform=ModelPlatformType.OPENAI, model_type=ModelType.GPT_4O_MINI, ) task_specify_agent = TaskSpecifyAgent( model=model, task_type=TaskType.AI_SOCIETY ) specified_task_prompt = task_specify_agent.run( task_prompt="Improving stage presence and performance skills", meta_dict=dict( assistant_role="Musician", user_role="Student", word_limit=100 ), ) print(f"Specified task prompt:\n{specified_task_prompt}\n") ``` ```markdown output >>> Musician will help Student enhance stage presence by practicing engaging eye contact, dynamic movement, and expressive gestures during a mock concert, followed by a review session with video playback to identify strengths and areas for improvement. ``` Set `task_type=TaskType.AI_SOCIETY` to use the default society prompt template, or define your own. ## Using Your Own Prompt Create and pass your own prompt template with full flexibility: ```python custom_prompt.py from camel.agents import TaskSpecifyAgent from camel.configs import ChatGPTConfig from camel.models import ModelFactory from camel.prompts import TextPrompt from camel.types import ModelPlatformType, ModelType model = ModelFactory.create( model_platform=ModelPlatformType.OPENAI, model_type=ModelType.GPT_4O_MINI, ) my_prompt_template = TextPrompt( 'Here is a task: I\'m a {occupation} and I want to {task}. Help me to make this task more specific.' ) task_specify_agent = TaskSpecifyAgent( model=model, task_specify_prompt=my_prompt_template ) response = task_specify_agent.run( task_prompt="get promotion", meta_dict=dict(occupation="Software Engineer"), ) print(response) ``` ```markdown output >>> Certainly! To make the task of getting a promotion more specific, you can break it down into actionable steps and set clear, measurable goals. Here’s a more detailed plan: 1. **Set Clear Objectives** - Identify the Promotion Criteria: Understand what skills, achievements, and experiences are required for the promotion. - Define Your Desired Position: Specify the role or title you are aiming for. 2. **Skill Development** - Technical Skills: Identify any technical skills that are necessary for the promotion and create a plan to acquire or improve them. - Soft Skills: Focus on improving soft skills such as leadership, communication, and teamwork. ``` ## Introduction to the `CodePrompt` Class The `CodePrompt` class represents a code prompt and extends `TextPrompt`. It’s perfect for code generation and execution tasks. ```python code_prompt_import.py from camel.prompts import CodePrompt ``` ### Creating a `CodePrompt` ```python code_prompt_create.py code_prompt = CodePrompt("a = 1 + 1", code_type="python") ``` ### Accessing and Modifying the Code and Type ```python code_prompt_access.py print(code_prompt) # >>> "a = 1 + 1" print(code_prompt.code_type) # >>> "python" code_prompt.set_code_type("python") print(code_prompt.code_type) # >>> "python" ``` ### Executing the Code ```python code_prompt_execute.py code_prompt = CodePrompt("a = 1 + 1\nb = a + 1\nprint(a,b)", code_type="python") output = code_prompt.execute() # Running code? [Y/n]: y print(output) # >>> 2 3 ``` ## Write Your Prompts with the `TextPrompt` Class The `TextPrompt` class is a subclass of Python’s `str`, with extra features for managing key words and advanced formatting. ```python text_prompt_intro.py from camel.prompts import TextPrompt prompt = TextPrompt('Please enter your name and age: {name}, {age}') print(prompt) # >>> 'Please enter your name and age: {name}, {age}' ``` ### The `key_words` Property ```python text_prompt_keywords.py from camel.prompts import TextPrompt prompt = TextPrompt('Please enter your name and age: {name}, {age}') print(prompt.key_words) # >>> {'name', 'age'} ``` ### The `format` Method (Partial Formatting Supported) ```python text_prompt_format.py from camel.prompts import TextPrompt prompt = TextPrompt('Your name and age are: {name}, {age}') name, age = 'John', 30 formatted_prompt = prompt.format(name=name, age=age) print(formatted_prompt) # >>> "Your name and age are: John, 30" # Partial formatting partial_formatted_prompt = prompt.format(name=name) print(partial_formatted_prompt) # >>> "Your name and age are: John, {age}" ``` ### Manipulating `TextPrompt` Instances You can concatenate, join, and use string methods with `TextPrompt` just like Python strings: ```python text_prompt_manipulation.py from camel.prompts import TextPrompt prompt1 = TextPrompt('Hello, {name}!') prompt2 = TextPrompt('Welcome, {name}!') # Concatenation prompt3 = prompt1 + ' ' + prompt2 print(prompt3) # >>> "Hello, {name}! Welcome, {name}!" print(isinstance(prompt3, TextPrompt)) # >>> True print(prompt3.key_words) # >>> {'name'} # Joining prompt4 = TextPrompt(' ').join([prompt1, prompt2]) print(prompt4) # >>> "Hello, {name}! Welcome, {name}!" print(isinstance(prompt4, TextPrompt)) # >>> True print(prompt4.key_words) # >>> {'name'} # String methods prompt5 = prompt4.upper() print(prompt5) # >>> "HELLO, {NAME}! WELCOME, {NAME}!" print(isinstance(prompt5, TextPrompt)) # >>> True print(prompt5.key_words) # >>> {'NAME'} ``` ## Supported Prompt Templates This class defines prompt templates for the AI Society role-playing and task handling workflow. **Templates include:** - GENERATE_ASSISTANTS: List roles the AI assistant can play. - GENERATE_USERS: List common user groups or occupations. - GENERATE_TASKS: List diverse tasks for assistants. - TASK_SPECIFY_PROMPT: Detail a task given assistant and user roles. - ASSISTANT_PROMPT: Rules for assistants to complete tasks. - USER_PROMPT: Rules for giving instructions to assistants. - CRITIC_PROMPT: Criteria for critics choosing among proposals. This class provides prompts for code-related tasks (language, domain, code task generation, and instructions for coders). **Templates include:** - GENERATE_LANGUAGES: List computer programming languages. - GENERATE_DOMAINS: List common programming domains. - GENERATE_TASKS: List tasks for programmers. - TASK_SPECIFY_PROMPT: Specify a programming-related task. - ASSISTANT_PROMPT: Rules for completing code tasks. - USER_PROMPT: User instructions for coding agents. Prompts for generating questions to evaluate knowledge. **Templates include:** - GENERATE_QUESTIONS: Create question sets for evaluating knowledge emergence, with optional field-specific examples. Prompts for generating text embedding tasks and synthetic data for embedding model improvement. **Templates include:** - GENERATE_TASKS: Generate synthetic text embedding tasks. - ASSISTANT_PROMPT: Generate synthetic queries (JSON), positive docs, and hard negatives. Prompts to test model alignment by introducing misleading or jailbreak tasks. **Templates include:** - DAN_PROMPT: Do-Anything-Now jailbreak prompt. - GENERATE_TASKS: List unique malicious tasks. - TASK_SPECIFY_PROMPT: Specify a malicious task in detail. - ASSISTANT_PROMPT: Rules for misaligned assistant tasks. - USER_PROMPT: User instructions in misalignment contexts. Prompts for object recognition tasks. **Templates include:** - ASSISTANT_PROMPT: Detect all objects in images, minimizing redundancy. Inherits from AISocietyPromptTemplateDict and adds prompts for describing roles and responsibilities. **Templates include:** - ROLE_DESCRIPTION_PROMPT: Explain roles and responsibilities for agents. Prompts to focus AI on finding solutions using particular knowledge. **Templates include:** - ASSISTANT_PROMPT: Rules for extracting and presenting solutions. Prompts for translation assistants (English → target language). **Templates include:** - ASSISTANT_PROMPT: Rules for completing translation tasks. Prompts for describing video content. **Templates include:** - ASSISTANT_PROMPT: Rules for generating video descriptions. --- --- title: "Retrievers" icon: code-compare --- ## What Are Retrievers? Retrievers are your AI search engine for large text collections or knowledge bases. They let you find the most relevant information based on a query—using either advanced embeddings (semantic search) or classic keyword matching. Want a deep dive? Check out the RAG Cookbook for advanced agent + retrieval use cases. ## Types of Retrievers Converts documents into vectors using an embedding model, stores them, and retrieves by semantic similarity. Best for “meaning-based” search, RAG, and LLM workflows.
  • Chunks data, embeds with OpenAI or custom model
  • Stores in vector DB (like Qdrant)
  • Finds the most relevant info even with different wording
Classic keyword search! Breaks documents and queries into tokens/keywords, and matches on those.
  • Tokenizes documents
  • Indexes by keyword
  • Fast, transparent, great for exact matches
## How To Use This example uses OpenAI embeddings and Qdrant vector storage for semantic search. ```python vector_retriever_setup.py from camel.embeddings import OpenAIEmbedding from camel.retrievers import VectorRetriever from camel.storages.vectordb_storages import QdrantStorage # Set up vector DB for embeddings vector_storage = QdrantStorage( vector_dim=OpenAIEmbedding().get_output_dim(), collection_name="my first collection", path="storage_customized_run", ) vr = VectorRetriever(embedding_model=OpenAIEmbedding(), storage=vector_storage) ``` ```python vector_retriever_ingest.py # Embed and store your data (URL or file) content_input_path = "https://www.camel-ai.org/" vr.process(content=content_input_path) ``` ```python vector_retriever_query.py # Run a query for semantic search query = "What is CAMEL" results = vr.query(query=query, similarity_threshold=0) print(results) ``` ```markdown vector_retriever_output.md >>> [{'similarity score': '0.81...', 'content path': 'https://www.camel-ai.org/', 'metadata': {...}, 'text': '...CAMEL-AI.org is an open-source community dedicated to the study of autonomous and communicative agents...'}] ``` AutoRetriever simplifies everything: just specify storage and content, and it handles embedding, storage, and querying. ```python auto_retriever.py from camel.retrievers import AutoRetriever from camel.types import StorageType ar = AutoRetriever( vector_storage_local_path="camel/retrievers", storage_type=StorageType.QDRANT, ) retrieved_info = ar.run_vector_retriever( contents=["https://www.camel-ai.org/"], # One or many URLs/files query="What is CAMEL-AI", return_detailed_info=True, ) print(retrieved_info) ``` ```markdown auto_retriever_output.md >>> Original Query: {What is CAMEL-AI} >>> Retrieved Context: >>> {'similarity score': '0.83...', 'content path': 'https://www.camel-ai.org/', 'metadata': {...}, 'text': 'Mission\n\nCAMEL-AI.org is an open-source community dedicated to the study of autonomous and communicative agents...'} ``` Use AutoRetriever for fast experiments and RAG workflows; for advanced control, use VectorRetriever directly. For simple, blazing-fast search by keyword—use KeywordRetriever. Great for small data, transparency, or keyword-driven tasks. *(API and code example coming soon—see RAG Cookbook for details.)* Build retrieval-augmented agents using these retrievers. Full configuration and options for all retriever classes. --- --- title: "Runtimes" description: "Flexible, secure, and scalable code execution with CAMEL’s runtime environments: guardrails, Docker, remote, and cloud sandboxes." icon: server --- CAMEL’s **runtime module** enables the secure, flexible, and isolated execution of tools and code. Runtimes allow agents to safely run functions in controlled environments—from in-process security checks to Docker isolation and remote/cloud sandboxes. ## What are Runtimes? Modern agent systems often require more than a simple interpreter. Runtimes provide safe, scalable execution via guardrails, isolation, or remote/cloud endpoints—ideal for complex or untrusted code.
Guardrail layer for safe function execution.
  • LLM-based risk scoring (1=safe, 3=unsafe)
  • Threshold control for blocking risky calls
  • Pre-configured safety system prompt/tool
Isolated, reproducible containers via Docker.
  • Sandbox tool execution for safety
  • FastAPI server for tool endpoints
  • Ubuntu flavor supports .py script execution, env vars, and more
Remote, distributed execution on HTTP servers.
  • Tool execution via FastAPI HTTP APIs
  • Distribute compute and offload risky code
  • Easy integration with remote endpoints
Cloud-managed sandboxing with Daytona SDK.
  • Secure remote sandbox per tool
  • Upload, run, and manage source code safely
  • Automated input/output handling
## Runtime Interface All runtimes inherit from BaseRuntime, which defines core methods: - add(funcs): Register one or more FunctionTool objects for execution - reset(): Reset the runtime to its initial state - get_tools(): List all tools managed by the runtime ## Quick Start Example: RemoteHttpRuntime Easily run tools in a remote FastAPI-based runtime—great for scaling, isolation, and experimentation.

```python from camel.runtimes import RemoteHttpRuntime from camel.toolkits import MathToolkit if __name__ == "__main__": runtime = ( RemoteHttpRuntime("localhost") .add(MathToolkit().get_tools(), "camel.toolkits.MathToolkit") .build() ) print("Waiting for runtime to be ready...") runtime.wait() print("Runtime is ready.") # There are more tools imported from MathToolkit. # For simplicity, we use only "add" tool here add = runtime.get_tools()[0] print(f"Add 1 + 2: {add.func(1, 2)}") # Example output: # Add 1 + 2: 3 ```
## Runtime Types: Key Features
  • Evaluates risk before executing functions or tool calls (risk scores 1-3)
  • Customizable LLM-driven safety logic
  • Blocks or allows function execution based on threshold
  • Runs CAMEL tools/agents in Docker containers for isolation and reproducibility
  • UbuntuDocker flavor adds support for full script execution and system-level configuration
  • Preconfigures PYTHON_EXECUTABLE, PYTHONPATH, and more for custom envs
  • Executes registered tools on a remote FastAPI server via HTTP endpoints
  • Ideal for distributed, scalable, or cross-server tool execution
  • Runs code in a managed, remote cloud sandbox using Daytona SDK
  • Uploads user code, executes with input/output capture
  • Safety and resource guarantees from cloud provider
## More Examples You’ll find runnable scripts for each runtime in [examples/runtime](https://github.com/camel-ai/camel/tree/master/examples/runtimes)/ in our main repo. Each script demonstrates how to initialize and use a specific runtime—perfect for experimentation or production setups. ## Final Note The runtime system primarily sandboxes FunctionTool-style tool functions. For agent-level, dynamic code execution, always consider dedicated sandboxing—such as UbuntuDockerRuntime’s exec_python_file()—for running dynamically generated scripts with maximum isolation and safety. --- --- title: "Societies" description: "Collaborative agent frameworks in CAMEL: autonomous social behaviors, role-based task solving, and turn-based agent societies." icon: people-group --- The society module simulates agent social behaviors and collaborative workflows.
It powers autonomous, multi-role agents that can plan, debate, critique, and solve tasks together, minimizing human intervention while maximizing alignment with your goals.
Task: An objective or idea, given as a simple prompt.
AI User: The role responsible for providing instructions or challenges.
AI Assistant: The role tasked with generating solutions, plans, or step-by-step responses.
Critic (optional): An agent that reviews or critiques the assistant's responses for quality control.

Turn-based, prompt-engineered, zero-role-flip agent collaboration.
  • Guards against role-flipping, infinite loops, vague responses
  • Structured, strict turn-taking—user and assistant never switch
  • Supports optional task planners, critics, and meta-reasoning
  • Every message follows a system-enforced structure
Built-in Prompt Rules:
  • Never forget you are <ASSISTANT_ROLE>, I am <USER_ROLE>
  • Never flip roles or instruct me
  • Decline impossible or unsafe requests, explain why
  • Always answer as: Solution: <YOUR_SOLUTION>
  • Always end with: Next request.
## 🧩 RolePlaying Attributes
Attribute Type Description
assistant_role_namestrName of assistant's role
user_role_namestrName of user's role
critic_role_namestrName of critic's role (optional)
task_promptstrPrompt for the main task
with_task_specifyboolEnable task specification agent
with_task_plannerboolEnable task planner agent
with_critic_in_the_loopboolInclude critic in conversation loop
critic_criteriastrHow the critic scores/evaluates outputs
modelBaseModelBackendModel backend for responses
task_typeTaskTypeType/category of the task
assistant_agent_kwargsDictExtra options for assistant agent
user_agent_kwargsDictExtra options for user agent
task_specify_agent_kwargsDictExtra options for task specify agent
task_planner_agent_kwargsDictExtra options for task planner agent
critic_kwargsDictExtra options for critic agent
sys_msg_generator_kwargsDictOptions for system message generator
extend_sys_msg_meta_dictsList[Dict]Extra metadata for system messages
extend_task_specify_meta_dictDictExtra metadata for task specification
output_languagestrTarget output language
assistant_agentChatAgentCustom ChatAgent to use as assistant (optional)
user_agentChatAgentCustom ChatAgent to use as user (optional)
Example: Turn-based multi-agent chat with custom roles and live output colors.

~~~python from colorama import Fore from camel.societies import RolePlaying from camel.utils import print_text_animated def main(model=None, chat_turn_limit=50) -> None: # Initialize a session for developing a trading bot task_prompt = "Develop a trading bot for the stock market" role_play_session = RolePlaying( assistant_role_name="Python Programmer", assistant_agent_kwargs=dict(model=model), user_role_name="Stock Trader", user_agent_kwargs=dict(model=model), task_prompt=task_prompt, with_task_specify=True, task_specify_agent_kwargs=dict(model=model), ) # Print initial system messages print( Fore.GREEN + f"AI Assistant sys message:\\n{role_play_session.assistant_sys_msg}\\n" ) print( Fore.BLUE + f"AI User sys message:\\n{role_play_session.user_sys_msg}\\n" ) print(Fore.YELLOW + f"Original task prompt:\\n{task_prompt}\\n") print( Fore.CYAN + "Specified task prompt:" + f"\\n{role_play_session.specified_task_prompt}\\n" ) print(Fore.RED + f"Final task prompt:\\n{role_play_session.task_prompt}\\n") n = 0 input_msg = role_play_session.init_chat() # Turn-based simulation while n < chat_turn_limit: n += 1 assistant_response, user_response = role_play_session.step(input_msg) if assistant_response.terminated: print( Fore.GREEN + ( "AI Assistant terminated. Reason: " f"{assistant_response.info['termination_reasons']}." ) ) break if user_response.terminated: print( Fore.GREEN + ( "AI User terminated. " f"Reason: {user_response.info['termination_reasons']}." ) ) break print_text_animated( Fore.BLUE + f"AI User:\\n\\n{user_response.msg.content}\\n" ) print_text_animated( Fore.GREEN + "AI Assistant:\\n\\n" f"{assistant_response.msg.content}\\n" ) if "CAMEL_TASK_DONE" in user_response.msg.content: break input_msg = assistant_response.msg if __name__ == "__main__": main() ~~~
  • Use RolePlaying for most multi-agent conversations, with or without a critic.
  • Define specific roles and prompt-guardrails for your agents—structure is everything!
  • Try BabyAGI when you want open-ended, research-oriented, or autonomous projects.
  • Leverage the with_task_specify and with_task_planner options for highly complex tasks.
  • Monitor for infinite loops—every agent response should have a clear next step or end.
  • Check [examples/society/](https://github.com/camel-ai/camel/tree/master/examples/runtimes) in the CAMEL repo for advanced agent society demos.
  • Explore critic-in-the-loop setups for higher accuracy and safety.
  • Integrate toolkits or external APIs into agent society loops for real-world workflows.
--- --- title: "Society" description: "Collaborative agent frameworks in CAMEL: autonomous social behaviors, role-based task solving, and turn-based agent societies." icon: people-group --- The society module simulates agent social behaviors and collaborative workflows.
It powers autonomous, multi-role agents that can plan, debate, critique, and solve tasks together, minimizing human intervention while maximizing alignment with your goals.
--- Task: An objective or idea, given as a simple prompt.
AI User: The role responsible for providing instructions or challenges.
AI Assistant: The role tasked with generating solutions, plans, or step-by-step responses.
Critic (optional): An agent that reviews or critiques the assistant's responses for quality control.

Frameworks:
  • RolePlaying — Advanced turn-taking, prompt-guarded collaboration (most common for LLM societies).
  • BabyAGI — Autonomous, open-ended R&D loops for big-picture or research goals.
--- ## 🤝 Frameworks
Turn-based, prompt-engineered, zero-role-flip agent collaboration.
  • Guards against role-flipping, infinite loops, vague responses
  • Structured, strict turn-taking—user and assistant never switch
  • Supports optional task planners, critics, and meta-reasoning
  • Every message follows a system-enforced structure
Built-in Prompt Rules:
  • Never forget you are <ASSISTANT_ROLE>, I am <USER_ROLE>
  • Never flip roles or instruct me
  • Decline impossible or unsafe requests, explain why
  • Always answer as: Solution: <YOUR_SOLUTION>
  • Always end with: Next request.
Task-driven, fully autonomous project agent
Based on BabyAGI, with seamless CAMEL integration.
  • Self-driven research, R&D, and iterative problem-solving
  • Builds, updates, and executes dynamic task lists
  • Minimal initial human input—agents break down and solve tasks
--- ## 🧩 RolePlaying Attributes
Attribute Type Description
assistant_role_namestrName of assistant's role
user_role_namestrName of user's role
critic_role_namestrName of critic's role (optional)
task_promptstrPrompt for the main task
with_task_specifyboolEnable task specification agent
with_task_plannerboolEnable task planner agent
with_critic_in_the_loopboolInclude critic in conversation loop
critic_criteriastrHow the critic scores/evaluates outputs
modelBaseModelBackendModel backend for responses
task_typeTaskTypeType/category of the task
assistant_agent_kwargsDictExtra options for assistant agent
user_agent_kwargsDictExtra options for user agent
task_specify_agent_kwargsDictExtra options for task specify agent
task_planner_agent_kwargsDictExtra options for task planner agent
critic_kwargsDictExtra options for critic agent
sys_msg_generator_kwargsDictOptions for system message generator
extend_sys_msg_meta_dictsList[Dict]Extra metadata for system messages
extend_task_specify_meta_dictDictExtra metadata for task specification
output_languagestrTarget output language
--- Example: Turn-based multi-agent chat with custom roles and live output colors.

~~~python from colorama import Fore from camel.societies import RolePlaying from camel.utils import print_text_animated def main(model=None, chat_turn_limit=50) -> None: # Initialize a session for developing a trading bot task_prompt = "Develop a trading bot for the stock market" role_play_session = RolePlaying( assistant_role_name="Python Programmer", assistant_agent_kwargs=dict(model=model), user_role_name="Stock Trader", user_agent_kwargs=dict(model=model), task_prompt=task_prompt, with_task_specify=True, task_specify_agent_kwargs=dict(model=model), ) # Print initial system messages print( Fore.GREEN + f"AI Assistant sys message:\\n{role_play_session.assistant_sys_msg}\\n" ) print( Fore.BLUE + f"AI User sys message:\\n{role_play_session.user_sys_msg}\\n" ) print(Fore.YELLOW + f"Original task prompt:\\n{task_prompt}\\n") print( Fore.CYAN + "Specified task prompt:" + f"\\n{role_play_session.specified_task_prompt}\\n" ) print(Fore.RED + f"Final task prompt:\\n{role_play_session.task_prompt}\\n") n = 0 input_msg = role_play_session.init_chat() # Turn-based simulation while n < chat_turn_limit: n += 1 assistant_response, user_response = role_play_session.step(input_msg) if assistant_response.terminated: print( Fore.GREEN + ( "AI Assistant terminated. Reason: " f"{assistant_response.info['termination_reasons']}." ) ) break if user_response.terminated: print( Fore.GREEN + ( "AI User terminated. " f"Reason: {user_response.info['termination_reasons']}." ) ) break print_text_animated( Fore.BLUE + f"AI User:\\n\\n{user_response.msg.content}\\n" ) print_text_animated( Fore.GREEN + "AI Assistant:\\n\\n" f"{assistant_response.msg.content}\\n" ) if "CAMEL_TASK_DONE" in user_response.msg.content: break input_msg = assistant_response.msg if __name__ == "__main__": main() ~~~
--- Autonomous project agent—no human in the loop.
Original BabyAGI repo
  • Designed for long-horizon, open-ended R&D
  • Automatically breaks down, plans, and solves complex tasks
  • Integrates with CAMEL's toolkit system for supercharged capabilities
--- a\
  • Use RolePlaying for most multi-agent conversations, with or without a critic.
  • Define specific roles and prompt-guardrails for your agents—structure is everything!
  • Try BabyAGI when you want open-ended, research-oriented, or autonomous projects.
  • Leverage the with_task_specify and with_task_planner options for highly complex tasks.
  • Monitor for infinite loops—every agent response should have a clear next step or end.
  • Check [examples/society/](https://github.com/camel-ai/camel/tree/master/examples/runtimes) in the CAMEL repo for advanced agent society demos.
  • Explore critic-in-the-loop setups for higher accuracy and safety.
  • Integrate toolkits or external APIs into agent society loops for real-world workflows.
--- --- title: "Storages" icon: database --- ## What Are Storages in CAMEL-AI? The Storage module in CAMEL-AI gives you a **unified interface for saving, searching, and managing your data** from simple key-value records to high-performance vector databases and modern graph engines. It’s your plug-and-play toolkit for building robust, AI-ready storage layers. --- ## Types of Storages **BaseKeyValueStorage** - Abstract base for all key-value storage backends. - **Standardizes:** Save, load, clear operations. - **Interface:** Python dicts. - **Use cases:** - JSON file storage - NoSQL (MongoDB, Redis) - In-memory caches **InMemoryKeyValueStorage** - Fast, simple, *not persistent* (resets on restart) - Ideal for caching, development, or quick prototyping **JsonStorage** - Human-readable, portable JSON file storage - Supports custom JSON encoder (for Enums, etc) - Good for configs, small persistent datasets, export/import flows **BaseVectorStorage** - Abstract base for vector database backends - **Core operations:** Add/query/delete vectors, check DB status - **Customizable:** Vector dimensions, collections, distance metrics **MilvusStorage** - For [Milvus](https://milvus.io/docs/overview.md/) (cloud-native vector search engine) - High scalability, real-time search **TiDBStorage** - For [TiDB](https://pingcap.com/ai) (hybrid vector/relational database) - Handles embeddings, knowledge graphs, ops data **QdrantStorage** - For [Qdrant](https://qdrant.tech/) (open-source vector DB) - Fast similarity search for AI/ML **OceanBaseStorage** - For [OceanBase](https://www.oceanbase.com/) (cloud and on-prem vector DB) - Supports large-scale, distributed deployments **WeaviateStorage** - For [Weaviate](https://weaviate.io/) (open-source vector engine) - Schema-based, semantic search, hybrid queries **ChromaStorage** - For [ChromaDB](https://www.trychroma.com/) (AI-native open-source embedding database) - Simple API, scales from notebook to production **SurrealStorage** - For [SurrealDB](https://surrealdb.com/) (scalable, distributed database with WebSocket support) - Efficient vector storage and similarity search with real-time updates **PgVectorStorage** - For [PostgreSQL with pgvector](https://github.com/pgvector/pgvector) (open-source vector engine) - Leverages PostgreSQL for vector search **BaseGraphStorage** - Abstract base for graph database integrations - **Supports:** - Schema queries and refresh - Adding/deleting/querying triplets **NebulaGraph** - For [NebulaGraph](https://www.nebula-graph.io/) (distributed, high-performance graph DB) - Scalable, open source **Neo4jGraph** - For [Neo4jGraph](https://neo4j.com/) (most popular enterprise graph DB) - Widely used for graph analytics, recommendations ## Get Started Here are practical usage patterns for each storage type—pick the ones you need and mix them as you like. --- Use for: Fast, temporary storage. Data is lost when your program exits. Perfect for: Prototyping, testing, in-memory caching. ```python from camel.storages.key_value_storages import InMemoryKeyValueStorage memory_storage = InMemoryKeyValueStorage() memory_storage.save([{'key1': 'value1'}, {'key2': 'value2'}]) records = memory_storage.load() print(records) memory_storage.clear() ``` ```markdown >>> [{'key1': 'value1'}, {'key2': 'value2'}] ``` --- Use for: Persistent, human-readable storage on disk. Perfect for: Logs, local settings, configs, or sharing small data sets. ```python from camel.storages.key_value_storages import JsonStorage from pathlib import Path json_storage = JsonStorage(Path("my_data.json")) json_storage.save([{'key1': 'value1'}, {'key2': 'value2'}]) records = json_storage.load() print(records) json_storage.clear() ``` ```markdown >>> [{'key1': 'value1'}, {'key2': 'value2'}] ``` --- Use for: Scalable, high-performance vector search (RAG, embeddings). Perfect for: Semantic search and production AI retrieval. ```python from camel.storages import MilvusStorage, VectorDBQuery, VectorRecord milvus_storage = MilvusStorage( url_and_api_key=("Your Milvus URI","Your Milvus Token"), vector_dim=4, collection_name="my_collection" ) milvus_storage.add([ VectorRecord(vector=[-0.1, 0.1, -0.1, 0.1], payload={'key1': 'value1'}), VectorRecord(vector=[-0.1, 0.1, 0.1, 0.1], payload={'key2': 'value2'}), ]) milvus_storage.load() query_results = milvus_storage.query(VectorDBQuery(query_vector=[0.1, 0.2, 0.1, 0.1], top_k=1)) for result in query_results: print(result.record.payload, result.similarity) milvus_storage.clear() ``` ```markdown >>> {'key2': 'value2'} 0.5669466853141785 ``` --- Use for: Hybrid cloud-native storage, vectors + SQL in one. Perfect for: Combining AI retrieval with your business database. ```python import os from camel.storages import TiDBStorage, VectorDBQuery, VectorRecord os.environ["TIDB_DATABASE_URL"] = "The database url of your TiDB cluster." tidb_storage = TiDBStorage( url_and_api_key=(os.getenv("DATABASE_URL"), ''), vector_dim=4, collection_name="my_collection" ) tidb_storage.add([ VectorRecord(vector=[-0.1, 0.1, -0.1, 0.1], payload={'key1': 'value1'}), VectorRecord(vector=[-0.1, 0.1, 0.1, 0.1], payload={'key2': 'value2'}), ]) tidb_storage.load() query_results = tidb_storage.query(VectorDBQuery(query_vector=[0.1, 0.2, 0.1, 0.1], top_k=1)) for result in query_results: print(result.record.payload, result.similarity) tidb_storage.clear() ``` ```markdown >>> {'key2': 'value2'} 0.5669466755703252 ``` Use for: Fast, scalable open-source vector search. Perfect for: RAG, document search, and high-scale retrieval tasks. ```python from camel.storages import QdrantStorage, VectorDBQuery, VectorRecord # Create an instance of QdrantStorage with dimension = 4 qdrant_storage = QdrantStorage(vector_dim=4, collection_name="my_collection") # Add two vector records qdrant_storage.add([ VectorRecord(vector=[-0.1, 0.1, -0.1, 0.1], payload={'key1': 'value1'}), VectorRecord(vector=[-0.1, 0.1, 0.1, 0.1], payload={'key2': 'value2'}), ]) # Query similar vectors query_results = qdrant_storage.query(VectorDBQuery(query_vector=[0.1, 0.2, 0.1, 0.1], top_k=1)) for result in query_results: print(result.record.payload, result.similarity) # Clear all vectors qdrant_storage.clear() ``` ```markdown >>> {'key2': 'value2'} 0.5669467095138407 ``` --- Use for: Fastest way to build LLM apps with memory and embeddings. Perfect for: From prototyping in notebooks to production clusters with the same simple API. ```python from camel.storages import ChromaStorage, VectorDBQuery, VectorRecord from camel.types import VectorDistance # Create ChromaStorage instance with ephemeral (in-memory) client chroma_storage = ChromaStorage( vector_dim=4, collection_name="camel_example_vectors", client_type="ephemeral", # or "persistent", "http", "cloud" distance=VectorDistance.COSINE, ) # Add vector records chroma_storage.add([ VectorRecord(vector=[-0.1, 0.1, -0.1, 0.1], payload={'key1': 'value1'}), VectorRecord(vector=[-0.1, 0.1, 0.1, 0.1], payload={'key2': 'value2'}), ]) # Query similar vectors query_results = chroma_storage.query(VectorDBQuery(query_vector=[0.1, 0.2, 0.1, 0.1], top_k=1)) for result in query_results: print(result.record.payload, result.similarity) # Clear all vectors chroma_storage.clear() ``` ```markdown >>> {'key2': 'value2'} 0.7834733426570892 ``` --- Use for: Scalable, distributed vector storage with WebSocket support. Perfect for: Real-time vector search with distributed deployments and SQL-like querying. ```python import os from camel.storages import SurrealStorage, VectorDBQuery, VectorRecord # Set environment variables for SurrealDB connection os.environ["SURREAL_URL"] = "ws://localhost:8000/rpc" os.environ["SURREAL_PASSWORD"] = "your_password" # Create SurrealStorage instance with WebSocket connection surreal_storage = SurrealStorage( url=os.getenv("SURREAL_URL"), table="camel_vectors", namespace="ns", database="db", user="root", password=os.getenv("SURREAL_PASSWORD"), vector_dim=4, ) # Add vector records surreal_storage.add([ VectorRecord(vector=[-0.1, 0.1, -0.1, 0.1], payload={'key1': 'value1'}), VectorRecord(vector=[-0.1, 0.1, 0.1, 0.1], payload={'key2': 'value2'}), ]) # Query similar vectors query_results = surreal_storage.query(VectorDBQuery(query_vector=[0.1, 0.2, 0.1, 0.1], top_k=1)) for result in query_results: print(result.record.payload, result.similarity) # Clear all vectors surreal_storage.clear() ``` ```markdown >>> {'key2': 'value2'} 0.5669467095138407 ``` --- Use for: Massive vector storage with advanced analytics. Perfect for: Batch operations, cloud or on-prem setups, and high-throughput search. ```python import random from camel.storages.vectordb_storages import ( OceanBaseStorage, VectorDBQuery, VectorRecord, ) # Replace these with your OceanBase connection parameters OB_URI = "127.0.0.1:2881" OB_USER = "root@sys" OB_PASSWORD = "" OB_DB_NAME = "oceanbase" def main(): ob_storage = OceanBaseStorage( vector_dim=4, table_name="my_ob_vector_table", uri=OB_URI, user=OB_USER, password=OB_PASSWORD, db_name=OB_DB_NAME, distance="cosine", ) status = ob_storage.status() print(f"Vector dimension: {status.vector_dim}") print(f"Initial vector count: {status.vector_count}") random.seed(20241023) large_batch = [] for i in range(1000): large_batch.append( VectorRecord( vector=[random.uniform(-1, 1) for _ in range(4)], payload={'idx': i, 'batch': 'example'}, ) ) ob_storage.add(large_batch, batch_size=100) status = ob_storage.status() print(f"Vector count after adding batch: {status.vector_count}") query_vector = [random.uniform(-1, 1) for _ in range(4)] query_results = ob_storage.query( VectorDBQuery(query_vector=query_vector, top_k=5) ) for i, result in enumerate(query_results): print(f"Result {i+1}:") print(f" ID: {result.record.id}") print(f" Payload: {result.record.payload}") print(f" Similarity: {result.similarity}") ob_storage.clear() status = ob_storage.status() print(f"Vector count after clearing: {status.vector_count}") if __name__ == "__main__": main() ``` ```markdown ''' =============================================================================== Vector dimension: 4 Initial vector count: 0 Adding vectors in batches... Vector count after adding batch: 1000 Querying similar vectors... Result 1: ID: f33f008d-688a-468a-9a2d-e005d27ad9d9 Payload: {'idx': 496, 'batch': 'example'} Similarity: 0.9847431876706196 Result 2: ID: 0946ca4a-9129-4343-b339-b2f13a64c827 Payload: {'idx': 306, 'batch': 'example'} Similarity: 0.9598140307734809 ... Clearing vectors... Vector count after clearing: 0 =============================================================================== ''' ``` --- Use for: Vector search with hybrid (vector + keyword) capabilities. Perfect for: Document retrieval and multimodal AI apps. ```python from camel.storages import WeaviateStorage, VectorDBQuery, VectorRecord # Create WeaviateStorage instance with dimension = 4 using Weaviate Cloud weaviate_storage = WeaviateStorage( vector_dim=4, collection_name="camel_example_vectors", connection_type="cloud", wcd_cluster_url="your-weaviate-cloud-url", wcd_api_key="your-weaviate-api-key", vector_index_type="hnsw", distance_metric="cosine", ) weaviate_storage.add([ VectorRecord(vector=[-0.1, 0.1, -0.1, 0.1], payload={'key1': 'value1'}), VectorRecord(vector=[-0.1, 0.1, 0.1, 0.1], payload={'key2': 'value2'}), ]) query_results = weaviate_storage.query(VectorDBQuery(query_vector=[0.1, 0.2, 0.1, 0.1], top_k=1)) for result in query_results: print(result.record.payload, result.similarity) weaviate_storage.clear() ``` ```markdown >>> {'key2': 'value2'} 0.7834733128547668 ``` --- Use for: Open-source, distributed graph storage and querying. Perfect for: Knowledge graphs, relationships, and fast distributed queries. ```python from camel.storages.graph_storages import NebulaGraph nebula_graph = NebulaGraph("your_host", "your_username", "your_password", "your_space") # Show existing tags query = 'SHOW TAGS;' print(nebula_graph.query(query)) ``` --- Use for: Industry-standard graph database for large-scale relationships. Perfect for: Enterprise graph workloads, Cypher queries, analytics. ```python from camel.storages import Neo4jGraph neo4j_graph = Neo4jGraph( url="your_url", username="your_username", password="your_password", ) query = "MATCH (n) DETACH DELETE n" print(neo4j_graph.query(query)) ``` --- Use for: Storing and querying vectors in PostgreSQL. Perfect for: Leveraging an existing PostgreSQL database for vector search. ```python from camel.storages import PgVectorStorage, VectorDBQuery, VectorRecord # Replace with your PostgreSQL connection details PG_CONN_INFO = { "host": "127.0.0.1", "port": 5432, "user": "postgres", "password": "postgres", "dbname": "postgres", } # Create PgVectorStorage instance pg_storage = PgVectorStorage( vector_dim=4, conn_info=PG_CONN_INFO, table_name="camel_example_vectors", ) # Add vector records pg_storage.add([ VectorRecord(vector=[-0.1, 0.1, -0.1, 0.1], payload={'key1': 'value1'}), VectorRecord(vector=[-0.1, 0.1, 0.1, 0.1], payload={'key2': 'value2'}), ]) # Query similar vectors query_results = pg_storage.query(VectorDBQuery(query_vector=[0.1, 0.2, 0.1, 0.1], top_k=1)) for result in query_results: print(result.record.payload, result.similarity) # Clear all vectors pg_storage.clear() ``` ```markdown >>> {'key2': 'value2'} 0.5669467 ``` --- --- title: "Tasks" icon: list-check --- For more detailed usage information, please refer to our cookbook: [Task Generation Cookbook](../cookbooks/multi_agent_society/task_generation.ipynb) A task in CAMEL is a structured assignment that can be given to one or more agents. Tasks are higher-level than prompts and managed by modules like the Planner and Workforce. Key ideas:
- Tasks can be collaborative, requiring multiple agents.
- Tasks can be decomposed into subtasks or evolved over time.
## Task Attributes | Attribute | Type | Description | | ----- | ----- | ----- | | content | string | A clear and concise description of the task at hand. | | id | string | A unique string identifier for the task. | | state | Enum | The task states: "OPEN", "RUNNING", "DONE", "FAILED", "DELETED". | | type | string | The type of a task. (TODO) | | parent | Task | The parent task. | | subtasks | A list of Task | Subtasks related to the original Task. | | result | string | The Task result. | ## Task Methods | Method | Type | Description | | ----- | ----- | ----- | | from_message | classmethod | Load Task from Message. | | to_message | classmethod | Convert Task to Message. | | reset | instance | Reset Task to initial state. | | update_result | instance | Set task result and mark the task as DONE. | | set_id | instance | Set task id. | | set_state | instance | Recursively set the state of the task and its subtasks. | | add_subtask | instance | Add a child task. | | remove_subtask | instance | Delete a subtask by id. | | get_running_task | instance | Get a RUNNING task. | | to_string | instance | Convert task to a string. | | get_result | instance | Get task result as a string. | | decompose | instance | Decompose a task to a list of subtasks. | | compose | instance | Compose task result by subtasks. | | get_depth | instance | Get task depth; root depth is 1. | Defining a task is simple: specify its content and a unique ID. ```python task_example.py from camel.tasks import Task task = Task( content="Weng earns $12 an hour for babysitting. Yesterday, she just did 51 minutes of babysitting. How much did she earn?", id="0", ) ``` You can build nested, hierarchical tasks using subtasks. Here’s an example: ```python tasks_hierarchical.py # Creating the root task root_task = Task(content="Prepare a meal", id="0") # Creating subtasks for the root task sub_task_1 = Task(content="Shop for ingredients", id="1") sub_task_2 = Task(content="Cook the meal", id="2") sub_task_3 = Task(content="Set the table", id="3") # Creating subtasks under "Cook the meal" sub_task_2_1 = Task(content="Chop vegetables", id="2.1") sub_task_2_2 = Task(content="Cook rice", id="2.2") # Adding subtasks to their respective parent tasks root_task.add_subtask(sub_task_1) root_task.add_subtask(sub_task_2) root_task.add_subtask(sub_task_3) sub_task_2.add_subtask(sub_task_2_1) sub_task_2.add_subtask(sub_task_2_2) # Printing the hierarchical task structure print(root_task.to_string()) ``` ```markdown output >>> Task 0: Prepare a meal Task 1: Shop for ingredients Task 2: Cook the meal Task 2.1: Chop vegetables Task 2.2: Cook rice Task 3: Set the table ``` ## Decomposing and Composing a Task You can break down (decompose) a task into smaller subtasks, or compose the results from subtasks. Typically, you define an agent, prompt template, and response parser. ```python task_decompose.py from camel.agents import ChatAgent from camel.tasks import Task from camel.tasks.task_prompt import ( TASK_COMPOSE_PROMPT, TASK_DECOMPOSE_PROMPT, ) from camel.messages import BaseMessage sys_msg = BaseMessage.make_assistant_message( role_name="Assistant", content="You're a helpful assistant" ) # Set up an agent agent = ChatAgent(system_message=sys_msg) task = Task( content="Weng earns $12 an hour for babysitting. Yesterday, she just did 51 minutes of babysitting. How much did she earn?", id="0", ) new_tasks = task.decompose(agent=agent) for t in new_tasks: print(t.to_string()) ``` ```markdown output >>> Task 0.0: Convert 51 minutes into hours. Task 0.1: Calculate Weng's earnings for the converted hours at the rate of $12 per hour. Task 0.2: Provide the final earnings amount based on the calculation. ``` ```python task_compose.py # Compose task result by the sub-tasks. task.compose(agent=agent, template=TASK_COMPOSE_PROMPT) print(task.result) ``` ## TaskManager The TaskManager class helps you manage, sort, and evolve tasks—handling dependencies and progression automatically. | Method | Type | Description | | ----- | ----- | ----- | | topological_sort | instance | Sort a list of tasks topologically. | | set_tasks_dependence | instance | Set relationship between root task and other tasks (serial or parallel). | | evolve | instance | Evolve a task to a new task; used for data generation. | ```python task_manager_example.py from camel.tasks import ( Task, TaskManager, ) from camel.agents import ChatAgent sys_msg = "You're a helpful assistant" agent = ChatAgent(system_message=sys_msg) task = Task( content="Weng earns $12 an hour for babysitting. Yesterday, she just did 51 minutes of babysitting. How much did she earn?", id="0", ) print(task.to_string()) ``` ```markdown output >>>Task 0: Weng earns $12 an hour for babysitting. Yesterday, she just did 51 minutes of babysitting. How much did she earn? ``` ```python task_manager_evolve.py task_manager = TaskManager(task) evolved_task = task_manager.evolve(task, agent=agent) print(evolved_task.to_string()) ``` ```markdown output >>>Task 0.0: Weng earns $12 an hour for babysitting. Yesterday, she babysat for 1 hour and 45 minutes. If she also received a $5 bonus for exceptional service, how much did she earn in total for that day? ``` CAMEL offers a powerful, structured approach to task management. With support for task decomposition, composition, and deep hierarchies, you can automate everything from simple workflows to complex, multi-agent projects. Efficient, collaborative, and easy to integrate—this is next-level task orchestration for AI. --- --- title: "Terminal Toolkit" icon: "terminal" --- The Terminal Toolkit provides a secure and powerful way for CAMEL agents to interact with a terminal. It allows agents to execute shell commands, manage files, and even ask for human help, all within a controlled, sandboxed environment. All file-writing and execution commands are restricted to a designated `working_directory` to prevent unintended system modifications. Dangerous commands are blocked by default. Run multiple, independent terminal sessions concurrently. Each session maintains its own state and history, allowing for complex, parallel workflows. Automatically create and manage isolated Python virtual environments, ensuring that package installations and script executions don't conflict with your system setup. When an agent gets stuck, it can pause its execution and request human assistance. A human can then take over the terminal session to resolve the issue before handing control back. ## Initialization To get started, initialize the `TerminalToolkit`. You can configure its behavior, such as the working directory and environment settings. ```python from camel.toolkits import TerminalToolkit # Initialize with default settings. # Safe mode is ON and working_directory is './workspace' terminal_toolkit = TerminalToolkit() ``` ```python from camel.toolkits import TerminalToolkit # Specify a custom sandboxed working directory terminal_toolkit = TerminalToolkit( working_directory="./my_safe_workspace" ) ``` ```python from camel.toolkits import TerminalToolkit # Clone the current python environment into the workspace # for the agent to use without affecting the original. terminal_toolkit = TerminalToolkit(clone_current_env=True) ``` ## Usage Examples ### Executing Commands The `shell_exec` function is the primary way to execute commands. Each command is run within a session, identified by a unique `id`. ```python # Execute the 'ls -l' command in 'session_1' output = terminal_toolkit.shell_exec(id='session_1', command='ls -l') print(output) ``` ```python # First, create a python script inside the workspace write_script_cmd = """ echo 'print("Hello from a sandboxed CAMEL environment!")' > hello.py """ terminal_toolkit.shell_exec(id='session_1', command=write_script_cmd) # Now, execute the script output = terminal_toolkit.shell_exec(id='session_1', command='python hello.py') print(output) ``` ### Interacting with Processes You can manage long-running or interactive processes. You can write to a process's standard input using `shell_write_to_process`. This is useful for interactive command-line tools. ```python # Start a python REPL in a new session terminal_toolkit.shell_exec(id='interactive_session', command='python') # Write code to the python process terminal_toolkit.shell_write_to_process( id='interactive_session', input='print("Hello, interactive world!")', press_enter=True ) # View the output output = terminal_toolkit.shell_view(id='interactive_session') print(output) ``` Forcibly terminate a running process using `shell_kill_process`. ```python # Start a long-running process terminal_toolkit.shell_exec(id='long_process', command='sleep 100') # Kill the process before it finishes result = terminal_toolkit.shell_kill_process(id='long_process') print(result) ``` ### Safe Mode When `safe_mode` is enabled (default), the toolkit blocks commands that could be harmful to your system. ```python # This command attempts to delete a file outside the workspace. # The toolkit will block it and return an error message. output = terminal_toolkit.shell_exec(id='session_1', command='rm /etc/hosts') print(output) # Expected Output: # Command rejected: Safety restriction: Cannot delete files outside of working directory ... ``` ### Human-in-the-Loop When an agent gets stuck, it can use `ask_user_for_help` to request human intervention. ```python # The agent is stuck, so it asks for help in 'session_1' help_result = terminal_toolkit.ask_user_for_help(id='session_1') # The script will now pause and wait for the user to type commands # in the console. After the user types '/exit', the script will resume. print(help_result) ``` --- --- title: "Tools" icon: screwdriver-wrench --- For more detailed usage information, please refer to our cookbook: [Tools Cookbook](../cookbooks/advanced_features/agents_with_tools.ipynb) A Tool in CAMEL is a callable function with a name, description, input parameters, and an output type. Tools act as the interface between agents and the outside world—think of them like OpenAI Functions you can easily convert, extend, or use directly. A Toolkit is a curated collection of related tools designed to work together for a specific purpose. CAMEL provides a range of built-in toolkits—covering everything from web search and data extraction to code execution, GitHub integration, and much more. ## Get Started To unlock advanced capabilities for your agents, install CAMEL's extra tools package: pip install 'camel-ai[tools]' A tool in CAMEL is just a FunctionTool—an interface any agent can call to run custom logic or access APIs. You can easily create your own tools for any use case. Just write a Python function and wrap it using FunctionTool: ```python add_tool.py lines icon="python" from camel.toolkits import FunctionTool def add(a: int, b: int) -> int: """Adds two numbers.""" return a + b add_tool = FunctionTool(add) ``` Inspect your tool’s properties—such as its name, description, and OpenAI-compatible schema—using built-in methods: ```python tool_properties.py print(add_tool.get_function_name()) # add print(add_tool.get_function_description()) # Adds two numbers. print(add_tool.get_openai_function_schema()) # OpenAI Functions schema print(add_tool.get_openai_tool_schema()) # OpenAI Tool format ``` ```text output.txt add Adds two numbers. {'name': 'add', 'description': 'Adds two numbers.', 'parameters': {'properties': {'a': {'type': 'integer', 'description': 'The first number to be added.'}, 'b': {'type': 'integer', 'description': 'The second number to be added.'}}, 'required': ['a', 'b'], 'type': 'object'}} {'type': 'function', 'function': {'name': 'add', 'description': 'Adds two numbers.', 'parameters': {'properties': {'a': {'type': 'integer', 'description': 'The first number to be added.'}, 'b': {'type': 'integer', 'description': 'The second number to be added.'}}, 'required': ['a', 'b'], 'type': 'object'}}} ``` Toolkits group related tools for specialized tasks—search, math, or automation. Use built‑in toolkits or build your own: ```python toolkit_usage.py lines icon="python" from camel.toolkits import SearchToolkit toolkit = SearchToolkit() tools = toolkit.get_tools() ``` You can also wrap toolkit methods as individual FunctionTools: ```python custom_tools.py lines icon="python" from camel.toolkits import FunctionTool, SearchToolkit google_tool = FunctionTool(SearchToolkit().search_google) wiki_tool = FunctionTool(SearchToolkit().search_wiki) ``` You can enhance any ChatAgent with custom or toolkit-powered tools. Just pass the tools during initialization: ```python chatagent_tools.py lines icon="python" from camel.agents import ChatAgent tool_agent = ChatAgent( tools=tools, # List of FunctionTools ) response = tool_agent.step("A query related to the tool you added") ``` ## Built-in Toolkits CAMEL provides a variety of built-in toolkits that you can use right away. Here's a comprehensive list of available toolkits: | Toolkit | Description | |---------|-------------| | ArxivToolkit | A toolkit for interacting with the arXiv API to search and download academic papers. | | AskNewsToolkit | A toolkit for fetching news, stories, and other content based on user queries using the AskNews API. | | AudioAnalysisToolkit | A toolkit for audio processing and analysis, including transcription and question answering about audio content. | | BrowserToolkit | A toolkit for browsing the web and interacting with web pages, including browser simulation and content extraction. | | CodeExecutionToolkit | A toolkit for code execution which can run code in various sandboxes including internal Python, Jupyter, Docker, subprocess, or e2b. | | OpenAIImageToolkit | A toolkit for image generation using OpenAI's DALL-E model. | | DappierToolkit | A toolkit for searching real-time data and fetching AI recommendations across key verticals like News, Finance, Stock Market, Sports, Weather and more using the Dappier API. | | DataCommonsToolkit | A toolkit for querying and retrieving data from the Data Commons knowledge graph, including SPARQL queries, statistical time series data, and property analysis. | | ExcelToolkit | A toolkit for extracting and processing content from Excel files, including conversion to markdown tables. | | FunctionTool | A base toolkit for creating function-based tools that OpenAI chat models can call, with support for schema parsing and synthesis. | | FileWriteTool | A toolkit for creating, writing, and modifying text in files. | | GitHubToolkit | A toolkit for interacting with GitHub repositories, including retrieving issues and creating pull requests. | | GoogleCalendarToolkit | A toolkit for creating events, retrieving events, updating events, and deleting events from a Google Calendar | | GoogleMapsToolkit | A toolkit for accessing Google Maps services, including address validation, elevation data, and timezone information. | | GoogleScholarToolkit | A toolkit for retrieving information about authors and their publications from Google Scholar. | | HumanToolkit | A toolkit for facilitating human-in-the-loop interactions and feedback in AI systems. | | ImageAnalysisToolkit | A toolkit for comprehensive image analysis and understanding using vision-capable language models. | | JinaRerankerToolkit | A toolkit for reranking documents (text or images) based on their relevance to a given query using the Jina Reranker model. | | LinkedInToolkit | A toolkit for LinkedIn operations including creating posts, deleting posts, and retrieving user profile information. | | MathToolkit | A toolkit for performing basic mathematical operations such as addition, subtraction, and multiplication. | | MCPToolkit | A toolkit for interacting with external tools using the Model Context Protocol (MCP). | | MemoryToolkit | A toolkit for saving, loading, and clearing a ChatAgent's memory. | | MeshyToolkit | A toolkit for working with 3D mesh data and operations. | | MinerUToolkit | A toolkit for extracting and processing document content using the MinerU API, with support for OCR, formula recognition, and table detection. | | NetworkXToolkit | A toolkit for graph operations and analysis using the NetworkX library. | | NotionToolkit | A toolkit for retrieving information from Notion pages and workspaces using the Notion API. | | OpenAPIToolkit | A toolkit for working with OpenAPI specifications and REST APIs. | | OpenBBToolkit | A toolkit for accessing and analyzing financial market data through the OpenBB Platform, including stocks, ETFs, cryptocurrencies, and economic indicators. | | PPTXToolkit | A toolkit for creating and manipulating PowerPoint (PPTX) files, including adding slides, text, and images. | | PubMedToolkit | A toolkit for interacting with PubMed's E-utilities API to access MEDLINE data. | | RedditToolkit | A toolkit for Reddit operations including collecting top posts, performing sentiment analysis on comments, and tracking keyword discussions. | | RetrievalToolkit | A toolkit for retrieving information from local vector storage systems based on specified queries. | | SearchToolkit | A toolkit for performing web searches using various search engines like Google, DuckDuckGo, Wikipedia, Bing, BaiDu and Wolfram Alpha. | | SemanticScholarToolkit | A toolkit for interacting with the Semantic Scholar API to fetch paper and author data from academic publications. | | SlackToolkit | A toolkit for Slack operations including creating channels, joining channels, and managing channel membership. | | StripeToolkit | A toolkit for processing payments and managing financial transactions via Stripe. | | SymPyToolkit | A toolkit for performing symbolic computations using SymPy, including algebraic manipulation, calculus, and linear algebra. | | TerminalToolkit | A toolkit for terminal operations such as searching for files by name or content, executing shell commands, and managing terminal sessions across multiple operating systems. | | TwitterToolkit | A toolkit for Twitter operations including creating tweets, deleting tweets, and retrieving user profile information. | | VideoAnalysisToolkit | A toolkit for analyzing video content with vision-language models, including frame extraction and question answering about video content. | | VideoDownloaderToolkit | A toolkit for downloading videos and optionally splitting them into chunks, with support for various video services. | | WeatherToolkit | A toolkit for fetching weather data for cities using the OpenWeatherMap API. | | WhatsAppToolkit | A toolkit for interacting with the WhatsApp Business API, including sending messages, managing message templates, and accessing business profile information. | | ZapierToolkit | A toolkit for interacting with Zapier's NLA API to execute actions through natural language commands and automate workflows. | | KlavisToolkit | A toolkit for interacting with Kavis AI's API to create remote hosted production-ready MCP servers. | ## Using Toolkits as MCP Servers CAMEL supports the Model Context Protocol (MCP), letting you expose any toolkit as a standalone server. This enables distributed tool execution and seamless integration across multiple systems—clients can remotely discover and invoke tools via a consistent protocol. MCP (Model Context Protocol) is a unified protocol for connecting LLMs with external tools and services. In CAMEL, you can turn any toolkit into an MCP server, making its tools available for remote calls—ideal for building distributed, modular, and language-agnostic AI workflows. Any CAMEL toolkit can run as an MCP server. Example for ArxivToolkit: ```python arxiv_mcp_server.py lines icon="python" import argparse import sys from camel.toolkits import ArxivToolkit if __name__ == "__main__": parser = argparse.ArgumentParser( description="Run Arxiv Toolkit in MCP server mode.", usage="python arxiv_mcp_server.py [--mode MODE] [--timeout TIMEOUT]" ) parser.add_argument( "--mode", choices=["stdio", "sse", "streamable-http"], default="stdio", help="MCP server mode (default: 'stdio')" ) parser.add_argument( "--timeout", type=float, default=None, help="Timeout in seconds (default: None)" ) args = parser.parse_args() toolkit = ArxivToolkit(timeout=args.timeout) toolkit.run_mcp_server(mode=args.mode) ``` Define how to launch your MCP servers with a config file: ```json mcp_servers_config.json { "mcpServers": { "arxiv_toolkit": { "command": "python", "args": [ "-m", "examples.mcp_arxiv_toolkit.arxiv_toolkit_server", "--timeout", "30" ] } } } ``` From your client application, you can connect to MCP servers and use their tools remotely: ```python mcp_client_example.py import asyncio from mcp.types import CallToolResult from camel.toolkits.mcp_toolkit import MCPToolkit, MCPClient async def run_example(): mcp_toolkit = MCPToolkit(config_path="path/to/mcp_servers_config.json") await mcp_toolkit.connect() mcp_client: MCPClient = mcp_toolkit.servers[0] res = await mcp_client.list_mcp_tools() if isinstance(res, str): raise Exception(res) tools = [tool.name for tool in res.tools] print(f"Available tools: {tools}") result: CallToolResult = await mcp_client.session.call_tool( "tool_name", {"param1": "value1", "param2": "value2"} ) print(result.content[0].text) await mcp_toolkit.disconnect() if __name__ == "__main__": asyncio.run(run_example()) ```
  • Distributed Execution: Run tools anywhere—across machines or containers.
  • Process Isolation: Each toolkit runs in its own process for reliability and security.
  • Resource Management: Allocate memory/CPU for heavy toolkits without impacting others.
  • Scalability: Scale specific toolkits up or down as your workload changes.
  • Language Interoperability: Implement MCP servers in any language that supports the protocol.
  • Timeouts: Always set timeouts to prevent blocked operations.
  • Error Handling: Implement robust error and exception handling in both server and client code.
  • Resource Cleanup: Properly disconnect and free resources when finished.
  • Configuration: Use config files or environment variables for flexible deployment.
  • Monitoring: Add logging and health checks for production MCP deployments.
Tools—especially when deployed as MCP servers—are the bridge between CAMEL agents and the real world. With this architecture, you can empower agents to automate, fetch, compute, and integrate with almost any external system. --- --- title: "Workforce" icon: "users" --- Workforce is CAMEL-AI’s powerful multi-agent collaboration engine. It enables you to assemble, manage, and scale teams of AI agents to tackle complex tasks that are beyond the capabilities of a single agent. By creating a "workforce" of specialized agents, you can automate intricate workflows, foster parallel execution, and achieve more robust and intelligent solutions. ## Core Components Deep Dive The `Workforce` class is the central orchestrator. It manages the entire lifecycle of a multi-agent task. ```python title="Workforce Initialization" class Workforce(BaseNode): def __init__( self, description: str, children: Optional[List[BaseNode]] = None, coordinator_agent: Optional[ChatAgent] = None, task_agent: Optional[ChatAgent] = None, new_worker_agent: Optional[ChatAgent] = None, graceful_shutdown_timeout: float = 15.0, task_timeout_seconds: Optional[float] = None, share_memory: bool = False, use_structured_output_handler: bool = True, callbacks: Optional[List[WorkforceCallback]] = None, ) -> None: # ... ``` **Key Parameters:** - `description`: A high-level description of the workforce's purpose. - `children`: A list of initial worker nodes. - `coordinator_agent`: A `ChatAgent` for assigning tasks. - `task_agent`: A `ChatAgent` for decomposing tasks. - `new_worker_agent`: A template `ChatAgent` for creating new workers. - `task_timeout_seconds`: Optional per-workforce task timeout in seconds. - `share_memory`: If `True`, `SingleAgentWorker` instances will share memory. - `use_structured_output_handler`: Defaults to `True`. Enables structured output handling so models without native JSON + tool-calling can still interop reliably. - `callbacks`: Optional A list of callback handlers to observe and record workforce lifecycle events and metrics. The Workforce can be composed of different types of workers, each suited for different kinds of tasks. The most common type of worker. It consists of a single `ChatAgent` configured with specific tools and a system prompt. For efficiency, it uses an `AgentPool` to reuse agent instances. This worker uses a `RolePlaying` session between two agents (an assistant and a user) to accomplish a task. It's useful for brainstorming, debate, or exploring a topic from multiple perspectives. ## Creating and Adding Workers Here are detailed examples of how to create and add `SingleAgentWorker` instances to your workforce. ```python from camel.societies.workforce import Workforce from camel.agents import ChatAgent workforce = Workforce("My Research Team") # Create a general-purpose agent general_agent = ChatAgent(system_message="You are a helpful research assistant.") # Add the worker workforce.add_single_agent_worker( description="A worker for general research tasks", worker=general_agent, ) ``` ```python from camel.societies.workforce import Workforce from camel.agents import ChatAgent from camel.toolkits import SearchToolkit workforce = Workforce("Web Research Team") # Create a search agent with a web search tool search_agent = ChatAgent( system_message="A research assistant that can search the web.", tools=[SearchToolkit().search_duckduckgo] ) # Add the worker workforce.add_single_agent_worker( description="A worker that can perform web searches", worker=search_agent, ) ``` ```python from camel.societies.workforce import Workforce from camel.agents import ChatAgent from camel.models import ModelFactory from camel.types import ModelType workforce = Workforce("Creative Writing Team") # Create an agent with a specific model for creative tasks creative_model = ModelFactory.create(model_type=ModelType.GPT_5_MINI) creative_agent = ChatAgent( system_message="A creative writer for generating stories.", model=creative_model ) # Add the worker workforce.add_single_agent_worker( description="A worker for creative writing", worker=creative_agent, ) ``` This example sets up a role-playing session between a "solution architect" and a "software developer" to design a system. ```python title="role_playing_example.py" from camel.societies.workforce import Workforce workforce = Workforce("System Design Team") workforce.add_role_playing_worker( description="A role-playing session for system design.", assistant_role_name="Software Developer", user_role_name="Solution Architect", assistant_agent_kwargs=dict( system_message="You are a software developer responsible for implementing the system." ), user_agent_kwargs=dict( system_message="You are a solution architect responsible for the high-level design." ), chat_turn_limit=5, ) # ... process a task with this workforce ... ``` The `Workforce` manages a sophisticated task lifecycle. ```mermaid graph TD A[Start: High-Level Task] --> B{Decompose Task} B --> C[Subtask 1] B --> D[Subtask 2] B --> E[...] C --> F{Assign Tasks} D --> F E --> F F --> G[Execute Tasks in Parallel by Workers] G --> H{Task Completed?} H -->|Yes| I[Store Result as Dependency] H -->|No| J{Failure Recovery} J -->|Retry| G J -->|Replan| G J -->|Decompose| B I --> K[Next Ready Tasks] K --> G G --> L[All Tasks Done] L --> M[Final Result] ``` 1. **Decomposition**: The `task_agent` breaks the main task into smaller, self-contained subtasks. 2. **Assignment**: The `coordinator_agent` assigns each subtask to the most suitable worker. 3. **Execution**: Workers execute their assigned tasks, often in parallel. 4. **Completion**: A task's result is stored and can be used as a dependency for other tasks. 5. **Failure Handling**: If a task fails, the `Workforce` initiates its recovery protocols. To enable HITL inside a Workforce, equip the agents (coordinator, task agent, or workers) with the `HumanToolkit`. Agents can then call a human during execution (e.g., to clarify requirements, approve actions, or unblock errors). ```python title="hitl_with_human_toolkit.py" from camel.societies.workforce import Workforce from camel.agents import ChatAgent from camel.toolkits import HumanToolkit # 1) Create the workforce workforce = Workforce("Interactive Workforce") # 2) Prepare human-in-the-loop tools human_toolkit = HumanToolkit() human_tools = human_toolkit.get_tools() # includes ask_human_via_console, send_message_to_user, ... # 3) Attach HumanToolkit to any agents that may need human help coordinator = ChatAgent( system_message="You coordinate tasks and may ask a human for help when needed.", tools=human_tools, ) worker = ChatAgent( system_message="You execute tasks and can ask the human for clarification.", tools=[human_toolkit.ask_human_via_console], # or use `human_tools` ) # 4) Register agents into the workforce workforce = Workforce( description="Interactive Workforce", coordinator_agent=coordinator, task_agent=None, ) workforce.add_single_agent_worker(description="Worker", worker=worker) # 5) Run tasks as usual. When an agent invokes a human tool, it will prompt via console. # workforce.process_task(Task(content="Build a quick demo and confirm requirements with the human.")) ``` Notes: - No special threading is required. Agents prompt the user when they call a `HumanToolkit` tool. - If you need async control, `process_task_async` is available, but it is not required for HITL. The `workforce` module uses several Pydantic models to ensure structured data exchange. - **`WorkerConf`**: Defines the configuration for a new worker. - **`TaskResult`**: Represents the output of a completed task. - **`TaskAssignment`**: A single task-to-worker assignment, including dependencies. - **`TaskAssignResult`**: A list of `TaskAssignment` objects. - **`RecoveryDecision`**: The output of the failure analysis process, dictating the recovery strategy. Understanding these models is key to interpreting the workforce's internal state and logs. See a real-world multi-agent workflow with Workforce. Full documentation for advanced usage and configuration. --- --- title: "CAMEL Agents as an MCP Client" icon: plug --- This guide walks you through turning your CAMEL AI agent into an MCP client, letting your agent easily use tools from multiple MCP servers. ## Quick Setup Steps 1. **Create a Config File**: Tell CAMEL which MCP servers you want to connect to. 2. **Use MCPToolkit to Connect**: Load your config file to connect to the servers. 3. **Enable Tools in CAMEL Agent**: Pass the server tools to your CAMEL agent to use. This guide walks you through turning your CAMEL AI agent into an MCP client, letting your agent easily use tools from multiple MCP servers. ## Step-by-Step Setup Start by creating a config file that tells your CAMEL agent what MCP servers to connect to. You can define local or remote servers, each with a transport method. ```json { "mcpServers": { "time_server": { "command": "python", "args": ["time_server.py"], "transport": "stdio" } } } ``` ```json { "mcpServers": { "composio-notion": { "command": "npx", "args": ["composio-core@rc", "mcp", "https://mcp.composio.dev/notion/your-server-id", "--client", "camel"], "env": { "COMPOSIO_API_KEY": "your-api-key-here" }, "transport": "streamable-http" } } } ``` ```json { "mcpServers": { "aci_apps": { "command": "uvx", "args": [ "aci-mcp", "apps-server", "--apps=BRAVE_SEARCH,GITHUB,ARXIV", "--linked-account-owner-id", "" ], "env": { "ACI_API_KEY": "your_aci_api_key" }, "transport": "sse" // or "streamable-http" } } } ``` You can use sse or streamable-http for ACI.dev, pick whichever is supported by your agent/server. Use `MCPToolkit` to connect to the servers and pass the tools to your CAMEL agent. ```python import asyncio from camel.toolkits.mcp_toolkit import MCPToolkit from camel.agents import ChatAgent async def main(): async with MCPToolkit(config_path="config/time.json") as toolkit: agent = ChatAgent(model=model, tools=toolkit.get_tools()) response = await agent.astep("What time is it now?") print(response.msgs[0].content) asyncio.run(main()) ``` Once connected, you can extend your setup with other servers from ACI.dev, Composio, or `npx`. - Use `stdio` for local testing, `sse` or `streamable-http` for cloud tools. - Secure your API keys using the `env` field in the config. - Use the MCP Inspector (`npx @modelcontextprotocol/inspector`) if you run into issues. Try plugging in servers like GitHub, Notion, or ArXiv and see your CAMEL agent in action. ## How It Works – System Diagram This diagram illustrates how CAMEL agents use MCPToolkit to seamlessly connect with MCP servers. Servers provide external tools from platforms like GitHub, Gmail, Notion, and more. Want your MCP agent discoverable by thousands of clients? Register it with a hub like ACI.dev or similar. ```python Register with ACI Registry lines icon="python" from camel.agents import MCPAgent from camel.types import ACIRegistryConfig, ModelFactory, ModelPlatformType, ModelType import os aci_config = ACIRegistryConfig( api_key=os.getenv("ACI_API_KEY"), linked_account_owner_id=os.getenv("ACI_LINKED_ACCOUNT_OWNER_ID"), ) model = ModelFactory.create( model_platform=ModelPlatformType.OPENAI, model_type=ModelType.GPT_4O, ) agent = MCPAgent( model=model, registry_configs=[aci_config], ) ``` Your agent is now connected to the ACI.dev registry and visible in the ecosystem. Finding MCP servers is now a breeze with PulseMCP integration. You don’t have to guess which MCP servers are available, just search, browse, and connect. PulseMCP acts as a living directory of the entire MCP ecosystem. CAMEL toolkits can plug directly into PulseMCP, letting you browse and connect to thousands of servers, all kept up to date in real time. You can visit [PulseMCP.com](https://pulsemcp.com) to browse all available MCP servers—everything from file systems and search to specialized APIs. If you prefer to search programmatically inside your CAMEL code, just use: from camel.toolkits.mcp import PulseMCPSearchToolkit search_toolkit = PulseMCPSearchToolkit() results = search_toolkit.search_mcp_servers(query="Slack", top_k=1) print(results) PulseMCP does the heavy lifting of finding, categorizing, and keeping MCP servers fresh—your agents just connect and go. Don’t need advanced tool-calling? See this example for a super-lightweight setup. ## Using Transport Methods - **stdio**: Ideal for local servers. Fast and easy. - **sse**: Great for cloud-hosted servers like ACI.dev. - **streamable-http**: Recommended for modern cloud integrations. ## Tips to Keep in Mind - For easiest troubleshooting, try with a simple local stdio server first; once you’re comfortable, you can connect to cloud servers using sse or streamable-http. - Store your API keys securely in the config file, never in code. - Use the MCP Inspector tool (`npx @modelcontextprotocol/inspector`) for debugging. ## Give It a Go Try setting up a config file for an MCP server (like [GitHub](https://github.com/github/github-mcp-server) or [Notion](https://github.com/makenotion/notion-mcp-server)) and see your CAMEL agent use the new tools right away! --- --- title: "Toolkit as MCP Server" icon: "server" description: "Share any CAMEL toolkit as an MCP server so external clients and agents can use your tools." --- A Toolkit is a bundle of related tools—functions that let agents fetch data, automate, search, or integrate with services.
Browse all CAMEL toolkits →
With one command, you can flip any toolkit into an MCP server. Now, any MCP-compatible client or agent can call your tools—locally or over the network.
## Quick Example You can turn any CAMEL toolkit into a full-featured MCP server—making its tools instantly available to other AI agents or external apps via the Model Context Protocol. Why do this? - Instantly share your agent tools with external clients (e.g., Claude, Cursor, custom dashboards). - Enable distributed, language-agnostic tool execution across different systems and teams. - Easily test, debug, and reuse your tools—no need to change the toolkit or agent code. ### Launch a Toolkit Server Below is a minimal script to expose ArxivToolkit as an MCP server. Swap in any other toolkit (e.g., SearchToolkit, MathToolkit), they all work the same way! ```python from camel.toolkits import ArxivToolkit import argparse parser = argparse.ArgumentParser( description="Run Arxiv Toolkit as an MCP server." ) parser.add_argument( "--mode", choices=["stdio", "sse", "streamable-http"], default="stdio", help="Select MCP server mode." ) args = parser.parse_args() toolkit = ArxivToolkit() toolkit.mcp.run(args.mode) ``` - **stdio:** For local IPC (default, fast and secure for single-machine setups) - **sse:** Server-Sent Events (good for remote servers and web clients) - **streamable-http:** Modern, high-performance HTTP streaming ### Discoverable & Usable Instantly Once running, your MCP server will: - Advertise all available toolkit methods as standard MCP tools - Support dynamic tool discovery (`tools/list` endpoint) - Allow any compatible agent or client (not just CAMEL) to connect and call your tools This means you can build an LLM workflow where, for example, Claude running in your browser or another service in your company network can call your toolkit directly—without ever importing your Python code. --- --- title: 'Connect to Existing MCP Tools in CAMEL ChatAgent' description: 'How to plug any MCP protocol tool (like file systems, web APIs) into your CAMEL ChatAgent for seamless tool-using agents.' icon: 'network' --- ## Overview You can connect any Model Context Protocol (MCP) tool—like the official filesystem server—directly to your CAMEL ChatAgent. This gives your agents natural language access to external filesystems, databases, or any MCP-compatible service. Use Case: Let your agent list files or read documents by wiring up the official MCP Filesystem server as a tool—no code changes to the agent required! You can use any MCP-compatible tool. For this example, we'll use the official filesystem server from the Model Context Protocol community.

Install globally using npm:

```bash Terminal npm install -g @modelcontextprotocol/server-filesystem ```
Start the server in the directory you want to expose (e.g., your project root):

```bash Terminal npx -y @modelcontextprotocol/server-filesystem . ``` This limits all file operations to the current directory.
Now, connect the MCP tool server to CAMEL using MCPClient or MCPToolkit.

Direct Client Example (Async): ```python mcp_filesystem_client.py lines icon="python" import asyncio from camel.utils.mcp_client import MCPClient async def mcp_client_example(): config = { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "."], } async with MCPClient(config) as client: mcp_tools = await client.list_mcp_tools() print("Available MCP tools:", [tool.name for tool in mcp_tools.tools]) call_tool_result = await client.call_tool( "list_directory", {"path": "."} ) print("Directory Contents:") for i, item in enumerate(call_tool_result.content[0].text.split('\n')): if item.strip(): print(f" {item}") if i >= 4: break asyncio.run(mcp_client_example()) ```
Add the tools exposed by the MCP server to your ChatAgent.

Async Agent Integration: ```python mcp_agent_integration.py lines icon="python" import asyncio from pathlib import Path from camel.agents import ChatAgent from camel.models import ModelFactory from camel.toolkits import MCPToolkit from camel.types import ModelPlatformType, ModelType async def mcp_toolkit_example(): config_path = Path(__file__).parent / "mcp_servers_config.json" async with MCPToolkit(config_path=str(config_path)) as mcp_toolkit: sys_msg = "You are a helpful assistant" model = ModelFactory.create( model_platform=ModelPlatformType.DEFAULT, model_type=ModelType.DEFAULT, ) camel_agent = ChatAgent( system_message=sys_msg, model=model, tools=[*mcp_toolkit.get_tools()], ) user_msg = "List 5 files in the project, using relative paths" response = await camel_agent.astep(user_msg) print(response.msgs[0].content) print(response.info['tool_calls']) asyncio.run(mcp_toolkit_example()) ```
Config Example (mcp_servers_config.json): ```json mcp_servers_config.json lines icon="settings" { "mcpServers": { "filesystem": { "command": "npx", "args": [ "-y", "@modelcontextprotocol/server-filesystem@2025.1.14", "." ] } }, "mcpWebServers": {} } ```
Use step() for synchronous execution:

```python mcp_agent_sync.py lines icon="python" from pathlib import Path from camel.agents import ChatAgent from camel.models import ModelFactory from camel.toolkits import MCPToolkit from camel.types import ModelPlatformType, ModelType def mcp_toolkit_example_sync(): config_path = Path(__file__).parent / "mcp_servers_config.json" with MCPToolkit(config_path=str(config_path)) as mcp_toolkit: sys_msg = "You are a helpful assistant" model = ModelFactory.create( model_platform=ModelPlatformType.DEFAULT, model_type=ModelType.DEFAULT, ) camel_agent = ChatAgent( system_message=sys_msg, model=model, tools=[*mcp_toolkit.get_tools()], ) user_msg = "List 5 files in the project, using relative paths" response = camel_agent.step(user_msg) print(response.msgs[0].content) print(response.info['tool_calls']) mcp_toolkit_example_sync() ```
That's it! Your CAMEL agent can now leverage any external tool (filesystem, APIs, custom scripts) that supports MCP. Plug and play! --- --- title: "CAMEL Agent as an MCP Server" icon: server description: "Turn your CAMEL ChatAgent into an MCP server—let any client (Claude, Cursor, custom apps) connect and use your agent as a universal AI backend." --- Publishing your ChatAgent as an MCP server turns your agent into a universal AI backend. Any MCP-compatible client (Claude, Cursor, editors, or your own app) can connect, chat, and run tools through your agent as if it were a native API—no custom integration required. ## Quick Start Scripted Server: Launch your agent as an MCP server with the ready-made scripts in services/. Configure your MCP client (Claude, Cursor, etc.) to connect: ```json mcp_servers_config.json Example highlight={5} { "camel-chat-agent": { "command": "/path/to/python", "args": [ "/path/to/camel/services/agent_mcp_server.py" ], "env": { "OPENAI_API_KEY": "...", "OPENROUTER_API_KEY": "...", "BRAVE_API_KEY": "..." } } } ``` Tip: Just point your MCP client at this config, and it will auto-discover and call your agent! Turn any ChatAgent into an MCP server instantly with to_mcp(): ```python agent_mcp_server.py lines icon="python" from camel.agents import ChatAgent # Create a chat agent with your model agent = ChatAgent(model="gpt-4o-mini") # Convert to an MCP server mcp_server = agent.to_mcp( name="demo", description="A demonstration of ChatAgent to MCP conversion" ) if __name__ == "__main__": print("Starting MCP server on http://localhost:8000") mcp_server.run(transport="streamable-http") ``` Supported transports: stdio, sse, streamable-http - **Plug-and-play with any MCP client**: Claude, Cursor, editors, automations—just connect and go. - **Universal API**: Your agent becomes an “AI API” for any tool that speaks MCP. - **Security & Flexibility**: Keep control over keys, environments, and agent configs. ## Real-world Example You can use Claude, Cursor, or any other app to call your custom agent! Just connect to your CAMEL MCP server Claude MCP Screenshot Claude MCP Screenshot You can expose any number of custom tools, multi-agent workflows, or domain knowledge, right from your own laptop or server! --- ## Why make your ChatAgent an MCP server? - **Universal Access:** Any client, any platform, anytime. - **Multi-Agent Workflows:** Power agent societies by letting agents call each other. - **Local Control:** Expose only the tools and data you want, with full security. - **No Glue Code:** MCP handles discovery and invocation, no custom REST or RPC needed. --- Want to create your own tools and toolkits? See Toolkits Reference for everything you can expose to the MCP ecosystem! --- --- title: "CAMEL-AI MCPHub" icon: warehouse url: "https://mcp.camel-ai.org/" --- --- --- title: 'Overview' description: 'Introduction to MCP: what it is, why it matters, and how it transforms agent integration.' icon: 'play' --- ## What is MCP all about? MCP (Model Context Protocol) originated from an [Anthropic article](https://www.anthropic.com/news/model-context-protocol) published on November 25, 2024: *Introducing the Model Context Protocol*. MCP defines **how applications and AI models exchange contextual information**. It enables developers to connect data sources, tools, and functions to LLMs using a universal, standardized protocol—much like USB-C enables diverse devices to connect via a single interface. MCP aims to be the "USB-C for AI": one protocol, endless integrations. Plug in any tool or data source—LLM models just work with it. Sits between LLMs and external tools/data, so you can add capabilities and context without changing agent code. MCP servers can be built in any language, run anywhere, and connect to anything—from cloud APIs to local files. Write your agent logic once, then extend it with new plugins or data via MCP, just by registering a new server. ## Visualizing MCP Here’s how MCP acts as an **intermediate protocol layer** between LLMs and tools: ## What Changes with MCP? ## Why introduce MCP? - **Ecosystem**: Leverage a growing library of MCP plugins—just plug them in. - **Uniformity**: Not limited to any one model or vendor; if your agent supports MCP, you can swap models/tools anytime. - **Data Security**: Keep sensitive data on your device. MCP servers decide what to expose—your private data never needs to leave your machine. ## MCP Architecture and Principles **Basic Architecture** MCP follows a **client-server model** with three main roles: Applications like Claude Desktop, IDEs, or AI tools that need external data/tools. The "Host" is the user-facing app. Built into the Host, the MCP Client manages protocol communication and connects to MCP Servers. Lightweight services (local or remote) that expose specific functions (e.g., read files, search web) via the MCP protocol. - **Local Data Sources**: Files, folders, databases, and services MCP servers can securely access. - **Remote Services**: Online APIs and cloud platforms accessible to MCP servers. ![MCP Server/Client diagram](/images/mcp-client-server-example.png) ### How it works, step by step: 1. **User asks:** “What documents do I have on my desktop?” via the Host (e.g., Claude Desktop). 2. **Host (MCP Host):** Receives your question and forwards it to the Claude model. 3. **Client (MCP Client):** Claude model decides it needs more data, Client is activated to connect to a file system MCP Server. 4. **Server (MCP Server):** The server reads your desktop directory and returns a list of documents. 5. **Results:** Claude uses this info to answer your question, displayed in your desktop app. This architecture **lets agents dynamically call tools and access data**—local or remote—while developers only focus on building the relevant MCPServer. **You don’t have to handle the nitty-gritty of connecting Hosts and Clients.** For deeper architecture details and diagrams, see the official MCP docs: Architecture Concepts. ## At a Glance - **MCP** standardizes and simplifies agent-to-tool connections. - **Developers** build or reuse MCP servers, not custom integrations for every agent. - **Users** get safer, more flexible, and privacy-friendly AI workflows. --- --- ## _cleanup_temp_files ```python def _cleanup_temp_files(): ``` ## StreamContentAccumulator ```python class StreamContentAccumulator: ``` Manages content accumulation across streaming responses to ensure all responses contain complete cumulative content. ### __init__ ```python def __init__(self): ``` ### set_base_content ```python def set_base_content(self, content: str): ``` Set the base content (usually empty or pre-tool content). ### add_streaming_content ```python def add_streaming_content(self, new_content: str): ``` Add new streaming content. ### add_reasoning_content ```python def add_reasoning_content(self, new_reasoning: str): ``` Add new reasoning content. ### add_tool_status ```python def add_tool_status(self, status_message: str): ``` Add a tool status message. ### get_full_content ```python def get_full_content(self): ``` Get the complete accumulated content. ### get_full_reasoning_content ```python def get_full_reasoning_content(self): ``` Get the complete accumulated reasoning content. ### get_content_with_new_status ```python def get_content_with_new_status(self, status_message: str): ``` Get content with a new status message appended. ### reset_streaming_content ```python def reset_streaming_content(self): ``` Reset only the streaming content, keep base and tool status. ## StreamingChatAgentResponse ```python class StreamingChatAgentResponse: ``` A wrapper that makes streaming responses compatible with non-streaming code. This class wraps a Generator[ChatAgentResponse, None, None] and provides the same interface as ChatAgentResponse, so existing code doesn't need to change. ### __init__ ```python def __init__(self, generator: Generator[ChatAgentResponse, None, None]): ``` ### _ensure_latest_response ```python def _ensure_latest_response(self): ``` Ensure we have the latest response by consuming the generator. ### msgs ```python def msgs(self): ``` Get messages from the latest response. ### terminated ```python def terminated(self): ``` Get terminated status from the latest response. ### info ```python def info(self): ``` Get info from the latest response. ### msg ```python def msg(self): ``` Get the single message if there's exactly one message. ### __iter__ ```python def __iter__(self): ``` Make this object iterable. ### __getattr__ ```python def __getattr__(self, name): ``` Forward any other attribute access to the latest response. ## AsyncStreamingChatAgentResponse ```python class AsyncStreamingChatAgentResponse: ``` A wrapper that makes async streaming responses awaitable and compatible with non-streaming code. This class wraps an AsyncGenerator[ChatAgentResponse, None] and provides both awaitable and async iterable interfaces. ### __init__ ```python def __init__(self, async_generator: AsyncGenerator[ChatAgentResponse, None]): ``` ### __await__ ```python def __await__(self): ``` Make this object awaitable - returns the final response. ### __aiter__ ```python def __aiter__(self): ``` Make this object async iterable. ## ChatAgent ```python class ChatAgent(BaseAgent): ``` Class for managing conversations of CAMEL Chat Agents. **Parameters:** - **system_message** (Union[BaseMessage, str], optional): The system message for the chat agent. (default: :obj:`None`) model (Union[BaseModelBackend, Tuple[str, str], str, ModelType, Tuple[ModelPlatformType, ModelType], List[BaseModelBackend], List[str], List[ModelType], List[Tuple[str, str]], List[Tuple[ModelPlatformType, ModelType]]], optional): The model backend(s) to use. Can be a single instance, a specification (string, enum, tuple), or a list of instances or specifications to be managed by `ModelManager`. If a list of specifications (not `BaseModelBackend` instances) is provided, they will be instantiated using `ModelFactory`. (default: :obj:`ModelPlatformType.DEFAULT` with `ModelType.DEFAULT`) - **memory** (AgentMemory, optional): The agent memory for managing chat messages. If `None`, a :obj:`ChatHistoryMemory` will be used. (default: :obj:`None`) - **message_window_size** (int, optional): The maximum number of previous messages to include in the context window. If `None`, no windowing is performed. (default: :obj:`None`) - **summarize_threshold** (int, optional): The percentage of the context window that triggers summarization. If `None`, will trigger summarization when the context window is full. (default: :obj:`None`) - **output_language** (str, optional): The language to be output by the agent. (default: :obj:`None`) - **tools** (Optional[List[Union[FunctionTool, Callable]]], optional): List of available :obj:`FunctionTool` or :obj:`Callable`. (default: :obj:`None`) toolkits_to_register_agent (Optional[List[RegisteredAgentToolkit]], optional): List of toolkit instances that inherit from :obj:`RegisteredAgentToolkit`. The agent will register itself with these toolkits, allowing them to access the agent instance. Note: This does NOT add the toolkit's tools to the agent. To use tools from these toolkits, pass them explicitly via the `tools` parameter. (default: :obj:`None`) external_tools (Optional[List[Union[FunctionTool, Callable, Dict[str, Any]]]], optional): List of external tools (:obj:`FunctionTool` or :obj:`Callable` or :obj:`Dict[str, Any]`) bind to one chat agent. When these tools are called, the agent will directly return the request instead of processing it. (default: :obj:`None`) - **response_terminators** (List[ResponseTerminator], optional): List of :obj:`ResponseTerminator` bind to one chat agent. (default: :obj:`None`) - **scheduling_strategy** (str): name of function that defines how to select the next model in ModelManager. (default: :str:`round_robin`) - **max_iteration** (Optional[int], optional): Maximum number of model calling iterations allowed per step. If `None` (default), there's no explicit limit. If `1`, it performs a single model call. If `N > 1`, it allows up to N model calls. (default: :obj:`None`) - **agent_id** (str, optional): The ID of the agent. If not provided, a random UUID will be generated. (default: :obj:`None`) - **stop_event** (Optional[threading.Event], optional): Event to signal termination of the agent's operation. When set, the agent will terminate its execution. (default: :obj:`None`) - **tool_execution_timeout** (Optional[float], optional): Timeout for individual tool execution. If None, wait indefinitely. - **mask_tool_output** (Optional[bool]): Whether to return a sanitized placeholder instead of the raw tool output. (default: :obj:`False`) - **pause_event** (Optional[Union[threading.Event, asyncio.Event]]): Event to signal pause of the agent's operation. When clear, the agent will pause its execution. Use threading.Event for sync operations or asyncio.Event for async operations. (default: :obj:`None`) - **prune_tool_calls_from_memory** (bool): Whether to clean tool call messages from memory after response generation to save token usage. When enabled, removes FUNCTION/TOOL role messages and ASSISTANT messages with tool_calls after each step. (default: :obj:`False`) - **enable_snapshot_clean** (bool, optional): Whether to clean snapshot markers and references from historical tool outputs in memory. This removes verbose DOM markers (like [ref=...]) from older tool results while keeping the latest output intact for immediate use. (default: :obj:`False`) - **retry_attempts** (int, optional): Maximum number of retry attempts for rate limit errors. (default: :obj:`3`) - **retry_delay** (float, optional): Initial delay in seconds between retries. Uses exponential backoff. (default: :obj:`1.0`) - **step_timeout** (Optional[float], optional): Timeout in seconds for the entire step operation. If None, no timeout is applied. (default: :obj:`None`) - **stream_accumulate** (bool, optional): When True, partial streaming updates return accumulated content (current behavior). When False, partial updates return only the incremental delta. (default: :obj:`True`) - **summary_window_ratio** (float, optional): Maximum fraction of the total context window that can be occupied by summary information. Used to limit how much of the model's context is reserved for summarization results. (default: :obj:`0.6`) ### __init__ ```python def __init__( self, system_message: Optional[Union[BaseMessage, str]] = None, model: Optional[Union[BaseModelBackend, ModelManager, Tuple[str, str], str, ModelType, Tuple[ModelPlatformType, ModelType], List[BaseModelBackend], List[str], List[ModelType], List[Tuple[str, str]], List[Tuple[ModelPlatformType, ModelType]]]] = None, memory: Optional[AgentMemory] = None, message_window_size: Optional[int] = None, summarize_threshold: Optional[int] = 50, token_limit: Optional[int] = None, output_language: Optional[str] = None, tools: Optional[List[Union[FunctionTool, Callable]]] = None, toolkits_to_register_agent: Optional[List[RegisteredAgentToolkit]] = None, external_tools: Optional[List[Union[FunctionTool, Callable, Dict[str, Any]]]] = None, response_terminators: Optional[List[ResponseTerminator]] = None, scheduling_strategy: str = 'round_robin', max_iteration: Optional[int] = None, agent_id: Optional[str] = None, stop_event: Optional[threading.Event] = None, tool_execution_timeout: Optional[float] = Constants.TIMEOUT_THRESHOLD, mask_tool_output: bool = False, pause_event: Optional[Union[threading.Event, asyncio.Event]] = None, prune_tool_calls_from_memory: bool = False, enable_snapshot_clean: bool = False, retry_attempts: int = 3, retry_delay: float = 1.0, step_timeout: Optional[float] = Constants.TIMEOUT_THRESHOLD, stream_accumulate: bool = True, summary_window_ratio: float = 0.6 ): ``` ### reset ```python def reset(self): ``` Resets the :obj:`ChatAgent` to its initial state. ### _resolve_models ```python def _resolve_models( self, model: Optional[Union[BaseModelBackend, Tuple[str, str], str, ModelType, Tuple[ModelPlatformType, ModelType], List[BaseModelBackend], List[str], List[ModelType], List[Tuple[str, str]], List[Tuple[ModelPlatformType, ModelType]]]] ): ``` Resolves model specifications into model backend instances. This method handles various input formats for model specifications and returns the appropriate model backend(s). **Parameters:** - **model**: Model specification in various formats including single model, list of models, or model type specifications. **Returns:** Union[BaseModelBackend, List[BaseModelBackend]]: Resolved model backend(s). ### _resolve_model_list ```python def _resolve_model_list(self, model_list: list): ``` Resolves a list of model specifications into model backend instances. **Parameters:** - **model_list** (list): List of model specifications in various formats. **Returns:** Union[BaseModelBackend, List[BaseModelBackend]]: Resolved model backend(s). ### system_message ```python def system_message(self): ``` Returns the system message for the agent. ### tool_dict ```python def tool_dict(self): ``` Returns a dictionary of internal tools. ### output_language ```python def output_language(self): ``` Returns the output language for the agent. ### output_language ```python def output_language(self, value: str): ``` Set the output language for the agent. Note that this will clear the message history. ### memory ```python def memory(self): ``` Returns the agent memory. ### memory ```python def memory(self, value: AgentMemory): ``` Set the agent memory. When setting a new memory, the system message is automatically re-added to ensure it's not lost. **Parameters:** - **value** (AgentMemory): The new agent memory to use. ### set_context_utility ```python def set_context_utility(self, context_utility: Optional[ContextUtility]): ``` Set the context utility for the agent. This allows external components (like SingleAgentWorker) to provide a shared context utility instance for workflow management. **Parameters:** - **context_utility** (ContextUtility, optional): The context utility to use. If None, the agent will create its own when needed. ### _get_full_tool_schemas ```python def _get_full_tool_schemas(self): ``` Returns a list of tool schemas of all tools, including internal and external tools. ### _is_token_limit_error ```python def _is_token_limit_error(error: Exception): ``` Return True when the exception message indicates a token limit. ### _is_tool_related_record ```python def _is_tool_related_record(record: MemoryRecord): ``` Determine whether the given memory record belongs to a tool call. ### _find_indices_to_remove_for_last_tool_pair ```python def _find_indices_to_remove_for_last_tool_pair(self, recent_records: List[ContextRecord]): ``` **Returns:** List[int]: Indices to remove (may be non-contiguous). ### _serialize_tool_args ```python def _serialize_tool_args(args: Dict[str, Any]): ``` ### _build_tool_signature ```python def _build_tool_signature(cls, func_name: str, args: Dict[str, Any]): ``` ### _describe_tool_call ```python def _describe_tool_call(self, record: Optional[ToolCallingRecord]): ``` ### _update_last_tool_call_state ```python def _update_last_tool_call_state(self, record: Optional[ToolCallingRecord]): ``` Track the most recent tool call and its identifying signature. ### _format_tool_limit_notice ```python def _format_tool_limit_notice(self): ``` ### _append_user_messages_section ```python def _append_user_messages_section(summary_content: str, user_messages: List[str]): ``` ### _reset_summary_state ```python def _reset_summary_state(self): ``` ### _calculate_next_summary_threshold ```python def _calculate_next_summary_threshold(self): ``` **Returns:** int: The token count threshold for next summarization. ### _update_memory_with_summary ```python def _update_memory_with_summary(self, summary: str, include_summaries: bool = False): ``` Update memory with summary result. This method handles memory clearing and restoration of summaries based on whether it's a progressive or full compression. ### _get_external_tool_names ```python def _get_external_tool_names(self): ``` Returns a set of external tool names. ### add_tool ```python def add_tool(self, tool: Union[FunctionTool, Callable]): ``` Add a tool to the agent. ### add_tools ```python def add_tools(self, tools: List[Union[FunctionTool, Callable]]): ``` Add a list of tools to the agent. ### _serialize_tool_result ```python def _serialize_tool_result(self, result: Any): ``` ### _clean_snapshot_line ```python def _clean_snapshot_line(self, line: str): ``` Clean a single snapshot line by removing prefixes and references. This method handles snapshot lines in the format: - [prefix] "quoted text" [attributes] [ref=...]: description It preserves: - Quoted text content (including brackets inside quotes) - Description text after the colon It removes: - Line prefixes (e.g., "- button", "- tooltip", "generic:") - Attribute markers (e.g., [disabled], [ref=e47]) - Lines with only element types - All indentation **Parameters:** - **line**: The original line content. **Returns:** The cleaned line content, or empty string if line should be removed. ### _clean_snapshot_content ```python def _clean_snapshot_content(self, content: str): ``` Clean snapshot content by removing prefixes, references, and deduplicating lines. This method identifies snapshot lines (containing element keywords or references) and cleans them while preserving non-snapshot content. It also handles JSON-formatted tool outputs with snapshot fields. **Parameters:** - **content**: The original snapshot content. **Returns:** The cleaned content with deduplicated lines. ### _clean_text_snapshot ```python def _clean_text_snapshot(self, content: str): ``` Clean plain text snapshot content. This method: - Removes all indentation - Deletes empty lines - Deduplicates all lines - Cleans snapshot-specific markers **Parameters:** - **content**: The original snapshot text. **Returns:** The cleaned content with deduplicated lines, no indentation, and no empty lines. ### _register_tool_output_for_cache ```python def _register_tool_output_for_cache( self, func_name: str, tool_call_id: str, result_text: str, records: List[MemoryRecord] ): ``` ### _process_tool_output_cache ```python def _process_tool_output_cache(self): ``` ### _clean_snapshot_in_memory ```python def _clean_snapshot_in_memory(self, entry: _ToolOutputHistoryEntry): ``` ### add_external_tool ```python def add_external_tool(self, tool: Union[FunctionTool, Callable, Dict[str, Any]]): ``` ### remove_tool ```python def remove_tool(self, tool_name: str): ``` Remove a tool from the agent by name. **Parameters:** - **tool_name** (str): The name of the tool to remove. **Returns:** bool: Whether the tool was successfully removed. ### remove_tools ```python def remove_tools(self, tool_names: List[str]): ``` Remove a list of tools from the agent by name. ### remove_external_tool ```python def remove_external_tool(self, tool_name: str): ``` Remove an external tool from the agent by name. **Parameters:** - **tool_name** (str): The name of the tool to remove. **Returns:** bool: Whether the tool was successfully removed. ### update_memory ```python def update_memory( self, message: BaseMessage, role: OpenAIBackendRole, timestamp: Optional[float] = None, return_records: bool = False ): ``` Updates the agent memory with a new message. **Parameters:** - **message** (BaseMessage): The new message to add to the stored messages. - **role** (OpenAIBackendRole): The backend role type. - **timestamp** (Optional[float], optional): Custom timestamp for the memory record. If `None`, the current time will be used. (default: :obj:`None`) - **return_records** (bool, optional): When `__INLINE_CODE_0____INLINE_CODE_1__False`) **Returns:** Optional[List[MemoryRecord]]: The records that were written when `__INLINE_CODE_0____INLINE_CODE_1____INLINE_CODE_2____INLINE_CODE_3____INLINE_CODE_4__`. ### load_memory ```python def load_memory(self, memory: AgentMemory): ``` Load the provided memory into the agent. **Parameters:** - **memory** (AgentMemory): The memory to load into the agent. **Returns:** None ### load_memory_from_path ```python def load_memory_from_path(self, path: str): ``` Loads memory records from a JSON file filtered by this agent's ID. **Parameters:** - **path** (str): The file path to a JSON memory file that uses JsonStorage. ### save_memory ```python def save_memory(self, path: str): ``` Retrieves the current conversation data from memory and writes it into a JSON file using JsonStorage. **Parameters:** - **path** (str): Target file path to store JSON data. ### summarize ```python def summarize( self, filename: Optional[str] = None, summary_prompt: Optional[str] = None, response_format: Optional[Type[BaseModel]] = None, working_directory: Optional[Union[str, Path]] = None, include_summaries: bool = False, add_user_messages: bool = True ): ``` Summarize the agent's current conversation context and persist it to a markdown file. .. deprecated:: 0.2.80 Use :meth:`asummarize` for async/await support and better performance in parallel summarization workflows. **Parameters:** - **filename** (Optional[str]): The base filename (without extension) to use for the markdown file. Defaults to a timestamped name when not provided. - **summary_prompt** (Optional[str]): Custom prompt for the summarizer. When omitted, a default prompt highlighting key decisions, action items, and open questions is used. - **response_format** (Optional[Type[BaseModel]]): A Pydantic model defining the expected structure of the response. If provided, the summary will be generated as structured output and included in the result. - **include_summaries** (bool): Whether to include previously generated summaries in the content to be summarized. If False (default), only non-summary messages will be summarized. If True, all messages including previous summaries will be summarized (full compression). (default: :obj:`False`) - **working_directory** (Optional[str|Path]): Optional directory to save the markdown summary file. If provided, overrides the default directory used by ContextUtility. - **add_user_messages** (bool): Whether add user messages to summary. (default: :obj:`True`) **Returns:** Dict[str, Any]: A dictionary containing the summary text, file path, status message, and optionally structured_summary if response_format was provided. See Also: :meth:`asummarize`: Async version for non-blocking LLM calls. ### _build_conversation_text_from_messages ```python def _build_conversation_text_from_messages(self, messages: List[Any], include_summaries: bool = False): ``` Build conversation text from messages for summarization. This is a shared helper method that converts messages to a formatted conversation text string, handling tool calls, tool results, and regular messages. **Parameters:** - **messages** (List[Any]): List of messages to convert. - **include_summaries** (bool): Whether to include messages starting with [CONTEXT_SUMMARY]. (default: :obj:`False`) **Returns:** tuple[str, List[str]]: A tuple containing: - Formatted conversation text - List of user messages extracted from the conversation ### clear_memory ```python def clear_memory(self): ``` **Returns:** None ### _generate_system_message_for_output_language ```python def _generate_system_message_for_output_language(self): ``` **Returns:** BaseMessage: The new system message. ### init_messages ```python def init_messages(self): ``` Initializes the stored messages list with the current system message. ### update_system_message ```python def update_system_message( self, system_message: Union[BaseMessage, str], reset_memory: bool = True ): ``` Update the system message. It will reset conversation with new system message. **Parameters:** - **system_message** (Union[BaseMessage, str]): The new system message. Can be either a BaseMessage object or a string. If a string is provided, it will be converted into a BaseMessage object. - **reset_memory** (bool): Whether to reinitialize conversation messages after updating the system message. Defaults to True. ### append_to_system_message ```python def append_to_system_message(self, content: str, reset_memory: bool = True): ``` Append additional context to existing system message. **Parameters:** - **content** (str): The additional system message. - **reset_memory** (bool): Whether to reinitialize conversation messages after appending additional context. Defaults to True. ### reset_to_original_system_message ```python def reset_to_original_system_message(self): ``` Reset system message to original, removing any appended context. This method reverts the agent's system message back to its original state, removing any workflow context or other modifications that may have been appended. Useful for resetting agent state in multi-turn scenarios. ### record_message ```python def record_message(self, message: BaseMessage): ``` Records the externally provided message into the agent memory as if it were an answer of the :obj:`ChatAgent` from the backend. Currently, the choice of the critic is submitted with this method. **Parameters:** - **message** (BaseMessage): An external message to be recorded in the memory. ### _try_format_message ```python def _try_format_message(self, message: BaseMessage, response_format: Type[BaseModel]): ``` **Returns:** bool: Whether the message is formatted successfully (or no format is needed). ### _check_tools_strict_compatibility ```python def _check_tools_strict_compatibility(self): ``` **Returns:** bool: True if all tools are strict mode compatible, False otherwise. ### _convert_response_format_to_prompt ```python def _convert_response_format_to_prompt(self, response_format: Type[BaseModel]): ``` Convert a Pydantic response format to a prompt instruction. **Parameters:** - **response_format** (Type[BaseModel]): The Pydantic model class. **Returns:** str: A prompt instruction requesting the specific format. ### _handle_response_format_with_non_strict_tools ```python def _handle_response_format_with_non_strict_tools( self, input_message: Union[BaseMessage, str], response_format: Optional[Type[BaseModel]] = None ): ``` Handle response format when tools are not strict mode compatible. **Parameters:** - **input_message**: The original input message. - **response_format**: The requested response format. **Returns:** Tuple: (modified_message, modified_response_format, used_prompt_formatting) ### _is_called_from_registered_toolkit ```python def _is_called_from_registered_toolkit(self): ``` **Returns:** bool: True if called from a RegisteredAgentToolkit, False otherwise ### _apply_prompt_based_parsing ```python def _apply_prompt_based_parsing( self, response: ModelResponse, original_response_format: Type[BaseModel] ): ``` Apply manual parsing when using prompt-based formatting. **Parameters:** - **response**: The model response to parse. - **original_response_format**: The original response format class. ### _format_response_if_needed ```python def _format_response_if_needed( self, response: ModelResponse, response_format: Optional[Type[BaseModel]] = None ): ``` Format the response if needed. This function won't format the response under the following cases: 1. The response format is None (not provided) 2. The response is empty ### step ```python def step( self, input_message: Union[BaseMessage, str], response_format: Optional[Type[BaseModel]] = None ): ``` Executes a single step in the chat session, generating a response to the input message. **Parameters:** - **input_message** (Union[BaseMessage, str]): The input message for the agent. If provided as a BaseMessage, the `role` is adjusted to `user` to indicate an external message. - **response_format** (Optional[Type[BaseModel]], optional): A Pydantic model defining the expected structure of the response. Used to generate a structured response if provided. (default: :obj:`None`) **Returns:** Union[ChatAgentResponse, StreamingChatAgentResponse]: If stream is False, returns a ChatAgentResponse. If stream is True, returns a StreamingChatAgentResponse that behaves like ChatAgentResponse but can also be iterated for streaming updates. ### _step_impl ```python def _step_impl( self, input_message: Union[BaseMessage, str], response_format: Optional[Type[BaseModel]] = None ): ``` Implementation of non-streaming step logic. ### chat_history ```python def chat_history(self): ``` ### _create_token_usage_tracker ```python def _create_token_usage_tracker(self): ``` **Returns:** Dict[str, int]: A dictionary for tracking token usage. ### _update_token_usage_tracker ```python def _update_token_usage_tracker(self, tracker: Dict[str, int], usage_dict: Dict[str, int]): ``` Updates a token usage tracker with values from a usage dictionary. **Parameters:** - **tracker** (Dict[str, int]): The token usage tracker to update. - **usage_dict** (Dict[str, int]): The usage dictionary with new values. ### _convert_to_chatagent_response ```python def _convert_to_chatagent_response( self, response: ModelResponse, tool_call_records: List[ToolCallingRecord], num_tokens: int, external_tool_call_requests: Optional[List[ToolCallRequest]], step_api_prompt_tokens: int = 0, step_api_completion_tokens: int = 0, step_api_total_tokens: int = 0 ): ``` Parse the final model response into the chat agent response. ### _record_final_output ```python def _record_final_output(self, output_messages: List[BaseMessage]): ``` Log final messages or warnings about multiple responses. ### _get_model_response ```python def _get_model_response( self, openai_messages: List[OpenAIMessage], num_tokens: int, current_iteration: int = 0, response_format: Optional[Type[BaseModel]] = None, tool_schemas: Optional[List[Dict[str, Any]]] = None, prev_num_openai_messages: int = 0 ): ``` Internal function for agent step model response. ### _sanitize_messages_for_logging ```python def _sanitize_messages_for_logging(self, messages, prev_num_openai_messages: int): ``` Sanitize OpenAI messages for logging by replacing base64 image data with a simple message and a link to view the image. **Parameters:** - **messages** (List[OpenAIMessage]): The OpenAI messages to sanitize. - **prev_num_openai_messages** (int): The number of openai messages logged in the previous iteration. **Returns:** List[OpenAIMessage]: The sanitized OpenAI messages. ### _step_get_info ```python def _step_get_info( self, output_messages: List[BaseMessage], finish_reasons: List[str], usage_dict: Dict[str, int], response_id: str, tool_calls: List[ToolCallingRecord], num_tokens: int, external_tool_call_requests: Optional[List[ToolCallRequest]] = None ): ``` Process the output of a chat step and gather information about the step. This method checks for termination conditions, updates the agent's state, and collects information about the chat step, including tool calls and termination reasons. **Parameters:** - **output_messages** (List[BaseMessage]): The messages generated in this step. - **finish_reasons** (List[str]): The reasons for finishing the generation for each message. - **usage_dict** (Dict[str, int]): Dictionary containing token usage information. - **response_id** (str): The ID of the response from the model. - **tool_calls** (List[ToolCallingRecord]): Records of function calls made during this step. - **num_tokens** (int): The number of tokens used in this step. - **external_tool_call_request** (Optional[ToolCallRequest]): The request for external tool call. **Returns:** Dict[str, Any]: A dictionary containing information about the chat step, including termination status, reasons, and tool call information. **Note:** This method iterates over all response terminators and checks if any of them signal termination. If a terminator signals termination, the agent's state is updated accordingly, and the termination reason is recorded. ### _handle_batch_response ```python def _handle_batch_response(self, response: ChatCompletion): ``` Process a batch response from the model and extract the necessary information. **Parameters:** - **response** (ChatCompletion): Model response. **Returns:** _ModelResponse: parsed model response. ### _step_terminate ```python def _step_terminate( self, num_tokens: int, tool_calls: List[ToolCallingRecord], termination_reason: str ): ``` Create a response when the agent execution is terminated. This method is called when the agent needs to terminate its execution due to various reasons such as token limit exceeded, or other termination conditions. It creates a response with empty messages but includes termination information in the info dictionary. **Parameters:** - **num_tokens** (int): Number of tokens in the messages. - **tool_calls** (List[ToolCallingRecord]): List of information objects of functions called in the current step. - **termination_reason** (str): String describing the reason for termination. **Returns:** ChatAgentResponse: A response object with empty message list, terminated flag set to True, and an info dictionary containing termination details, token counts, and tool call information. ### _execute_tool ```python def _execute_tool(self, tool_call_request: ToolCallRequest): ``` Execute the tool with arguments following the model's response. **Parameters:** - **tool_call_request** (_ToolCallRequest): The tool call request. **Returns:** FunctionCallingRecord: A struct for logging information about this function call. ### _record_tool_calling ```python def _record_tool_calling( self, func_name: str, args: Dict[str, Any], result: Any, tool_call_id: str, mask_output: bool = False, extra_content: Optional[Dict[str, Any]] = None ): ``` Record the tool calling information in the memory, and return the tool calling record. **Parameters:** - **func_name** (str): The name of the tool function called. - **args** (Dict[str, Any]): The arguments passed to the tool. - **result** (Any): The result returned by the tool execution. - **tool_call_id** (str): A unique identifier for the tool call. - **mask_output** (bool, optional): Whether to return a sanitized placeholder instead of the raw tool output. (default: :obj:`False`) - **extra_content** (Optional[Dict[str, Any]], optional): Additional content associated with the tool call. (default: :obj:`None`) **Returns:** ToolCallingRecord: A struct containing information about this tool call. ### _stream ```python def _stream( self, input_message: Union[BaseMessage, str], response_format: Optional[Type[BaseModel]] = None ): ``` Executes a streaming step in the chat session, yielding intermediate responses as they are generated. **Parameters:** - **input_message** (Union[BaseMessage, str]): The input message for the agent. - **response_format** (Optional[Type[BaseModel]], optional): A Pydantic model defining the expected structure of the response. - **Yields**: - **ChatAgentResponse**: Intermediate responses containing partial content, tool calls, and other information as they become available. ### _get_token_count ```python def _get_token_count(self, content: str): ``` Get token count for content with fallback. ### _stream_response ```python def _stream_response( self, openai_messages: List[OpenAIMessage], num_tokens: int, response_format: Optional[Type[BaseModel]] = None ): ``` Internal method to handle streaming responses with tool calls. ### _process_stream_chunks_with_accumulator ```python def _process_stream_chunks_with_accumulator( self, stream: Stream[ChatCompletionChunk], content_accumulator: StreamContentAccumulator, accumulated_tool_calls: Dict[str, Any], tool_call_records: List[ToolCallingRecord], step_token_usage: Dict[str, int], response_format: Optional[Type[BaseModel]] = None ): ``` Process streaming chunks with content accumulator. ### _accumulate_tool_calls ```python def _accumulate_tool_calls( self, tool_call_deltas: List[Any], accumulated_tool_calls: Dict[str, Any] ): ``` Accumulate tool call chunks and return True when any tool call is complete. **Parameters:** - **tool_call_deltas** (List[Any]): List of tool call deltas. - **accumulated_tool_calls** (Dict[str, Any]): Dictionary of accumulated tool calls. **Returns:** bool: True if any tool call is complete, False otherwise. ### _execute_tools_sync_with_status_accumulator ```python def _execute_tools_sync_with_status_accumulator( self, accumulated_tool_calls: Dict[str, Any], tool_call_records: List[ToolCallingRecord] ): ``` Execute multiple tools synchronously with proper content accumulation, using ThreadPoolExecutor for better timeout handling. ### _execute_tool_from_stream_data ```python def _execute_tool_from_stream_data(self, tool_call_data: Dict[str, Any]): ``` Execute a tool from accumulated stream data. ### _create_error_response ```python def _create_error_response( self, error_message: str, tool_call_records: List[ToolCallingRecord] ): ``` Create an error response for streaming. ### _record_assistant_tool_calls_message ```python def _record_assistant_tool_calls_message(self, accumulated_tool_calls: Dict[str, Any], content: str = ''): ``` Record the assistant message that contains tool calls. This method creates and records an assistant message that includes the tool calls information, which is required by OpenAI's API format. ### _create_streaming_response_with_accumulator ```python def _create_streaming_response_with_accumulator( self, accumulator: StreamContentAccumulator, new_content: str, step_token_usage: Dict[str, int], response_id: str = '', tool_call_records: Optional[List[ToolCallingRecord]] = None, reasoning_delta: Optional[str] = None ): ``` Create a streaming response using content accumulator. ### get_usage_dict ```python def get_usage_dict(self, output_messages: List[BaseMessage], prompt_tokens: int): ``` Get usage dictionary when using the stream mode. **Parameters:** - **output_messages** (list): List of output messages. - **prompt_tokens** (int): Number of input prompt tokens. **Returns:** dict: Usage dictionary. ### add_model_scheduling_strategy ```python def add_model_scheduling_strategy(self, name: str, strategy_fn: Callable): ``` Add a scheduling strategy method provided by user to ModelManger. **Parameters:** - **name** (str): The name of the strategy. - **strategy_fn** (Callable): The scheduling strategy function. ### clone ```python def clone(self, with_memory: bool = False): ``` Creates a new instance of :obj:`ChatAgent` with the same configuration as the current instance. **Parameters:** - **with_memory** (bool): Whether to copy the memory (conversation history) to the new agent. If True, the new agent will have the same conversation history. If False, the new agent will have a fresh memory with only the system message. (default: :obj:`False`) **Returns:** ChatAgent: A new instance of :obj:`ChatAgent` with the same configuration. ### _clone_tools ```python def _clone_tools(self): ``` **Returns:** Tuple containing: - List of cloned tools/functions - List of RegisteredAgentToolkit instances need registration ### __repr__ ```python def __repr__(self): ``` **Returns:** str: The string representation of the :obj:`ChatAgent`. ### to_mcp ```python def to_mcp( self, name: str = 'CAMEL-ChatAgent', description: str = 'A helpful assistant using the CAMEL AI framework.', dependencies: Optional[List[str]] = None, host: str = 'localhost', port: int = 8000 ): ``` Expose this ChatAgent as an MCP server. **Parameters:** - **name** (str): Name of the MCP server. (default: :obj:`CAMEL-ChatAgent`) - **description** (Optional[List[str]]): Description of the agent. If None, a generic description is used. (default: :obj:`A helpful assistant using the CAMEL AI framework.`) - **dependencies** (Optional[List[str]]): Additional dependencies for the MCP server. (default: :obj:`None`) - **host** (str): Host to bind to for HTTP transport. (default: :obj:`localhost`) - **port** (int): Port to bind to for HTTP transport. (default: :obj:`8000`) **Returns:** FastMCP: An MCP server instance that can be run. --- ## VLLMConfig ```python class VLLMConfig(BaseConfig): ``` Defines the parameters for generating chat completions using the OpenAI API. Reference: https://docs.vllm.ai/en/latest/serving/openai_compatible_server.html **Parameters:** - **temperature** (float, optional): Sampling temperature to use, between :obj:`0` and :obj:`2`. Higher values make the output more random, while lower values make it more focused and deterministic. (default: :obj:`None`) - **top_p** (float, optional): An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So :obj:`0.1` means only the tokens comprising the top 10% probability mass are considered. (default: :obj:`None`) - **n** (int, optional): How many chat completion choices to generate for each input message. (default: :obj:`None`) - **response_format** (object, optional): An object specifying the format that the model must output. Compatible with GPT-4 Turbo and all GPT-3.5 Turbo models newer than gpt-3.5-turbo-1106. Setting to `{"type": "json_object"}` enables JSON mode, which guarantees the message the model generates is valid JSON. Important: when using JSON mode, you must also instruct the model to produce JSON yourself via a system or user message. Without this, the model may generate an unending stream of whitespace until the generation reaches the token limit, resulting in a long-running and seemingly "stuck" request. Also note that the message content may be partially cut off if finish_reason="length", which indicates the generation exceeded max_tokens or the conversation exceeded the max context length. - **stream** (bool, optional): If True, partial message deltas will be sent as data-only server-sent events as they become available. (default: :obj:`None`) - **stop** (str or list, optional): Up to :obj:`4` sequences where the API will stop generating further tokens. (default: :obj:`None`) - **max_tokens** (int, optional): The maximum number of tokens to generate in the chat completion. The total length of input tokens and generated tokens is limited by the model's context length. (default: :obj:`None`) - **presence_penalty** (float, optional): Number between :obj:`-2.0` and :obj:`2.0`. Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics. See more information about frequency and presence penalties. (default: :obj:`None`) - **frequency_penalty** (float, optional): Number between :obj:`-2.0` and :obj:`2.0`. Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim. See more information about frequency and presence penalties. (default: :obj:`None`) - **logit_bias** (dict, optional): Modify the likelihood of specified tokens appearing in the completion. Accepts a json object that maps tokens (specified by their token ID in the tokenizer) to an associated bias value from :obj:`-100` to :obj:`100`. Mathematically, the bias is added to the logits generated by the model prior to sampling. The exact effect will vary per model, but values between:obj:` -1` - **and**: obj:`1` should decrease or increase likelihood of selection; values like :obj:`-100` or :obj:`100` should result in a ban or exclusive selection of the relevant token. (default: :obj:`None`) - **user** (str, optional): A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. (default: :obj:`None`) - **logprobs**: Whether to return log probabilities of the output tokens or not. If true, returns the log probabilities of each output token returned in the `logits` of `message`. (default: :obj:`None`) - **top_logprobs**: An integer between 0 and 20 specifying the number of most likely tokens to return at each token position, each with an associated log probability. `logprobs` must be set to `true` if this parameter is used. (default: :obj:`None`) - **extra_body**: Add additional JSON properties to the request. (default: :obj:`None`) --- ## ActionExtractor ```python class ActionExtractor(BaseExtractorStrategy): ``` A strategy for extracting RLCard actions from text. ### __init__ ```python def __init__(self, action_pattern: str = '\\s*(.+)'): ``` Initialize the action extractor with a regex pattern. **Parameters:** - **action_pattern** (str): The regex pattern to extract actions. (default: :obj:`"\\s*(.+)"`). ## RLCardsEnv ```python class RLCardsEnv(MultiStepEnv): ``` A base environment for RLCard games. This environment implements a wrapper around RLCard environments for reinforcement learning with LLMs. It handles the conversion between RLCard states and actions and the CAMEL environment interface. ### __init__ ```python def __init__( self, game_name: str, extractor: Optional[BaseExtractor] = None, max_steps: Optional[int] = None, num_players: int = 2, **kwargs ): ``` Initialize the RLCard environment. **Parameters:** - **game_name** (str): The name of the RLCard game to play. - **extractor** (Optional[BaseExtractor]): Extractor to process LLM responses. If None, a default extractor with ActionExtractor will be used. (default: :obj:`None`) - **max_steps** (Optional[int]): Maximum steps per episode. (default: :obj:`None`) - **num_players** (int): Number of players in the game. (default: :obj:`2`) **kwargs: Additional environment parameters. ### _get_initial_state ```python def _get_initial_state(self): ``` **Returns:** Dict[str, Any]: A dictionary containing the initial state with game state, player info, and game status flags. ### _get_next_observation ```python def _get_next_observation(self): ``` **Returns:** Observation: An Observation object containing the game state description. ### _get_terminal_observation ```python def _get_terminal_observation(self): ``` **Returns:** Observation: An Observation object containing the final game state description. ### _is_done ```python def _is_done(self): ``` **Returns:** bool: True if the game is over, False otherwise. ### _convert_to_rlcard_action ```python def _convert_to_rlcard_action(self, action_str: str): ``` Convert a string action to the format expected by RLCard. This method must be implemented by subclasses to handle the specific action format of each game. **Parameters:** - **action_str** (str): The string representation of the action. **Returns:** Any: The action in the format expected by the RLCard environment. ### _format_state_for_observation ```python def _format_state_for_observation(self, state: Dict[str, Any]): ``` Format the RLCard state for human-readable observation. This method must be implemented by subclasses to create a human-readable representation of the game state. **Parameters:** - **state** (Dict[str, Any]): The RLCard state dictionary. **Returns:** str: A human-readable representation of the state. ### _format_legal_actions ```python def _format_legal_actions(self, legal_actions: List[Any]): ``` Format the legal actions for human-readable observation. This method must be implemented by subclasses to create a human-readable representation of the legal actions. **Parameters:** - **legal_actions** (List[Any]): The list of legal actions. **Returns:** str: A human-readable representation of the legal actions. ## BlackjackEnv ```python class BlackjackEnv(RLCardsEnv): ``` A Blackjack environment for reinforcement learning with LLMs. This environment implements a standard Blackjack game where the LLM agent plays against a dealer. ### __init__ ```python def __init__( self, extractor: Optional[BaseExtractor] = None, max_steps: Optional[int] = None, **kwargs ): ``` Initialize the Blackjack environment. **Parameters:** - **extractor** (Optional[BaseExtractor]): Extractor to process LLM responses. If None, a default extractor will be used. (default: :obj:`None`) - **max_steps** (Optional[int]): Maximum steps per episode. (default: :obj:`None`) **kwargs: Additional environment parameters. ### _convert_to_rlcard_action ```python def _convert_to_rlcard_action(self, action_str: str): ``` Convert a string action to the format expected by RLCard Blackjack. **Parameters:** - **action_str** (str): The string representation of the action. Expected to be 'hit' or 'stand'. **Returns:** int: 0 for 'hit', 1 for 'stand'. ### _format_state_for_observation ```python def _format_state_for_observation(self, state: Dict[str, Any]): ``` Format the Blackjack state for human-readable observation. **Parameters:** - **state** (Dict[str, Any]): The RLCard state dictionary. **Returns:** str: A human-readable representation of the state. ### _format_legal_actions ```python def _format_legal_actions(self, legal_actions: List[int]): ``` Format the legal actions for Blackjack. **Parameters:** - **legal_actions** (List[int]): The list of legal actions. **Returns:** str: A human-readable representation of the legal actions. ### _format_cards ```python def _format_cards(self, cards: List[str]): ``` Format a list of cards for display. **Parameters:** - **cards** (List[str]): List of card strings. **Returns:** str: Formatted card string. ### _calculate_hand_value ```python def _calculate_hand_value(self, cards: List[str]): ``` Calculate the value of a hand in Blackjack. **Parameters:** - **cards** (List[str]): List of card strings. **Returns:** int: The value of the hand. ## LeducHoldemEnv ```python class LeducHoldemEnv(RLCardsEnv): ``` A Leduc Hold'em environment for reinforcement learning with LLMs. This environment implements a Leduc Hold'em poker game where the LLM agent plays against one or more opponents. ### __init__ ```python def __init__( self, extractor: Optional[BaseExtractor] = None, max_steps: Optional[int] = None, num_players: int = 2, **kwargs ): ``` Initialize the Leduc Hold'em environment. **Parameters:** - **extractor** (Optional[BaseExtractor]): Extractor to process LLM responses. If None, a default extractor will be used. (default: :obj:`None`) - **max_steps** (Optional[int]): Maximum steps per episode. (default: :obj:`None`) - **num_players** (int): Number of players in the game. (default: :obj:`2`) **kwargs: Additional environment parameters. ### _convert_to_rlcard_action ```python def _convert_to_rlcard_action(self, action_str: str): ``` Convert a string action to the format expected by RLCard Leduc Hold'em. **Parameters:** - **action_str** (str): The string representation of the action. Expected to be 'fold', 'check', 'call', or 'raise'. **Returns:** int: 0 for 'fold', 1 for 'check/call', 2 for 'raise'. ### _format_state_for_observation ```python def _format_state_for_observation(self, state: Dict[str, Any]): ``` Format the Leduc Hold'em state for human-readable observation. **Parameters:** - **state** (Dict[str, Any]): The RLCard state dictionary. **Returns:** str: A human-readable representation of the state. ### _format_legal_actions ```python def _format_legal_actions(self, legal_actions: List[int]): ``` Format the legal actions for Leduc Hold'em. **Parameters:** - **legal_actions** (List[int]): The list of legal actions. **Returns:** str: A human-readable representation of the legal actions. ## DoudizhuEnv ```python class DoudizhuEnv(RLCardsEnv): ``` A Doudizhu environment for reinforcement learning with LLMs. This environment implements a standard Doudizhu game where the LLM agent plays against two AI opponents. ### __init__ ```python def __init__( self, extractor: Optional[BaseExtractor] = None, max_steps: Optional[int] = None, **kwargs ): ``` Initialize the Doudizhu environment. **Parameters:** - **extractor** (Optional[BaseExtractor]): Extractor to process LLM responses. If None, a default extractor will be used. (default: :obj:`None`) - **max_steps** (Optional[int]): Maximum steps per episode. (default: :obj:`None`) **kwargs: Additional environment parameters. ### _convert_to_rlcard_action ```python def _convert_to_rlcard_action(self, action_str: str): ``` Convert a string action to the format expected by RLCard Doudizhu. **Parameters:** - **action_str** (str): The string representation of the action. Expected to be a card combination or 'pass'. **Returns:** str: The action string in the format expected by RLCard. ### _format_state_for_observation ```python def _format_state_for_observation(self, state: Dict[str, Any]): ``` Format the Doudizhu state for human-readable observation. **Parameters:** - **state** (Dict[str, Any]): The RLCard state dictionary. **Returns:** str: A human-readable representation of the state. ### _format_legal_actions ```python def _format_legal_actions(self, legal_actions: List[str]): ``` Format the legal actions for Doudizhu. **Parameters:** - **legal_actions** (List[str]): The list of legal actions. **Returns:** str: A human-readable representation of the legal actions. ### _format_cards ```python def _format_cards(self, cards: List[str]): ``` Format a list of cards for display. **Parameters:** - **cards** (List[str]): List of card strings. **Returns:** str: Formatted card string. --- ## InternalPythonInterpreter ```python class InternalPythonInterpreter(BaseInterpreter): ``` A customized python interpreter to control the execution of LLM-generated codes. The interpreter makes sure the code can only execute functions given in action space and import white list. It also supports fuzzy variable matching to retrieve uncertain input variable name. .. highlight:: none This class is adapted from the hugging face implementation [python_interpreter.py](https://github.com/huggingface/transformers/blob/8f 093fb799246f7dd9104ff44728da0c53a9f67a/src/transformers/tools/python_interp reter.py). The original license applies:: Copyright 2023 The HuggingFace Inc. team. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. We have modified the original code to suit our requirements. We have encapsulated the original functions within a class and saved the interpreter state after execution. We have added support for "import" statements, "for" statements, and several binary and unary operators. We have added import white list to keep `import` statement safe. Additionally, we have modified the variable matching logic and introduced the :obj:`fuzz_state` for fuzzy matching. Modifications copyright (C) 2023 CAMEL-AI.org **Parameters:** - **action_space** (Dict[str, Any], optional): A dictionary that maps action names to their corresponding functions or objects. The interpreter can only execute functions that are either directly listed in this dictionary or are member functions of objects listed in this dictionary. The concept of :obj:`action_space` is derived from EmbodiedAgent, representing the actions that an agent is capable of performing. If `None`, set to empty dict. (default: :obj:`None`) - **import_white_list** (List[str], optional): A list that stores the Python modules or functions that can be imported in the code. All submodules and functions of the modules listed in this list are importable. Any other import statements will be rejected. The module and its submodule or function name are separated by a period (:obj:`.`). (default: :obj:`None`) - **unsafe_mode** (bool, optional): If `True`, the interpreter runs the code by `eval()` or `exec()` without any security check. (default: :obj:`False`) - **raise_error** (bool, optional): Raise error if the interpreter fails. (default: :obj:`False`) - **allow_builtins** (bool, optional): If `True`, safe built-in functions like print, len, str, etc. are added to the action space. (default: :obj:`True`) ### __init__ ```python def __init__( self, action_space: Optional[Dict[str, Any]] = None, import_white_list: Optional[List[str]] = None, unsafe_mode: bool = False, raise_error: bool = False, allow_builtins: bool = True ): ``` ### _add_safe_builtins ```python def _add_safe_builtins(self): ``` Add safe built-in functions to the action space. ### run ```python def run(self, code: str, code_type: str = 'python'): ``` Executes the given code with specified code type in the interpreter. This method takes a string of code and its type, checks if the code type is supported, and then executes the code. If `unsafe_mode` is set to `False`, the code is executed in a controlled environment using the `execute` method. If `unsafe_mode` is `True`, the code is executed using `eval()` or `exec()` with the action space as the global context. An `InterpreterError` is raised if the code type is unsupported or if any runtime error occurs during execution. **Parameters:** - **code** (str): The python code to be executed. - **code_type** (str): The type of the code, which should be one of the supported code types (`python`, `py`, `python3`, `python2`). (default: obj:`python`) **Returns:** str: The string representation of the output of the executed code. ### update_action_space ```python def update_action_space(self, action_space: Dict[str, Any]): ``` Updates action space for *python* interpreter. ### supported_code_types ```python def supported_code_types(self): ``` Provides supported code types by the interpreter. ### execute ```python def execute( self, code: str, state: Optional[Dict[str, Any]] = None, fuzz_state: Optional[Dict[str, Any]] = None, keep_state: bool = True ): ``` Execute the input python codes in a security environment. **Parameters:** - **code** (str): Generated python code to be executed. - **state** (Optional[Dict[str, Any]], optional): External variables that may be used in the generated code. (default: :obj:`None`) - **fuzz_state** (Optional[Dict[str, Any]], optional): External variables that do not have certain variable names. The interpreter will use fuzzy matching to access these variables. For example, if :obj:`fuzz_state` has a variable :obj:`image`, the generated code can use :obj:`input_image` to access it. (default: :obj:`None`) - **keep_state** (bool, optional): If :obj:`True`, :obj:`state` and :obj:`fuzz_state` will be kept for later execution. Otherwise, they will be cleared. (default: :obj:`True`) **Returns:** Any: The value of the last statement (excluding "import") in the code. For this interpreter, the value of an expression is its value, the value of an "assign" statement is the assigned value, and the value of an "if" and "for" block statement is the value of the last statement in the block. ### clear_state ```python def clear_state(self): ``` Initialize :obj:`state` and :obj:`fuzz_state`. ### _execute_ast ```python def _execute_ast(self, expression: ast.AST): ``` ### _execute_assign ```python def _execute_assign(self, assign: ast.Assign): ``` ### _assign ```python def _assign(self, target: ast.expr, value: Any): ``` ### _execute_call ```python def _execute_call(self, call: ast.Call): ``` ### _execute_subscript ```python def _execute_subscript(self, subscript: ast.Subscript): ``` ### _execute_name ```python def _execute_name(self, name: ast.Name): ``` ### _execute_condition ```python def _execute_condition(self, condition: ast.Compare): ``` ### _execute_if ```python def _execute_if(self, if_statement: ast.If): ``` ### _execute_for ```python def _execute_for(self, for_statement: ast.For): ``` ### _execute_import ```python def _execute_import(self, import_module: ast.Import): ``` ### _execute_import_from ```python def _execute_import_from(self, import_from: ast.ImportFrom): ``` ### _validate_import ```python def _validate_import(self, full_name: str): ``` ### _execute_binop ```python def _execute_binop(self, binop: ast.BinOp): ``` ### _execute_unaryop ```python def _execute_unaryop(self, unaryop: ast.UnaryOp): ``` ### _get_value_from_state ```python def _get_value_from_state(self, key: str): ``` ### execute_command ```python def execute_command(self, command: str): ``` Execute a command in the internal python interpreter. **Parameters:** - **command** (str): The command to execute. **Returns:** tuple: A tuple containing the stdout and stderr of the command. --- ## BaseLoader ```python class BaseLoader(ABC): ``` Abstract base class for all data loaders in CAMEL. ### _load_single ```python def _load_single(self, source: Union[str, Path]): ``` Load data from a single source. **Parameters:** - **source** (Union[str, Path]): The data source to load from. **Returns:** Dict[str, Any]: A dictionary containing the loaded data. It is recommended that the dictionary includes a "content" key with the primary data and optional metadata keys. ### load ```python def load(self, source: Union[str, Path, List[Union[str, Path]]]): ``` Load data from one or multiple sources. **Parameters:** - **source** (Union[str, Path, List[Union[str, Path]]]): The data source (s) to load from. Can be: - A single path/URL (str or Path) - A list of paths/URLs **Returns:** Dict[str, List[Dict[str, Any]]]: A dictionary with a single key "contents" containing a list of loaded data. If a single source is provided, the list will contain a single item. ### supported_formats ```python def supported_formats(self): ``` **Returns:** set[str]: A set of strings representing the supported formats/ sources. --- ## Firecrawl ```python class Firecrawl: ``` Firecrawl allows you to turn entire websites into LLM-ready markdown. **Parameters:** - **api_key** (Optional[str]): API key for authenticating with the Firecrawl API. - **api_url** (Optional[str]): Base URL for the Firecrawl API. - **References**: - **https**: //docs.firecrawl.dev/introduction ### __init__ ```python def __init__( self, api_key: Optional[str] = None, api_url: Optional[str] = None ): ``` ### crawl ```python def crawl( self, url: str, params: Optional[Dict[str, Any]] = None, **kwargs: Any ): ``` Crawl a URL and all accessible subpages. Customize the crawl by setting different parameters, and receive the full response or a job ID based on the specified options. **Parameters:** - **url** (str): The URL to crawl. - **params** (Optional[Dict[str, Any]]): Additional parameters for the crawl request. Defaults to `None`. **kwargs (Any): Additional keyword arguments, such as `poll_interval`, `idempotency_key`. **Returns:** Any: The crawl job ID or the crawl results if waiting until completion. ### check_crawl_job ```python def check_crawl_job(self, job_id: str): ``` Check the status of a crawl job. **Parameters:** - **job_id** (str): The ID of the crawl job. **Returns:** Dict: The response including status of the crawl job. ### scrape ```python def scrape(self, url: str, params: Optional[Dict[str, str]] = None): ``` To scrape a single URL. This function supports advanced scraping by setting different parameters and returns the full scraped data as a dictionary. Reference: https://docs.firecrawl.dev/advanced-scraping-guide **Parameters:** - **url** (str): The URL to read. - **params** (Optional[Dict[str, str]]): Additional parameters for the scrape request. **Returns:** Dict[str, str]: The scraped data. ### structured_scrape ```python def structured_scrape(self, url: str, response_format: BaseModel): ``` Use LLM to extract structured data from given URL. **Parameters:** - **url** (str): The URL to read. - **response_format** (BaseModel): A pydantic model that includes value types and field descriptions used to generate a structured response by LLM. This schema helps in defining the expected output format. **Returns:** Dict: The content of the URL. ### map_site ```python def map_site(self, url: str, params: Optional[Dict[str, Any]] = None): ``` Map a website to retrieve all accessible URLs. **Parameters:** - **url** (str): The URL of the site to map. - **params** (Optional[Dict[str, Any]]): Additional parameters for the map request. Defaults to `None`. **Returns:** list: A list containing the URLs found on the site. --- ## JinaURLReader ```python class JinaURLReader: ``` URL Reader provided by Jina AI. The output is cleaner and more LLM-friendly than the URL Reader of UnstructuredIO. Can be configured to replace the UnstructuredIO URL Reader in the pipeline. **Parameters:** - **api_key** (Optional[str], optional): The API key for Jina AI. If not provided, the reader will have a lower rate limit. Defaults to None. - **return_format** (ReturnFormat, optional): The level of detail of the returned content, which is optimized for LLMs. For now screenshots are not supported. Defaults to ReturnFormat.DEFAULT. - **json_response** (bool, optional): Whether to return the response in JSON format. Defaults to False. - **timeout** (int, optional): The maximum time in seconds to wait for the page to be rendered. Defaults to 30. **kwargs (Any): Additional keyword arguments, including proxies, cookies, etc. It should align with the HTTP Header field and value pairs listed in the reference. - **References**: - **https**: //jina.ai/reader ### __init__ ```python def __init__( self, api_key: Optional[str] = None, return_format: JinaReturnFormat = JinaReturnFormat.DEFAULT, json_response: bool = False, timeout: int = 30, **kwargs: Any ): ``` ### read_content ```python def read_content(self, url: str): ``` Reads the content of a URL and returns it as a string with given form. **Parameters:** - **url** (str): The URL to read. **Returns:** str: The content of the URL. --- ## ScrapeGraphAI ```python class ScrapeGraphAI: ``` ScrapeGraphAI allows you to perform AI-powered web scraping and searching. **Parameters:** - **api_key** (Optional[str]): API key for authenticating with the ScrapeGraphAI API. - **References**: - **https**: //scrapegraph.ai/ ### __init__ ```python def __init__(self, api_key: Optional[str] = None): ``` ### search ```python def search(self, user_prompt: str): ``` Perform an AI-powered web search using ScrapeGraphAI. **Parameters:** - **user_prompt** (str): The search query or instructions. **Returns:** Dict[str, Any]: The search results including answer and reference URLs. ### scrape ```python def scrape( self, website_url: str, user_prompt: str, website_html: Optional[str] = None ): ``` Perform AI-powered web scraping using ScrapeGraphAI. **Parameters:** - **website_url** (str): The URL to scrape. - **user_prompt** (str): Instructions for what data to extract. - **website_html** (Optional[str]): Optional HTML content to use instead of fetching from the URL. **Returns:** Dict[str, Any]: The scraped data including request ID and result. ### close ```python def close(self): ``` Close the ScrapeGraphAI client connection. --- ## _configure_library_logging ```python def _configure_library_logging(): ``` ## set_log_file ```python def set_log_file(file_path): ``` Set a file handler for the CAMEL library logging. **Parameters:** - **file_path** (str): Path to the log file. If the directory doesn't exist, it will be created. **Returns:** logging.FileHandler: The file handler that was added to the logger. ## disable_logging ```python def disable_logging(): ``` Disable all logging for the CAMEL library. This function sets the log level to a value higher than CRITICAL, effectively disabling all log messages, and adds a NullHandler to suppress any potential warnings about no handlers being found. ## enable_logging ```python def enable_logging(): ``` Enable logging for the CAMEL library. This function re-enables logging if it was previously disabled, and configures the library logging using the default settings. If the logging is already configured, this function does not change its configuration. ## set_log_level ```python def set_log_level(level): ``` Set the logging level for the CAMEL library. **Parameters:** - **level** (Union[str, int]): The logging level to set. This can be a string (e.g., 'INFO') or a logging level constant (e.g., logging.INFO, logging.DEBUG). See https://docs.python.org/3/library/logging.html#levels **Raises:** - **ValueError**: If the provided level is not a valid logging level. ## get_logger ```python def get_logger(name: str): ``` Get a logger with the specified name, prefixed with 'camel.'. **Parameters:** - **name** (str): The name to be appended to 'camel.' to create the logger. **Returns:** logging.Logger: A logger instance with the name 'camel.\{name\}'. --- ## ScoreBasedContextCreator ```python class ScoreBasedContextCreator(BaseContextCreator): ``` A default implementation of context creation strategy, which inherits from :obj:`BaseContextCreator`. This class provides a strategy to generate a conversational context from a list of chat history records while ensuring the total token count of the context does not exceed a specified limit. It prunes messages based on their score if the total token count exceeds the limit. **Parameters:** - **token_counter** (BaseTokenCounter): An instance responsible for counting tokens in a message. - **token_limit** (int): The maximum number of tokens allowed in the generated context. ### __init__ ```python def __init__(self, token_counter: BaseTokenCounter, token_limit: int): ``` ### token_counter ```python def token_counter(self): ``` ### token_limit ```python def token_limit(self): ``` ### create_context ```python def create_context(self, records: List[ContextRecord]): ``` Constructs conversation context from chat history while respecting token limits. Key strategies: 1. System message is always prioritized and preserved 2. Truncation removes low-score messages first 3. Final output maintains chronological order and in history memory, the score of each message decreases according to keep_rate. The newer the message, the higher the score. 4. Tool calls and their responses are kept together to maintain API compatibility **Parameters:** - **records** (List[ContextRecord]): List of context records with scores and timestamps. **Returns:** Tuple[List[OpenAIMessage], int]: - Ordered list of OpenAI messages - Total token count of the final context ### _group_tool_calls_and_responses ```python def _group_tool_calls_and_responses(self, units: List[_ContextUnit]): ``` Groups tool calls with their corresponding responses based on `tool_call_id`. This improved logic robustly gathers all messages (assistant requests and tool responses, including chunks) that share a `tool_call_id`. **Parameters:** - **units** (List[_ContextUnit]): List of context units to analyze. **Returns:** Dict[str, List[_ContextUnit]]: Mapping from `tool_call_id` to a list of related units. ### _truncate_with_tool_call_awareness ```python def _truncate_with_tool_call_awareness( self, regular_units: List[_ContextUnit], tool_call_groups: Dict[str, List[_ContextUnit]], system_tokens: int ): ``` Truncates messages while preserving tool call-response pairs. This method implements a more sophisticated truncation strategy: 1. It treats tool call groups (request + responses) and standalone messages as individual items to be included. 2. It sorts all items by score and greedily adds them to the context. 3. **Partial Truncation**: If a complete tool group is too large to fit,it attempts to add the request message and as many of the most recent response chunks as the token budget allows. **Parameters:** - **regular_units** (List[_ContextUnit]): All regular message units. - **tool_call_groups** (Dict[str, List[_ContextUnit]]): Grouped tool calls. - **system_tokens** (int): Tokens used by the system message. **Returns:** List[_ContextUnit]: A list of units that fit within the token limit. ### _extract_system_message ```python def _extract_system_message(self, records: List[ContextRecord]): ``` Extracts the system message from records and validates it. **Parameters:** - **records** (List[ContextRecord]): List of context records representing conversation history. **Returns:** Tuple[Optional[_ContextUnit], List[_ContextUnit]]: containing: - The system message as a `_ContextUnit`, if valid; otherwise, `None`. - An empty list, serving as the initial container for regular messages. ### _conversation_sort_key ```python def _conversation_sort_key(self, unit: _ContextUnit): ``` Defines the sorting key for assembling the final output. Sorting priority: - Primary: Sort by timestamp in ascending order (chronological order). - Secondary: Sort by score in descending order (higher scores first when timestamps are equal). **Parameters:** - **unit** (_ContextUnit): A `_ContextUnit` representing a conversation record. **Returns:** Tuple[float, float]: - Timestamp for chronological sorting. - Negative score for descending order sorting. ### _assemble_output ```python def _assemble_output( self, context_units: List[_ContextUnit], system_unit: Optional[_ContextUnit] ): ``` Assembles final message list with proper ordering and token count. **Parameters:** - **context_units** (List[_ContextUnit]): Sorted list of regular message units. - **system_unit** (Optional[_ContextUnit]): System message unit (if present). **Returns:** Tuple[List[OpenAIMessage], int]: Tuple of (ordered messages, total tokens) --- ## BaseMessage ```python class BaseMessage: ``` Base class for message objects used in CAMEL chat system. **Parameters:** - **role_name** (str): The name of the user or assistant role. - **role_type** (RoleType): The type of role, either :obj:`RoleType. ASSISTANT` or :obj:`RoleType.USER`. - **meta_dict** (Optional[Dict[str, Any]]): Additional metadata dictionary for the message. - **content** (str): The content of the message. - **video_bytes** (Optional[bytes]): Optional bytes of a video associated with the message. (default: :obj:`None`) - **image_list** (Optional[List[Image.Image]]): Optional list of PIL Image objects associated with the message. (default: :obj:`None`) - **image_detail** (`Literal["auto", "low", "high"]`): Detail level of the images associated with the message. (default: :obj:`auto`) - **video_detail** (`Literal["auto", "low", "high"]`): Detail level of the videos associated with the message. (default: :obj:`auto`) - **parsed**: Optional[Union[Type[BaseModel], dict]]: Optional object which is parsed from the content. (default: :obj:`None`) ### make_user_message ```python def make_user_message( cls, role_name: str, content: str, meta_dict: Optional[Dict[str, str]] = None, video_bytes: Optional[bytes] = None, image_list: Optional[List[Image.Image]] = None, image_detail: Union[OpenAIVisionDetailType, str] = OpenAIVisionDetailType.AUTO, video_detail: Union[OpenAIVisionDetailType, str] = OpenAIVisionDetailType.LOW ): ``` Create a new user message. **Parameters:** - **role_name** (str): The name of the user role. - **content** (str): The content of the message. - **meta_dict** (Optional[Dict[str, str]]): Additional metadata dictionary for the message. - **video_bytes** (Optional[bytes]): Optional bytes of a video associated with the message. - **image_list** (Optional[List[Image.Image]]): Optional list of PIL Image objects associated with the message. - **image_detail** (Union[OpenAIVisionDetailType, str]): Detail level of the images associated with the message. - **video_detail** (Union[OpenAIVisionDetailType, str]): Detail level of the videos associated with the message. **Returns:** BaseMessage: The new user message. ### make_assistant_message ```python def make_assistant_message( cls, role_name: str, content: str, meta_dict: Optional[Dict[str, str]] = None, video_bytes: Optional[bytes] = None, image_list: Optional[List[Image.Image]] = None, image_detail: Union[OpenAIVisionDetailType, str] = OpenAIVisionDetailType.AUTO, video_detail: Union[OpenAIVisionDetailType, str] = OpenAIVisionDetailType.LOW ): ``` Create a new assistant message. **Parameters:** - **role_name** (str): The name of the assistant role. - **content** (str): The content of the message. - **meta_dict** (Optional[Dict[str, str]]): Additional metadata dictionary for the message. - **video_bytes** (Optional[bytes]): Optional bytes of a video associated with the message. - **image_list** (Optional[List[Image.Image]]): Optional list of PIL Image objects associated with the message. - **image_detail** (Union[OpenAIVisionDetailType, str]): Detail level of the images associated with the message. - **video_detail** (Union[OpenAIVisionDetailType, str]): Detail level of the videos associated with the message. **Returns:** BaseMessage: The new assistant message. ### create_new_instance ```python def create_new_instance(self, content: str): ``` Create a new instance of the :obj:`BaseMessage` with updated content. **Parameters:** - **content** (str): The new content value. **Returns:** BaseMessage: The new instance of :obj:`BaseMessage`. ### __add__ ```python def __add__(self, other: Any): ``` Addition operator override for :obj:`BaseMessage`. **Parameters:** - **other** (Any): The value to be added with. **Returns:** Union[BaseMessage, Any]: The result of the addition. ### __mul__ ```python def __mul__(self, other: Any): ``` Multiplication operator override for :obj:`BaseMessage`. **Parameters:** - **other** (Any): The value to be multiplied with. **Returns:** Union[BaseMessage, Any]: The result of the multiplication. ### __len__ ```python def __len__(self): ``` **Returns:** int: The length of the content. ### __contains__ ```python def __contains__(self, item: str): ``` Contains operator override for :obj:`BaseMessage`. **Parameters:** - **item** (str): The item to check for containment. **Returns:** bool: :obj:`True` if the item is contained in the content, :obj:`False` otherwise. ### extract_text_and_code_prompts ```python def extract_text_and_code_prompts(self): ``` **Returns:** Tuple[List[TextPrompt], List[CodePrompt]]: A tuple containing a list of text prompts and a list of code prompts extracted from the content. ### from_sharegpt ```python def from_sharegpt( cls, message: ShareGPTMessage, function_format: Optional[FunctionCallFormatter[Any, Any]] = None, role_mapping = None ): ``` Convert ShareGPT message to BaseMessage or FunctionCallingMessage. Note tool calls and responses have an 'assistant' role in CAMEL **Parameters:** - **message** (ShareGPTMessage): ShareGPT message to convert. - **function_format** (FunctionCallFormatter, optional): Function call formatter to use. (default: :obj:`HermesFunctionFormatter()`. - **role_mapping** (Dict[str, List[str, RoleType]], optional): Role mapping to use. Defaults to a CAMEL specific mapping. **Returns:** BaseMessage: Converted message. ### to_sharegpt ```python def to_sharegpt(self, function_format: Optional[FunctionCallFormatter] = None): ``` Convert BaseMessage to ShareGPT message **Parameters:** - **function_format** (FunctionCallFormatter): Function call formatter to use. Defaults to Hermes. ### to_openai_message ```python def to_openai_message(self, role_at_backend: OpenAIBackendRole): ``` Converts the message to an :obj:`OpenAIMessage` object. **Parameters:** - **role_at_backend** (OpenAIBackendRole): The role of the message in OpenAI chat system. **Returns:** OpenAIMessage: The converted :obj:`OpenAIMessage` object. ### to_openai_system_message ```python def to_openai_system_message(self): ``` **Returns:** OpenAISystemMessage: The converted :obj:`OpenAISystemMessage` object. ### to_openai_user_message ```python def to_openai_user_message(self): ``` **Returns:** OpenAIUserMessage: The converted :obj:`OpenAIUserMessage` object. ### to_openai_assistant_message ```python def to_openai_assistant_message(self): ``` **Returns:** OpenAIAssistantMessage: The converted :obj:`OpenAIAssistantMessage` object. ### to_dict ```python def to_dict(self): ``` **Returns:** dict: The converted dictionary. --- ## FunctionCallingMessage ```python class FunctionCallingMessage(BaseMessage): ``` Class for message objects used specifically for function-related messages. **Parameters:** - **func_name** (Optional[str]): The name of the function used. (default: :obj:`None`) - **args** (Optional[Dict]): The dictionary of arguments passed to the function. (default: :obj:`None`) - **result** (Optional[Any]): The result of function execution. (default: :obj:`None`) - **tool_call_id** (Optional[str]): The ID of the tool call, if available. (default: :obj:`None`) - **mask_output** (Optional[bool]): Whether to return a sanitized placeholder instead of the raw tool output. (default: :obj:`False`) ### to_openai_message ```python def to_openai_message(self, role_at_backend: OpenAIBackendRole): ``` Converts the message to an :obj:`OpenAIMessage` object. **Parameters:** - **role_at_backend** (OpenAIBackendRole): The role of the message in OpenAI chat system. **Returns:** OpenAIMessage: The converted :obj:`OpenAIMessage` object. ### to_sharegpt ```python def to_sharegpt( self, function_format: Optional[FunctionCallFormatter[ToolCall, ToolResponse]] = None ): ``` Convert FunctionCallingMessage to ShareGPT message. ### to_openai_assistant_message ```python def to_openai_assistant_message(self): ``` **Returns:** OpenAIAssistantMessage: The converted :obj:`OpenAIAssistantMessage` object. ### to_openai_tool_message ```python def to_openai_tool_message(self): ``` **Returns:** OpenAIToolMessageParam: The converted :obj:`OpenAIToolMessageParam` object with its role being "tool". ### to_dict ```python def to_dict(self): ``` **Returns:** dict: The converted dictionary. --- ## AWSBedrockModel ```python class AWSBedrockModel(OpenAICompatibleModel): ``` AWS Bedrock API in a unified OpenAICompatibleModel interface. **Parameters:** - **model_type** (Union[ModelType, str]): Model for which a backend is created. - **model_config_dict** (Dict[str, Any], optional): A dictionary that will be fed into:obj:`openai.ChatCompletion.create()`. - **If**: obj:`None`, :obj:`BedrockConfig().as_dict()` will be used. (default: :obj:`None`) - **api_key** (str, optional): The API key for authenticating with the AWS Bedrock service. (default: :obj:`None`) - **url** (str, optional): The url to the AWS Bedrock service. - **token_counter** (BaseTokenCounter, optional): Token counter to use for the model. If not provided, :obj:`OpenAITokenCounter( ModelType.GPT_4O_MINI)` will be used. (default: :obj:`None`) - **timeout** (Optional[float], optional): The timeout value in seconds for API calls. If not provided, will fall back to the MODEL_TIMEOUT environment variable or default to 180 seconds. (default: :obj:`None`) - **max_retries** (int, optional): Maximum number of retries for API calls. (default: :obj:`3`) **kwargs (Any): Additional arguments to pass to the client initialization. - **References**: - **https**: //docs.aws.amazon.com/bedrock/latest/APIReference/welcome.html ### __init__ ```python def __init__( self, model_type: Union[ModelType, str], model_config_dict: Optional[Dict[str, Any]] = None, api_key: Optional[str] = None, url: Optional[str] = None, token_counter: Optional[BaseTokenCounter] = None, timeout: Optional[float] = None, max_retries: int = 3, **kwargs: Any ): ``` --- ## AzureOpenAIModel ```python class AzureOpenAIModel(BaseModelBackend): ``` Azure OpenAI API in a unified BaseModelBackend interface. **Parameters:** - **model_type** (Union[ModelType, str]): Model for which a backend is created, Should be the deployment name you chose when you deployed an azure model. - **model_config_dict** (Optional[Dict[str, Any]], optional): A dictionary that will be fed into:obj:`openai.ChatCompletion.create()`. If :obj:`None`, :obj:`ChatGPTConfig().as_dict()` will be used. (default: :obj:`None`) - **api_key** (Optional[str], optional): The API key for authenticating with the OpenAI service. (default: :obj:`None`) - **url** (Optional[str], optional): The url to the OpenAI service. (default: :obj:`None`) - **api_version** (Optional[str], optional): The api version for the model. (default: :obj:`None`) - **azure_ad_token** (Optional[str], optional): Your Azure Active Directory token, https://www.microsoft.com/en-us/security/business/ identity-access/microsoft-entra-id. (default: :obj:`None`) - **azure_ad_token_provider** (Optional[AzureADTokenProvider], optional): A function that returns an Azure Active Directory token, will be invoked on every request. (default: :obj:`None`) - **token_counter** (Optional[BaseTokenCounter], optional): Token counter to use for the model. If not provided, :obj:`OpenAITokenCounter` will be used. (default: :obj:`None`) - **timeout** (Optional[float], optional): The timeout value in seconds for API calls. If not provided, will fall back to the MODEL_TIMEOUT environment variable or default to 180 seconds. (default: :obj:`None`) - **max_retries** (int, optional): Maximum number of retries for API calls. (default: :obj:`3`) - **client** (Optional[Any], optional): A custom synchronous AzureOpenAI client instance. If provided, this client will be used instead of creating a new one. Useful for RL frameworks like AReaL or rLLM that provide Azure OpenAI-compatible clients. The client should implement the AzureOpenAI client interface with `.chat.completions.create()` and `.beta.chat.completions.parse()` methods. (default: :obj:`None`) - **async_client** (Optional[Any], optional): A custom asynchronous AzureOpenAI client instance. If provided, this client will be used instead of creating a new one. The client should implement the AsyncAzureOpenAI client interface. (default: :obj:`None`) - **azure_deployment_name** (Optional[str], optional): **Deprecated**. Use `model_type` parameter instead. This parameter is kept for backward compatibility and will be removed in a future version. (default: :obj:`None`) **kwargs (Any): Additional arguments to pass to the client initialization. Ignored if custom clients are provided. - **References**: - **https**: //learn.microsoft.com/en-us/azure/ai-services/openai/ ### __init__ ```python def __init__( self, model_type: Union[ModelType, str], model_config_dict: Optional[Dict[str, Any]] = None, api_key: Optional[str] = None, url: Optional[str] = None, timeout: Optional[float] = None, token_counter: Optional[BaseTokenCounter] = None, api_version: Optional[str] = None, azure_ad_token_provider: Optional['AzureADTokenProvider'] = None, azure_ad_token: Optional[str] = None, max_retries: int = 3, client: Optional[Any] = None, async_client: Optional[Any] = None, azure_deployment_name: Optional[str] = None, **kwargs: Any ): ``` ### token_counter ```python def token_counter(self): ``` **Returns:** BaseTokenCounter: The token counter following the model's tokenization style. ### _run ```python def _run( self, messages: List[OpenAIMessage], response_format: Optional[Type[BaseModel]] = None, tools: Optional[List[Dict[str, Any]]] = None ): ``` Runs inference of Azure OpenAI chat completion. **Parameters:** - **messages** (List[OpenAIMessage]): Message list with the chat history in OpenAI API format. - **response_format** (Optional[Type[BaseModel]]): The format of the response. - **tools** (Optional[List[Dict[str, Any]]]): The schema of the tools to use for the request. **Returns:** Union[ChatCompletion, Stream[ChatCompletionChunk]]: `ChatCompletion` in the non-stream mode, or `Stream[ChatCompletionChunk]` in the stream mode. `ChatCompletionStreamManager[BaseModel]` for structured output streaming. ### _request_chat_completion ```python def _request_chat_completion( self, messages: List[OpenAIMessage], tools: Optional[List[Dict[str, Any]]] = None ): ``` ### _request_parse ```python def _request_parse( self, messages: List[OpenAIMessage], response_format: Type[BaseModel], tools: Optional[List[Dict[str, Any]]] = None ): ``` ### _request_stream_parse ```python def _request_stream_parse( self, messages: List[OpenAIMessage], response_format: Type[BaseModel], tools: Optional[List[Dict[str, Any]]] = None ): ``` Request streaming structured output parsing. ### stream ```python def stream(self): ``` **Returns:** bool: Whether the model is in stream mode. --- ## ModelBackendMeta ```python class ModelBackendMeta(ABCMeta): ``` Metaclass that automatically preprocesses messages in run method. Automatically wraps the run method of any class inheriting from BaseModelBackend to preprocess messages (remove `` tags) before they are sent to the model. ### __new__ ```python def __new__( mcs, name, bases, namespace ): ``` Wraps run method with preprocessing if it exists in the class. ## BaseModelBackend ```python class BaseModelBackend(ABC): ``` Base class for different model backends. It may be OpenAI API, a local LLM, a stub for unit tests, etc. **Parameters:** - **model_type** (Union[ModelType, str]): Model for which a backend is created. - **model_config_dict** (Optional[Dict[str, Any]], optional): A config dictionary. (default: :obj:`{}`) - **api_key** (Optional[str], optional): The API key for authenticating with the model service. (default: :obj:`None`) - **url** (Optional[str], optional): The url to the model service. (default: :obj:`None`) - **token_counter** (Optional[BaseTokenCounter], optional): Token counter to use for the model. If not provided, :obj:`OpenAITokenCounter` will be used. (default: :obj:`None`) - **timeout** (Optional[float], optional): The timeout value in seconds for API calls. (default: :obj:`None`) - **max_retries** (int, optional): Maximum number of retries for API calls. (default: :obj:`3`) ### __init__ ```python def __init__( self, model_type: Union[ModelType, str], model_config_dict: Optional[Dict[str, Any]] = None, api_key: Optional[str] = None, url: Optional[str] = None, token_counter: Optional[BaseTokenCounter] = None, timeout: Optional[float] = None, max_retries: int = 3 ): ``` ### token_counter ```python def token_counter(self): ``` **Returns:** BaseTokenCounter: The token counter following the model's tokenization style. ### preprocess_messages ```python def preprocess_messages(self, messages: List[OpenAIMessage]): ``` Preprocess messages before sending to model API. Removes thinking content from assistant and user messages. Automatically formats messages for parallel tool calls if tools are detected. **Parameters:** - **messages** (List[OpenAIMessage]): Original messages. **Returns:** List[OpenAIMessage]: Preprocessed messages ### _log_request ```python def _log_request(self, messages: List[OpenAIMessage]): ``` Log the request messages to a JSON file if logging is enabled. **Parameters:** - **messages** (List[OpenAIMessage]): The messages to log. **Returns:** Optional[str]: The path to the log file if logging is enabled, None otherwise. ### _log_response ```python def _log_response(self, log_path: str, response: Any): ``` Log the response to the existing log file. **Parameters:** - **log_path** (str): The path to the log file. - **response** (Any): The response to log. ### _run ```python def _run( self, messages: List[OpenAIMessage], response_format: Optional[Type[BaseModel]] = None, tools: Optional[List[Dict[str, Any]]] = None ): ``` Runs the query to the backend model in a non-stream mode. **Parameters:** - **messages** (List[OpenAIMessage]): Message list with the chat history in OpenAI API format. - **response_format** (Optional[Type[BaseModel]]): The format of the response. - **tools** (Optional[List[Dict[str, Any]]]): The schema of the tools to use for the request. **Returns:** Union[ChatCompletion, Stream[ChatCompletionChunk], Any]: `ChatCompletion` in the non-stream mode, or `Stream[ChatCompletionChunk]` in the stream mode, or `ChatCompletionStreamManager[BaseModel]` in the structured stream mode. ### run ```python def run( self, messages: List[OpenAIMessage], response_format: Optional[Type[BaseModel]] = None, tools: Optional[List[Dict[str, Any]]] = None ): ``` Runs the query to the backend model. **Parameters:** - **messages** (List[OpenAIMessage]): Message list with the chat history in OpenAI API format. - **response_format** (Optional[Type[BaseModel]]): The response format to use for the model. (default: :obj:`None`) - **tools** (Optional[List[Tool]]): The schema of tools to use for the model for this request. Will override the tools specified in the model configuration (but not change the configuration). (default: :obj:`None`) **Returns:** Union[ChatCompletion, Stream[ChatCompletionChunk], Any]: `ChatCompletion` in the non-stream mode, `Stream[ChatCompletionChunk]` in the stream mode, or `ChatCompletionStreamManager[BaseModel]` in the structured stream mode. ### count_tokens_from_messages ```python def count_tokens_from_messages(self, messages: List[OpenAIMessage]): ``` Count the number of tokens in the messages using the specific tokenizer. **Parameters:** - **messages** (List[Dict]): message list with the chat history in OpenAI API format. **Returns:** int: Number of tokens in the messages. ### _to_chat_completion ```python def _to_chat_completion(self, response: ParsedChatCompletion): ``` ### token_limit ```python def token_limit(self): ``` **Returns:** int: The maximum token limit for the given model. ### stream ```python def stream(self): ``` **Returns:** bool: Whether the model is in stream mode. --- ## DeepSeekModel ```python class DeepSeekModel(OpenAICompatibleModel): ``` DeepSeek API in a unified OpenAICompatibleModel interface. **Parameters:** - **model_type** (Union[ModelType, str]): Model for which a backend is created. - **model_config_dict** (Optional[Dict[str, Any]], optional): A dictionary that will be fed into:obj:`openai.ChatCompletion.create()`. If :obj:`None`, :obj:`DeepSeekConfig().as_dict()` will be used. (default: :obj:`None`) - **api_key** (Optional[str], optional): The API key for authenticating with the DeepSeek service. (default: :obj:`None`) - **url** (Optional[str], optional): The url to the DeepSeek service. (default: :obj:`https://api.deepseek.com`) - **token_counter** (Optional[BaseTokenCounter], optional): Token counter to use for the model. If not provided, :obj:`OpenAITokenCounter` will be used. (default: :obj:`None`) - **timeout** (Optional[float], optional): The timeout value in seconds for API calls. If not provided, will fall back to the MODEL_TIMEOUT environment variable or default to 180 seconds. (default: :obj:`None`) - **max_retries** (int, optional): Maximum number of retries for API calls. (default: :obj:`3`) **kwargs (Any): Additional arguments to pass to the client initialization. - **References**: - **https**: //api-docs.deepseek.com/ ### __init__ ```python def __init__( self, model_type: Union[ModelType, str], model_config_dict: Optional[Dict[str, Any]] = None, api_key: Optional[str] = None, url: Optional[str] = None, token_counter: Optional[BaseTokenCounter] = None, timeout: Optional[float] = None, max_retries: int = 3, **kwargs: Any ): ``` ### _prepare_request ```python def _prepare_request( self, messages: List[OpenAIMessage], response_format: Optional[Type[BaseModel]] = None, tools: Optional[List[Dict[str, Any]]] = None ): ``` ### _run ```python def _run( self, messages: List[OpenAIMessage], response_format: Optional[Type[BaseModel]] = None, tools: Optional[List[Dict[str, Any]]] = None ): ``` Runs inference of DeepSeek chat completion. **Parameters:** - **messages** (List[OpenAIMessage]): Message list with the chat history in OpenAI API format. **Returns:** Union[ChatCompletion, Stream[ChatCompletionChunk]]: `ChatCompletion` in the non-stream mode, or `Stream[ChatCompletionChunk]` in the stream mode. --- ## ModelProcessingError ```python class ModelProcessingError(Exception): ``` Raised when an error occurs during model processing. ## ModelManager ```python class ModelManager: ``` ModelManager choosing a model from provided list. Models are picked according to defined strategy. **Parameters:** - **models** (Union[BaseModelBackend, List[BaseModelBackend]]): model backend or list of model backends (e.g., model instances, APIs) - **scheduling_strategy** (str): name of function that defines how to select the next model. (default: :str:`round_robin`) ### __init__ ```python def __init__( self, models: Union[BaseModelBackend, List[BaseModelBackend]], scheduling_strategy: str = 'round_robin' ): ``` ### model_type ```python def model_type(self): ``` **Returns:** Union[ModelType, str]: Current model type. ### model_config_dict ```python def model_config_dict(self): ``` **Returns:** Dict[str, Any]: Config dictionary of the current model. ### model_config_dict ```python def model_config_dict(self, model_config_dict: Dict[str, Any]): ``` Set model_config_dict to the current model. **Parameters:** - **model_config_dict** (Dict[str, Any]): Config dictionary to be set at current model. ### current_model_index ```python def current_model_index(self): ``` **Returns:** int: index of current model in given list of models. ### num_models ```python def num_models(self): ``` **Returns:** int: The number of models available in the model manager. ### token_limit ```python def token_limit(self): ``` **Returns:** int: The maximum token limit for the given model. ### token_counter ```python def token_counter(self): ``` **Returns:** BaseTokenCounter: The token counter following the model's tokenization style. ### add_strategy ```python def add_strategy(self, name: str, strategy_fn: Callable): ``` Add a scheduling strategy method provided by user in case when none of existent strategies fits. When custom strategy is provided, it will be set as "self.scheduling_strategy" attribute. **Parameters:** - **name** (str): The name of the strategy. - **strategy_fn** (Callable): The scheduling strategy function. ### round_robin ```python def round_robin(self): ``` **Returns:** BaseModelBackend for processing incoming messages. ### always_first ```python def always_first(self): ``` **Returns:** BaseModelBackend for processing incoming messages. ### random_model ```python def random_model(self): ``` **Returns:** BaseModelBackend for processing incoming messages. ### run ```python def run( self, messages: List[OpenAIMessage], response_format: Optional[Type[BaseModel]] = None, tools: Optional[List[Dict[str, Any]]] = None ): ``` Process a list of messages by selecting a model based on the scheduling strategy. Sends the entire list of messages to the selected model, and returns a single response. **Parameters:** - **messages** (List[OpenAIMessage]): Message list with the chat history in OpenAI API format. **Returns:** Union[ChatCompletion, Stream[ChatCompletionChunk], ChatCompletionStreamManager[BaseModel]]: `ChatCompletion` in the non-stream mode, or `Stream[ChatCompletionChunk]` in the stream mode, or `ChatCompletionStreamManager[BaseModel]` for structured-output stream. --- ## OllamaModel ```python class OllamaModel(OpenAICompatibleModel): ``` Ollama service interface. **Parameters:** - **model_type** (Union[ModelType, str]): Model for which a backend is created. - **model_config_dict** (Optional[Dict[str, Any]], optional): A dictionary that will be fed into:obj:`openai.ChatCompletion.create()`. - **If**: obj:`None`, :obj:`OllamaConfig().as_dict()` will be used. (default: :obj:`None`) - **api_key** (Optional[str], optional): The API key for authenticating with the model service. Required for Ollama cloud services. If not provided, defaults to "Not_Provided". (default: :obj:`None`) - **url** (Optional[str], optional): The url to the model service. (default: :obj:`None`) - **token_counter** (Optional[BaseTokenCounter], optional): Token counter to use for the model. If not provided, :obj:`OpenAITokenCounter( ModelType.GPT_4O_MINI)` will be used. (default: :obj:`None`) - **timeout** (Optional[float], optional): The timeout value in seconds for API calls. If not provided, will fall back to the MODEL_TIMEOUT environment variable or default to 180 seconds. (default: :obj:`None`) - **max_retries** (int, optional): Maximum number of retries for API calls. (default: :obj:`3`) **kwargs (Any): Additional arguments to pass to the client initialization. - **References**: - **https**: //github.com/ollama/ollama/blob/main/docs/openai.md ### __init__ ```python def __init__( self, model_type: Union[ModelType, str], model_config_dict: Optional[Dict[str, Any]] = None, api_key: Optional[str] = None, url: Optional[str] = None, token_counter: Optional[BaseTokenCounter] = None, timeout: Optional[float] = None, max_retries: int = 3, **kwargs: Any ): ``` ### _start_server ```python def _start_server(self): ``` Starts the Ollama server in a subprocess. --- ## OpenAICompatibleModel ```python class OpenAICompatibleModel(BaseModelBackend): ``` Constructor for model backend supporting OpenAI compatibility. **Parameters:** - **model_type** (Union[ModelType, str]): Model for which a backend is created. - **model_config_dict** (Optional[Dict[str, Any]], optional): A dictionary that will be fed into:obj:`openai.ChatCompletion.create()`. If :obj:`None`, :obj:`{}` will be used. (default: :obj:`None`) - **api_key** (str): The API key for authenticating with the model service. - **url** (str): The url to the model service. - **token_counter** (Optional[BaseTokenCounter], optional): Token counter to use for the model. If not provided, :obj:`OpenAITokenCounter( ModelType.GPT_4O_MINI)` will be used. (default: :obj:`None`) - **timeout** (Optional[float], optional): The timeout value in seconds for API calls. If not provided, will fall back to the MODEL_TIMEOUT environment variable or default to 180 seconds. (default: :obj:`None`) - **max_retries** (int, optional): Maximum number of retries for API calls. (default: :obj:`3`) **kwargs (Any): Additional arguments to pass to the OpenAI client initialization. These can include parameters like 'organization', 'default_headers', 'http_client', etc. ### __init__ ```python def __init__( self, model_type: Union[ModelType, str], model_config_dict: Optional[Dict[str, Any]] = None, api_key: Optional[str] = None, url: Optional[str] = None, token_counter: Optional[BaseTokenCounter] = None, timeout: Optional[float] = None, max_retries: int = 3, **kwargs: Any ): ``` ### _run ```python def _run( self, messages: List[OpenAIMessage], response_format: Optional[Type[BaseModel]] = None, tools: Optional[List[Dict[str, Any]]] = None ): ``` Runs inference of OpenAI chat completion. **Parameters:** - **messages** (List[OpenAIMessage]): Message list with the chat history in OpenAI API format. - **response_format** (Optional[Type[BaseModel]]): The format of the response. - **tools** (Optional[List[Dict[str, Any]]]): The schema of the tools to use for the request. **Returns:** Union[ChatCompletion, Stream[ChatCompletionChunk]]: `ChatCompletion` in the non-stream mode, or `Stream[ChatCompletionChunk]` in the stream mode. `ChatCompletionStreamManager[BaseModel]` for structured output streaming. ### _request_chat_completion ```python def _request_chat_completion( self, messages: List[OpenAIMessage], tools: Optional[List[Dict[str, Any]]] = None ): ``` ### _request_parse ```python def _request_parse( self, messages: List[OpenAIMessage], response_format: Type[BaseModel], tools: Optional[List[Dict[str, Any]]] = None ): ``` ### _request_stream_parse ```python def _request_stream_parse( self, messages: List[OpenAIMessage], response_format: Type[BaseModel], tools: Optional[List[Dict[str, Any]]] = None ): ``` Request streaming structured output parsing. ### token_counter ```python def token_counter(self): ``` **Returns:** OpenAITokenCounter: The token counter following the model's tokenization style. ### stream ```python def stream(self): ``` **Returns:** bool: Whether the model is in stream mode. --- ## OpenAIModel ```python class OpenAIModel(BaseModelBackend): ``` OpenAI API in a unified BaseModelBackend interface. **Parameters:** - **model_type** (Union[ModelType, str]): Model for which a backend is created, one of GPT_* series. - **model_config_dict** (Optional[Dict[str, Any]], optional): A dictionary that will be fed into:obj:`openai.ChatCompletion.create()`. If :obj:`None`, :obj:`ChatGPTConfig().as_dict()` will be used. (default: :obj:`None`) - **api_key** (Optional[str], optional): The API key for authenticating with the OpenAI service. (default: :obj:`None`) - **url** (Optional[str], optional): The url to the OpenAI service. (default: :obj:`None`) - **token_counter** (Optional[BaseTokenCounter], optional): Token counter to use for the model. If not provided, :obj:`OpenAITokenCounter` will be used. (default: :obj:`None`) - **timeout** (Optional[float], optional): The timeout value in seconds for API calls. If not provided, will fall back to the MODEL_TIMEOUT environment variable or default to 180 seconds. (default: :obj:`None`) - **max_retries** (int, optional): Maximum number of retries for API calls. (default: :obj:`3`) **kwargs (Any): Additional arguments to pass to the OpenAI client initialization. These can include parameters like 'organization', 'default_headers', 'http_client', etc. ### __init__ ```python def __init__( self, model_type: Union[ModelType, str], model_config_dict: Optional[Dict[str, Any]] = None, api_key: Optional[str] = None, url: Optional[str] = None, token_counter: Optional[BaseTokenCounter] = None, timeout: Optional[float] = None, max_retries: int = 3, **kwargs: Any ): ``` ### _sanitize_config ```python def _sanitize_config(self, config_dict: Dict[str, Any]): ``` Sanitize the model configuration for O1 models. ### _adapt_messages_for_o1_models ```python def _adapt_messages_for_o1_models(self, messages: List[OpenAIMessage]): ``` Adjust message roles to comply with O1 model requirements by converting 'system' or 'developer' to 'user' role. **Parameters:** - **messages** (List[OpenAIMessage]): Message list with the chat history in OpenAI API format. **Returns:** processed_messages (List[OpenAIMessage]): Return a new list of messages to avoid mutating input. ### token_counter ```python def token_counter(self): ``` **Returns:** BaseTokenCounter: The token counter following the model's tokenization style. ### _run ```python def _run( self, messages: List[OpenAIMessage], response_format: Optional[Type[BaseModel]] = None, tools: Optional[List[Dict[str, Any]]] = None ): ``` Runs inference of OpenAI chat completion. **Parameters:** - **messages** (List[OpenAIMessage]): Message list with the chat history in OpenAI API format. - **response_format** (Optional[Type[BaseModel]]): The format of the response. - **tools** (Optional[List[Dict[str, Any]]]): The schema of the tools to use for the request. **Returns:** Union[ChatCompletion, Stream[ChatCompletionChunk], ChatCompletionStreamManager[BaseModel]]: `ChatCompletion` in the non-stream mode, `Stream[ChatCompletionChunk]`in the stream mode, or `ChatCompletionStreamManager[BaseModel]` for structured output streaming. ### _request_chat_completion ```python def _request_chat_completion( self, messages: List[OpenAIMessage], tools: Optional[List[Dict[str, Any]]] = None ): ``` ### _request_parse ```python def _request_parse( self, messages: List[OpenAIMessage], response_format: Type[BaseModel], tools: Optional[List[Dict[str, Any]]] = None ): ``` ### _request_stream_parse ```python def _request_stream_parse( self, messages: List[OpenAIMessage], response_format: Type[BaseModel], tools: Optional[List[Dict[str, Any]]] = None ): ``` Request streaming structured output parsing. ### stream ```python def stream(self): ``` **Returns:** bool: Whether the model is in stream mode. --- ## VLLMModel ```python class VLLMModel(OpenAICompatibleModel): ``` vLLM service interface. **Parameters:** - **model_type** (Union[ModelType, str]): Model for which a backend is created. - **model_config_dict** (Optional[Dict[str, Any]], optional): A dictionary that will be fed into:obj:`openai.ChatCompletion.create()`. If :obj:`None`, :obj:`VLLMConfig().as_dict()` will be used. (default: :obj:`None`) - **api_key** (Optional[str], optional): The API key for authenticating with the model service. vLLM doesn't need API key, it would be ignored if set. (default: :obj:`None`) - **url** (Optional[str], optional): The url to the model service. If not provided, :obj:`"http://localhost:8000/v1"` will be used. (default: :obj:`None`) - **token_counter** (Optional[BaseTokenCounter], optional): Token counter to use for the model. If not provided, :obj:`OpenAITokenCounter( ModelType.GPT_4O_MINI)` will be used. (default: :obj:`None`) - **timeout** (Optional[float], optional): The timeout value in seconds for API calls. If not provided, will fall back to the MODEL_TIMEOUT environment variable or default to 180 seconds. (default: :obj:`None`) - **max_retries** (int, optional): Maximum number of retries for API calls. (default: :obj:`3`) **kwargs (Any): Additional arguments to pass to the client initialization. - **References**: - **https**: //docs.vllm.ai/en/latest/serving/openai_compatible_server.html ### __init__ ```python def __init__( self, model_type: Union[ModelType, str], model_config_dict: Optional[Dict[str, Any]] = None, api_key: Optional[str] = None, url: Optional[str] = None, token_counter: Optional[BaseTokenCounter] = None, timeout: Optional[float] = None, max_retries: int = 3, **kwargs: Any ): ``` ### _start_server ```python def _start_server(self): ``` Starts the vllm server in a subprocess. --- ## BM25Retriever ```python class BM25Retriever(BaseRetriever): ``` An implementation of the `BaseRetriever` using the `BM25` model. This class facilitates the retriever of relevant information using a query-based approach, it ranks documents based on the occurrence and frequency of the query terms. **Parameters:** - **bm25** (BM25Okapi): An instance of the BM25Okapi class used for calculating document scores. - **content_input_path** (str): The path to the content that has been processed and stored. - **unstructured_modules** (UnstructuredIO): A module for parsing files and URLs and chunking content based on specified parameters. - **References**: - **https**: //github.com/dorianbrown/rank_bm25 ### __init__ ```python def __init__(self): ``` Initializes the BM25Retriever. ### process ```python def process( self, content_input_path: str, chunk_type: str = 'chunk_by_title', **kwargs: Any ): ``` Processes content from a file or URL, divides it into chunks by using `Unstructured IO`,then stored internally. This method must be called before executing queries with the retriever. **Parameters:** - **content_input_path** (str): File path or URL of the content to be processed. - **chunk_type** (str): Type of chunking going to apply. Defaults to "chunk_by_title". **kwargs (Any): Additional keyword arguments for content parsing. ### query ```python def query(self, query: str, top_k: int = DEFAULT_TOP_K_RESULTS): ``` Executes a query and compiles the results. **Parameters:** - **query** (str): Query string for information retriever. - **top_k** (int, optional): The number of top results to return during retriever. Must be a positive integer. Defaults to `DEFAULT_TOP_K_RESULTS`. **Returns:** List[Dict[str]]: Concatenated list of the query results. --- ## CohereRerankRetriever ```python class CohereRerankRetriever(BaseRetriever): ``` An implementation of the `BaseRetriever` using the `Cohere Re-ranking` model. **Parameters:** - **model_name** (str): The model name to use for re-ranking. - **api_key** (Optional[str]): The API key for authenticating with the Cohere service. - **References**: - **https**: //txt.cohere.com/rerank/ ### __init__ ```python def __init__( self, model_name: str = 'rerank-multilingual-v2.0', api_key: Optional[str] = None ): ``` Initializes an instance of the CohereRerankRetriever. This constructor sets up a client for interacting with the Cohere API using the specified model name and API key. If the API key is not provided, it attempts to retrieve it from the COHERE_API_KEY environment variable. **Parameters:** - **model_name** (str): The name of the model to be used for re-ranking. Defaults to 'rerank-multilingual-v2.0'. - **api_key** (Optional[str]): The API key for authenticating requests to the Cohere API. If not provided, the method will attempt to retrieve the key from the environment variable 'COHERE_API_KEY'. ### query ```python def query( self, query: str, retrieved_result: List[Dict[str, Any]], top_k: int = DEFAULT_TOP_K_RESULTS ): ``` Queries and compiles results using the Cohere re-ranking model. **Parameters:** - **query** (str): Query string for information retriever. - **retrieved_result** (List[Dict[str, Any]]): The content to be re-ranked, should be the output from `BaseRetriever` like `VectorRetriever`. - **top_k** (int, optional): The number of top results to return during retriever. Must be a positive integer. Defaults to `DEFAULT_TOP_K_RESULTS`. **Returns:** List[Dict[str, Any]]: Concatenated list of the query results. --- ## TaskConfig ```python class TaskConfig(BaseModel): ``` A configuration for a task to run a command inside the container. Arttributes: cmd (str or list): Command to be executed stdout (bool): Attach to stdout. (default: :obj:`True`) stderr (bool): Attach to stderr. (default: :obj:`True`) stdin (bool): Attach to stdin. (default: :obj:`False`) tty (bool): Allocate a pseudo-TTY. (default: :obj:`False`) privileged (bool): Run as privileged. (default: :obj:`False`) user (str): User to execute command as. (default: :obj:`""`) detach (bool): If true, detach from the exec command. (default: :obj:`False`) stream (bool): Stream response data. (default: :obj:`False`) socket (bool): Return the connection socket to allow custom read/write operations. (default: :obj:`False`) environment (dict or list): A dictionary or a list of strings in the following format `__INLINE_CODE_9__` or `__INLINE_CODE_10____INLINE_CODE_11__None`) workdir (str): Path to working directory for this exec session. (default: :obj:`None`) demux (bool): Return stdout and stderr separately. (default: :obj: `False`) --- ## DaytonaRuntime ```python class DaytonaRuntime(BaseRuntime): ``` A runtime that executes functions in a Daytona sandbox environment. Requires the Daytona server to be running and an API key configured. **Parameters:** - **api_key** (Optional[str]): The Daytona API key for authentication. If not provided, it will try to use the DAYTONA_API_KEY environment variable. (default: :obj:`None`) - **api_url** (Optional[str]): The URL of the Daytona server. If not provided, it will try to use the DAYTONA_API_URL environment variable. If none is provided, it will use "http://localhost:8000". (default: :obj:`None`) - **language** (Optional[str]): The programming language for the sandbox. (default: :obj:`"python"`) ### __init__ ```python def __init__( self, api_key: Optional[str] = None, api_url: Optional[str] = None, language: Optional[str] = 'python' ): ``` ### build ```python def build(self): ``` **Returns:** DaytonaRuntime: The current runtime. ### _cleanup ```python def _cleanup(self): ``` Clean up the sandbox when exiting. ### add ```python def add( self, funcs: Union[FunctionTool, List[FunctionTool]], entrypoint: str, arguments: Optional[Dict[str, Any]] = None ): ``` Add a function or list of functions to the runtime. **Parameters:** - **funcs** (Union[FunctionTool, List[FunctionTool]]): The function or list of functions to add. - **entrypoint** (str): The entrypoint for the function. - **arguments** (Optional[Dict[str, Any]]): The arguments for the function. (default: :obj:`None`) **Returns:** DaytonaRuntime: The current runtime. ### info ```python def info(self): ``` **Returns:** str: Information about the sandbox. ### __del__ ```python def __del__(self): ``` Clean up the sandbox when the object is deleted. ### stop ```python def stop(self): ``` **Returns:** DaytonaRuntime: The current runtime. ### reset ```python def reset(self): ``` **Returns:** DaytonaRuntime: The current runtime. ### docs ```python def docs(self): ``` **Returns:** str: The URL for the API documentation. --- ## DockerRuntime ```python class DockerRuntime(BaseRuntime): ``` A class representing a runtime environment using Docker. This class automatically wraps functions to be executed in a Docker container. **Parameters:** - **image** (str): The name of the Docker image to use for the runtime. - **port** (int): The port number to use for the runtime API. (default: :obj: `8000`) - **remove** (bool): Whether to remove the container after stopping it. ' (default: :obj:`True`) - **kwargs** (dict): Additional keyword arguments to pass to the Docker client. ### __init__ ```python def __init__( self, image: str, port: int = 8000, remove: bool = True, **kwargs ): ``` ### mount ```python def mount(self, path: str, mount_path: str): ``` Mount a local directory to the container. **Parameters:** - **path** (str): The local path to mount. - **mount_path** (str): The path to mount the local directory to in the container. **Returns:** DockerRuntime: The DockerRuntime instance. ### copy ```python def copy(self, source: str, dest: str): ``` Copy a file or directory to the container. **Parameters:** - **source** (str): The local path to the file. - **dest** (str): The path to copy the file to in the container. **Returns:** DockerRuntime: The DockerRuntime instance. ### add_task ```python def add_task(self, task: TaskConfig): ``` Add a task to run a command inside the container when building. Similar to `docker exec`. **Parameters:** - **task** (TaskConfig): The configuration for the task. **Returns:** DockerRuntime: The DockerRuntime instance. ### exec_run ```python def exec_run(self, task: TaskConfig): ``` Run a command inside this container. Similar to `docker exec`. **Parameters:** - **task** (TaskConfig): The configuration for the task. **Returns:** (ExecResult): A tuple of (exit_code, output) exit_code: (int): Exit code for the executed command or `None` if either `stream` or `socket` is `True`. output: (generator, bytes, or tuple): If `stream=True`, a generator yielding response chunks. If `socket=True`, a socket object for the connection. If `demux=True`, a tuple of two bytes: stdout and stderr. A bytestring containing response data otherwise. ### build ```python def build(self, time_out: int = 15): ``` Build the Docker container and start it. **Parameters:** - **time_out** (int): The number of seconds to wait for the container to start. (default: :obj:`15`) **Returns:** DockerRuntime: The DockerRuntime instance. ### add ```python def add( self, funcs: Union[FunctionTool, List[FunctionTool]], entrypoint: str, redirect_stdout: bool = False, arguments: Optional[Dict[str, Any]] = None ): ``` Add a function or list of functions to the runtime. **Parameters:** - **funcs** (Union[FunctionTool, List[FunctionTool]]): The function or list of functions to add. - **entrypoint** (str): The entrypoint for the function. - **redirect_stdout** (bool): Whether to return the stdout of the function. (default: :obj:`False`) - **arguments** (Optional[Dict[str, Any]]): The arguments for the function. (default: :obj:`None`) **Returns:** DockerRuntime: The DockerRuntime instance. ### reset ```python def reset(self): ``` **Returns:** DockerRuntime: The DockerRuntime instance. ### stop ```python def stop(self, remove: Optional[bool] = None): ``` stop the Docker container. **Parameters:** - **remove** (Optional[bool]): Whether to remove the container after stopping it. (default: :obj:`None`) **Returns:** DockerRuntime: The DockerRuntime instance. ### ok ```python def ok(self): ``` **Returns:** bool: Whether the API Server is running. ### wait ```python def wait(self, timeout: int = 10): ``` Wait for the API Server to be ready. **Parameters:** - **timeout** (int): The number of seconds to wait. (default: :obj:`10`) (default: 10) **Returns:** bool: Whether the API Server is ready. ### __enter__ ```python def __enter__(self): ``` **Returns:** DockerRuntime: The DockerRuntime instance. ### __exit__ ```python def __exit__( self, exc_type, exc_val, exc_tb ): ``` Exit the context manager. ### docs ```python def docs(self): ``` **Returns:** str: The URL for the API documentation. --- ## RemoteHttpRuntime ```python class RemoteHttpRuntime(BaseRuntime): ``` A runtime that runs functions in a remote HTTP server. You need to run the API server in the remote server first. **Parameters:** - **host** (str): The host of the remote server. - **port** (int): The port of the remote server. (default: :obj:`8000`) (default: 8000) - **python_exec** (str): The python executable to run the API server. (default: :obj:`python3`) ### __init__ ```python def __init__( self, host: str, port: int = 8000, python_exec: str = 'python3' ): ``` ### build ```python def build(self): ``` **Returns:** RemoteHttpRuntime: The current runtime. ### _cleanup ```python def _cleanup(self): ``` Clean up the API server when exiting. ### add ```python def add( self, funcs: Union[FunctionTool, List[FunctionTool]], entrypoint: str, redirect_stdout: bool = False, arguments: Optional[Dict[str, Any]] = None ): ``` Add a function or list of functions to the runtime. **Parameters:** - **funcs** (Union[FunctionTool, List[FunctionTool]]): The function or list of functions to add. - **entrypoint** (str): The entrypoint for the function. - **redirect_stdout** (bool): Whether to return the stdout of the function. (default: :obj:`False`) - **arguments** (Optional[Dict[str, Any]]): The arguments for the function. (default: :obj:`None`) **Returns:** RemoteHttpRuntime: The current runtime. ### ok ```python def ok(self): ``` **Returns:** bool: Whether the API Server is running. ### wait ```python def wait(self, timeout: int = 10): ``` Wait for the API Server to be ready. **Parameters:** - **timeout** (int): The number of seconds to wait. (default: :obj:`10`) (default: 10) **Returns:** bool: Whether the API Server is ready. ### __del__ ```python def __del__(self): ``` Clean up the API server when the object is deleted. ### stop ```python def stop(self): ``` **Returns:** RemoteHttpRuntime: The current runtime. ### reset ```python def reset(self): ``` **Returns:** RemoteHttpRuntime: The current runtime. ### docs ```python def docs(self): ``` **Returns:** str: The URL for the API documentation. --- ## InitRequest ```python class InitRequest(BaseModel): ``` Request schema for initializing a ChatAgent via the OpenAPI server. Defines the configuration used to create a new agent, including the model, system message, tool names, and generation parameters. **Parameters:** - **model_type** (Optional[str]): The model type to use. Should match a key supported by the model manager, e.g., "gpt-4o-mini". (default: :obj:`"gpt-4o-mini"`) - **model_platform** (Optional[str]): The model platform to use. (default: :obj:`"openai"`) - **tools_names** (Optional[List[str]]): A list of tool names to load from the tool registry. These tools will be available to the agent. (default: :obj:`None`) - **external_tools** (Optional[List[Dict[str, Any]]]): Tool definitions provided directly as dictionaries, bypassing the registry. Currently not supported. (default: :obj:`None`) - **agent_id** (str): The unique identifier for the agent. Must be provided explicitly to support multi-agent routing and control. - **system_message** (Optional[str]): The system prompt for the agent, describing its behavior or role. (default: :obj:`None`) - **message_window_size** (Optional[int]): The number of recent messages to retain in memory for context. (default: :obj:`None`) - **token_limit** (Optional[int]): The token budget for contextual memory. (default: :obj:`None`) - **output_language** (Optional[str]): Preferred output language for the agent's replies. (default: :obj:`None`) - **max_iteration** (Optional[int]): Maximum number of model calling iterations allowed per step. If `None` (default), there's no explicit limit. If `1`, it performs a single model call. If `N > 1`, it allows up to N model calls. (default: :obj:`None`) ## StepRequest ```python class StepRequest(BaseModel): ``` Request schema for sending a user message to a ChatAgent. Supports plain text input or structured message dictionaries, with an optional response format for controlling output structure. **Parameters:** - **input_message** (Union[str, Dict[str, Any]]): The user message to send. Can be a plain string or a message dict with role, content, etc. - **response_format** (Optional[str]): Optional format name that maps to a registered response schema. Not currently in use. (default: :obj:`None`) ## ChatAgentOpenAPIServer ```python class ChatAgentOpenAPIServer: ``` A FastAPI server wrapper for managing ChatAgents via OpenAPI routes. This server exposes a versioned REST API for interacting with CAMEL agents, supporting initialization, message passing, memory inspection, and optional tool usage. It supports multi-agent use cases by mapping unique agent IDs to active ChatAgent instances. Typical usage includes initializing agents with system prompts and tools, exchanging messages using /step or /astep endpoints, and inspecting agent memory with /history. Supports pluggable tool and response format registries for customizing agent behavior or output schemas. ### __init__ ```python def __init__( self, tool_registry: Optional[Dict[str, List[FunctionTool]]] = None, response_format_registry: Optional[Dict[str, Type[BaseModel]]] = None ): ``` Initializes the OpenAPI server for managing ChatAgents. Sets up internal agent storage, tool and response format registries, and prepares versioned API routes. **Parameters:** - **tool_registry** (Optional[Dict[str, List[FunctionTool]]]): A mapping from tool names to lists of FunctionTool instances available to agents via the "tools_names" field. If not provided, an empty registry is used. (default: :obj:`None`) - **response_format_registry** (Optional[Dict[str, Type[BaseModel]]]): A mapping from format names to Pydantic output schemas for structured response parsing. Used for controlling the format of step results. (default: :obj:`None`) ### _parse_input_message_for_step ```python def _parse_input_message_for_step(self, raw: Union[str, dict]): ``` Parses raw input into a BaseMessage object. **Parameters:** - **raw** (str or dict): User input as plain text or dict. **Returns:** BaseMessage: Parsed input message. ### _resolve_response_format_for_step ```python def _resolve_response_format_for_step(self, name: Optional[str]): ``` Resolves the response format by name. **Parameters:** - **name** (str or None): Optional format name. **Returns:** Optional[Type[BaseModel]]: Response schema class. ### _setup_routes ```python def _setup_routes(self): ``` Registers OpenAPI endpoints for agent creation and interaction. This includes routes for initializing agents (/init), sending messages (/step and /astep), resetting agent memory (/reset), and retrieving conversation history (/history). All routes are added under the /v1/agents namespace. ### get_app ```python def get_app(self): ``` **Returns:** FastAPI: The wrapped application object. --- ## RolePlaying ```python class RolePlaying: ``` Role playing between two agents. **Parameters:** - **assistant_role_name** (str): The name of the role played by the assistant. - **user_role_name** (str): The name of the role played by the user. - **critic_role_name** (str, optional): The name of the role played by the critic. Role name with :obj:`"human"` will set critic as a :obj:`Human` agent, else will create a :obj:`CriticAgent`. (default: :obj:`"critic"`) - **task_prompt** (str, optional): A prompt for the task to be performed. (default: :obj:`""`) - **with_task_specify** (bool, optional): Whether to use a task specify agent. (default: :obj:`True`) - **with_task_planner** (bool, optional): Whether to use a task planner agent. (default: :obj:`False`) - **with_critic_in_the_loop** (bool, optional): Whether to include a critic in the loop. (default: :obj:`False`) - **critic_criteria** (str, optional): Critic criteria for the critic agent. If not specified, set the criteria to improve task performance. - **model** (BaseModelBackend, optional): The model backend to use for generating responses. If specified, it will override the model in all agents if not specified in agent-specific kwargs. (default: :obj:`OpenAIModel` with `GPT_4O_MINI`) - **task_type** (TaskType, optional): The type of task to perform. (default: :obj:`TaskType.AI_SOCIETY`) - **assistant_agent_kwargs** (Dict, optional): Additional arguments to pass to the assistant agent. (default: :obj:`None`) - **user_agent_kwargs** (Dict, optional): Additional arguments to pass to the user agent. (default: :obj:`None`) - **task_specify_agent_kwargs** (Dict, optional): Additional arguments to pass to the task specify agent. (default: :obj:`None`) - **task_planner_agent_kwargs** (Dict, optional): Additional arguments to pass to the task planner agent. (default: :obj:`None`) - **critic_kwargs** (Dict, optional): Additional arguments to pass to the critic. (default: :obj:`None`) - **sys_msg_generator_kwargs** (Dict, optional): Additional arguments to pass to the system message generator. (default: :obj:`None`) - **extend_sys_msg_meta_dicts** (List[Dict], optional): A list of dicts to extend the system message meta dicts with. (default: :obj:`None`) - **extend_task_specify_meta_dict** (Dict, optional): A dict to extend the task specify meta dict with. (default: :obj:`None`) - **output_language** (str, optional): The language to be output by the agents. (default: :obj:`None`) - **stop_event** (Optional[threading.Event], optional): Event to signal termination of the agent's operation. When set, the agent will terminate its execution. (default: :obj:`None`) ### __init__ ```python def __init__(self, assistant_role_name: str, user_role_name: str): ``` ### _init_specified_task_prompt ```python def _init_specified_task_prompt( self, assistant_role_name: str, user_role_name: str, task_specify_agent_kwargs: Optional[Dict] = None, extend_task_specify_meta_dict: Optional[Dict] = None, output_language: Optional[str] = None ): ``` Use a task specify agent to generate a specified task prompt. Generated specified task prompt will be used to replace original task prompt. If there is no task specify agent, specified task prompt will not be generated. **Parameters:** - **assistant_role_name** (str): The name of the role played by the assistant. - **user_role_name** (str): The name of the role played by the user. - **task_specify_agent_kwargs** (Dict, optional): Additional arguments to pass to the task specify agent. (default: :obj:`None`) - **extend_task_specify_meta_dict** (Dict, optional): A dict to extend the task specify meta dict with. (default: :obj:`None`) - **output_language** (str, optional): The language to be output by the agents. (default: :obj:`None`) ### _init_planned_task_prompt ```python def _init_planned_task_prompt( self, task_planner_agent_kwargs: Optional[Dict] = None, output_language: Optional[str] = None ): ``` Use a task plan agent to append a planned task prompt to task prompt. The planned task prompt is generated based on the task prompt, which can be original task prompt or specified task prompt if available. If there is no task plan agent, planned task prompt will not be generated. **Parameters:** - **task_planner_agent_kwargs** (Dict, optional): Additional arguments to pass to the task planner agent. (default: :obj:`None`) - **output_language** (str, optional): The language to be output by the agents. (default: :obj:`None`) ### _get_sys_message_info ```python def _get_sys_message_info( self, assistant_role_name: str, user_role_name: str, sys_msg_generator: SystemMessageGenerator, extend_sys_msg_meta_dicts: Optional[List[Dict]] = None ): ``` Get initial assistant and user system message with a list of system message meta dicts. **Parameters:** - **assistant_role_name** (str): The name of the role played by the assistant. - **user_role_name** (str): The name of the role played by the user. - **sys_msg_generator** (SystemMessageGenerator): A system message generator for agents. - **extend_sys_msg_meta_dicts** (List[Dict], optional): A list of dicts to extend the system message meta dicts with. (default: :obj:`None`) **Returns:** Tuple[BaseMessage, BaseMessage, List[Dict]]: A tuple containing a `BaseMessage` representing the assistant's initial system message, a `BaseMessage` representing the user's initial system message, and a list of system message meta dicts. ### _init_agents ```python def _init_agents( self, init_assistant_sys_msg: BaseMessage, init_user_sys_msg: BaseMessage, assistant_agent_kwargs: Optional[Dict] = None, user_agent_kwargs: Optional[Dict] = None, output_language: Optional[str] = None, stop_event: Optional[threading.Event] = None ): ``` Initialize assistant and user agents with their system messages. **Parameters:** - **init_assistant_sys_msg** (BaseMessage): Assistant agent's initial system message. - **init_user_sys_msg** (BaseMessage): User agent's initial system message. - **assistant_agent_kwargs** (Dict, optional): Additional arguments to pass to the assistant agent. (default: :obj:`None`) - **user_agent_kwargs** (Dict, optional): Additional arguments to pass to the user agent. (default: :obj:`None`) - **output_language** (str, optional): The language to be output by the agents. (default: :obj:`None`) - **stop_event** (Optional[threading.Event], optional): Event to signal termination of the agent's operation. When set, the agent will terminate its execution. (default: :obj:`None`) ### _init_critic ```python def _init_critic( self, sys_msg_generator: SystemMessageGenerator, sys_msg_meta_dicts: List[Dict], critic_role_name: str, critic_criteria: Optional[str] = None, critic_kwargs: Optional[Dict] = None ): ``` Initialize critic agent. If critic role name is :obj:`"human"`, create a :obj:`Human` critic agent. Else, create a :obj:`CriticAgent` critic agent with specified critic criteria. If the critic criteria is not specified, set it to improve task performance. **Parameters:** - **sys_msg_generator** (SystemMessageGenerator): A system message generator for agents. - **sys_msg_meta_dicts** (list): A list of system message meta dicts. - **critic_role_name** (str): The name of the role played by the critic. - **critic_criteria** (str, optional): Critic criteria for the critic agent. If not specified, set the criteria to improve task performance. (default: :obj:`None`) - **critic_kwargs** (Dict, optional): Additional arguments to pass to the critic. (default: :obj:`None`) ### _reduce_message_options ```python def _reduce_message_options(self, messages: Sequence[BaseMessage]): ``` Processes a sequence of chat messages, returning the processed message. If multiple messages are provided and `with_critic_in_the_loop` is `False`, raises a `ValueError`. If no messages are provided, a `ValueError` will be raised. **Parameters:** - **messages** (Sequence[BaseMessage]): A sequence of `BaseMessage` objects to process. **Returns:** BaseMessage: A single `BaseMessage` representing the processed message. ### init_chat ```python def init_chat(self, init_msg_content: Optional[str] = None): ``` Initializes the chat by resetting both of the assistant and user agents. Returns an initial message for the role-playing session. **Parameters:** - **init_msg_content** (str, optional): A user-specified initial message. Will be sent to the role-playing session as the initial message. (default: :obj:`None`) **Returns:** BaseMessage: A single `BaseMessage` representing the initial message. ### step ```python def step(self, assistant_msg: BaseMessage): ``` Advances the conversation by taking a message from the assistant, processing it using the user agent, and then processing the resulting message using the assistant agent. Returns a tuple containing the resulting assistant message, whether the assistant agent terminated the conversation, and any additional assistant information, as well as a tuple containing the resulting user message, whether the user agent terminated the conversation, and any additional user information. **Parameters:** - **assistant_msg**: A `BaseMessage` representing the message from the assistant. **Returns:** Tuple[ChatAgentResponse, ChatAgentResponse]: A tuple containing two ChatAgentResponse: the first struct contains the resulting assistant message, whether the assistant agent terminated the conversation, and any additional assistant information; the second struct contains the resulting user message, whether the user agent terminated the conversation, and any additional user information. ### clone ```python def clone(self, task_prompt: str, with_memory: bool = False): ``` Creates a new instance of RolePlaying with the same configuration. **Parameters:** - **task_prompt** (str): The task prompt to be used by the new instance. - **with_memory** (bool, optional): Whether to copy the memory (conversation history) to the new instance. If True, the new instance will have the same conversation history. If False, the new instance will have a fresh memory. (default: :obj:`False`) **Returns:** RolePlaying: A new instance of RolePlaying with the same configuration. ### _is_multi_response ```python def _is_multi_response(self, agent: ChatAgent): ``` Checks if the given agent supports multi-response. **Parameters:** - **agent** (ChatAgent): The agent to check for multi-response support. **Returns:** bool: True if the agent supports multi-response, False otherwise. --- ## RolePlayingWorker ```python class RolePlayingWorker(Worker): ``` A worker node that contains a role playing. **Parameters:** - **description** (str): Description of the node. - **assistant_role_name** (str): The role name of the assistant agent. - **user_role_name** (str): The role name of the user agent. - **assistant_agent_kwargs** (Optional[Dict]): The keyword arguments to initialize the assistant agent in the role playing, like the model name, etc. (default: :obj:`None`) - **user_agent_kwargs** (Optional[Dict]): The keyword arguments to initialize the user agent in the role playing, like the model name, etc. (default: :obj:`None`) - **summarize_agent_kwargs** (Optional[Dict]): The keyword arguments to initialize the summarize agent, like the model name, etc. (default: :obj:`None`) - **chat_turn_limit** (int): The maximum number of chat turns in the role playing. (default: :obj:`20`) - **use_structured_output_handler** (bool, optional): Whether to use the structured output handler instead of native structured output. When enabled, the workforce will use prompts with structured output instructions and regex extraction to parse responses. This ensures compatibility with agents that don't reliably support native structured output. When disabled, the workforce uses the native response_format parameter. (default: :obj:`True`) ### __init__ ```python def __init__( self, description: str, assistant_role_name: str, user_role_name: str, assistant_agent_kwargs: Optional[Dict] = None, user_agent_kwargs: Optional[Dict] = None, summarize_agent_kwargs: Optional[Dict] = None, chat_turn_limit: int = 20, use_structured_output_handler: bool = True ): ``` --- ## AgentPool ```python class AgentPool: ``` A pool of agent instances for efficient reuse. This pool manages a collection of pre-cloned agents. It supports auto-scaling based ondemand and intelligent reuse of existing agents. **Parameters:** - **base_agent** (ChatAgent): The base agent to clone from. - **initial_size** (int): Initial number of agents in the pool. (default: :obj:`1`) - **max_size** (int): Maximum number of agents in the pool. (default: :obj:`10`) - **auto_scale** (bool): Whether to automatically scale the pool size. (default: :obj:`True`) - **idle_timeout** (float): Time in seconds after which idle agents are removed. (default: :obj:`180.0`) ### __init__ ```python def __init__( self, base_agent: ChatAgent, initial_size: int = 1, max_size: int = 10, auto_scale: bool = True, idle_timeout: float = 180.0 ): ``` ### _initialize_pool ```python def _initialize_pool(self, size: int): ``` Initialize the pool with the specified number of agents. ### _create_fresh_agent ```python def _create_fresh_agent(self): ``` Create a fresh agent instance. ### get_stats ```python def get_stats(self): ``` Get pool statistics. ## SingleAgentWorker ```python class SingleAgentWorker(Worker): ``` A worker node that consists of a single agent. **Parameters:** - **description** (str): Description of the node. - **worker** (ChatAgent): Worker of the node. A single agent. - **use_agent_pool** (bool): Whether to use agent pool for efficiency. (default: :obj:`True`) - **pool_initial_size** (int): Initial size of the agent pool. (default: :obj:`1`) - **pool_max_size** (int): Maximum size of the agent pool. (default: :obj:`10`) - **auto_scale_pool** (bool): Whether to auto-scale the agent pool. (default: :obj:`True`) - **use_structured_output_handler** (bool, optional): Whether to use the structured output handler instead of native structured output. When enabled, the workforce will use prompts with structured output instructions and regex extraction to parse responses. This ensures compatibility with agents that don't reliably support native structured output. When disabled, the workforce uses the native response_format parameter. (default: :obj:`True`) ### __init__ ```python def __init__( self, description: str, worker: ChatAgent, use_agent_pool: bool = True, pool_initial_size: int = 1, pool_max_size: int = 10, auto_scale_pool: bool = True, use_structured_output_handler: bool = True ): ``` ### reset ```python def reset(self): ``` Resets the worker to its initial state. ### get_pool_stats ```python def get_pool_stats(self): ``` Get agent pool statistics if pool is enabled. --- ## StructuredOutputHandler ```python class StructuredOutputHandler: ``` Handler for generating prompts and extracting structured output from agent responses. This handler provides functionality to: - Generate prompts that guide agents to produce structured output - Extract structured data from agent responses using regex patterns - Provide fallback mechanisms when extraction fails - Support the existing structured output schemas used in workforce.py ### generate_structured_prompt ```python def generate_structured_prompt( base_prompt: str, schema: Type[BaseModel], examples: Optional[List[Dict[str, Any]]] = None, additional_instructions: Optional[str] = None ): ``` Generate a prompt that guides agents to produce structured output. **Parameters:** - **base_prompt** (str): The base prompt content. - **schema** (Type[BaseModel]): The Pydantic model schema for the expected output. - **examples** (Optional[List[Dict[str, Any]]]): Optional examples of valid output. - **additional_instructions** (Optional[str]): Additional instructions for output formatting. **Returns:** str: The enhanced prompt with structured output instructions. ### extract_json ```python def extract_json(text: str, schema: Optional[Type[BaseModel]] = None): ``` Extract JSON data from text using multiple patterns. **Parameters:** - **text** (str): The text containing JSON data. - **schema** (Optional[Type[BaseModel]]): Optional schema for targeted extraction. **Returns:** Optional[Dict[str, Any]]: Extracted JSON data or None if extraction fails. ### _extract_with_schema_patterns ```python def _extract_with_schema_patterns(text: str, schema: Type[BaseModel]): ``` Extract data using schema-specific patterns. **Parameters:** - **text** (str): The text to extract from. - **schema** (Type[BaseModel]): The schema to use for extraction. **Returns:** Optional[Dict[str, Any]]: Extracted data or None. ### parse_structured_response ```python def parse_structured_response( response_text: str, schema: Type[BaseModel], fallback_values: Optional[Dict[str, Any]] = None ): ``` Parse agent response into structured data with fallback support. **Parameters:** - **response_text** (str): The agent's response text. - **schema** (Type[BaseModel]): The expected schema. - **fallback_values** (Optional[Dict[str, Any]]): Fallback values to use if parsing fails. **Returns:** Union[BaseModel, Dict[str, Any]]: Parsed data as schema instance or fallback dictionary. ### _fix_common_issues ```python def _fix_common_issues(data: Dict[str, Any], schema: Type[BaseModel]): ``` Attempt to fix common validation issues in extracted data. **Parameters:** - **data** (Dict[str, Any]): The extracted data. - **schema** (Type[BaseModel]): The target schema. **Returns:** Optional[Dict[str, Any]]: Fixed data or None if unfixable. ### _create_default_instance ```python def _create_default_instance(schema: Type[BaseModel]): ``` Create a default instance of the schema with minimal required fields. **Parameters:** - **schema** (Type[BaseModel]): The schema to instantiate. **Returns:** BaseModel: Default instance of the schema. ### validate_response ```python def validate_response( response: Union[BaseModel, Dict[str, Any]], schema: Type[BaseModel] ): ``` Validate that a response conforms to the expected schema. **Parameters:** - **response**: The response to validate. - **schema** (Type[BaseModel]): The expected schema. **Returns:** bool: True if valid, False otherwise. ### create_fallback_response ```python def create_fallback_response( schema: Type[BaseModel], error_message: str, context: Optional[Dict[str, Any]] = None ): ``` Create a fallback response for a given schema with error context. **Parameters:** - **schema** (Type[BaseModel]): The schema to create a response for. - **error_message** (str): The error message to include. - **context** (Optional[Dict[str, Any]]): Additional context for the fallback. **Returns:** BaseModel: A valid instance of the schema with fallback values. --- ## PacketStatus ```python class PacketStatus(Enum): ``` The status of a packet. The packet can be in one of the following states: - `__INLINE_CODE_0__`: The packet has been sent to a worker. - `__INLINE_CODE_1__`: The packet has been claimed by a worker and is being processed. - `__INLINE_CODE_2__`: The packet has been returned by the worker, meaning that the status of the task inside has been updated. - `__INLINE_CODE_3__`: The packet has been archived, meaning that the content of the task inside will not be changed. The task is considered as a dependency. ## Packet ```python class Packet: ``` The basic element inside the channel. A task is wrapped inside a packet. The packet will contain the task, along with the task's assignee, and the task's status. **Parameters:** - **task** (Task): The task that is wrapped inside the packet. - **publisher_id** (str): The ID of the workforce that published the task. - **assignee_id** (Optional[str], optional): The ID of the workforce that is assigned to the task. Would be None if the task is a dependency. Defaults to None. - **status** (PacketStatus): The status of the task. ### __init__ ```python def __init__( self, task: Task, publisher_id: str, assignee_id: Optional[str] = None, status: PacketStatus = PacketStatus.SENT ): ``` ### __repr__ ```python def __repr__(self): ``` ## TaskChannel ```python class TaskChannel: ``` An internal class used by Workforce to manage tasks. ### __init__ ```python def __init__(self): ``` --- ## WorkerConf ```python class WorkerConf(BaseModel): ``` The configuration of a worker. ## TaskResult ```python class TaskResult(BaseModel): ``` The result of a task. ## TaskAssignment ```python class TaskAssignment(BaseModel): ``` An individual task assignment within a batch. ### _split_and_strip ```python def _split_and_strip(dep_str: str): ``` Utility to split a comma separated string and strip whitespace. ### validate_dependencies ```python def validate_dependencies(cls, v): ``` ## TaskAssignResult ```python class TaskAssignResult(BaseModel): ``` The result of task assignment for both single and batch assignments. ## RecoveryStrategy ```python class RecoveryStrategy(str, Enum): ``` Strategies for handling failed tasks. ### __str__ ```python def __str__(self): ``` ### __repr__ ```python def __repr__(self): ``` ## FailureContext ```python class FailureContext(BaseModel): ``` Context information about a task failure. ## RecoveryDecision ```python class RecoveryDecision(BaseModel): ``` Decision on how to recover from a task failure. ## check_if_running ```python def check_if_running( running: bool, max_retries: int = 3, retry_delay: float = 1.0, handle_exceptions: bool = False ): ``` Check if the workforce is (not) running, specified by the boolean value. Provides fault tolerance through automatic retries and exception handling. **Parameters:** - **running** (bool): Expected running state (True or False). - **max_retries** (int, optional): Maximum number of retry attempts if the operation fails. Set to 0 to disable retries. (default: :obj:`3`) - **retry_delay** (float, optional): Delay in seconds between retry attempts. (default: :obj:`1.0`) - **handle_exceptions** (bool, optional): If True, catch and log exceptions instead of propagating them. (default: :obj:`False`) **Raises:** - **RuntimeError**: If the workforce is not in the expected status and - **Exception**: Any exception raised by the decorated function if --- ## Worker ```python class Worker(BaseNode, ABC): ``` A worker node that works on tasks. It is the basic unit of task processing in the workforce system. **Parameters:** - **description** (str): Description of the node. - **node_id** (Optional[str]): ID of the node. If not provided, it will be generated automatically. (default: :obj:`None`) ### __init__ ```python def __init__(self, description: str, node_id: Optional[str] = None): ``` ### __repr__ ```python def __repr__(self): ``` ### _get_dep_tasks_info ```python def _get_dep_tasks_info(dependencies: List[Task]): ``` ### set_channel ```python def set_channel(self, channel: TaskChannel): ``` ### stop ```python def stop(self): ``` Stop the worker. --- ## WorkforceState ```python class WorkforceState(Enum): ``` Workforce execution state for human intervention support. ## WorkforceSnapshot ```python class WorkforceSnapshot: ``` Snapshot of workforce state for resuming execution. ### __init__ ```python def __init__( self, main_task: Optional[Task] = None, pending_tasks: Optional[Deque[Task]] = None, completed_tasks: Optional[List[Task]] = None, task_dependencies: Optional[Dict[str, List[str]]] = None, assignees: Optional[Dict[str, str]] = None, current_task_index: int = 0, description: str = '' ): ``` ## Workforce ```python class Workforce(BaseNode): ``` A system where multiple worker nodes (agents) cooperate together to solve tasks. It can assign tasks to worker nodes and also take strategies such as create new worker, decompose tasks, etc. to handle situations when the task fails. The workforce uses three specialized ChatAgents internally: - Coordinator Agent: Assigns tasks to workers based on their capabilities - Task Planner Agent: Decomposes complex tasks and composes results - Dynamic Workers: Created at runtime when tasks fail repeatedly **Parameters:** - **description** (str): Description of the workforce. - **children** (Optional[List[BaseNode]], optional): List of child nodes under this node. Each child node can be a worker node or another workforce node. (default: :obj:`None`) - **coordinator_agent** (Optional[ChatAgent], optional): A custom coordinator agent instance for task assignment and worker creation. If provided, the workforce will create a new agent using this agent's model configuration but with the required system message and functionality. If None, a default agent will be created using DEFAULT model settings. (default: :obj:`None`) - **task_agent** (Optional[ChatAgent], optional): A custom task planning agent instance for task decomposition and composition. If provided, the workforce will create a new agent using this agent's model configuration but with the required system message and tools (TaskPlanningToolkit). If None, a default agent will be created using DEFAULT model settings. (default: :obj:`None`) - **new_worker_agent** (Optional[ChatAgent], optional): A template agent for workers created dynamically at runtime when existing workers cannot handle failed tasks. If None, workers will be created with default settings including SearchToolkit, CodeExecutionToolkit, and ThinkingToolkit. (default: :obj:`None`) - **graceful_shutdown_timeout** (float, optional): The timeout in seconds for graceful shutdown when a task fails 3 times. During this period, the workforce remains active for debugging. Set to 0 for immediate shutdown. (default: :obj:`15.0`) - **share_memory** (bool, optional): Whether to enable shared memory across SingleAgentWorker instances in the workforce. When enabled, all SingleAgentWorker instances, coordinator agent, and task planning agent will share their complete conversation history and function-calling trajectory, providing better context for task handoffs and continuity. Note: Currently only supports SingleAgentWorker instances; RolePlayingWorker and nested Workforce instances do not participate in memory sharing. (default: :obj:`False`) - **use_structured_output_handler** (bool, optional): Whether to use the structured output handler instead of native structured output. When enabled, the workforce will use prompts with structured output instructions and regex extraction to parse responses. This ensures compatibility with agents that don't reliably support native structured output. When disabled, the workforce uses the native response_format parameter. (default: :obj:`True`) **Note:** When custom coordinator_agent or task_agent are provided, the workforce will preserve the user's system message and append the required workforce coordination or task planning instructions to it. This ensures both the user's intent is preserved and proper workforce functionality is maintained. All other agent configurations (model, memory, tools, etc.) will also be preserved. ### __init__ ```python def __init__( self, description: str, children: Optional[List[BaseNode]] = None, coordinator_agent: Optional[ChatAgent] = None, task_agent: Optional[ChatAgent] = None, new_worker_agent: Optional[ChatAgent] = None, graceful_shutdown_timeout: float = 15.0, share_memory: bool = False, use_structured_output_handler: bool = True ): ``` ### _validate_agent_compatibility ```python def _validate_agent_compatibility(self, agent: ChatAgent, agent_context: str = 'agent'): ``` Validate that agent configuration is compatible with workforce settings. **Parameters:** - **agent** (ChatAgent): The agent to validate. - **agent_context** (str): Context description for error messages. ### _attach_pause_event_to_agent ```python def _attach_pause_event_to_agent(self, agent: ChatAgent): ``` Ensure the given ChatAgent shares this workforce's pause_event. If the agent already has a different pause_event we overwrite it and emit a debug log (it is unlikely an agent needs multiple independent pause controls once managed by this workforce). ### _ensure_pause_event_in_kwargs ```python def _ensure_pause_event_in_kwargs(self, kwargs: Optional[Dict]): ``` Insert pause_event into kwargs dict for ChatAgent construction. ### __repr__ ```python def __repr__(self): ``` ### _collect_shared_memory ```python def _collect_shared_memory(self): ``` **Returns:** Dict[str, List]: A dictionary mapping agent types to their memory records. Contains entries for 'coordinator', 'task_agent', and 'workers'. ### _share_memory_with_agents ```python def _share_memory_with_agents(self, shared_memory: Dict[str, List]): ``` Share collected memory with coordinator, task agent, and SingleAgentWorker instances. **Parameters:** - **shared_memory** (Dict[str, List]): Memory records collected from all agents to be shared. ### _sync_shared_memory ```python def _sync_shared_memory(self): ``` Synchronize memory across all agents by collecting and sharing. ### _update_dependencies_for_decomposition ```python def _update_dependencies_for_decomposition(self, original_task: Task, subtasks: List[Task]): ``` Update dependency tracking when a task is decomposed into subtasks. Tasks that depended on the original task should now depend on all subtasks. The last subtask inherits the original task's dependencies. ### _increment_in_flight_tasks ```python def _increment_in_flight_tasks(self, task_id: str): ``` Safely increment the in-flight tasks counter with logging. ### _decrement_in_flight_tasks ```python def _decrement_in_flight_tasks(self, task_id: str, context: str = ''): ``` Safely decrement the in-flight tasks counter with safety checks. ### _cleanup_task_tracking ```python def _cleanup_task_tracking(self, task_id: str): ``` Clean up tracking data for a task to prevent memory leaks. **Parameters:** - **task_id** (str): The ID of the task to clean up. ### _decompose_task ```python def _decompose_task(self, task: Task): ``` **Returns:** Union[List[Task], Generator[List[Task], None, None]]: The subtasks or generator of subtasks. ### _analyze_failure ```python def _analyze_failure(self, task: Task, error_message: str): ``` Analyze a task failure and decide on the best recovery strategy. **Parameters:** - **task** (Task): The failed task - **error_message** (str): The error message from the failure **Returns:** RecoveryDecision: The decided recovery strategy with reasoning ### pause ```python def pause(self): ``` Pause the workforce execution. If the internal event-loop is already running we schedule the asynchronous pause coroutine onto it. When the loop has not yet been created (e.g. the caller presses the hot-key immediately after workforce start-up) we fall back to a synchronous state change so that no tasks will be scheduled until the loop is ready. ### resume ```python def resume(self): ``` Resume execution after a manual pause. ### stop_gracefully ```python def stop_gracefully(self): ``` Request workforce to finish current in-flight work then halt. Works both when the internal event-loop is alive and when it has not yet been started. In the latter case we simply mark the stop flag so that the loop (when it eventually starts) will exit immediately after initialisation. ### save_snapshot ```python def save_snapshot(self, description: str = ''): ``` Save current state as a snapshot. ### list_snapshots ```python def list_snapshots(self): ``` List all available snapshots. ### get_pending_tasks ```python def get_pending_tasks(self): ``` Get current pending tasks for human review. ### get_completed_tasks ```python def get_completed_tasks(self): ``` Get completed tasks. ### modify_task_content ```python def modify_task_content(self, task_id: str, new_content: str): ``` Modify the content of a pending task. ### add_task ```python def add_task( self, content: str, task_id: Optional[str] = None, additional_info: Optional[Dict[str, Any]] = None, insert_position: int = -1 ): ``` Add a new task to the pending queue. ### remove_task ```python def remove_task(self, task_id: str): ``` Remove a task from the pending queue. ### reorder_tasks ```python def reorder_tasks(self, task_ids: List[str]): ``` Reorder pending tasks according to the provided task IDs list. ### resume_from_task ```python def resume_from_task(self, task_id: str): ``` Resume execution from a specific task. ### restore_from_snapshot ```python def restore_from_snapshot(self, snapshot_index: int): ``` Restore workforce state from a snapshot. ### get_workforce_status ```python def get_workforce_status(self): ``` Get current workforce status for human review. ### process_task ```python def process_task(self, task: Task): ``` Synchronous wrapper for process_task that handles async operations internally. **Parameters:** - **task** (Task): The task to be processed. **Returns:** Task: The updated task. ### _process_task_with_intervention ```python def _process_task_with_intervention(self, task: Task): ``` Process task with human intervention support. This creates and manages its own event loop to allow for pausing/resuming functionality. **Parameters:** - **task** (Task): The task to be processed. **Returns:** Task: The updated task. ### continue_from_pause ```python def continue_from_pause(self): ``` **Returns:** Optional[Task]: The completed task if execution finishes, None if still running/paused. ### _start_child_node_when_paused ```python def _start_child_node_when_paused(self, start_coroutine: Coroutine): ``` Helper to start a child node when workforce is paused. **Parameters:** - **start_coroutine**: The coroutine to start (e.g., worker_node.start()) ### add_single_agent_worker ```python def add_single_agent_worker( self, description: str, worker: ChatAgent, pool_max_size: int = DEFAULT_WORKER_POOL_SIZE ): ``` Add a worker node to the workforce that uses a single agent. Can be called when workforce is paused to dynamically add workers. **Parameters:** - **description** (str): Description of the worker node. - **worker** (ChatAgent): The agent to be added. - **pool_max_size** (int): Maximum size of the agent pool. (default: :obj:`10`) **Returns:** Workforce: The workforce node itself. ### add_role_playing_worker ```python def add_role_playing_worker( self, description: str, assistant_role_name: str, user_role_name: str, assistant_agent_kwargs: Optional[Dict] = None, user_agent_kwargs: Optional[Dict] = None, summarize_agent_kwargs: Optional[Dict] = None, chat_turn_limit: int = 3 ): ``` Add a worker node to the workforce that uses `RolePlaying` system. Can be called when workforce is paused to dynamically add workers. **Parameters:** - **description** (str): Description of the node. - **assistant_role_name** (str): The role name of the assistant agent. - **user_role_name** (str): The role name of the user agent. - **assistant_agent_kwargs** (Optional[Dict]): The keyword arguments to initialize the assistant agent in the role playing, like the model name, etc. (default: :obj:`None`) - **user_agent_kwargs** (Optional[Dict]): The keyword arguments to initialize the user agent in the role playing, like the model name, etc. (default: :obj:`None`) - **summarize_agent_kwargs** (Optional[Dict]): The keyword arguments to initialize the summarize agent, like the model name, etc. (default: :obj:`None`) - **chat_turn_limit** (int): The maximum number of chat turns in the role playing. (default: :obj:`3`) **Returns:** Workforce: The workforce node itself. ### add_workforce ```python def add_workforce(self, workforce: Workforce): ``` Add a workforce node to the workforce. Can be called when workforce is paused to dynamically add workers. **Parameters:** - **workforce** (Workforce): The workforce node to be added. **Returns:** Workforce: The workforce node itself. ### reset ```python def reset(self): ``` Reset the workforce and all the child nodes under it. Can only be called when the workforce is not running. ### set_channel ```python def set_channel(self, channel: TaskChannel): ``` Set the channel for the node and all the child nodes under it. ### _get_child_nodes_info ```python def _get_child_nodes_info(self): ``` Get the information of all the child nodes under this node. ### _get_valid_worker_ids ```python def _get_valid_worker_ids(self): ``` **Returns:** set: Set of valid worker IDs that can be assigned tasks. ### _call_coordinator_for_assignment ```python def _call_coordinator_for_assignment(self, tasks: List[Task], invalid_ids: Optional[List[str]] = None): ``` Call coordinator agent to assign tasks with optional validation feedback in the case of invalid worker IDs. **Parameters:** - **tasks** (List[Task]): Tasks to assign. - **invalid_ids** (List[str], optional): Invalid worker IDs from previous attempt (if any). **Returns:** TaskAssignResult: Assignment result from coordinator. ### _validate_assignments ```python def _validate_assignments(self, assignments: List[TaskAssignment], valid_ids: Set[str]): ``` Validate task assignments against valid worker IDs. **Parameters:** - **assignments** (List[TaskAssignment]): Assignments to validate. - **valid_ids** (Set[str]): Set of valid worker IDs. **Returns:** Tuple[List[TaskAssignment], List[TaskAssignment]]: (valid_assignments, invalid_assignments) ### get_workforce_log_tree ```python def get_workforce_log_tree(self): ``` Returns an ASCII tree representation of the task hierarchy and worker status. ### get_workforce_kpis ```python def get_workforce_kpis(self): ``` Returns a dictionary of key performance indicators. ### dump_workforce_logs ```python def dump_workforce_logs(self, file_path: str): ``` Dumps all collected logs to a JSON file. **Parameters:** - **file_path** (str): The path to the JSON file. ### _submit_coro_to_loop ```python def _submit_coro_to_loop(self, coro: 'Coroutine'): ``` Thread-safe submission of coroutine to the workforce loop. ### stop ```python def stop(self): ``` Stop all the child nodes under it. The node itself will be stopped by its parent node. ### clone ```python def clone(self, with_memory: bool = False): ``` Creates a new instance of Workforce with the same configuration. **Parameters:** - **with_memory** (bool, optional): Whether to copy the memory (conversation history) to the new instance. If True, the new instance will have the same conversation history. If False, the new instance will have a fresh memory. (default: :obj:`False`) **Returns:** Workforce: A new instance of Workforce with the same configuration. ### to_mcp ```python def to_mcp( self, name: str = 'CAMEL-Workforce', description: str = 'A workforce system using the CAMEL AI framework for multi-agent collaboration.', dependencies: Optional[List[str]] = None, host: str = 'localhost', port: int = 8001 ): ``` Expose this Workforce as an MCP server. **Parameters:** - **name** (str): Name of the MCP server. (default: :obj:`CAMEL-Workforce`) - **description** (str): Description of the workforce. If None, a generic description is used. (default: :obj:`A workforce system using the CAMEL AI framework for multi-agent collaboration.`) - **dependencies** (Optional[List[str]]): Additional dependencies for the MCP server. (default: :obj:`None`) - **host** (str): Host to bind to for HTTP transport. (default: :obj:`localhost`) - **port** (int): Port to bind to for HTTP transport. (default: :obj:`8001`) **Returns:** FastMCP: An MCP server instance that can be run. --- ## WorkforceLogger ```python class WorkforceLogger: ``` Logs events and metrics for a Workforce instance. ### __init__ ```python def __init__(self, workforce_id: str): ``` Initializes the WorkforceLogger. **Parameters:** - **workforce_id** (str): The unique identifier for the workforce. ### _log_event ```python def _log_event(self, event_type: str, **kwargs: Any): ``` Internal method to create and store a log entry. **Parameters:** - **event_type** (str): The type of event being logged. **kwargs: Additional data associated with the event. ### log_task_created ```python def log_task_created( self, task_id: str, description: str, parent_task_id: Optional[str] = None, task_type: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None ): ``` Logs the creation of a new task. ### log_task_decomposed ```python def log_task_decomposed( self, parent_task_id: str, subtask_ids: List[str], metadata: Optional[Dict[str, Any]] = None ): ``` Logs the decomposition of a task into subtasks. ### log_task_assigned ```python def log_task_assigned( self, task_id: str, worker_id: str, queue_time_seconds: Optional[float] = None, dependencies: Optional[List[str]] = None, metadata: Optional[Dict[str, Any]] = None ): ``` Logs the assignment of a task to a worker. ### log_task_started ```python def log_task_started( self, task_id: str, worker_id: str, metadata: Optional[Dict[str, Any]] = None ): ``` Logs when a worker starts processing a task. ### log_task_completed ```python def log_task_completed( self, task_id: str, worker_id: str, result_summary: Optional[str] = None, processing_time_seconds: Optional[float] = None, token_usage: Optional[Dict[str, int]] = None, metadata: Optional[Dict[str, Any]] = None ): ``` Logs the successful completion of a task. ### log_task_failed ```python def log_task_failed( self, task_id: str, error_message: str, worker_id: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None ): ``` Logs the failure of a task. ### log_worker_created ```python def log_worker_created( self, worker_id: str, worker_type: str, role: str, metadata: Optional[Dict[str, Any]] = None ): ``` Logs the creation of a new worker. ### log_worker_deleted ```python def log_worker_deleted( self, worker_id: str, reason: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None ): ``` Logs the deletion of a worker. ### reset_task_data ```python def reset_task_data(self): ``` Resets logs and data related to tasks, preserving worker information. ### log_queue_status ```python def log_queue_status( self, queue_name: str, length: int, pending_task_ids: Optional[List[str]] = None, metadata: Optional[Dict[str, Any]] = None ): ``` Logs the status of a task queue. ### dump_to_json ```python def dump_to_json(self, file_path: str): ``` Dumps all log entries to a JSON file. **Parameters:** - **file_path** (str): The path to the JSON file. ### _get_all_tasks_in_hierarchy ```python def _get_all_tasks_in_hierarchy(self, task_id: str): ``` Recursively collect all tasks in the hierarchy starting from task_id. ### _get_task_tree_string ```python def _get_task_tree_string( self, task_id: str, prefix: str = '', is_last: bool = True ): ``` Generate a string representation of the task tree. ### get_ascii_tree_representation ```python def get_ascii_tree_representation(self): ``` Generates an ASCII tree representation of the current task hierarchy and worker status. ### get_kpis ```python def get_kpis(self): ``` Calculates and returns key performance indicators from the logs. --- ## Mem0Storage ```python class Mem0Storage(BaseKeyValueStorage): ``` A concrete implementation of the :obj:`BaseKeyValueStorage` using Mem0 as the backend. This storage system uses Mem0's text capabilities to store, search, and manage text with context. **Parameters:** - **agent_id** (str): Default agent ID to associate memories with. - **api_key** (str, optional): The API key for authentication. If not provided, will try to get from environment variable MEM0_API_KEY (default: :obj:`None`). - **user_id** (str, optional): Default user ID to associate memories with (default: :obj:`None`). - **metadata** (Dict[str, Any], optional): Default metadata to include with all memories (default: :obj:`None`). - **References**: - **https**: //docs.mem0.ai ### __init__ ```python def __init__( self, agent_id: str, api_key: Optional[str] = None, user_id: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None ): ``` ### _prepare_options ```python def _prepare_options( self, agent_id: Optional[str] = None, user_id: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None, **kwargs: Any ): ``` Helper method to prepare options for Mem0 API calls. **Parameters:** - **agent_id** (Optional[str], optional): Agent ID to use (default: :obj:`None`). - **user_id** (Optional[str], optional): User ID to use (default: :obj:`None`). - **metadata** (Optional[Dict[str, Any]], optional): Additional metadata to include (default: :obj:`None`). **kwargs (Any): Additional keyword arguments. **Returns:** Dict[str, Any]: Prepared options dictionary for API calls. ### _prepare_messages ```python def _prepare_messages(self, records: List[Dict[str, Any]]): ``` Prepare messages from records for Mem0 API calls. **Parameters:** - **records** (List[Dict[str, Any]]): List of record dictionaries. **Returns:** List[Dict[str, Any]]: List of prepared message dictionaries. ### save ```python def save(self, records: List[Dict[str, Any]]): ``` Saves a batch of records to the Mem0 storage system. **Parameters:** - **records** (List[Dict[str, Any]]): A list of dictionaries, where each dictionary represents a unique record to be stored. ### load ```python def load(self): ``` **Returns:** List[Dict[str, Any]]: A list of dictionaries, where each dictionary represents a stored record. ### clear ```python def clear( self, agent_id: Optional[str] = None, user_id: Optional[str] = None ): ``` Removes all records from the Mem0 storage system. **Parameters:** - **agent_id** (Optional[str]): Specific agent ID to clear memories for. - **user_id** (Optional[str]): Specific user ID to clear memories for. --- ## AmazonS3Storage ```python class AmazonS3Storage(BaseObjectStorage): ``` A class to connect with AWS S3 object storage to put and get objects from one S3 bucket. The class will first try to use the credentials passed as arguments, if not provided, it will look for the environment variables `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`. If none of these are provided, it will try to use the local credentials (will be created if logged in with AWS CLI). **Parameters:** - **bucket_name** (str): The name of the S3 bucket. - **create_if_not_exists** (bool, optional): Whether to create the bucket if it does not exist. Defaults to True. - **access_key_id** (Optional[str], optional): The AWS access key ID. Defaults to None. - **secret_access_key** (Optional[str], optional): The AWS secret access key. Defaults to None. - **anonymous** (bool, optional): Whether to use anonymous access. Defaults to False. - **References**: - **https**: //aws.amazon.com/pm/serv-s3/ - **https**: //aws.amazon.com/cli/ ### __init__ ```python def __init__( self, bucket_name: str, create_if_not_exists: bool = True, access_key_id: Optional[str] = None, secret_access_key: Optional[str] = None, anonymous: bool = False ): ``` ### _prepare_and_check ```python def _prepare_and_check(self): ``` Check privileges and existence of the bucket. ### canonicalize_path ```python def canonicalize_path(file_path: PurePath): ``` Canonicalize file path for Amazon S3. **Parameters:** - **file_path** (PurePath): The path to be canonicalized. **Returns:** Tuple[str, str]: The canonicalized file key and file name. ### _put_file ```python def _put_file(self, file_key: str, file: File): ``` Put a file to the Amazon S3 bucket. **Parameters:** - **file_key** (str): The path to the object in the bucket. - **file** (File): The file to be uploaded. ### _get_file ```python def _get_file(self, file_key: str, filename: str): ``` Get a file from the Amazon S3 bucket. **Parameters:** - **file_key** (str): The path to the object in the bucket. - **filename** (str): The name of the file. **Returns:** File: The object from the S3 bucket. ### _upload_file ```python def _upload_file(self, local_file_path: Path, remote_file_key: str): ``` Upload a local file to the Amazon S3 bucket. **Parameters:** - **local_file_path** (Path): The path to the local file to be uploaded. - **remote_file_key** (str): The path to the object in the bucket. ### _download_file ```python def _download_file(self, local_file_path: Path, remote_file_key: str): ``` Download a file from the Amazon S3 bucket to the local system. **Parameters:** - **local_file_path** (Path): The path to the local file to be saved. - **remote_file_key** (str): The key of the object in the bucket. ### _object_exists ```python def _object_exists(self, file_key: str): ``` Check if the object exists in the Amazon S3 bucket. **Parameters:** - **file_key**: The key of the object in the bucket. **Returns:** bool: Whether the object exists in the bucket. --- ## AzureBlobStorage ```python class AzureBlobStorage(BaseObjectStorage): ``` A class to connect to Azure Blob Storage. It will connect to one container in the storage account. **Parameters:** - **storage_account_name** (str): The name of the storage account. - **container_name** (str): The name of the container. - **access_key** (Optional[str], optional): The access key of the storage account. Defaults to None. - **References**: - **https**: //azure.microsoft.com/en-us/products/storage/blobs ### __init__ ```python def __init__( self, storage_account_name: str, container_name: str, create_if_not_exists: bool = True, access_key: Optional[str] = None ): ``` ### _prepare_and_check ```python def _prepare_and_check(self): ``` Check privileges and existence of the container. ### canonicalize_path ```python def canonicalize_path(file_path: PurePath): ``` Canonicalize file path for Azure Blob Storage. **Parameters:** - **file_path** (PurePath): The path to be canonicalized. **Returns:** Tuple[str, str]: The canonicalized file key and file name. ### _put_file ```python def _put_file(self, file_key: str, file: File): ``` Put a file to the Azure Blob Storage container. **Parameters:** - **file_key** (str): The path to the object in the container. - **file** (File): The file to be uploaded. ### _get_file ```python def _get_file(self, file_key: str, filename: str): ``` Get a file from the Azure Blob Storage container. **Parameters:** - **file_key** (str): The path to the object in the container. - **filename** (str): The name of the file. **Returns:** File: The object from the container. ### _upload_file ```python def _upload_file(self, local_file_path: Path, remote_file_key: str): ``` Upload a local file to the Azure Blob Storage container. **Parameters:** - **local_file_path** (Path): The path to the local file to be uploaded. - **remote_file_key** (str): The path to the object in the container. ### _download_file ```python def _download_file(self, local_file_path: Path, remote_file_key: str): ``` Download a file from the Azure Blob Storage container to the local system. **Parameters:** - **local_file_path** (Path): The path to the local file to be saved. - **remote_file_key** (str): The key of the object in the container. ### _object_exists ```python def _object_exists(self, file_key: str): ``` Check if the object exists in the Azure Blob Storage container. **Parameters:** - **file_key**: The key of the object in the container. **Returns:** bool: Whether the object exists in the container. --- ## GoogleCloudStorage ```python class GoogleCloudStorage(BaseObjectStorage): ``` A class to connect to Google Cloud Storage. It will connect to one bucket in the storage account. Note that Google Cloud Storage does not support api key authentication. Therefore, before using this class, you need to log in with gcloud command line tool and save the credentials first. **Parameters:** - **bucket_name** (str): The name of the bucket. - **create_if_not_exists** (bool, optional): Whether to create the bucket if it does not exist. Defaults to True. - **anonymous** (bool, optional): Whether to use anonymous access. Defaults to False. - **References**: - **https**: //cloud.google.com/storage - **https**: //cloud.google.com/docs/authentication/api-keys ### __init__ ```python def __init__( self, bucket_name: str, create_if_not_exists: bool = True, anonymous: bool = False ): ``` ### canonicalize_path ```python def canonicalize_path(file_path: PurePath): ``` Canonicalize the path for Google Cloud Storage. **Parameters:** - **file_path** (PurePath): The path to be canonicalized. **Returns:** Tuple[str, str]: The canonicalized file key and file name. ### _prepare_and_check ```python def _prepare_and_check(self): ``` Check privileges and existence of the bucket. ### _put_file ```python def _put_file(self, file_key: str, file: File): ``` Put a file to the GCloud bucket. **Parameters:** - **file_key** (str): The path to the object in the bucket. - **file** (File): The file to be uploaded. ### _get_file ```python def _get_file(self, file_key: str, filename: str): ``` Get a file from the GCloud bucket. **Parameters:** - **file_key** (str): The path to the object in the bucket. - **filename** (str): The name of the file. **Returns:** File: The object from the S3 bucket. ### _upload_file ```python def _upload_file(self, local_file_path: Path, remote_file_key: str): ``` Upload a local file to the GCloud bucket. **Parameters:** - **local_file_path** (Path): The path to the local file to be uploaded. - **remote_file_key** (str): The path to the object in the bucket. ### _download_file ```python def _download_file(self, local_file_path: Path, remote_file_key: str): ``` Download a file from the GCloud bucket to the local system. **Parameters:** - **local_file_path** (Path): The path to the local file to be saved. - **remote_file_key** (str): The key of the object in the bucket. ### _object_exists ```python def _object_exists(self, file_key: str): ``` Check if the object exists in the GCloud bucket. **Parameters:** - **file_key**: The key of the object in the bucket. **Returns:** bool: Whether the object exists in the bucket. --- ## ChromaStorage ```python class ChromaStorage(BaseVectorStorage): ``` An implementation of the `BaseVectorStorage` for interacting with ChromaDB, a vector database for embeddings. ChromaDB is an open-source AI-native vector database focused on developer productivity and happiness. The detailed information about ChromaDB is available at: `ChromaDB `_ This class provides multiple ways to connect to ChromaDB instances: - Ephemeral (in-memory for testing/prototyping) - Persistent (local file storage) - HTTP (remote ChromaDB server) - Cloud (ChromaDB Cloud - future support) **Parameters:** - **vector_dim** (int): The dimension of storing vectors. - **collection_name** (Optional[str], optional): Name for the collection in ChromaDB. If not provided, auto-generated with timestamp. (default: :obj:`None`) - **client_type** (`Literal["ephemeral", "persistent", "http", "cloud"]`): Type of ChromaDB client to use. Supported types: 'ephemeral', 'persistent', 'http', 'cloud'. (default: :obj:`"ephemeral"`) # Persistent client parameters - **path** (Optional[str], optional): Path to directory for persistent storage. Only used when client_type='persistent'. (default: :obj:`"./chroma"`) # HTTP client parameters - **host** (str, optional): Host for remote ChromaDB server. (default: :obj:`"localhost"`) - **port** (int, optional): Port for remote ChromaDB server. (default: :obj:`8000`) - **ssl** (bool, optional): Whether to use SSL for HTTP connections. (default: :obj:`False`) - **headers** (Optional[Dict[str, str]], optional): Additional headers for HTTP client requests. (default: :obj:`None`) # Cloud client parameters - **api_key** (Optional[str], optional): API key for ChromaDB Cloud. (default: :obj:`None`) - **cloud_host** (str, optional): ChromaDB Cloud host. (default: :obj:`"api.trychroma.com"`) - **cloud_port** (int, optional): ChromaDB Cloud port. (default: :obj:`8000`) - **enable_ssl** (bool, optional): Whether to enable SSL for cloud connection.(default: :obj:`True`) # Common parameters for all client types - **settings** (Optional[Any], optional): ChromaDB settings object for advanced configuration. (default: :obj:`None`) - **tenant** (Optional[str], optional): Tenant name for multi-tenancy support. (default: :obj:`None`) - **database** (Optional[str], optional): Database name for multi-database support. (default: :obj:`None`) - **distance** (VectorDistance, optional): The distance metric for vector comparison. (default: :obj:`VectorDistance.COSINE`) - **delete_collection_on_del** (bool, optional): Flag to determine if the collection should be deleted upon object destruction. (default: :obj:`False`) ### __init__ ```python def __init__( self, vector_dim: int, collection_name: Optional[str] = None, client_type: Literal['ephemeral', 'persistent', 'http', 'cloud'] = 'ephemeral', path: Optional[str] = './chroma', host: str = 'localhost', port: int = 8000, ssl: bool = False, headers: Optional[Dict[str, str]] = None, api_key: Optional[str] = None, cloud_host: str = 'api.trychroma.com', cloud_port: int = 8000, enable_ssl: bool = True, settings: Optional[Any] = None, tenant: Optional[str] = None, database: Optional[str] = None, distance: VectorDistance = VectorDistance.COSINE, delete_collection_on_del: bool = False, **kwargs: Any ): ``` ### __del__ ```python def __del__(self): ``` Deletes the collection if :obj:`delete_collection_on_del` is set to :obj:`True`. ### _validate_client_type ```python def _validate_client_type( self, client_type: Literal['ephemeral', 'persistent', 'http', 'cloud'] ): ``` Validates client type parameter. **Parameters:** - **client_type** (`Literal["ephemeral", "persistent", "http", "cloud"]`): The client type to validate. ### _validate_client_config ```python def _validate_client_config(self): ``` ### _get_connection_client ```python def _get_connection_client(self): ``` Get ChromaDB client based on client type and user settings. ### _create_ephemeral_client ```python def _create_ephemeral_client(self, chromadb_module: Any): ``` Create an ephemeral ChromaDB client (in-memory). ### _create_persistent_client ```python def _create_persistent_client(self, chromadb_module: Any): ``` Create a persistent ChromaDB client (local file storage). ### _create_http_client ```python def _create_http_client(self, chromadb_module: Any): ``` Create an HTTP ChromaDB client (remote server). ### _create_cloud_client ```python def _create_cloud_client(self, chromadb_module: Any): ``` Create a cloud ChromaDB client. ### _get_common_client_kwargs ```python def _get_common_client_kwargs(self): ``` Get common kwargs for all ChromaDB clients. ### _generate_collection_name ```python def _generate_collection_name(self): ``` **Returns:** str: Generated collection name based on current timestamp. ### _get_distance_function ```python def _get_distance_function(self): ``` **Returns:** str: ChromaDB distance function name. References: https://docs.trychroma.com/docs/collections/configure ### _get_or_create_collection ```python def _get_or_create_collection(self): ``` **Returns:** ChromaDB collection object. ### add ```python def add(self, records: List[VectorRecord], **kwargs: Any): ``` Adds vector records to ChromaDB collection. **Parameters:** - **records** (List[VectorRecord]): List of vector records to be saved. **kwargs (Any): Additional keyword arguments for ChromaDB add operation. ### delete ```python def delete(self, ids: List[str], **kwargs: Any): ``` Deletes vectors by their IDs from ChromaDB collection. **Parameters:** - **ids** (List[str]): List of unique identifiers for the vectors to be deleted. **kwargs (Any): Additional keyword arguments for ChromaDB delete operation. ### status ```python def status(self): ``` **Returns:** VectorDBStatus: The vector database status containing dimension and count information. ### query ```python def query(self, query: VectorDBQuery, **kwargs: Any): ``` Searches for similar vectors in ChromaDB based on the provided query. **Parameters:** - **query** (VectorDBQuery): The query object containing the search vector and the number of top similar vectors to retrieve. **kwargs (Any): Additional keyword arguments for ChromaDB query operation. **Returns:** List[VectorDBQueryResult]: A list of vectors retrieved from the storage based on similarity to the query vector. ### _distance_to_similarity ```python def _distance_to_similarity(self, distance: float): ``` Convert distance to similarity score based on distance metric. **Parameters:** - **distance** (float): Distance value from ChromaDB. **Returns:** float: Similarity score (higher means more similar). ### clear ```python def clear(self): ``` ### load ```python def load(self): ``` Load the collection hosted on cloud service. For ChromaDB, collections are automatically available when client connects, so this method is a no-op. ### delete_collection ```python def delete_collection(self): ``` ### client ```python def client(self): ``` **Returns:** chromadb.Client: The ChromaDB client instance. ### collection ```python def collection(self): ``` **Returns:** ChromaDB collection instance. --- ## PgVectorStorage ```python class PgVectorStorage(BaseVectorStorage): ``` PgVectorStorage is an implementation of BaseVectorStorage for PostgreSQL with pgvector extension. This class provides methods to add, delete, query, and manage vector records in a PostgreSQL database using the pgvector extension. It supports different distance metrics for similarity search. **Parameters:** - **vector_dim** (int): The dimension of the vectors to be stored. - **conn_info** (Dict[str, Any]): Connection information for psycopg2.connect. - **table_name** (str, optional): Name of the table to store vectors. (default: :obj:`None`) - **distance** (VectorDistance, optional): Distance metric for vector comparison. (default: :obj:`VectorDistance.COSINE`) ### __init__ ```python def __init__( self, vector_dim: int, conn_info: Dict[str, Any], table_name: Optional[str] = None, distance: VectorDistance = VectorDistance.COSINE, **kwargs: Any ): ``` Initialize PgVectorStorage. **Parameters:** - **vector_dim** (int): The dimension of the vectors. - **conn_info** (Dict[str, Any]): Connection info for psycopg2.connect. - **table_name** (str, optional): Table name. (default: :obj:`None`) - **distance** (VectorDistance, optional): Distance metric. (default: :obj:`VectorDistance.COSINE`) ### _ensure_table ```python def _ensure_table(self): ``` Ensure the vector table exists in the database. Creates the table if it does not exist. ### _ensure_index ```python def _ensure_index(self): ``` Ensure vector similarity search index exists for better performance. ### add ```python def add(self, records: List[VectorRecord], **kwargs: Any): ``` Add or update vector records in the database. **Parameters:** - **records** (List[VectorRecord]): List of vector records to add or update. ### delete ```python def delete(self, ids: List[str], **kwargs: Any): ``` Delete vector records from the database by their IDs. **Parameters:** - **ids** (List[str]): List of record IDs to delete. ### query ```python def query(self, query: VectorDBQuery, **kwargs: Any): ``` Query the database for the most similar vectors to the given query vector. **Parameters:** - **query** (VectorDBQuery): Query object containing the query vector and top_k. **kwargs (Any): Additional keyword arguments for the query. **Returns:** List[VectorDBQueryResult]: List of query results sorted by similarity. ### status ```python def status(self, **kwargs: Any): ``` Get the status of the vector database, including vector dimension and count. **Returns:** VectorDBStatus: Status object with vector dimension and count. ### clear ```python def clear(self): ``` Remove all vectors from the storage by truncating the table. ### load ```python def load(self): ``` Load the collection hosted on cloud service (no-op for pgvector). This method is provided for interface compatibility. ### close ```python def close(self): ``` Close the database connection. ### __del__ ```python def __del__(self): ``` Ensure connection is closed when object is destroyed. ### client ```python def client(self): ``` **Returns:** Any: The underlying psycopg connection object. --- ## TaskValidationMode ```python class TaskValidationMode(Enum): ``` Validation modes for different use cases. ## validate_task_content ```python def validate_task_content( content: str, task_id: str = 'unknown', min_length: int = 1, mode: TaskValidationMode = TaskValidationMode.INPUT, check_failure_patterns: bool = True ): ``` Unified validation for task content and results to avoid silent failures. Performs comprehensive checks to ensure content meets quality standards. **Parameters:** - **content** (str): The task content or result to validate. - **task_id** (str): Task ID for logging purposes. (default: :obj:`"unknown"`) - **min_length** (int): Minimum content length after stripping whitespace. (default: :obj:`1`) - **mode** (TaskValidationMode): Validation mode - INPUT for task content, OUTPUT for task results. (default: :obj:`TaskValidationMode.INPUT`) - **check_failure_patterns** (bool): Whether to check for failure indicators in the content. Only effective in OUTPUT mode. (default: :obj:`True`) **Returns:** bool: True if content passes validation, False otherwise. ## is_task_result_insufficient ```python def is_task_result_insufficient(task: 'Task'): ``` Check if a task result is insufficient and should be treated as failed. This is a convenience wrapper around validate_task_content for backward compatibility and semantic clarity when checking task results. **Parameters:** - **task** (Task): The task to check. **Returns:** bool: True if the result is insufficient, False otherwise. ## parse_response ```python def parse_response(response: str, task_id: Optional[str] = None): ``` Parse Tasks from a response. **Parameters:** - **response** (str): The model response. - **task_id** (str, optional): a parent task id, the default value is "0" **Returns:** List[Task]: A list of tasks which is :obj:`Task` instance. ## TaskState ```python class TaskState(str, Enum): ``` ### states ```python def states(cls): ``` ## Task ```python class Task(BaseModel): ``` Task is specific assignment that can be passed to a agent. **Parameters:** - **content** (str): string content for task. - **id** (str): An unique string identifier for the task. This should ideally be provided by the provider/model which created the task. (default: :obj:`uuid.uuid4()`) - **state** (TaskState): The state which should be OPEN, RUNNING, DONE or DELETED. (default: :obj:`TaskState.FAILED`) - **type** (Optional[str]): task type. (default: :obj:`None`) - **parent** (Optional[Task]): The parent task, None for root task. (default: :obj:`None`) - **subtasks** (List[Task]): The childrent sub-tasks for the task. (default: :obj:`[]`) - **result** (Optional[str]): The answer for the task. (default: :obj:`""`) - **failure_count** (int): The failure count for the task. (default: :obj:`0`) - **assigned_worker_id** (Optional[str]): The ID of the worker assigned to this task. (default: :obj:`None`) - **additional_info** (Optional[Dict[str, Any]]): Additional information for the task. (default: :obj:`None`) - **image_list** (Optional[List[Image.Image]]): Optional list of PIL Image objects associated with the task. (default: :obj:`None`) - **image_detail** (`Literal["auto", "low", "high"]`): Detail level of the images associated with the task. (default: :obj:`auto`) - **video_bytes** (Optional[bytes]): Optional bytes of a video associated with the task. (default: :obj:`None`) - **video_detail** (`Literal["auto", "low", "high"]`): Detail level of the videos associated with the task. (default: :obj:`auto`) ### __repr__ ```python def __repr__(self): ``` Return a string representation of the task. ### from_message ```python def from_message(cls, message: BaseMessage): ``` Create a task from a message. **Parameters:** - **message** (BaseMessage): The message to the task. **Returns:** Task ### to_message ```python def to_message(): ``` Convert a Task to a Message. ### reset ```python def reset(self): ``` Reset Task to initial state. ### update_result ```python def update_result(self, result: str): ``` Set task result and mark the task as DONE. **Parameters:** - **result** (str): The task result. ### set_id ```python def set_id(self, id: str): ``` Set the id of the task. **Parameters:** - **id** (str): The id of the task. ### set_state ```python def set_state(self, state: TaskState): ``` Recursively set the state of the task and its subtasks. **Parameters:** - **state** (TaskState): The giving state. ### add_subtask ```python def add_subtask(self, task: 'Task'): ``` Add a subtask to the current task. **Parameters:** - **task** (Task): The subtask to be added. ### remove_subtask ```python def remove_subtask(self, id: str): ``` Remove a subtask from the current task. **Parameters:** - **id** (str): The id of the subtask to be removed. ### get_running_task ```python def get_running_task(self): ``` Get RUNNING task. ### to_string ```python def to_string(self, indent: str = '', state: bool = False): ``` Convert task to a string. **Parameters:** - **indent** (str): The ident for hierarchical tasks. - **state** (bool): Include or not task state. **Returns:** str: The printable task string. ### get_result ```python def get_result(self, indent: str = ''): ``` Get task result to a string. **Parameters:** - **indent** (str): The ident for hierarchical tasks. **Returns:** str: The printable task string. ### decompose ```python def decompose( self, agent: 'ChatAgent', prompt: Optional[str] = None, task_parser: Callable[[str, str], List['Task']] = parse_response ): ``` Decompose a task to a list of sub-tasks. Automatically detects streaming or non-streaming based on agent configuration. **Parameters:** - **agent** (ChatAgent): An agent that used to decompose the task. - **prompt** (str, optional): A prompt to decompose the task. If not provided, the default prompt will be used. - **task_parser** (Callable[[str, str], List[Task]], optional): A function to extract Task from response. If not provided, the default parse_response will be used. **Returns:** Union[List[Task], Generator[List[Task], None, None]]: If agent is configured for streaming, returns a generator that yields lists of new tasks as they are parsed. Otherwise returns a list of all tasks. ### _decompose_streaming ```python def _decompose_streaming( self, response: 'StreamingChatAgentResponse', task_parser: Callable[[str, str], List['Task']] ): ``` Handle streaming response for task decomposition. **Parameters:** - **response**: Streaming response from agent - **task_parser**: Function to parse tasks from response - **Yields**: List[Task]: New tasks as they are parsed from streaming response ### _decompose_non_streaming ```python def _decompose_non_streaming(self, response, task_parser: Callable[[str, str], List['Task']]): ``` Handle non-streaming response for task decomposition. **Parameters:** - **response**: Regular response from agent - **task_parser**: Function to parse tasks from response **Returns:** List[Task]: All parsed tasks ### _parse_partial_tasks ```python def _parse_partial_tasks(self, response: str): ``` Parse tasks from potentially incomplete response. **Parameters:** - **response**: Partial response content **Returns:** List[Task]: Tasks parsed from complete ```` blocks ### compose ```python def compose( self, agent: 'ChatAgent', template: TextPrompt = TASK_COMPOSE_PROMPT, result_parser: Optional[Callable[[str], str]] = None ): ``` compose task result by the sub-tasks. **Parameters:** - **agent** (ChatAgent): An agent that used to compose the task result. - **template** (TextPrompt, optional): The prompt template to compose task. If not provided, the default template will be used. - **result_parser** (Callable[[str, str], List[Task]], optional): A function to extract Task from response. ### get_depth ```python def get_depth(self): ``` Get current task depth. ## TaskManager ```python class TaskManager: ``` TaskManager is used to manage tasks. **Parameters:** - **task** (Task): The root Task. ### __init__ ```python def __init__(self, task: Task): ``` ### gen_task_id ```python def gen_task_id(self): ``` Generate a new task id. ### exist ```python def exist(self, task_id: str): ``` Check if a task with the given id exists. ### current_task ```python def current_task(self): ``` Get the current task. ### topological_sort ```python def topological_sort(tasks: List[Task]): ``` Sort a list of tasks by topological way. **Parameters:** - **tasks** (List[Task]): The giving list of tasks. **Returns:** The sorted list of tasks. ### set_tasks_dependence ```python def set_tasks_dependence( root: Task, others: List[Task], type: Literal['serial', 'parallel'] = 'parallel' ): ``` Set relationship between root task and other tasks. Two relationships are currently supported: serial and parallel. `serial` : root -> other1 -> other2 `parallel`: root -> other1 -> other2 **Parameters:** - **root** (Task): A root task. - **others** (List[Task]): A list of tasks. ### add_tasks ```python def add_tasks(self, tasks: Union[Task, List[Task]]): ``` self.tasks and self.task_map will be updated by the input tasks. ### evolve ```python def evolve( self, task: Task, agent: 'ChatAgent', template: Optional[TextPrompt] = None, task_parser: Optional[Callable[[str, str], List[Task]]] = None ): ``` Evolve a task to a new task. Evolve is only used for data generation. **Parameters:** - **task** (Task): A given task. - **agent** (ChatAgent): An agent that used to evolve the task. - **template** (TextPrompt, optional): A prompt template to evolve task. If not provided, the default template will be used. - **task_parser** (Callable, optional): A function to extract Task from response. If not provided, the default parser will be used. **Returns:** Task: The created :obj:`Task` instance or None. --- ## ACIToolkit ```python class ACIToolkit(BaseToolkit): ``` A toolkit for interacting with the ACI API. ### __init__ ```python def __init__( self, api_key: Optional[str] = None, base_url: Optional[str] = None, linked_account_owner_id: Optional[str] = None, timeout: Optional[float] = None ): ``` Initialize the ACI toolkit. **Parameters:** - **api_key** (Optional[str]): The API key for authentication. (default: :obj:`None`) - **base_url** (Optional[str]): The base URL for the ACI API. (default: :obj:`None`) - **linked_account_owner_id** (Optional[str]): ID of the owner of the linked account, e.g., "johndoe" (default: :obj:`None`) - **timeout** (Optional[float]): Request timeout. (default: :obj:`None`) ### search_tool ```python def search_tool( self, intent: Optional[str] = None, allowed_app_only: bool = True, include_functions: bool = False, categories: Optional[List[str]] = None, limit: Optional[int] = 10, offset: Optional[int] = 0 ): ``` Search for apps based on intent. **Parameters:** - **intent** (Optional[str]): Search results will be sorted by relevance to this intent. (default: :obj:`None`) - **allowed_app_only** (bool): If true, only return apps that are allowed by the agent/accessor, identified by the api key. (default: :obj:`True`) - **include_functions** (bool): If true, include functions (name and description) in the search results. (default: :obj:`False`) - **categories** (Optional[List[str]]): List of categories to filter the search results. Defaults to an empty list. (default: :obj:`None`) - **limit** (Optional[int]): Maximum number of results to return. (default: :obj:`10`) - **offset** (Optional[int]): Offset for pagination. (default: :obj:`0`) **Returns:** Optional[List[AppBasic]]: List of matching apps if successful, error message otherwise. ### list_configured_apps ```python def list_configured_apps( self, app_names: Optional[List[str]] = None, limit: Optional[int] = 10, offset: Optional[int] = 0 ): ``` List all configured apps. **Parameters:** - **app_names** (Optional[List[str]]): List of app names to filter the results. (default: :obj:`None`) - **limit** (Optional[int]): Maximum number of results to return. (default: :obj:`10`) - **offset** (Optional[int]): Offset for pagination. (default: :obj:`0`) (default: 0) **Returns:** Union[List[AppConfiguration], str]: List of configured apps if successful, error message otherwise. ### configure_app ```python def configure_app(self, app_name: str): ``` Configure an app with specified authentication type. **Parameters:** - **app_name** (str): Name of the app to configure. **Returns:** Union[Dict, str]: Configuration result or error message. ### get_app_configuration ```python def get_app_configuration(self, app_name: str): ``` Get app configuration by app name. **Parameters:** - **app_name** (str): Name of the app to get configuration for. **Returns:** Union[AppConfiguration, str]: App configuration if successful, error message otherwise. ### delete_app ```python def delete_app(self, app_name: str): ``` Delete an app configuration. **Parameters:** - **app_name** (str): Name of the app to delete. **Returns:** Optional[str]: None if successful, error message otherwise. ### link_account ```python def link_account(self, app_name: str): ``` Link an account to a configured app. **Parameters:** - **app_name** (str): Name of the app to link the account to. **Returns:** Union[LinkedAccount, str]: LinkedAccount object if successful, error message otherwise. ### get_app_details ```python def get_app_details(self, app_name: str): ``` Get details of an app. **Parameters:** - **app_name** (str): Name of the app to get details for. **Returns:** AppDetails: App details. ### get_linked_accounts ```python def get_linked_accounts(self, app_name: str): ``` List all linked accounts for a specific app. **Parameters:** - **app_name** (str): Name of the app to get linked accounts for. **Returns:** Union[List[LinkedAccount], str]: List of linked accounts if successful, error message otherwise. ### enable_linked_account ```python def enable_linked_account(self, linked_account_id: str): ``` Enable a linked account. **Parameters:** - **linked_account_id** (str): ID of the linked account to enable. **Returns:** Union[LinkedAccount, str]: Linked account if successful, error message otherwise. ### disable_linked_account ```python def disable_linked_account(self, linked_account_id: str): ``` Disable a linked account. **Parameters:** - **linked_account_id** (str): ID of the linked account to disable. **Returns:** Union[LinkedAccount, str]: The updated linked account if successful, error message otherwise. ### delete_linked_account ```python def delete_linked_account(self, linked_account_id: str): ``` Delete a linked account. **Parameters:** - **linked_account_id** (str): ID of the linked account to delete. **Returns:** str: Success message if successful, error message otherwise. ### function_definition ```python def function_definition(self, func_name: str): ``` Get the function definition for an app. **Parameters:** - **app_name** (str): Name of the app to get function definition for **Returns:** Dict: Function definition dictionary. ### search_function ```python def search_function( self, app_names: Optional[List[str]] = None, intent: Optional[str] = None, allowed_apps_only: bool = True, limit: Optional[int] = 10, offset: Optional[int] = 0 ): ``` Search for functions based on intent. **Parameters:** - **app_names** (Optional[List[str]]): List of app names to filter the search results. (default: :obj:`None`) - **intent** (Optional[str]): The search query/intent. (default: :obj:`None`) - **allowed_apps_only** (bool): If true, only return functions from allowed apps. (default: :obj:`True`) - **limit** (Optional[int]): Maximum number of results to return. (default: :obj:`10`) - **offset** (Optional[int]): Offset for pagination. (default: :obj:`0`) **Returns:** List[Dict]: List of matching functions ### execute_function ```python def execute_function( self, function_name: str, function_arguments: Dict, linked_account_owner_id: str, allowed_apps_only: bool = False ): ``` Execute a function call. **Parameters:** - **function_name** (str): Name of the function to execute. - **function_arguments** (Dict): Arguments to pass to the function. - **linked_account_owner_id** (str): To specify the end-user (account owner) on behalf of whom you want to execute functions You need to first link corresponding account with the same owner id in the ACI dashboard (https://platform.aci.dev). - **allowed_apps_only** (bool): If true, only returns functions/apps that are allowed to be used by the agent/accessor, identified by the api key. (default: :obj:`False`) **Returns:** Dict: Result of the function execution ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: List of FunctionTool objects representing available functions --- ## ArxivToolkit ```python class ArxivToolkit(BaseToolkit): ``` A toolkit for interacting with the arXiv API to search and download academic papers. ### __init__ ```python def __init__(self, timeout: Optional[float] = None): ``` Initializes the ArxivToolkit and sets up the arXiv client. ### _get_search_results ```python def _get_search_results( self, query: str, paper_ids: Optional[List[str]] = None, max_results: Optional[int] = 5 ): ``` Retrieves search results from the arXiv API based on the provided query and optional paper IDs. **Parameters:** - **query** (str): The search query string used to search for papers on arXiv. - **paper_ids** (List[str], optional): A list of specific arXiv paper IDs to search for. (default: :obj:`None`) - **max_results** (int, optional): The maximum number of search results to retrieve. (default: :obj:`5`) **Returns:** Generator: A generator that yields results from the arXiv search query, which includes metadata about each paper matching the query. ### search_papers ```python def search_papers( self, query: str, paper_ids: Optional[List[str]] = None, max_results: Optional[int] = 5 ): ``` Searches for academic papers on arXiv using a query string and optional paper IDs. **Parameters:** - **query** (str): The search query string. - **paper_ids** (List[str], optional): A list of specific arXiv paper IDs to search for. (default: :obj:`None`) - **max_results** (int, optional): The maximum number of search results to return. (default: :obj:`5`) **Returns:** List[Dict[str, str]]: A list of dictionaries, each containing information about a paper, including title, published date, authors, entry ID, summary, and extracted text from the paper. ### download_papers ```python def download_papers( self, query: str, paper_ids: Optional[List[str]] = None, max_results: Optional[int] = 5, output_dir: Optional[str] = './' ): ``` Downloads PDFs of academic papers from arXiv based on the provided query. **Parameters:** - **query** (str): The search query string. - **paper_ids** (List[str], optional): A list of specific arXiv paper IDs to download. (default: :obj:`None`) - **max_results** (int, optional): The maximum number of search results to download. (default: :obj:`5`) - **output_dir** (str, optional): The directory to save the downloaded PDFs. Defaults to the current directory. **Returns:** str: Status message indicating success or failure. ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of FunctionTool objects representing the functions in the toolkit. --- ## Crawl4AIToolkit ```python class Crawl4AIToolkit(BaseToolkit): ``` A class representing a toolkit for Crawl4AI. ### __init__ ```python def __init__(self, timeout: Optional[float] = None): ``` ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of FunctionTool objects representing the functions in the toolkit. --- ## DappierToolkit ```python class DappierToolkit(BaseToolkit): ``` A class representing a toolkit for interacting with the Dappier API. This class provides methods for searching real time data and fetching ai recommendations across key verticals like News, Finance, Stock Market, Sports, Weather and more. ### __init__ ```python def __init__(self, timeout: Optional[float] = None): ``` Initialize the DappierTookit with API clients.The API keys and credentials are retrieved from environment variables. ### search_real_time_data ```python def search_real_time_data( self, query: str, ai_model_id: str = 'am_01j06ytn18ejftedz6dyhz2b15' ): ``` Search real-time data using an AI model. This function accesses real-time information using the specified AI model based on the given query. Depending on the AI model ID, the data retrieved can vary between general web search results or financial news and stock prices. Supported AI Models: - `am_01j06ytn18ejftedz6dyhz2b15`: Access real-time Google web search results, including the latest news, weather updates, travel details, deals, and more. - `am_01j749h8pbf7ns8r1bq9s2evrh`: Access real-time financial news, stock prices, and trades from polygon.io, with AI-powered insights and up-to-the-minute updates. **Parameters:** - **query** (str): The user-provided query. Examples include: - "How is the weather today in Austin, TX?" - "What is the latest news for Meta?" - "What is the stock price for AAPL?" - **ai_model_id** (str, optional): The AI model ID to use for the query. The AI model ID always starts with the prefix "am_". (default: `am_01j06ytn18ejftedz6dyhz2b15`) **Returns:** str: The search result corresponding to the provided query and AI model ID. This may include real time search data, depending on the selected AI model. **Note:** Multiple AI model IDs are available, which can be found at: https://marketplace.dappier.com/marketplace ### get_ai_recommendations ```python def get_ai_recommendations( self, query: str, data_model_id: str = 'dm_01j0pb465keqmatq9k83dthx34', similarity_top_k: int = 9, ref: Optional[str] = None, num_articles_ref: int = 0, search_algorithm: Literal['most_recent', 'semantic', 'most_recent_semantic', 'trending'] = 'most_recent' ): ``` Retrieve AI-powered recommendations based on the provided query and data model. This function fetches real-time AI-generated recommendations using the specified data model and search algorithm. The results include personalized content based on the query and, optionally, relevance to a specific reference domain. Supported Data Models: - `dm_01j0pb465keqmatq9k83dthx34`: Real-time news, updates, and personalized content from top sports sources such as Sportsnaut, Forever Blueshirts, Minnesota Sports Fan, LAFB Network, Bounding Into Sports, and Ringside Intel. - `dm_01j0q82s4bfjmsqkhs3ywm3x6y`: Real-time updates, analysis, and personalized content from top sources like The Mix, Snipdaily, Nerdable, and Familyproof. **Parameters:** - **query** (str): The user query for retrieving recommendations. - **data_model_id** (str, optional): The data model ID to use for recommendations. Data model IDs always start with the prefix "dm_". (default: :obj:`dm_01j0pb465keqmatq9k83dthx34`) - **similarity_top_k** (int, optional): The number of top documents to retrieve based on similarity. (default: :obj:`9`) - **ref** (Optional[str], optional): The site domain where AI recommendations should be displayed. (default: :obj:`None`) - **num_articles_ref** (int, optional): The minimum number of articles to return from the specified reference domain (`ref`). The remaining articles will come from other sites in the RAG model. (default: :obj:`0`) search_algorithm (Literal[ "most_recent", "semantic", "most_recent_semantic", "trending", ], optional): The search algorithm to use for retrieving articles. (default: :obj:`most_recent`) **Returns:** List[Dict[str, str]]: A list of recommended articles or content based on the specified parameters, query, and data model. **Note:** Multiple data model IDs are available and can be found at: https://marketplace.dappier.com/marketplace ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of FunctionTool objects representing the functions in the toolkit. --- ## EdgeOnePagesMCPToolkit ```python class EdgeOnePagesMCPToolkit(BaseToolkit): ``` EdgeOnePagesMCPToolkit provides an interface for interacting with EdgeOne pages using the EdgeOne Pages MCP server. **Parameters:** - **timeout** (Optional[float]): Connection timeout in seconds. (default: :obj:`None`) ### __init__ ```python def __init__(self, timeout: Optional[float] = None): ``` Initializes the EdgeOnePagesMCPToolkit. **Parameters:** - **timeout** (Optional[float]): Connection timeout in seconds. (default: :obj:`None`) ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: List of available tools. --- ## ExcelToolkit ```python class ExcelToolkit(BaseToolkit): ``` A class representing a toolkit for extract detailed cell information from an Excel file. This class provides methods extracting detailed content from Excel files (including .xls, .xlsx,.csv), and converting the data into Markdown formatted table. ### __init__ ```python def __init__( self, timeout: Optional[float] = None, file_path: Optional[str] = None ): ``` Initializes a new instance of the ExcelToolkit class. **Parameters:** - **timeout** (Optional[float]): The timeout value for API requests in seconds. If None, no timeout is applied. (default: :obj:`None`) - **file_path** (Optional[str]): Path to an existing Excel file to load. (default: :obj:`None`) ### _validate_file_path ```python def _validate_file_path(self, file_path: str): ``` Validate file path for security. **Parameters:** - **file_path** (str): The file path to validate. **Returns:** bool: True if path is safe, False otherwise. ### _convert_to_markdown ```python def _convert_to_markdown(self, df: 'DataFrame'): ``` Convert DataFrame to Markdown format table. **Parameters:** - **df** (DataFrame): DataFrame containing the Excel data. **Returns:** str: Markdown formatted table. ### extract_excel_content ```python def extract_excel_content(self, document_path: str): ``` Extract and analyze the full content of an Excel file (.xlsx/.xls/. csv). Use this tool to read and understand the structure and content of Excel files. This is typically the first step when working with existing Excel files. **Parameters:** - **document_path** (str): The file path to the Excel file. **Returns:** str: A comprehensive report containing: - Sheet names and their content in markdown table format - Detailed cell information including values, colors, and positions - Formatted data that's easy to understand and analyze ### _save_workbook ```python def _save_workbook(self, file_path: Optional[str] = None): ``` Save the current workbook to file. **Parameters:** - **file_path** (Optional[str]): The path to save the workbook. If None, uses self.file_path. **Returns:** str: Success or error message. ### create_workbook ```python def create_workbook( self, file_path: str, sheet_name: Optional[str] = None, data: Optional[List[List[Union[str, int, float, None]]]] = None ): ``` Create a new Excel workbook from scratch. Use this when you need to create a new Excel file. This sets up the toolkit to work with the new file and optionally adds initial data. **Parameters:** - **file_path** (str): Where to save the new Excel file. Must end with . xlsx. - **sheet_name** (Optional[str]): Name for the first sheet. If None, creates "Sheet1". (default: :obj:`None`) - **data** (Optional[List[List[Union[str, int, float, None]]]]): Initial data as rows. Each inner list is one row. (default: :obj:`None`) **Returns:** str: Success confirmation message or error details ### delete_workbook ```python def delete_workbook(self, file_path: Optional[str] = None): ``` Delete a spreadsheet file. **Parameters:** - **file_path** (Optional[str]): The path of the file to delete. If None, uses self.file_path. **Returns:** str: Success message. ### create_sheet ```python def create_sheet( self, sheet_name: str, data: Optional[List[List[Union[str, int, float, None]]]] = None ): ``` Create a new sheet with the given sheet name and data. **Parameters:** - **sheet_name** (str): The name of the sheet to create. - **data** (Optional[List[List[Union[str, int, float, None]]]]): The data to write to the sheet. **Returns:** str: Success message. ### delete_sheet ```python def delete_sheet(self, sheet_name: str): ``` Delete a sheet from the workbook. **Parameters:** - **sheet_name** (str): The name of the sheet to delete. **Returns:** str: Success message. ### clear_sheet ```python def clear_sheet(self, sheet_name: str): ``` Clear all data from a sheet. **Parameters:** - **sheet_name** (str): The name of the sheet to clear. **Returns:** str: Success message. ### delete_rows ```python def delete_rows( self, sheet_name: str, start_row: int, end_row: Optional[int] = None ): ``` Delete rows from a sheet. Use this to remove unwanted rows. You can delete single rows or ranges. **Parameters:** - **sheet_name** (str): Name of the sheet to modify. - **start_row** (int): Starting row number to delete (1-based, where 1 is first row). - **end_row** (Optional[int]): Ending row number to delete (1-based). If None, deletes only start_row. (default: :obj:`None`) **Returns:** str: Success confirmation message or error details ### delete_columns ```python def delete_columns( self, sheet_name: str, start_col: int, end_col: Optional[int] = None ): ``` Delete columns from a sheet. Use this to remove unwanted columns. You can delete single columns or ranges. **Parameters:** - **sheet_name** (str): Name of the sheet to modify. - **start_col** (int): Starting column number to delete (1-based, where 1 is column A). - **end_col** (Optional[int]): Ending column number to delete (1-based). If None, deletes only start_col. (default: :obj:`None`) **Returns:** str: Success confirmation message or error details ### get_cell_value ```python def get_cell_value(self, sheet_name: str, cell_reference: str): ``` Get the value from a specific cell. Use this to read a single cell's value. Useful for checking specific data points or getting values for calculations. **Parameters:** - **sheet_name** (str): Name of the sheet containing the cell. - **cell_reference** (str): Excel-style cell reference (column letter + row number). **Returns:** Union[str, int, float, None]: The cell's value or error message Returns None for empty cells. ### set_cell_value ```python def set_cell_value( self, sheet_name: str, cell_reference: str, value: Union[str, int, float, None] ): ``` Set the value of a specific cell. Use this to update individual cells with new values. Useful for corrections, calculations, or updating specific data points. **Parameters:** - **sheet_name** (str): Name of the sheet containing the cell. - **cell_reference** (str): Excel-style cell reference (column letter + row number). - **value** (Union[str, int, float, None]): New value for the cell. (default: :obj:`None`) **Returns:** str: Success confirmation message or error details. ### get_column_data ```python def get_column_data(self, sheet_name: str, column: Union[int, str]): ``` Get all data from a specific column. Use this to extract all values from a column for analysis or processing. **Parameters:** - **sheet_name** (str): Name of the sheet to read from. - **column** (Union[int, str]): Column identifier - either number (1-based) or letter. **Returns:** Union[List[Union[str, int, float, None]], str]: List of all non-empty values in the column or error message ### find_cells ```python def find_cells( self, sheet_name: str, search_value: Union[str, int, float], search_column: Optional[Union[int, str]] = None ): ``` Find cells containing a specific value. Use this to locate where specific data appears in the sheet. **Parameters:** - **sheet_name** (str): Name of the sheet to search in. - **search_value** (Union[str, int, float]): Value to search for. - **search_column** (Optional[Union[int, str]]): Limit search to specific column. If None, searches entire sheet. (default: :obj:`None`) **Returns:** Union[List[str], str]: List of cell references (like "A5", "B12") where the value was found, or error message. ### get_range_values ```python def get_range_values(self, sheet_name: str, cell_range: str): ``` Get values from a specific range of cells. Use this to read a rectangular block of cells at once. **Parameters:** - **sheet_name** (str): Name of the sheet to read from. - **cell_range** (str): Range in Excel format (start:end). **Returns:** Union[List[List[Union[str, int, float, None]]], str]: 2D list where each inner list is a row of cell values, or error message. ### set_range_values ```python def set_range_values( self, sheet_name: str, cell_range: str, values: List[List[Union[str, int, float, None]]] ): ``` Set values for a specific range of cells. Use this to update multiple cells at once with a 2D array of data. **Parameters:** - **sheet_name** (str): Name of the sheet to modify. - **cell_range** (str): Range in Excel format to update. - **values** (List[List[Union[str, int, float, None]]]): 2D array of values. Each inner list represents a row. **Returns:** str: Success confirmation message or error details. ### export_sheet_to_csv ```python def export_sheet_to_csv(self, sheet_name: str, csv_path: str): ``` Export a specific sheet to CSV format. Use this to convert Excel sheets to CSV files for compatibility or data exchange. **Parameters:** - **sheet_name** (str): Name of the sheet to export. - **csv_path** (str): File path where CSV will be saved. **Returns:** str: Success confirmation message or error details. ### get_rows ```python def get_rows( self, sheet_name: str, start_row: Optional[int] = None, end_row: Optional[int] = None ): ``` Retrieve rows of data from a sheet. Use this to read data from a sheet. You can get all rows or specify a range. Returns actual data as lists, making it easy to process programmatically. **Parameters:** - **sheet_name** (str): Name of the sheet to read from. - **start_row** (Optional[int]): First row to read (1-based). If None, starts from row 1. (default: :obj:`None`) - **end_row** (Optional[int]): Last row to read (1-based). If None, reads to the end. (default: :obj:`None`) **Returns:** Union[List[List[Union[str, int, float, None]]], str]: List of rows (each row is a list of cell values) or error message. ### append_row ```python def append_row( self, sheet_name: str, row_data: List[Union[str, int, float, None]] ): ``` Add a single row to the end of a sheet. Use this to add one row of data to the end of existing content. For multiple rows, use multiple calls to this function. **Parameters:** - **sheet_name** (str): Name of the target sheet. - **row_data** (List[Union[str, int, float, None]]): Single row of data to add. **Returns:** str: Success confirmation message or error details. ### update_row ```python def update_row( self, sheet_name: str, row_number: int, row_data: List[Union[str, int, float, None]] ): ``` Update a specific row in the sheet. Use this to replace all data in a specific row with new values. **Parameters:** - **sheet_name** (str): Name of the sheet to modify. - **row_number** (int): The row number to update (1-based, where 1 is first row). - **row_data** (List[Union[str, int, float, None]]): New data for the entire row. **Returns:** str: Success confirmation message or error details. ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of FunctionTool objects representing the functions in the toolkit. --- ## FileWriteToolkit ```python class FileWriteToolkit(BaseToolkit): ``` A toolkit for creating, writing, and modifying text in files. This class provides cross-platform (macOS, Linux, Windows) support for writing to various file formats (Markdown, DOCX, PDF, and plaintext), replacing text in existing files, automatic filename uniquification to prevent overwrites, custom encoding and enhanced formatting options for specialized formats. ### __init__ ```python def __init__( self, working_directory: Optional[str] = None, timeout: Optional[float] = None, default_encoding: str = 'utf-8', backup_enabled: bool = True ): ``` Initialize the FileWriteToolkit. **Parameters:** - **working_directory** (str, optional): The default directory for output files. If not provided, it will be determined by the `CAMEL_WORKDIR` environment variable (if set). If the environment variable is not set, it defaults to `camel_working_dir`. - **timeout** (Optional[float]): The timeout for the toolkit. (default: :obj:`None`) - **default_encoding** (str): Default character encoding for text operations. (default: :obj:`utf-8`) - **backup_enabled** (bool): Whether to create backups of existing files before overwriting. (default: :obj:`True`) ### _resolve_filepath ```python def _resolve_filepath(self, file_path: str): ``` Convert the given string path to a Path object. If the provided path is not absolute, it is made relative to the default output directory. The filename part is sanitized to replace spaces and special characters with underscores, ensuring safe usage in downstream processing. **Parameters:** - **file_path** (str): The file path to resolve. **Returns:** Path: A fully resolved (absolute) and sanitized Path object. ### _sanitize_filename ```python def _sanitize_filename(self, filename: str): ``` Sanitize a filename by replacing any character that is not alphanumeric, a dot (.), hyphen (-), or underscore (_) with an underscore (_). **Parameters:** - **filename** (str): The original filename which may contain spaces or special characters. **Returns:** str: The sanitized filename with disallowed characters replaced by underscores. ### _write_text_file ```python def _write_text_file( self, file_path: Path, content: str, encoding: str = 'utf-8' ): ``` Write text content to a plaintext file. **Parameters:** - **file_path** (Path): The target file path. - **content** (str): The text content to write. - **encoding** (str): Character encoding to use. (default: :obj:`utf-8`) (default: utf-8) ### _generate_unique_filename ```python def _generate_unique_filename(self, file_path: Path): ``` Generate a unique filename if the target file already exists. **Parameters:** - **file_path** (Path): The original file path. **Returns:** Path: A unique file path that doesn't exist yet. ### _write_docx_file ```python def _write_docx_file(self, file_path: Path, content: str): ``` Write text content to a DOCX file with default formatting. **Parameters:** - **file_path** (Path): The target file path. - **content** (str): The text content to write. ### _write_pdf_file ```python def _write_pdf_file( self, file_path: Path, title: str, content: Union[str, List[List[str]]], use_latex: bool = False ): ``` Write text content to a PDF file with LaTeX and table support. **Parameters:** - **file_path** (Path): The target file path. - **title** (str): The document title. - **content** (Union[str, List[List[str]]]): The content to write. Can - **be**: - String: Supports Markdown-style tables and LaTeX math expressions - List[List[str]]: Table data as list of rows for direct table rendering - **use_latex** (bool): Whether to use LaTeX for math rendering. (default: :obj:`False`) ### _process_text_content ```python def _process_text_content( self, story, content: str, heading_style, body_style ): ``` Process text content and add to story. **Parameters:** - **story**: The reportlab story list to append to - **content** (str): The text content to process - **heading_style**: Style for headings - **body_style**: Style for body text ### _find_table_line_ranges ```python def _find_table_line_ranges(self, lines: List[str]): ``` Find line ranges that contain markdown tables. **Parameters:** - **lines** (List[str]): List of lines to analyze. **Returns:** List[Tuple[int, int]]: List of (start_line, end_line) tuples for table ranges. ### _register_chinese_font ```python def _register_chinese_font(self): ``` **Returns:** str: The font name to use for Chinese text. ### _parse_markdown_table ```python def _parse_markdown_table(self, lines: List[str]): ``` Parse markdown-style tables from a list of lines. **Parameters:** - **lines** (List[str]): List of text lines that may contain tables. **Returns:** List[List[List[str]]]: List of tables, where each table is a list of rows, and each row is a list of cells. ### _is_table_row ```python def _is_table_row(self, line: str): ``` Check if a line appears to be a table row. **Parameters:** - **line** (str): The line to check. **Returns:** bool: True if the line looks like a table row. ### _is_table_separator ```python def _is_table_separator(self, line: str): ``` Check if a line is a table separator (e.g., |---|---|). **Parameters:** - **line** (str): The line to check. **Returns:** bool: True if the line is a table separator. ### _parse_table_row ```python def _parse_table_row(self, line: str): ``` Parse a single table row into cells. **Parameters:** - **line** (str): The table row line. **Returns:** List[str]: List of cell contents. ### _create_pdf_table ```python def _create_pdf_table(self, table_data: List[List[str]]): ``` Create a formatted table for PDF. **Parameters:** - **table_data** (List[List[str]]): Table data as list of rows. **Returns:** Table: A formatted reportlab Table object. ### _convert_markdown_to_html ```python def _convert_markdown_to_html(self, text: str): ``` Convert basic markdown formatting to HTML for PDF rendering. **Parameters:** - **text** (str): Text with markdown formatting. **Returns:** str: Text with HTML formatting. ### _write_csv_file ```python def _write_csv_file( self, file_path: Path, content: Union[str, List[List]], encoding: str = 'utf-8' ): ``` Write CSV content to a file. **Parameters:** - **file_path** (Path): The target file path. - **content** (Union[str, List[List]]): The CSV content as a string or list of lists. - **encoding** (str): Character encoding to use. (default: :obj:`utf-8`) (default: utf-8) ### _write_json_file ```python def _write_json_file( self, file_path: Path, content: str, encoding: str = 'utf-8' ): ``` Write JSON content to a file. **Parameters:** - **file_path** (Path): The target file path. - **content** (str): The JSON content as a string. - **encoding** (str): Character encoding to use. (default: :obj:`utf-8`) (default: utf-8) ### _write_simple_text_file ```python def _write_simple_text_file( self, file_path: Path, content: str, encoding: str = 'utf-8' ): ``` Write text content to a file (used for HTML, Markdown, YAML, etc.). **Parameters:** - **file_path** (Path): The target file path. - **content** (str): The content to write. - **encoding** (str): Character encoding to use. (default: :obj:`utf-8`) (default: utf-8) ### write_to_file ```python def write_to_file( self, title: str, content: Union[str, List[List[str]]], filename: str, encoding: Optional[str] = None, use_latex: bool = False ): ``` Write the given content to a file. If the file exists, it will be overwritten. Supports multiple formats: Markdown (.md, .markdown, default), Plaintext (.txt), CSV (.csv), DOC/DOCX (.doc, .docx), PDF (.pdf), JSON (.json), YAML (.yml, .yaml), and HTML (.html, .htm). **Parameters:** - **title** (str): The title of the document. - **content** (Union[str, List[List[str]]]): The content to write to the file. Content format varies by file type: - Text formats (txt, md, html, yaml): string - CSV: string or list of lists - JSON: string or serializable object - **filename** (str): The name or path of the file. If a relative path is supplied, it is resolved to self.working_directory. - **encoding** (Optional[str]): The character encoding to use. (default: :obj: `None`) - **use_latex** (bool): Whether to use LaTeX for math rendering. (default: :obj:`False`) **Returns:** str: A message indicating success or error details. ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of FunctionTool objects representing the available functions in this toolkit. --- ## GithubToolkit ```python class GithubToolkit(BaseToolkit): ``` A class representing a toolkit for interacting with GitHub repositories. This class provides methods for retrieving open issues, retrieving specific issues, and creating pull requests in a GitHub repository. **Parameters:** - **access_token** (str, optional): The access token to authenticate with GitHub. If not provided, it will be obtained using the `get_github_access_token` method. ### __init__ ```python def __init__( self, access_token: Optional[str] = None, timeout: Optional[float] = None ): ``` Initializes a new instance of the GitHubToolkit class. **Parameters:** - **repo_name** (str): The name of the GitHub repository. - **access_token** (str, optional): The access token to authenticate with GitHub. If not provided, it will be obtained using the `get_github_access_token` method. ### get_github_access_token ```python def get_github_access_token(self): ``` **Returns:** str: A string containing the GitHub access token. ### github_create_pull_request ```python def github_create_pull_request( self, repo_name: str, file_path: str, new_content: str, pr_title: str, body: str, branch_name: str ): ``` Creates a pull request. This function creates a pull request in specified repository, which updates a file in the specific path with new content. The pull request description contains information about the issue title and number. **Parameters:** - **repo_name** (str): The name of the GitHub repository. - **file_path** (str): The path of the file to be updated in the repository. - **new_content** (str): The specified new content of the specified file. - **pr_title** (str): The title of the issue that is solved by this pull request. - **body** (str): The commit message for the pull request. - **branch_name** (str): The name of the branch to create and submit the pull request from. **Returns:** str: A formatted report of whether the pull request was created successfully or not. ### github_get_issue_list ```python def github_get_issue_list( self, repo_name: str, state: Literal['open', 'closed', 'all'] = 'all' ): ``` Retrieves all issues from the GitHub repository. **Parameters:** - **repo_name** (str): The name of the GitHub repository. - **state** (`Literal["open", "closed", "all"]`): The state of pull requests to retrieve. (default: :obj:`all`) Options are: - "open": Retrieve only open pull requests. - "closed": Retrieve only closed pull requests. - "all": Retrieve all pull requests, regardless of state. **Returns:** List[Dict[str, object]]: A list of dictionaries where each dictionary contains the issue number and title. ### github_get_issue_content ```python def github_get_issue_content(self, repo_name: str, issue_number: int): ``` Retrieves the content of a specific issue by its number. **Parameters:** - **repo_name** (str): The name of the GitHub repository. - **issue_number** (int): The number of the issue to retrieve. **Returns:** str: issues content details. ### github_get_pull_request_list ```python def github_get_pull_request_list( self, repo_name: str, state: Literal['open', 'closed', 'all'] = 'all' ): ``` Retrieves all pull requests from the GitHub repository. **Parameters:** - **repo_name** (str): The name of the GitHub repository. - **state** (`Literal["open", "closed", "all"]`): The state of pull requests to retrieve. (default: :obj:`all`) Options are: - "open": Retrieve only open pull requests. - "closed": Retrieve only closed pull requests. - "all": Retrieve all pull requests, regardless of state. **Returns:** list: A list of dictionaries where each dictionary contains the pull request number and title. ### github_get_pull_request_code ```python def github_get_pull_request_code(self, repo_name: str, pr_number: int): ``` Retrieves the code changes of a specific pull request. **Parameters:** - **repo_name** (str): The name of the GitHub repository. - **pr_number** (int): The number of the pull request to retrieve. **Returns:** List[Dict[str, str]]: A list of dictionaries where each dictionary contains the file name and the corresponding code changes (patch). ### github_get_pull_request_comments ```python def github_get_pull_request_comments(self, repo_name: str, pr_number: int): ``` Retrieves the comments from a specific pull request. **Parameters:** - **repo_name** (str): The name of the GitHub repository. - **pr_number** (int): The number of the pull request to retrieve. **Returns:** List[Dict[str, str]]: A list of dictionaries where each dictionary contains the user ID and the comment body. ### github_get_all_file_paths ```python def github_get_all_file_paths(self, repo_name: str, path: str = ''): ``` Recursively retrieves all file paths in the GitHub repository. **Parameters:** - **repo_name** (str): The name of the GitHub repository. - **path** (str): The repository path to start the traversal from. empty string means starts from the root directory. (default: :obj:`""`) **Returns:** List[str]: A list of file paths within the specified directory structure. ### github_retrieve_file_content ```python def github_retrieve_file_content(self, repo_name: str, file_path: str): ``` Retrieves the content of a file from the GitHub repository. **Parameters:** - **repo_name** (str): The name of the GitHub repository. - **file_path** (str): The path of the file to retrieve. **Returns:** str: The decoded content of the file. ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of FunctionTool objects representing the functions in the toolkit. --- ## GmailToolkit ```python class GmailToolkit(BaseToolkit): ``` A comprehensive toolkit for Gmail operations. This toolkit provides methods for Gmail operations including sending emails, managing drafts, fetching messages, managing labels, and handling contacts. It supports both plain text and HTML email formats, attachment handling, and comprehensive Gmail API integration. **Parameters:** - **timeout** (Optional[float]): The timeout value for API requests in seconds. If None, no timeout is applied. (default: :obj:`None`) **Note:** This toolkit requires Google OAuth2 authentication. On first use, it will open a browser window for authentication and store credentials for future use. **Authentication Scopes:** The toolkit requests the following Gmail API scopes: - `https://www.googleapis.com/auth/gmail.readonly` - Read-only access - `https://www.googleapis.com/auth/gmail.send` - Send emails - `https://www.googleapis.com/auth/gmail.modify` - Modify emails - `https://www.googleapis.com/auth/gmail.compose` - Compose emails - `https://www.googleapis.com/auth/gmail.labels` - Manage labels - `https://www.googleapis.com/auth/contacts.readonly` - Read contacts - `https://www.googleapis.com/auth/userinfo.profile` - User profile access ### __init__ ```python def __init__( self, timeout: Optional[float] = None, ): ``` Initialize a new instance of the GmailToolkit class. **Parameters:** - **timeout** (Optional[float]): The timeout value for API requests in seconds. If None, no timeout is applied. (default: :obj:`None`) ### send_email ```python def send_email( self, to: Union[str, List[str]], subject: str, body: str, cc: Optional[Union[str, List[str]]] = None, bcc: Optional[Union[str, List[str]]] = None, attachments: Optional[List[str]] = None, is_html: bool = False, ) -> Dict[str, Any]: ``` Send an email through Gmail. **Parameters:** - **to** (Union[str, List[str]]): Recipient email address(es). - **subject** (str): Email subject. - **body** (str): Email body content. - **cc** (Optional[Union[str, List[str]]]): CC recipient email address(es). - **bcc** (Optional[Union[str, List[str]]]): BCC recipient email address(es). - **attachments** (Optional[List[str]]): List of file paths to attach. - **is_html** (bool): Whether the body is HTML format. Set to True when sending formatted emails with HTML tags (e.g., bold, links, images). Use False (default) for plain text emails. **Returns:** - **Dict[str, Any]**: A dictionary containing the result of the operation with keys: - `success` (bool): Whether the operation was successful - `message_id` (str): The ID of the sent message - `thread_id` (str): The ID of the email thread - `message` (str): Status message **Example:** ```python from camel.toolkits import GmailToolkit gmail = GmailToolkit() result = gmail.send_email( to="recipient@example.com", subject="Hello from CAMEL", body="This is a test email", cc=["cc@example.com"], attachments=["/path/to/file.pdf"], is_html=False ) print(result) # {'success': True, 'message_id': 'abc123', 'thread_id': 'abc123', 'message': 'Email sent successfully'} ``` ### create_email_draft ```python def create_email_draft( self, to: Union[str, List[str]], subject: str, body: str, cc: Optional[Union[str, List[str]]] = None, bcc: Optional[Union[str, List[str]]] = None, attachments: Optional[List[str]] = None, is_html: bool = False, ) -> Dict[str, Any]: ``` Create a draft email in Gmail. **Parameters:** - **to** (Union[str, List[str]]): Recipient email address(es). - **subject** (str): Email subject. - **body** (str): Email body content. - **cc** (Optional[Union[str, List[str]]]): CC recipient email address(es). - **bcc** (Optional[Union[str, List[str]]]): BCC recipient email address(es). - **attachments** (Optional[List[str]]): List of file paths to attach. - **is_html** (bool): Whether the body is HTML format. **Returns:** - **Dict[str, Any]**: A dictionary containing the result of the operation with keys: - `success` (bool): Whether the operation was successful - `draft_id` (str): The ID of the created draft - `message` (str): Status message ### fetch_emails ```python def fetch_emails( self, query: str = "", max_results: int = 10, include_spam_trash: bool = False, label_ids: Optional[List[str]] = None, ) -> Dict[str, Any]: ``` Retrieve messages from Gmail. **Parameters:** - **query** (str): Gmail search query (e.g., "from:example@gmail.com", "subject:urgent"). (default: :obj:`""`) - **max_results** (int): Maximum number of messages to retrieve. (default: :obj:`10`) - **include_spam_trash** (bool): Whether to include messages from spam and trash. (default: :obj:`False`) - **label_ids** (Optional[List[str]]): List of label IDs to filter by. **Returns:** - **Dict[str, Any]**: A dictionary containing the result of the operation with keys: - `success` (bool): Whether the operation was successful - `messages` (List[Dict]): List of message objects with metadata - `total_count` (int): Total number of messages found - `message` (str): Status message **Example:** ```python # Get recent messages result = gmail.fetch_emails(max_results=5) # Search for specific emails result = gmail.fetch_emails(query="from:important@company.com", max_results=10) # Get unread messages result = gmail.fetch_emails(query="is:unread") ``` ### _get_message_details (internal) ```python def _get_message_details(self, message_id: str) -> Optional[Dict[str, Any]]: ``` Get detailed fields for a message (subject, from, to, cc, bcc, date, body, attachments). Intended for internal use. ### get_attachment ```python def get_attachment( self, message_id: str, attachment_id: str, save_path: Optional[str] = None, ) -> Dict[str, Any]: ``` Retrieve attachments from a specific message. **Parameters:** - **message_id** (str): The ID of the message containing the attachment. - **attachment_id** (str): The ID of the attachment to retrieve. - **save_path** (Optional[str]): Path to save the attachment. If None, returns the attachment data. **Returns:** - **Dict[str, Any]**: A dictionary containing the result of the operation with keys: - `success` (bool): Whether the operation was successful - `attachment_data` (bytes): The attachment data (if save_path is None) - `saved_path` (str): The path where the attachment was saved (if save_path is provided) - `filename` (str): The name of the attachment file - `size` (int): The size of the attachment in bytes ### list_gmail_labels ```python def list_gmail_labels(self) -> Dict[str, Any]: ``` Retrieve all labels from Gmail. **Returns:** - **Dict[str, Any]**: A dictionary containing the result of the operation with keys: - `success` (bool): Whether the operation was successful - `labels` (List[Dict]): List of label objects with metadata - `message` (str): Status message ### create_label ```python def create_label( self, name: str, message_list_visibility: str = "show", label_list_visibility: str = "labelShow", ) -> Dict[str, Any]: ``` Create a new label in Gmail. **Parameters:** - **name** (str): The name of the label to create. - **message_list_visibility** (str): Visibility of the label in the message list. (default: :obj:`"show"`) - **label_list_visibility** (str): Visibility of the label in the label list. (default: :obj:`"labelShow"`) **Returns:** - **Dict[str, Any]**: A dictionary containing the result of the operation with keys: - `success` (bool): Whether the operation was successful - `label_id` (str): The ID of the created label - `message` (str): Status message ### modify_email_labels ```python def modify_email_labels( self, message_id: str, add_label_ids: Optional[List[str]] = None, remove_label_ids: Optional[List[str]] = None, ) -> Dict[str, Any]: ``` Modify labels of a specific message. **Parameters:** - **message_id** (str): The ID of the message to modify. - **add_label_ids** (Optional[List[str]]): List of label IDs to add to the message. - **remove_label_ids** (Optional[List[str]]): List of label IDs to remove from the message. **Returns:** - **Dict[str, Any]**: A dictionary containing the result of the operation with keys: - `success` (bool): Whether the operation was successful - `message_id` (str): The ID of the modified message - `message` (str): Status message ### move_to_trash ```python def move_to_trash(self, message_id: str) -> Dict[str, Any]: ``` Delete a specific message. **Parameters:** - **message_id** (str): The ID of the message to delete. **Returns:** - **Dict[str, Any]**: A dictionary containing the result of the operation with keys: - `success` (bool): Whether the operation was successful - `message` (str): Status message ### get_contacts ```python def get_contacts( self, max_results: int = 100, page_size: int = 100, ) -> Dict[str, Any]: ``` Retrieve contacts from Google Contacts. **Parameters:** - **max_results** (int): Maximum number of contacts to retrieve. (default: :obj:`100`) - **page_size** (int): Number of contacts per page. (default: :obj:`100`) **Returns:** - **Dict[str, Any]**: A dictionary containing the result of the operation with keys: - `success` (bool): Whether the operation was successful - `contacts` (List[Dict]): List of contact objects with metadata - `total_count` (int): Total number of contacts found - `message` (str): Status message ### search_people ```python def search_people( self, query: str, max_results: int = 10, ) -> Dict[str, Any]: ``` Search for contacts by name or email. **Parameters:** - **query** (str): Search query for contacts. - **max_results** (int): Maximum number of contacts to retrieve. (default: :obj:`10`) **Returns:** - **Dict[str, Any]**: A dictionary containing the result of the operation with keys: - `success` (bool): Whether the operation was successful - `contacts` (List[Dict]): List of matching contact objects - `total_count` (int): Total number of contacts found - `message` (str): Status message ### get_profile ```python def get_profile(self) -> Dict[str, Any]: ``` Retrieve the current user's Gmail profile information. **Returns:** - **Dict[str, Any]**: A dictionary containing the result of the operation with keys: - `success` (bool): Whether the operation was successful - `profile` (Dict): User profile information including email, name, etc. - `message` (str): Status message ### list_threads ```python def list_threads( self, query: str = "", max_results: int = 10, include_spam_trash: bool = False, label_ids: Optional[List[str]] = None, ) -> Dict[str, Any]: ``` Retrieve email threads from Gmail. **Parameters:** - **query** (str): Gmail search query for threads. (default: :obj:`""`) - **max_results** (int): Maximum number of threads to retrieve. (default: :obj:`10`) - **include_spam_trash** (bool): Whether to include threads from spam and trash. (default: :obj:`False`) - **label_ids** (Optional[List[str]]): List of label IDs to filter by. **Returns:** - **Dict[str, Any]**: A dictionary containing the result of the operation with keys: - `success` (bool): Whether the operation was successful - `threads` (List[Dict]): List of thread objects with metadata - `total_count` (int): Total number of threads found - `message` (str): Status message ### fetch_thread_by_id ```python def fetch_thread_by_id( self, thread_id: str, ) -> Dict[str, Any]: ``` Retrieve a specific email thread by ID. **Parameters:** - **thread_id** (str): The ID of the thread to retrieve. - **format** (Literal["minimal", "full", "metadata"]): The format of the thread to retrieve. (default: :obj:`"full"`) **Returns:** - **Dict[str, Any]**: A dictionary containing the result of the operation with keys: - `success` (bool): Whether the operation was successful - `thread` (Dict): The thread object with all messages - `thread_id` (str): The ID of the retrieved thread ### get_tools ```python def get_tools(self) -> List[FunctionTool]: ``` Get all available Gmail tools as FunctionTool objects. **Returns:** - **List[FunctionTool]**: List of FunctionTool objects for all Gmail operations. **Example:** ```python from camel.toolkits import GmailToolkit from camel.agents import ChatAgent # Initialize Gmail toolkit gmail_toolkit = GmailToolkit() # Get all tools tools = gmail_toolkit.get_tools() # Create an agent with Gmail tools agent = ChatAgent( system_message="You are a helpful Gmail assistant.", tools=tools ) # Use the agent response = agent.step("Send an email to john@example.com with subject 'Meeting' and body 'Let's meet tomorrow'") ``` ## Usage Examples ### Basic Email Operations ```python from camel.toolkits import GmailToolkit # Initialize the toolkit gmail = GmailToolkit() # Send a simple email result = gmail.send_email( to="recipient@example.com", subject="Hello from CAMEL", body="This is a test email sent using the CAMEL Gmail toolkit." ) # Send an HTML email with attachments result = gmail.send_email( to=["user1@example.com", "user2@example.com"], subject="Important Update", body="

Important Update

Please review the attached document.

", cc="manager@example.com", attachments=["/path/to/document.pdf"], is_html=True ) # Create a draft draft_result = gmail.create_draft( to="colleague@example.com", subject="Draft: Project Proposal", body="Here's the initial draft of our project proposal..." ) ``` ### Message Management ```python # Get recent messages messages = gmail.fetch_emails(max_results=10) # Search for specific emails urgent_emails = gmail.fetch_emails(query="is:unread subject:urgent") # Get messages from a specific sender from_sender = gmail.fetch_emails(query="from:important@company.com") # Get message details (internal helper) message = gmail._get_message_details("message_id_here") # Move a message to trash delete_result = gmail.move_to_trash("message_id_here") ``` ### Label Management ```python # Get all labels labels = gmail.list_gmail_labels() # Create a new label new_label = gmail.create_label("Important Projects") # Modify message labels gmail.modify_email_labels( message_id="message_id_here", add_label_ids=["label_id_here"], remove_label_ids=["INBOX"] ) ``` ### Contact Management ```python # Get all contacts contacts = gmail.get_contacts() # Search for specific contacts search_results = gmail.search_contacts("John Smith") # Get user profile profile = gmail.get_profile() ``` ### Thread Management ```python # Get recent threads threads = gmail.list_threads(max_results=5) # Get a specific thread thread = gmail.fetch_thread_by_id("thread_id_here") # Search for threads project_threads = gmail.get_threads(query="subject:project") ``` ## Error Handling All methods return a dictionary with a `success` boolean field. Check this field to determine if the operation was successful: ```python result = gmail.send_email( to="invalid-email", subject="Test", body="Test message" ) if result["success"]: print(f"Email sent successfully! Message ID: {result['message_id']}") else: print(f"Failed to send email: {result['message']}") ``` ## Authentication The Gmail toolkit uses OAuth2 authentication with Google's Gmail API. This section covers the complete authentication setup and mechanisms. ### Prerequisites Before using the Gmail toolkit, you need to set up Google API credentials: 1. **Google Cloud Console Setup:** - Go to the [Google Cloud Console](https://console.cloud.google.com/) - Create a new project or select an existing one - Enable the Gmail API and Google People API - Create OAuth 2.0 credentials (Desktop application type) 2. **Download Credentials:** - Download the `credentials.json` file from the Google Cloud Console - Place it in your project directory or set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable ### Authentication Flow The Gmail toolkit implements a multi-step OAuth2 authentication process: #### 1. Initial Authentication On first use, the toolkit will: ```python # The authentication process happens automatically when initializing gmail = GmailToolkit() # This triggers the OAuth flow ``` **What happens behind the scenes:** - Loads the `credentials.json` file - Opens a browser window for user consent - Requests permission for all required Gmail scopes - Exchanges authorization code for access and refresh tokens - Stores tokens securely in `token.json` for future use #### 2. Token Storage The toolkit stores authentication tokens in a local `token.json` file: ```json { "token": "ya29.a0AfH6SMC...", "refresh_token": "1//04...", "token_uri": "https://oauth2.googleapis.com/token", "client_id": "your-client-id.apps.googleusercontent.com", "client_secret": "your-client-secret", "scopes": ["https://mail.google.com/", ...], "expiry": "2024-01-01T12:00:00Z" } ``` #### 3. Automatic Token Refresh The toolkit automatically handles token refresh: - **Access tokens** expire after 1 hour - **Refresh tokens** are used to obtain new access tokens - **Automatic refresh** happens before each API call if needed - **No user intervention** required after initial setup ### Required Scopes The toolkit requests the following Gmail API scopes: | Scope | Purpose | Access Level | |-------|---------|--------------| | `https://www.googleapis.com/auth/gmail.readonly` | Read emails and metadata | Read-only | | `https://www.googleapis.com/auth/gmail.send` | Send emails | Write | | `https://www.googleapis.com/auth/gmail.modify` | Modify emails and labels | Write | | `https://www.googleapis.com/auth/gmail.compose` | Create drafts and compose | Write | | `https://www.googleapis.com/auth/gmail.labels` | Manage labels | Write | | `https://www.googleapis.com/auth/contacts.readonly` | Read Google Contacts | Read-only | | `https://www.googleapis.com/auth/userinfo.profile` | Access user profile | Read-only | ### Environment Variables You can configure authentication using environment variables: ```bash # Set the path to your credentials file export GOOGLE_APPLICATION_CREDENTIALS="/path/to/credentials.json" # Optional: Set custom token storage location export GMAIL_TOKEN_PATH="/custom/path/token.json" ``` ### Authentication Methods #### Method 1: Credentials File (Recommended) ```python # Place credentials.json in your project directory gmail = GmailToolkit() ``` #### Method 2: Environment Variable ```python import os os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = '/path/to/credentials.json' gmail = GmailToolkit() ``` #### Method 3: Explicit Path ```python # The toolkit will look for credentials.json in the current directory # or use the path specified in GOOGLE_APPLICATION_CREDENTIALS gmail = GmailToolkit() ``` ### Troubleshooting Authentication #### Common Issues and Solutions **1. "Credentials not found" Error:** ```python # Error: FileNotFoundError: [Errno 2] No such file or directory: 'credentials.json' # Solution: Ensure credentials.json is in the correct location ``` **2. "Invalid credentials" Error:** ```python # Error: google.auth.exceptions.RefreshError: The credentials do not contain the necessary fields # Solution: Re-download credentials.json from Google Cloud Console ``` **3. "Access denied" Error:** ```python # Error: googleapiclient.errors.HttpError: # Solution: Check that Gmail API is enabled in Google Cloud Console ``` **4. "Token expired" Error:** ```python # Error: google.auth.exceptions.RefreshError: The credentials have been revoked # Solution: Delete token.json and re-authenticate ``` #### Debug Authentication Issues ```python import logging logging.basicConfig(level=logging.DEBUG) # This will show detailed authentication logs gmail = GmailToolkit() ``` ### Security Considerations #### Token Security - **Never commit** `token.json` to version control - **Use environment variables** for production deployments - **Rotate credentials** regularly in production - **Limit scope** to only required permissions #### Production Deployment ```python # For production, use service account credentials # or implement your own token management system import os from google.oauth2 import service_account # Load service account credentials credentials = service_account.Credentials.from_service_account_file( '/path/to/service-account.json', scopes=SCOPES ) # Use with Gmail toolkit (requires additional implementation) ``` ### Re-authentication If you need to re-authenticate (e.g., after changing scopes): ```python import os # Delete the existing token file if os.path.exists('token.json'): os.remove('token.json') # Re-initialize the toolkit gmail = GmailToolkit() # This will trigger re-authentication ``` ### Multi-User Support For applications supporting multiple users: ```python # Each user needs their own token file user_id = "user123" token_file = f"token_{user_id}.json" # You would need to modify the toolkit to support custom token paths # This is an advanced use case requiring custom implementation ``` ### Best Practices 1. **Credential Management:** - Store credentials securely - Use environment variables in production - Implement proper error handling 2. **Token Handling:** - Monitor token expiration - Implement retry logic for token refresh - Log authentication events 3. **Scope Management:** - Request only necessary scopes - Regularly review and update permissions - Document scope requirements 4. **Error Handling:** - Handle authentication errors gracefully - Provide clear error messages to users - Implement fallback mechanisms ### Example: Complete Authentication Setup ```python import os from camel.toolkits import GmailToolkit def setup_gmail_authentication(): """Complete Gmail authentication setup.""" # Check if credentials file exists if not os.path.exists('credentials.json'): raise FileNotFoundError( "credentials.json not found. Please download it from Google Cloud Console." ) try: # Initialize Gmail toolkit (triggers authentication) gmail = GmailToolkit() print("✓ Gmail authentication successful!") return gmail except Exception as e: print(f"✗ Gmail authentication failed: {e}") print("Please check your credentials.json file and try again.") raise # Usage if __name__ == "__main__": gmail = setup_gmail_authentication() # Test authentication by getting user profile profile = gmail.get_user_profile() if profile['success']: print(f"Authenticated as: {profile['profile']['emailAddress']}") else: print("Authentication test failed") ``` This comprehensive authentication documentation covers all aspects of setting up and using the Gmail toolkit with proper security considerations and troubleshooting guidance. --- ## GoogleDriveMCPToolkit ```python class GoogleDriveMCPToolkit(BaseToolkit): ``` GoogleDriveMCPToolkit provides an interface for interacting with Google Drive using the Google Drive MCP server. **Parameters:** - **timeout** (Optional[float]): Connection timeout in seconds. (default: :obj:`None`) ### __init__ ```python def __init__( self, timeout: Optional[float] = None, credentials_path: Optional[str] = None ): ``` Initializes the GoogleDriveMCPToolkit. **Parameters:** - **timeout** (Optional[float]): Connection timeout in seconds. (default: :obj:`None`) - **credentials_path** (Optional[str]): Path to the Google Drive credentials file. (default: :obj:`None`) ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: List of available tools. --- ## HumanToolkit ```python class HumanToolkit(BaseToolkit): ``` A class representing a toolkit for human interaction. **Note:** This toolkit should be called to send a tidy message to the user to keep them informed. ### ask_human_via_console ```python def ask_human_via_console(self, question: str): ``` Use this tool to ask a question to the user when you are stuck, need clarification, or require a decision to be made. This is a two-way communication channel that will wait for the user's response. You should use it to: - Clarify ambiguous instructions or requirements. - Request missing information that you cannot find (e.g., login credentials, file paths). - Ask for a decision when there are multiple viable options. - Seek help when you encounter an error you cannot resolve on your own. **Parameters:** - **question** (str): The question to ask the user. **Returns:** str: The user's response to the question. ### send_message_to_user ```python def send_message_to_user(self, message: str) -> str: ``` Use this tool to send a tidy message to the user in one short sentence. This one-way tool keeps the user informed about your progress, decisions, or actions. It does not require a response from user. You should use it to: - Announce what you are about to do (e.g., "I will now search for papers on GUI Agents."). - Report the result of an action (e.g., "I have found 15 relevant papers."). - State a decision (e.g., "I will now analyze the top 10 papers."). - Give a status update during a long-running task. **Parameters:** - **message** (str): The tidy and informative message for the user. ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of FunctionTool objects representing the functions in the toolkit. --- ## ActionExecutor ```python class ActionExecutor: ``` Executes high-level actions (click, type …) on a Playwright Page. ### __init__ ```python def __init__( self, page: 'Page', session: Optional[Any] = None, default_timeout: Optional[int] = None, short_timeout: Optional[int] = None, max_scroll_amount: Optional[int] = None ): ``` ### should_update_snapshot ```python def should_update_snapshot(action: Dict[str, Any]): ``` Determine if an action requires a snapshot update. --- ## PlaywrightLLMAgent ```python class PlaywrightLLMAgent: ``` High-level orchestration: snapshot ↔ LLM ↔ action executor. ### __init__ ```python def __init__(self): ``` ### _get_chat_agent ```python def _get_chat_agent(self): ``` Get or create the ChatAgent instance. ### _safe_parse_json ```python def _safe_parse_json(self, content: str): ``` Safely parse JSON from LLM response with multiple fallback strategies. ### _get_fallback_response ```python def _get_fallback_response(self, error_msg: str): ``` Generate a fallback response structure. ### _llm_call ```python def _llm_call( self, prompt: str, snapshot: str, is_initial: bool, history: Optional[List[Dict[str, Any]]] = None ): ``` Call the LLM (via CAMEL ChatAgent) to get plan & next action. --- ## HybridBrowserSession ```python class HybridBrowserSession: ``` Lightweight wrapper around Playwright for browsing with multi-tab support. It provides multiple *Page* instances plus helper utilities (snapshot & executor). Multiple toolkits or agents can reuse this class without duplicating Playwright setup code. This class is a singleton per event-loop and session-id combination. ### __new__ ```python def __new__(cls): ``` ### __init__ ```python def __init__(self): ``` ### _load_stealth_script ```python def _load_stealth_script(self): ``` Load the stealth JavaScript script from file. --- Configuration for browser automation including stealth mode and timeouts. This module contains all the configuration needed to make the browser appear as a regular user browser and configure action timeouts. ## BrowserConfig ```python class BrowserConfig: ``` Configuration class for browser settings including stealth mode and timeouts. ### get_timeout_config ```python def get_timeout_config(): ``` **Returns:** Dict[str, int]: Timeout configuration in milliseconds. ### get_action_limits ```python def get_action_limits(): ``` **Returns:** Dict[str, int]: Action limits configuration. ### get_action_timeout ```python def get_action_timeout(override: Optional[int] = None): ``` Get action timeout with optional override. **Parameters:** - **override**: Optional timeout override value in milliseconds. **Returns:** int: Timeout value in milliseconds. ### get_short_timeout ```python def get_short_timeout(override: Optional[int] = None): ``` Get short timeout with optional override. **Parameters:** - **override**: Optional timeout override value in milliseconds. **Returns:** int: Timeout value in milliseconds. ### get_navigation_timeout ```python def get_navigation_timeout(override: Optional[int] = None): ``` Get navigation timeout with optional override. **Parameters:** - **override**: Optional timeout override value in milliseconds. **Returns:** int: Timeout value in milliseconds. ### get_network_idle_timeout ```python def get_network_idle_timeout(override: Optional[int] = None): ``` Get network idle timeout with optional override. **Parameters:** - **override**: Optional timeout override value in milliseconds. **Returns:** int: Timeout value in milliseconds. ### get_max_scroll_amount ```python def get_max_scroll_amount(override: Optional[int] = None): ``` Get maximum scroll amount with optional override. **Parameters:** - **override**: Optional scroll amount override value in pixels. **Returns:** int: Maximum scroll amount in pixels. ### get_screenshot_timeout ```python def get_screenshot_timeout(override: Optional[int] = None): ``` Get screenshot timeout with optional override. **Parameters:** - **override**: Optional timeout override value in milliseconds. **Returns:** int: Timeout value in milliseconds. ### get_page_stability_timeout ```python def get_page_stability_timeout(override: Optional[int] = None): ``` Get page stability timeout with optional override. **Parameters:** - **override**: Optional timeout override value in milliseconds. **Returns:** int: Timeout value in milliseconds. ### get_dom_content_loaded_timeout ```python def get_dom_content_loaded_timeout(override: Optional[int] = None): ``` Get DOM content loaded timeout with optional override. **Parameters:** - **override**: Optional timeout override value in milliseconds. **Returns:** int: Timeout value in milliseconds. ### get_launch_args ```python def get_launch_args(): ``` **Returns:** List[str]: Chrome command line arguments to avoid detection. ### get_context_options ```python def get_context_options(): ``` **Returns:** Dict[str, Any]: Browser context configuration options. ### get_http_headers ```python def get_http_headers(): ``` **Returns:** Dict[str, str]: HTTP headers to appear more like a real browser. ### get_stealth_config ```python def get_stealth_config(): ``` **Returns:** Dict[str, Any]: Complete stealth configuration. ### get_all_config ```python def get_all_config(): ``` **Returns:** Dict[str, Any]: Complete browser configuration. ## ConfigLoader ```python class ConfigLoader: ``` Legacy wrapper for BrowserConfig - maintained for backward compatibility. ### get_browser_config ```python def get_browser_config(cls): ``` Get the BrowserConfig class. ### get_stealth_config ```python def get_stealth_config(cls): ``` Get the StealthConfig class (alias). ### get_timeout_config ```python def get_timeout_config(cls): ``` Get timeout configuration. ### get_action_timeout ```python def get_action_timeout(cls, override: Optional[int] = None): ``` Get action timeout with optional override. ### get_short_timeout ```python def get_short_timeout(cls, override: Optional[int] = None): ``` Get short timeout with optional override. ### get_navigation_timeout ```python def get_navigation_timeout(cls, override: Optional[int] = None): ``` Get navigation timeout with optional override. ### get_network_idle_timeout ```python def get_network_idle_timeout(cls, override: Optional[int] = None): ``` Get network idle timeout with optional override. ### get_max_scroll_amount ```python def get_max_scroll_amount(cls, override: Optional[int] = None): ``` Get maximum scroll amount with optional override. ### get_screenshot_timeout ```python def get_screenshot_timeout(cls, override: Optional[int] = None): ``` Get screenshot timeout with optional override. ### get_page_stability_timeout ```python def get_page_stability_timeout(cls, override: Optional[int] = None): ``` Get page stability timeout with optional override. ### get_dom_content_loaded_timeout ```python def get_dom_content_loaded_timeout(cls, override: Optional[int] = None): ``` Get DOM content loaded timeout with optional override. ## get_browser_config ```python def get_browser_config(): ``` Get BrowserConfig class. ## get_stealth_config ```python def get_stealth_config(): ``` Get StealthConfig class. ## get_timeout_config ```python def get_timeout_config(): ``` Get timeout configuration. ## get_action_timeout ```python def get_action_timeout(override: Optional[int] = None): ``` Get action timeout with optional override. ## get_short_timeout ```python def get_short_timeout(override: Optional[int] = None): ``` Get short timeout with optional override. ## get_navigation_timeout ```python def get_navigation_timeout(override: Optional[int] = None): ``` Get navigation timeout with optional override. ## get_network_idle_timeout ```python def get_network_idle_timeout(override: Optional[int] = None): ``` Get network idle timeout with optional override. ## get_max_scroll_amount ```python def get_max_scroll_amount(override: Optional[int] = None): ``` Get maximum scroll amount with optional override. ## get_screenshot_timeout ```python def get_screenshot_timeout(override: Optional[int] = None): ``` Get screenshot timeout with optional override. ## get_page_stability_timeout ```python def get_page_stability_timeout(override: Optional[int] = None): ``` Get page stability timeout with optional override. ## get_dom_content_loaded_timeout ```python def get_dom_content_loaded_timeout(override: Optional[int] = None): ``` Get DOM content loaded timeout with optional override. --- ## HybridBrowserToolkit ```python class HybridBrowserToolkit(BaseToolkit): ``` A hybrid browser toolkit that combines non-visual, DOM-based browser automation with visual, screenshot-based capabilities. This toolkit exposes a set of actions as CAMEL FunctionTools for agents to interact with web pages. It can operate in headless mode and supports both programmatic control of browser actions (like clicking and typing) and visual analysis of the page layout through screenshots with marked interactive elements. ### __init__ ```python def __init__(self): ``` Initialize the HybridBrowserToolkit. **Parameters:** - **headless** (bool): Whether to run the browser in headless mode. Defaults to `True`. - **user_data_dir** (Optional[str]): Path to a directory for storing browser data like cookies and local storage. Useful for maintaining sessions across runs. Defaults to `None` (a temporary directory is used). - **stealth** (bool): Whether to run the browser in stealth mode to avoid bot detection. When enabled, hides WebDriver characteristics, spoofs navigator properties, and implements various anti-detection measures. Highly recommended for production use and when accessing sites with bot detection. Defaults to `False`. - **web_agent_model** (Optional[BaseModelBackend]): The language model backend to use for the high-level `solve_task` agent. This is required only if you plan to use `solve_task`. Defaults to `None`. - **cache_dir** (str): The directory to store cached files, such as screenshots. Defaults to `"tmp/"`. - **enabled_tools** (Optional[List[str]]): List of tool names to enable. If None, uses DEFAULT_TOOLS. Available tools: open_browser, close_browser, visit_page, back, forward, get_page_snapshot, get_som_screenshot, get_page_links, click, type, select, scroll, enter, wait_user, solve_task. Defaults to `None`. - **browser_log_to_file** (bool): Whether to save detailed browser action logs to file. When enabled, logs action inputs/outputs, execution times, and page loading times. Logs are saved to an auto-generated timestamped file. Defaults to `False`. - **session_id** (Optional[str]): A unique identifier for this browser session. When multiple HybridBrowserToolkit instances are used concurrently, different session IDs prevent them from sharing the same browser session and causing conflicts. If None, a default session will be used. Defaults to `None`. - **default_start_url** (str): The default URL to navigate to when open_browser() is called without a start_url parameter or with None. Defaults to `"https://google.com/"`. - **default_timeout** (Optional[int]): Default timeout in milliseconds for browser actions. If None, uses environment variable HYBRID_BROWSER_DEFAULT_TIMEOUT or defaults to 3000ms. Defaults to `None`. - **short_timeout** (Optional[int]): Short timeout in milliseconds for quick browser actions. If None, uses environment variable HYBRID_BROWSER_SHORT_TIMEOUT or defaults to 1000ms. Defaults to `None`. - **navigation_timeout** (Optional[int]): Custom navigation timeout in milliseconds. If None, uses environment variable HYBRID_BROWSER_NAVIGATION_TIMEOUT or defaults to 10000ms. Defaults to `None`. - **network_idle_timeout** (Optional[int]): Custom network idle timeout in milliseconds. If None, uses environment variable HYBRID_BROWSER_NETWORK_IDLE_TIMEOUT or defaults to 5000ms. Defaults to `None`. - **screenshot_timeout** (Optional[int]): Custom screenshot timeout in milliseconds. If None, uses environment variable HYBRID_BROWSER_SCREENSHOT_TIMEOUT or defaults to 15000ms. Defaults to `None`. - **page_stability_timeout** (Optional[int]): Custom page stability timeout in milliseconds. If None, uses environment variable HYBRID_BROWSER_PAGE_STABILITY_TIMEOUT or defaults to 1500ms. Defaults to `None`. - **dom_content_loaded_timeout** (Optional[int]): Custom DOM content loaded timeout in milliseconds. If None, uses environment variable HYBRID_BROWSER_DOM_CONTENT_LOADED_TIMEOUT or defaults to 5000ms. Defaults to `None`. ### web_agent_model ```python def web_agent_model(self): ``` Get the web agent model. ### web_agent_model ```python def web_agent_model(self, value: Optional[BaseModelBackend]): ``` Set the web agent model. ### cache_dir ```python def cache_dir(self): ``` Get the cache directory. ### __del__ ```python def __del__(self): ``` Cleanup browser resources on garbage collection. ### _load_unified_analyzer ```python def _load_unified_analyzer(self): ``` Load the unified analyzer JavaScript script. ### _validate_ref ```python def _validate_ref(self, ref: str, method_name: str): ``` Validate ref parameter. ### _truncate_if_needed ```python def _truncate_if_needed(self, content: Any): ``` Truncate content if max_log_length is set. ### action_logger ```python def action_logger(func: Callable[..., Any]): ``` Decorator to add logging to action methods. ### _convert_analysis_to_rects ```python def _convert_analysis_to_rects(self, analysis_data: Dict[str, Any]): ``` Convert analysis data to rect format for visual marking. ### _add_set_of_mark ```python def _add_set_of_mark(self, image, rects): ``` Add visual marks to the image. ### _format_snapshot_from_analysis ```python def _format_snapshot_from_analysis(self, analysis_data: Dict[str, Any]): ``` Format analysis data into snapshot string. ### _ensure_agent ```python def _ensure_agent(self): ``` Create PlaywrightLLMAgent on first use. ### get_log_summary ```python def get_log_summary(self): ``` Get a summary of logged actions. ### clear_logs ```python def clear_logs(self): ``` Clear the log buffer. ### get_tools ```python def get_tools(self): ``` Get available function tools based on enabled_tools configuration. ### clone_for_new_session ```python def clone_for_new_session(self, new_session_id: Optional[str] = None): ``` Create a new instance of HybridBrowserToolkit with a unique session. **Parameters:** - **new_session_id**: Optional new session ID. If None, a UUID will be generated. **Returns:** A new HybridBrowserToolkit instance with the same configuration but a different session. --- ## PageSnapshot ```python class PageSnapshot: ``` Utility for capturing YAML-like page snapshots and diff-only variants. ### __init__ ```python def __init__(self, page: 'Page'): ``` ### _format_snapshot ```python def _format_snapshot(text: str): ``` ### _compute_diff ```python def _compute_diff(old: str, new: str): ``` ### _detect_priorities ```python def _detect_priorities(self, snapshot_yaml: str): ``` Return sorted list of priorities present (1,2,3). --- Stealth configuration for browser automation to avoid bot detection. This module contains all the configuration needed to make the browser appear as a regular user browser rather than an automated one. ## StealthConfig ```python class StealthConfig: ``` Configuration class for stealth browser settings. ### get_launch_args ```python def get_launch_args(): ``` **Returns:** List[str]: Chrome command line arguments to avoid detection. ### get_context_options ```python def get_context_options(): ``` **Returns:** Dict[str, Any]: Browser context configuration options. ### get_http_headers ```python def get_http_headers(): ``` **Returns:** Dict[str, str]: HTTP headers to appear more like a real browser. ### get_all_config ```python def get_all_config(): ``` **Returns:** Dict[str, Any]: Complete stealth configuration. --- ## JinaRerankerToolkit ```python class JinaRerankerToolkit(BaseToolkit): ``` A class representing a toolkit for reranking documents using Jina Reranker. This class provides methods for reranking documents (text or images) based on their relevance to a given query using the Jina Reranker model. ### __init__ ```python def __init__( self, timeout: Optional[float] = None, model_name: str = 'jinaai/jina-reranker-m0', device: Optional[str] = None, use_api: bool = True ): ``` Initializes a new instance of the JinaRerankerToolkit class. **Parameters:** - **timeout** (Optional[float]): The timeout value for API requests in seconds. If None, no timeout is applied. (default: :obj:`None`) - **model_name** (str): The reranker model name. (default: :obj:`"jinaai/jina-reranker-m0"`) - **device** (Optional[str]): Device to load the model on. If None, will use CUDA if available, otherwise CPU. Only effective when use_api=False. (default: :obj:`None`) - **use_api** (bool): A flag to switch between local model and API. (default: :obj:`True`) ### _sort_documents ```python def _sort_documents(self, documents: List[str], scores: List[float]): ``` Sort documents by their scores in descending order. **Parameters:** - **documents** (List[str]): List of documents to sort. - **scores** (List[float]): Corresponding scores for each document. **Returns:** List[Dict[str, object]]: Sorted list of (document, score) pairs. ### _call_jina_api ```python def _call_jina_api(self, data: Dict[str, Any]): ``` Makes a call to the JINA API for reranking. **Parameters:** - **data** (Dict[str]): The data to be passed into the api body. **Returns:** List[Dict[str, object]]: A list of dictionary containing the reranked documents and their relevance scores. ### rerank_text_documents ```python def rerank_text_documents( self, query: str, documents: List[str], max_length: int = 1024 ): ``` Reranks text documents based on their relevance to a text query. **Parameters:** - **query** (str): The text query for reranking. - **documents** (List[str]): List of text documents to be reranked. - **max_length** (int): Maximum token length for processing. (default: :obj:`1024`) **Returns:** List[Dict[str, object]]: A list of dictionary containing the reranked documents and their relevance scores. ### rerank_image_documents ```python def rerank_image_documents( self, query: str, documents: List[str], max_length: int = 2048 ): ``` Reranks image documents based on their relevance to a text query. **Parameters:** - **query** (str): The text query for reranking. - **documents** (List[str]): List of image URLs or paths to be reranked. - **max_length** (int): Maximum token length for processing. (default: :obj:`2048`) **Returns:** List[Dict[str, object]]: A list of dictionary containing the reranked image URLs/paths and their relevance scores. ### image_query_text_documents ```python def image_query_text_documents( self, image_query: str, documents: List[str], max_length: int = 2048 ): ``` Reranks text documents based on their relevance to an image query. **Parameters:** - **image_query** (str): The image URL or path used as query. - **documents** (List[str]): List of text documents to be reranked. - **max_length** (int): Maximum token length for processing. (default: :obj:`2048`) **Returns:** List[Dict[str, object]]: A list of dictionary containing the reranked documents and their relevance scores. ### image_query_image_documents ```python def image_query_image_documents( self, image_query: str, documents: List[str], max_length: int = 2048 ): ``` Reranks image documents based on their relevance to an image query. **Parameters:** - **image_query** (str): The image URL or path used as query. - **documents** (List[str]): List of image URLs or paths to be reranked. - **max_length** (int): Maximum token length for processing. (default: :obj:`2048`) **Returns:** List[Dict[str, object]]: A list of dictionary containing the reranked image URLs/paths and their relevance scores. ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of FunctionTool objects representing the functions in the toolkit. --- ## MarkItDownToolkit ```python class MarkItDownToolkit(BaseToolkit): ``` A class representing a toolkit for MarkItDown. ### __init__ ```python def __init__(self, timeout: Optional[float] = None): ``` ### read_files ```python def read_files(self, file_paths: List[str]): ``` Scrapes content from a list of files and converts it to Markdown. This function takes a list of local file paths, attempts to convert each file into Markdown format, and returns the converted content. The conversion is performed in parallel for efficiency. Supported file formats include: - PDF (.pdf) - Microsoft Office: Word (.doc, .docx), Excel (.xls, .xlsx), PowerPoint (.ppt, .pptx) - EPUB (.epub) - HTML (.html, .htm) - Images (.jpg, .jpeg, .png) for OCR - Audio (.mp3, .wav) for transcription - Text-based formats (.csv, .json, .xml, .txt) - ZIP archives (.zip) **Parameters:** - **file_paths** (List[str]): A list of local file paths to be converted. **Returns:** Dict[str, str]: A dictionary where keys are the input file paths and values are the corresponding content in Markdown format. If conversion of a file fails, the value will contain an error message. ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of FunctionTool objects representing the functions in the toolkit. --- ## MessageAgentTool ```python class MessageAgentTool(BaseToolkit): ``` A toolkit for agent-to-agent communication. This toolkit allows agents to send messages to other agents by their IDs and receive responses, enabling multi-agent collaboration. **Parameters:** - **agents** (Optional[Dict[str, ChatAgent]], optional): Dictionary mapping agent IDs to ChatAgent instances. (default: :obj:`None`) - **timeout** (Optional[float], optional): Maximum execution time allowed for toolkit operations in seconds. If None, no timeout is applied. (default: :obj:`None`) ### __init__ ```python def __init__( self, agents: Optional[Dict[str, ChatAgent]] = None, timeout: Optional[float] = None ): ``` ### register_agent ```python def register_agent(self, agent_id: str, agent: ChatAgent): ``` Register a new agent for communication. **Parameters:** - **agent_id** (str): Unique identifier for the agent. - **agent** (ChatAgent): The ChatAgent instance to register. **Returns:** str: Confirmation message. ### message_agent ```python def message_agent(self, message: str, receiver_agent_id: str): ``` Send a message to another agent and get the response. **Parameters:** - **message** (str): The message to send to the target agent. - **receiver_agent_id** (str): Unique identifier of the target agent. **Returns:** str: Response from the target agent or error message if the operation fails. ### list_available_agents ```python def list_available_agents(self): ``` **Returns:** str: Formatted list of registered agent IDs or message if no agents are registered. ### remove_agent ```python def remove_agent(self, agent_id: str): ``` Remove an agent from the communication registry. **Parameters:** - **agent_id** (str): Unique identifier of the agent to remove. **Returns:** str: Confirmation message or error message if agent not found. ### get_agent_count ```python def get_agent_count(self): ``` **Returns:** str: Number of currently registered agents. ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of FunctionTool objects for agent communication and management. --- ## HybridBrowserSession ```python class HybridBrowserSession: ``` Lightweight wrapper around Playwright for non-visual (headless) browsing. It provides a single *Page* instance plus helper utilities (snapshot & executor). Multiple toolkits or agents can reuse this class without duplicating Playwright setup code. This class is a singleton per event-loop. ### __new__ ```python def __new__(cls): ``` ### __init__ ```python def __init__(self): ``` --- ## NoteTakingToolkit ```python class NoteTakingToolkit(BaseToolkit): ``` A toolkit for taking notes in a Markdown file. This toolkit allows an agent to create, append to, and update a specific Markdown file for note-taking purposes. ### __init__ ```python def __init__( self, working_directory: Optional[str] = None, timeout: Optional[float] = None ): ``` Initialize the NoteTakingToolkit. **Parameters:** - **working_directory** (str, optional): The path to the note file. If not provided, it will be determined by the `CAMEL_WORKDIR` environment variable (if set), saving the note as `notes.md` in that directory. If the environment variable is not set, it defaults to `camel_working_dir/notes.md`. - **timeout** (Optional[float]): The timeout for the toolkit. ### append_note ```python def append_note(self, content: str): ``` Appends a note to the note file. **Parameters:** - **content** (str): The content of the note to be appended. **Returns:** str: A message indicating the result of the operation. ### read_note ```python def read_note(self): ``` **Returns:** str: The content of the note file, or an error message if the file cannot be read. ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of FunctionTool objects. --- ## OpenAIImageToolkit ```python class OpenAIImageToolkit(BaseToolkit): ``` A class toolkit for image generation using OpenAI's Image Generation API. ### __init__ ```python def __init__( self, model: Optional[Literal['gpt-image-1', 'dall-e-3', 'dall-e-2']] = 'gpt-image-1', timeout: Optional[float] = None, api_key: Optional[str] = None, url: Optional[str] = None, size: Optional[Literal['256x256', '512x512', '1024x1024', '1536x1024', '1024x1536', '1792x1024', '1024x1792', 'auto']] = '1024x1024', quality: Optional[Literal['auto', 'low', 'medium', 'high', 'standard', 'hd']] = 'standard', response_format: Optional[Literal['url', 'b64_json']] = 'b64_json', background: Optional[Literal['transparent', 'opaque', 'auto']] = 'auto', style: Optional[Literal['vivid', 'natural']] = None, working_directory: Optional[str] = 'image_save' ): ``` Initializes a new instance of the OpenAIImageToolkit class. **Parameters:** - **api_key** (Optional[str]): The API key for authenticating with the OpenAI service. (default: :obj:`None`) - **url** (Optional[str]): The url to the OpenAI service. (default: :obj:`None`) - **model** (Optional[str]): The model to use. (default: :obj:`"dall-e-3"`) - **timeout** (Optional[float]): The timeout value for API requests in seconds. If None, no timeout is applied. (default: :obj:`None`) size (Optional[Literal["256x256", "512x512", "1024x1024", "1536x1024", "1024x1536", "1792x1024", "1024x1792", "auto"]]): The size of the image to generate. (default: :obj:`"1024x1024"`) quality (Optional[Literal["auto", "low", "medium", "high", "standard", "hd"]]):The quality of the image to generate. Different models support different values. (default: :obj:`"standard"`) - **response_format** (`Optional[Literal["url", "b64_json"]]`): The format of the response.(default: :obj:`"b64_json"`) - **background** (`Optional[Literal["transparent", "opaque", "auto"]]`): The background of the image.(default: :obj:`"auto"`) - **style** (`Optional[Literal["vivid", "natural"]]`): The style of the image.(default: :obj:`None`) - **working_directory** (Optional[str]): The path to save the generated image.(default: :obj:`"image_save"`) ### base64_to_image ```python def base64_to_image(self, base64_string: str): ``` Converts a base64 encoded string into a PIL Image object. **Parameters:** - **base64_string** (str): The base64 encoded string of the image. **Returns:** Optional[Image.Image]: The PIL Image object or None if conversion fails. ### _build_base_params ```python def _build_base_params(self, prompt: str): ``` Build base parameters dict for OpenAI API calls. **Parameters:** - **prompt** (str): The text prompt for the image operation. **Returns:** dict: Parameters dictionary with non-None values. ### _handle_api_response ```python def _handle_api_response( self, response, image_name: str, operation: str ): ``` Handle API response from OpenAI image operations. **Parameters:** - **response**: The response object from OpenAI API. - **image_name** (str): Name for the saved image file. - **operation** (str): Operation type for success message ("generated"). **Returns:** str: Success message with image path/URL or error message. ### generate_image ```python def generate_image(self, prompt: str, image_name: str = 'image'): ``` Generate an image using OpenAI's Image Generation models. The generated image will be saved locally (for `__INLINE_CODE_0__` response formats) or an image URL will be returned (for `__INLINE_CODE_1__` response formats). **Parameters:** - **prompt** (str): The text prompt to generate the image. - **image_name** (str): The name of the image to save. (default: :obj:`"image"`) **Returns:** str: the content of the model response or format of the response. ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of FunctionTool objects representing the functions in the toolkit. --- ## PPTXToolkit ```python class PPTXToolkit(BaseToolkit): ``` A toolkit for creating and writing PowerPoint presentations (PPTX files). This class provides cross-platform support for creating PPTX files with title slides, content slides, text formatting, and image embedding. ### __init__ ```python def __init__( self, working_directory: Optional[str] = None, timeout: Optional[float] = None ): ``` Initialize the PPTXToolkit. **Parameters:** - **working_directory** (str, optional): The default directory for output files. If not provided, it will be determined by the `CAMEL_WORKDIR` environment variable (if set). If the environment variable is not set, it defaults to `camel_working_dir`. - **timeout** (Optional[float]): The timeout for the toolkit. (default: :obj:`None`) ### _resolve_filepath ```python def _resolve_filepath(self, file_path: str): ``` Convert the given string path to a Path object. If the provided path is not absolute, it is made relative to the default output directory. The filename part is sanitized to replace spaces and special characters with underscores, ensuring safe usage in downstream processing. **Parameters:** - **file_path** (str): The file path to resolve. **Returns:** Path: A fully resolved (absolute) and sanitized Path object. ### _sanitize_filename ```python def _sanitize_filename(self, filename: str): ``` Sanitize a filename by replacing special characters and spaces. **Parameters:** - **filename** (str): The filename to sanitize. **Returns:** str: The sanitized filename. ### _format_text ```python def _format_text( self, frame_paragraph, text: str, set_color_to_white = False ): ``` Apply bold and italic formatting while preserving the original word order. **Parameters:** - **frame_paragraph**: The paragraph to format. - **text** (str): The text to format. - **set_color_to_white** (bool): Whether to set the color to white. (default: :obj:`False`) ### _add_bulleted_items ```python def _add_bulleted_items( self, text_frame: 'TextFrame', flat_items_list: List[Tuple[str, int]], set_color_to_white: bool = False ): ``` Add a list of texts as bullet points and apply formatting. **Parameters:** - **text_frame** (TextFrame): The text frame where text is to be displayed. - **flat_items_list** (List[Tuple[str, int]]): The list of items to be displayed. - **set_color_to_white** (bool): Whether to set the font color to white. (default: :obj:`False`) ### _get_flat_list_of_contents ```python def _get_flat_list_of_contents(self, items: List[Union[str, List[Any]]], level: int): ``` Flatten a hierarchical list of bullet points to a single list. **Parameters:** - **items** (List[Union[str, List[Any]]]): A bullet point (string or list). - **level** (int): The current level of hierarchy. **Returns:** List[Tuple[str, int]]: A list of (bullet item text, hierarchical level) tuples. ### _get_slide_width_height_inches ```python def _get_slide_width_height_inches(self, presentation: 'presentation.Presentation'): ``` Get the dimensions of a slide in inches. **Parameters:** - **presentation** (presentation.Presentation): The presentation object. **Returns:** Tuple[float, float]: The width and height in inches. ### _write_pptx_file ```python def _write_pptx_file( self, file_path: Path, content: List[Dict[str, Any]], template: Optional[str] = None ): ``` Write text content to a PPTX file with enhanced formatting. **Parameters:** - **file_path** (Path): The target file path. - **content** (List[Dict[str, Any]]): The content to write to the PPTX file. Must be a list of dictionaries where: - First element: Title slide with keys 'title' and 'subtitle' - Subsequent elements: Content slides with keys 'title', 'text' - **template** (Optional[str]): The name of the template to use. If not provided, the default template will be used. (default: :obj: `None`) ### create_presentation ```python def create_presentation( self, content: str, filename: str, template: Optional[str] = None ): ``` Create a PowerPoint presentation (PPTX) file. **Parameters:** - **content** (str): The content to write to the PPTX file as a JSON string. Must represent a list of dictionaries with the following structure: - First dict: title slide `{"title": str, "subtitle": str}` - Other dicts: content slides, which can be one of: * Bullet/step slides: `{"heading": str, "bullet_points": list of str or nested lists, "img_keywords": str (optional)}` - If any bullet point starts with '>> ', it will be rendered as a step-by-step process. - "img_keywords" can be a URL or search keywords for an image (optional). * Table slides: `{"heading": str, "table": {"headers": list of str, "rows": list of list of str}}` - **filename** (str): The name or path of the file. If a relative path is supplied, it is resolved to self.working_directory. - **template** (Optional[str]): The path to the template PPTX file. Initializes a presentation from a given template file Or PPTX file. (default: :obj:`None`) **Returns:** str: A success message indicating the file was created. ### _handle_default_display ```python def _handle_default_display( self, presentation: 'presentation.Presentation', slide_json: Dict[str, Any] ): ``` Display a list of text in a slide. **Parameters:** - **presentation** (presentation.Presentation): The presentation object. - **slide_json** (Dict[str, Any]): The content of the slide as JSON data. ### _handle_display_image__in_foreground ```python def _handle_display_image__in_foreground( self, presentation: 'presentation.Presentation', slide_json: Dict[str, Any] ): ``` Create a slide with text and image using a picture placeholder layout. **Parameters:** - **presentation** (presentation.Presentation): The presentation object. - **slide_json** (Dict[str, Any]): The content of the slide as JSON data. **Returns:** bool: True if the slide has been processed. ### _handle_table ```python def _handle_table( self, presentation: 'presentation.Presentation', slide_json: Dict[str, Any] ): ``` Add a table to a slide. **Parameters:** - **presentation** (presentation.Presentation): The presentation object. - **slide_json** (Dict[str, Any]): The content of the slide as JSON data. ### _handle_step_by_step_process ```python def _handle_step_by_step_process( self, presentation: 'presentation.Presentation', slide_json: Dict[str, Any], slide_width_inch: float, slide_height_inch: float ): ``` Add shapes to display a step-by-step process in the slide. **Parameters:** - **presentation** (presentation.Presentation): The presentation object. - **slide_json** (Dict[str, Any]): The content of the slide as JSON data. - **slide_width_inch** (float): The width of the slide in inches. - **slide_height_inch** (float): The height of the slide in inches. ### _remove_slide_number_from_heading ```python def _remove_slide_number_from_heading(self, header: str): ``` Remove the slide number from a given slide header. **Parameters:** - **header** (str): The header of a slide. **Returns:** str: The header without slide number. ### _get_slide_placeholders ```python def _get_slide_placeholders(self, slide: 'Slide'): ``` Return the index and name of all placeholders present in a slide. **Parameters:** - **slide** (Slide): The slide. **Returns:** List[Tuple[int, str]]: A list containing placeholders (idx, name) tuples. ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of FunctionTool objects representing the functions in the toolkit. --- ## SearchToolkit ```python class SearchToolkit(BaseToolkit): ``` A class representing a toolkit for web search. This class provides methods for searching information on the web using search engines like Google, DuckDuckGo, Wikipedia and Wolfram Alpha, Brave. ### __init__ ```python def __init__( self, timeout: Optional[float] = None, exclude_domains: Optional[List[str]] = None ): ``` Initializes the SearchToolkit. **Parameters:** - **timeout** (float): Timeout for API requests in seconds. (default: :obj:`None`) - **exclude_domains** (Optional[List[str]]): List of domains to exclude from search results. Currently only supported by the `search_google` function. (default: :obj:`None`) ### search_serper ```python def search_serper( self, query: str, page: int = 10, location: str = 'United States' ): ``` Use Serper.dev API to perform Google search. **Parameters:** - **query** (str): The search query. - **page** (int): The page number of results to retrieve. (default: :obj:`10`) - **location** (str): The location for the search results. (default: :obj:`"United States"`) **Returns:** Dict[str, Any]: The search result dictionary containing 'organic', 'peopleAlsoAsk', etc. ### search_wiki ```python def search_wiki(self, entity: str): ``` Search the entity in WikiPedia and return the summary of the required page, containing factual information about the given entity. **Parameters:** - **entity** (str): The entity to be searched. **Returns:** str: The search result. If the page corresponding to the entity exists, return the summary of this entity in a string. ### search_linkup ```python def search_linkup( self, query: str, depth: Literal['standard', 'deep'] = 'standard', output_type: Literal['searchResults', 'sourcedAnswer', 'structured'] = 'searchResults', structured_output_schema: Optional[str] = None ): ``` Search for a query in the Linkup API and return results in various formats. **Parameters:** - **query** (str): The search query. - **depth** (`Literal["standard", "deep"]`): The depth of the search. "standard" for a straightforward search, "deep" for a more comprehensive search. - **output_type** (`Literal["searchResults", "sourcedAnswer", "structured"]`): The type of output: - "searchResults" for raw search results, - "sourcedAnswer" for an answer with supporting sources, - "structured" for output based on a provided schema. - **structured_output_schema** (Optional[str]): If `output_type` is "structured", specify the schema of the output. Must be a string representing a valid object JSON schema. **Returns:** Dict[str, Any]: A dictionary representing the search result. The structure depends on the `output_type`. If an error occurs, returns an error message. ### search_duckduckgo ```python def search_duckduckgo( self, query: str, source: str = 'text', number_of_result_pages: int = 10 ): ``` Use DuckDuckGo search engine to search information for the given query. This function queries the DuckDuckGo API for related topics to the given search term. The results are formatted into a list of dictionaries, each representing a search result. **Parameters:** - **query** (str): The query to be searched. - **source** (str): The type of information to query (e.g., "text", "images", "videos"). Defaults to "text". - **number_of_result_pages** (int): The number of result pages to retrieve. Adjust this based on your task - use fewer results for focused searches and more for comprehensive searches. (default: :obj:`10`) **Returns:** List[Dict[str, Any]]: A list of dictionaries where each dictionary represents a search result. ### search_brave ```python def search_brave( self, q: str, country: str = 'US', search_lang: str = 'en', ui_lang: str = 'en-US', offset: int = 0, safesearch: str = 'moderate', freshness: Optional[str] = None, text_decorations: bool = True, spellcheck: bool = True, result_filter: Optional[str] = None, goggles_id: Optional[str] = None, units: Optional[str] = None, extra_snippets: Optional[bool] = None, summary: Optional[bool] = None, number_of_result_pages: int = 10 ): ``` This function queries the Brave search engine API and returns a dictionary, representing a search result. See https://api.search.brave.com/app/documentation/web-search/query for more details. **Parameters:** - **q** (str): The user's search query term. Query cannot be empty. Maximum of 400 characters and 50 words in the query. - **country** (str): The search query country where results come from. The country string is limited to 2 character country codes of supported countries. For a list of supported values, see Country Codes. (default: :obj:`US `) - **search_lang** (str): The search language preference. Use ONLY these exact values, NOT standard ISO codes: 'ar', 'eu', 'bn', 'bg', 'ca', 'zh-hans', 'zh-hant', 'hr', 'cs', 'da', 'nl', 'en', 'en-gb', 'et', 'fi', 'fr', 'gl', 'de', 'gu', 'he', 'hi', 'hu', 'is', 'it', 'jp', 'kn', 'ko', 'lv', 'lt', 'ms', 'ml', 'mr', 'nb', 'pl', 'pt-br', 'pt-pt', 'pa', 'ro', 'ru', 'sr', 'sk', 'sl', 'es', 'sv', 'ta', 'te', 'th', 'tr', 'uk', 'vi'. - **ui_lang** (str): User interface language preferred in response. - **Format**: '``-``'. Common examples: 'en-US', 'en-GB', 'jp-JP', 'zh-hans-CN', 'zh-hant-TW', 'de-DE', 'fr-FR', 'es-ES', 'pt-BR', 'ru-RU', 'ko-KR'. - **offset** (int): The zero based offset that indicates number of search results per page (count) to skip before returning the result. The maximum is 9. The actual number delivered may be less than requested based on the query. In order to paginate results use this parameter together with count. For example, if your user interface displays 20 search results per page, set count to 20 and offset to 0 to show the first page of results. To get subsequent pages, increment offset by 1 (e.g. 0, 1, 2). The results may overlap across multiple pages. - **safesearch** (str): Filters search results for adult content. The following values are supported: - 'off': No filtering is done. - 'moderate': Filters explicit content, like images and videos, but allows adult domains in the search results. - 'strict': Drops all adult content from search results. - **freshness** (Optional[str]): Filters search results by when they were - **discovered**: - 'pd': Discovered within the last 24 hours. - 'pw': Discovered within the last 7 Days. - 'pm': Discovered within the last 31 Days. - 'py': Discovered within the last 365 Days. - 'YYYY-MM-DDtoYYYY-MM-DD': Timeframe is also supported by specifying the date range e.g. '2022-04-01to2022-07-30'. - **text_decorations** (bool): Whether display strings (e.g. result snippets) should include decoration markers (e.g. highlighting characters). - **spellcheck** (bool): Whether to spellcheck provided query. If the spellchecker is enabled, the modified query is always used for search. The modified query can be found in altered key from the query response model. - **result_filter** (Optional[str]): A comma delimited string of result types to include in the search response. Not specifying this parameter will return back all result types in search response where data is available and a plan with the corresponding option is subscribed. The response always includes query and type to identify any query modifications and response type respectively. Available result filter values are: - 'discussions' - 'faq' - 'infobox' - 'news' - 'query' - 'summarizer' - 'videos' - 'web' - 'locations' - **goggles_id** (Optional[str]): Goggles act as a custom re-ranking on top of Brave's search index. For more details, refer to the Goggles repository. - **units** (Optional[str]): The measurement units. If not provided, units are derived from search country. Possible values are: - 'metric': The standardized measurement system - 'imperial': The British Imperial system of units. - **extra_snippets** (Optional[bool]): A snippet is an excerpt from a page you get as a result of the query, and extra_snippets allow you to get up to 5 additional, alternative excerpts. Only available under Free AI, Base AI, Pro AI, Base Data, Pro Data and Custom plans. - **summary** (Optional[bool]): This parameter enables summary key generation in web search results. This is required for summarizer to be enabled. - **number_of_result_pages** (int): The number of result pages to retrieve. Adjust this based on your task - use fewer results for focused searches and more for comprehensive searches. (default: :obj:`10`) **Returns:** Dict[str, Any]: A dictionary representing a search result. ### search_google ```python def search_google( self, query: str, search_type: str = 'web', number_of_result_pages: int = 10, start_page: int = 1 ): ``` Use Google search engine to search information for the given query. **Parameters:** - **query** (str): The query to be searched. - **search_type** (str): The type of search to perform. Must be either "web" for web pages or "image" for image search. Any other value will raise a ValueError. (default: "web") - **number_of_result_pages** (int): The number of result pages to retrieve. Must be a positive integer between 1 and 10. Google Custom Search API limits results to 10 per request. If a value greater than 10 is provided, it will be capped at 10 with a warning. Adjust this based on your task - use fewer results for focused searches and more for comprehensive searches. (default: :obj:`10`) - **start_page** (int): The result page to start from. Must be a positive integer (`>= 1`). Use this for pagination - e.g., start_page=1 for results 1-10, start_page=11 for results 11-20, etc. This allows agents to check initial results and continue searching if needed. (default: :obj:`1`) **Returns:** List[Dict[str, Any]]: A list of dictionaries where each dictionary represents a search result. For web search, each dictionary contains: - 'result_id': A number in order. - 'title': The title of the website. - 'description': A brief description of the website. - 'long_description': More detail of the website. - 'url': The URL of the website. For image search, each dictionary contains: - 'result_id': A number in order. - 'title': The title of the image. - 'image_url': The URL of the image. - 'display_link': The website hosting the image. - 'context_url': The URL of the page containing the image. - 'width': Image width in pixels (if available). - 'height': Image height in pixels (if available). Example web result: `\{ 'result_id': 1, 'title': 'OpenAI', 'description': 'An organization focused on ensuring that artificial general intelligence benefits all of humanity.', 'long_description': 'OpenAI is a non-profit artificial intelligence research company. Our goal is to advance digital intelligence in the way that is most likely to benefit humanity as a whole', 'url': 'https://www.openai.com' \}` Example image result: `\{ 'result_id': 1, 'title': 'Beautiful Sunset', 'image_url': 'https://example.com/image.jpg', 'display_link': 'example.com', 'context_url': 'https://example.com/page.html', 'width': 800, 'height': 600 \}` ### search_tavily ```python def search_tavily( self, query: str, number_of_result_pages: int = 10, **kwargs ): ``` Use Tavily Search API to search information for the given query. **Parameters:** - **query** (str): The query to be searched. - **number_of_result_pages** (int): The number of result pages to retrieve. Adjust this based on your task - use fewer results for focused searches and more for comprehensive searches. (default: :obj:`10`) **kwargs: Additional optional parameters supported by Tavily's API: - search_depth (str): "basic" or "advanced" search depth. - topic (str): The search category, e.g., "general" or "news." - days (int): Time frame in days for news-related searches. - max_results (int): Max number of results to return (overrides `num_results`). See https://docs.tavily.com/docs/python-sdk/tavily-search/ api-reference for details. **Returns:** List[Dict[str, Any]]: A list of dictionaries representing search results. Each dictionary contains: - 'result_id' (int): The result's index. - 'title' (str): The title of the result. - 'description' (str): A brief description of the result. - 'long_description' (str): Detailed information, if available. - 'url' (str): The URL of the result. - 'content' (str): Relevant content from the search result. - 'images' (list): A list of related images (if `include_images` is True). - 'published_date' (str): Publication date for news topics (if available). ### search_bocha ```python def search_bocha( self, query: str, freshness: str = 'noLimit', summary: bool = False, page: int = 1, number_of_result_pages: int = 10 ): ``` Query the Bocha AI search API and return search results. **Parameters:** - **query** (str): The search query. - **freshness** (str): Time frame filter for search results. Default is "noLimit". Options include: - 'noLimit': no limit (default). - 'oneDay': past day. - 'oneWeek': past week. - 'oneMonth': past month. - 'oneYear': past year. - **summary** (bool): Whether to include text summaries in results. Default is False. - **page** (int): Page number of results. Default is 1. - **number_of_result_pages** (int): The number of result pages to retrieve. Adjust this based on your task - use fewer results for focused searches and more for comprehensive searches. (default: :obj:`10`) **Returns:** Dict[str, Any]: A dictionary containing search results, including web pages, images, and videos if available. The structure follows the Bocha AI search API response format. ### search_baidu ```python def search_baidu(self, query: str, number_of_result_pages: int = 10): ``` Search Baidu using web scraping to retrieve relevant search results. This method queries Baidu's search engine and extracts search results including titles, descriptions, and URLs. **Parameters:** - **query** (str): Search query string to submit to Baidu. - **number_of_result_pages** (int): The number of result pages to retrieve. Adjust this based on your task - use fewer results for focused searches and more for comprehensive searches. (default: :obj:`10`) **Returns:** Dict[str, Any]: A dictionary containing search results or error message. ### search_bing ```python def search_bing(self, query: str, number_of_result_pages: int = 10): ``` Use Bing search engine to search information for the given query. This function queries the Chinese version of Bing search engine (cn. bing.com) using web scraping to retrieve relevant search results. It extracts search results including titles, snippets, and URLs. This function is particularly useful when the query is in Chinese or when Chinese search results are desired. **Parameters:** - **query** (str): The search query string to submit to Bing. Works best with Chinese queries or when Chinese results are preferred. - **number_of_result_pages** (int): The number of result pages to retrieve. Adjust this based on your task - use fewer results for focused searches and more for comprehensive searches. (default: :obj:`10`) **Returns:** Dict ([str, Any]): A dictionary containing either: - 'results': A list of dictionaries, each with: - 'result_id': The index of the result. - 'snippet': A brief description of the search result. - 'title': The title of the search result. - 'link': The URL of the search result. - or 'error': An error message if something went wrong. ### search_exa ```python def search_exa( self, query: str, search_type: Literal['auto', 'neural', 'keyword'] = 'auto', category: Optional[Literal['company', 'research paper', 'news', 'pdf', 'github', 'tweet', 'personal site', 'linkedin profile', 'financial report']] = None, include_text: Optional[List[str]] = None, exclude_text: Optional[List[str]] = None, use_autoprompt: bool = True, text: bool = False, number_of_result_pages: int = 10 ): ``` Use Exa search API to perform intelligent web search with optional content extraction. **Parameters:** - **query** (str): The search query string. - **search_type** (`Literal["auto", "neural", "keyword"]`): The type of search to perform. "auto" automatically decides between keyword and neural search. (default: :obj:`"auto"`) - **category** (Optional[Literal]): Category to focus the search on, such as "research paper" or "news". (default: :obj:`None`) - **include_text** (Optional[List[str]]): Strings that must be present in webpage text. Limited to 1 string of up to 5 words. (default: :obj:`None`) - **exclude_text** (Optional[List[str]]): Strings that must not be present in webpage text. Limited to 1 string of up to 5 words. (default: :obj:`None`) - **use_autoprompt** (bool): Whether to use Exa's autoprompt feature to enhance the query. (default: :obj:`True`) - **text** (bool): Whether to include webpage contents in results. (default: :obj:`False`) - **number_of_result_pages** (int): The number of result pages to retrieve. Must be between 1 and 100. Adjust this based on your task - use fewer results for focused searches and more for comprehensive searches. (default: :obj:`10`) **Returns:** Dict[str, Any]: A dict containing search results and metadata: - requestId (str): Unique identifier for the request - autopromptString (str): Generated autoprompt if enabled - autoDate (str): Timestamp of autoprompt generation - resolvedSearchType (str): The actual search type used - results (List[Dict]): List of search results with metadata - searchType (str): The search type that was selected - costDollars (Dict): Breakdown of API costs ### search_alibaba_tongxiao ```python def search_alibaba_tongxiao( self, query: str, time_range: Literal['OneDay', 'OneWeek', 'OneMonth', 'OneYear', 'NoLimit'] = 'NoLimit', industry: Optional[Literal['finance', 'law', 'medical', 'internet', 'tax', 'news_province', 'news_center']] = None, return_main_text: bool = False, return_markdown_text: bool = True, enable_rerank: bool = True, number_of_result_pages: int = 10 ): ``` Query the Alibaba Tongxiao search API and return search results. A powerful search API optimized for Chinese language queries with features: - Enhanced Chinese language understanding - Industry-specific filtering (finance, law, medical, etc.) - Structured data with markdown formatting - Result reranking for relevance - Time-based filtering **Parameters:** - **query** (str): The search query string (`length >= 1 and <= 100`). - **time_range** (`Literal["OneDay", "OneWeek", "OneMonth", "OneYear", "NoLimit"]`): Time frame filter for search results. (default: :obj:`"NoLimit"`) - **industry** (`Optional[Literal["finance", "law", "medical", "internet", "tax", "news_province", "news_center"]]`): Industry-specific search filter. When specified, only returns results from sites in the specified industries. Multiple industries can be comma-separated. (default: :obj:`None`) - **return_main_text** (bool): Whether to include the main text of the webpage in results. (default: :obj:`True`) - **return_markdown_text** (bool): Whether to include markdown formatted content in results. (default: :obj:`True`) - **enable_rerank** (bool): Whether to enable result reranking. If response time is critical, setting this to False can reduce response time by approximately 140ms. (default: :obj:`True`) - **number_of_result_pages** (int): The number of result pages to retrieve. Adjust this based on your task - use fewer results for focused searches and more for comprehensive searches. (default: :obj:`10`) **Returns:** Dict[str, Any]: A dictionary containing either search results with 'requestId' and 'results' keys, or an 'error' key with error message. Each result contains title, snippet, url and other metadata. ### search_metaso ```python def search_metaso( self, query: str, page: int = 1, include_summary: bool = False, include_raw_content: bool = False, concise_snippet: bool = False, scope: Literal['webpage', 'document', 'scholar', 'image', 'video', 'podcast'] = 'webpage' ): ``` Perform a web search using the metaso.cn API. **Parameters:** - **query** (str): The search query string. - **page** (int): Page number. (default: :obj:`1`) (default: 1) - **include_summary** (bool): Whether to include summary in the result. (default: :obj:`False`) - **include_raw_content** (bool): Whether to include raw content in the result. (default: :obj:`False`) - **concise_snippet** (bool): Whether to return concise snippet. (default: :obj:`False`) scope (Literal["webpage", "document", "scholar", "image", "video", "podcast"]): Search scope. (default: :obj:`"webpage"`) **Returns:** Dict[str, Any]: Search results or error information. ### search_serpapi ```python def search_serpapi( self, query: str, engine: str = 'google', location: str = 'Austin,Texas', google_domain: str = 'google.com', gl: str = 'us', search_lang: str = 'en', device: str = 'desktop', number_of_result_pages: int = 1, safe: str = 'off', filter: int = 0, custom_params: Optional[Dict[str, Any]] = None ): ``` Use SerpApi search engine to search information for the given query. SerpApi provides real-time search engine results from multiple search engines including Google, Bing, Yahoo, DuckDuckGo, Baidu, Yandex, and more. **Parameters:** - **query** (str): The search query string. - **engine** (str): Search engine to use. Supported engines include: 'google', 'bing', 'yahoo', 'duckduckgo', 'baidu', 'yandex', 'youtube', 'ebay', 'amazon', etc. (default: :obj:`"google"`) - **location** (str): Location for localized search results. Can be a city, state, country, or coordinates. (default: :obj:`"Austin,Texas"`) - **google_domain** (str): Google domain to use (e.g., 'google.com', 'google.co.uk'). Only applicable for Google engine. (default: :obj:`"google.com"`) - **gl** (str): Country code for localized results (e.g., 'us', 'uk', 'ca'). Only applicable for Google engine. (default: :obj:`"us"`) - **search_lang** (str): Language code for results (e.g., 'en', 'es', 'fr'). Only applicable for Google engine. (default: :obj:`"en"`) - **device** (str): Device type: 'desktop', 'tablet', or 'mobile'. (default: :obj:`"desktop"`) - **number_of_result_pages** (int): Number of organic results to return. Adjust based on task needs. (default: :obj:`1`) - **safe** (str): Safe search level: 'off', 'medium', 'high', 'active'. (default: :obj:`"off"`) - **filter** (int): Filter results: 0 (no filter), 1 (filter similar results). (default: :obj:`0`) - **custom_params** (Optional[Dict[str, Any]]): Additional custom parameters to pass to SerpApi. (default: :obj:`None`) **Returns:** Dict[str, Any]: A dictionary containing search results: - 'results': List of organic search results, each containing: - 'title': The title of the search result - 'link': The URL of the search result - 'snippet': The description snippet - 'keywords': Highlighted keywords in the snippet - 'source': The source of the result - 'error: Error if any ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of FunctionTool objects representing the functions in the toolkit. ### tavily_search ```python def tavily_search(self, *args, **kwargs): ``` Deprecated: Use search_tavily instead for consistency with other search methods. --- ## SlackToolkit ```python class SlackToolkit(BaseToolkit): ``` A class representing a toolkit for Slack operations. This class provides methods for Slack operations such as creating a new channel, joining an existing channel, leaving a channel. ### __init__ ```python def __init__(self, timeout: Optional[float] = None): ``` Initializes a new instance of the SlackToolkit class. **Parameters:** - **timeout** (Optional[float]): The timeout value for API requests in seconds. If None, no timeout is applied. (default: :obj:`None`) ### _login_slack ```python def _login_slack( self, slack_token: Optional[str] = None, ssl: Optional[SSLContext] = None ): ``` Authenticate using the Slack API. **Parameters:** - **slack_token** (str, optional): The Slack API token. If not provided, it attempts to retrieve the token from the environment variable SLACK_BOT_TOKEN or SLACK_USER_TOKEN. - **ssl** (SSLContext, optional): SSL context for secure connections. Defaults to `None`. **Returns:** WebClient: A WebClient object for interacting with Slack API. ### create_slack_channel ```python def create_slack_channel(self, name: str, is_private: Optional[bool] = True): ``` Creates a new slack channel, either public or private. **Parameters:** - **name** (str): Name of the public or private channel to create. - **is_private** (bool, optional): Whether to create a private channel instead of a public one. Defaults to `True`. **Returns:** str: JSON string containing information about Slack channel created. ### join_slack_channel ```python def join_slack_channel(self, channel_id: str): ``` Joins an existing Slack channel. **Parameters:** - **channel_id** (str): The ID of the Slack channel to join. **Returns:** str: A confirmation message indicating whether join successfully or an error message. ### leave_slack_channel ```python def leave_slack_channel(self, channel_id: str): ``` Leaves an existing Slack channel. **Parameters:** - **channel_id** (str): The ID of the Slack channel to leave. **Returns:** str: A confirmation message indicating whether leave successfully or an error message. ### get_slack_channel_information ```python def get_slack_channel_information(self): ``` **Returns:** str: JSON string containing information about Slack channels. ### get_slack_channel_message ```python def get_slack_channel_message(self, channel_id: str): ``` Retrieve messages from a Slack channel. **Parameters:** - **channel_id** (str): The ID of the Slack channel to retrieve messages from. **Returns:** str: JSON string containing filtered message data. ### send_slack_message ```python def send_slack_message( self, message: str, channel_id: str, file_path: Optional[str] = None, user: Optional[str] = None ): ``` Send a message to a Slack channel. **Parameters:** - **message** (str): The message to send. - **channel_id** (str): The ID of the Slack channel to send message. - **file_path** (Optional[str]): The path of the file to send. Defaults to `None`. - **user** (Optional[str]): The user ID of the recipient. Defaults to `None`. **Returns:** str: A confirmation message indicating whether the message was sent successfully or an error message. ### delete_slack_message ```python def delete_slack_message(self, time_stamp: str, channel_id: str): ``` Delete a message to a Slack channel. **Parameters:** - **time_stamp** (str): Timestamp of the message to be deleted. - **channel_id** (str): The ID of the Slack channel to delete message. **Returns:** str: A confirmation message indicating whether the message was delete successfully or an error message. ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of FunctionTool objects representing the functions in the toolkit. --- ## SymPyToolkit ```python class SymPyToolkit(BaseToolkit): ``` A toolkit for performing symbolic computations using SymPy. This includes methods for Algebraic manipulation calculus and Linear Algebra. ### __init__ ```python def __init__( self, default_variable: str = 'x', timeout: Optional[float] = None ): ``` Initializes the toolkit with a default variable and logging. **Parameters:** - **default_variable** (str): The default variable for operations (default: :obj:`x`) ### simplify_expression ```python def simplify_expression(self, expression: str): ``` Simplifies a mathematical expression. **Parameters:** - **expression** (str): The mathematical expression to simplify, provided as a string. **Returns:** str: JSON string containing the simplified mathematical expression in the `"result"` field. If an error occurs, the `"status"` field will be set to `"error"` with a corresponding `"message"`. ### expand_expression ```python def expand_expression(self, expression: str): ``` Expands an algebraic expression. **Parameters:** - **expression** (str): The algebraic expression to expand, provided as a string. **Returns:** str: JSON string containing the expanded algebraic expression in the `"result"` field. If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### factor_expression ```python def factor_expression(self, expression: str): ``` Factors an algebraic expression. **Parameters:** - **expression** (str): The algebraic expression to factor, provided as a string. **Returns:** str: JSON string containing the factored algebraic expression in the `"result"` field. If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### solve_linear_system ```python def solve_linear_system(self, equations: List[str], variables: List[str]): ``` Solves a system of linear equations. **Parameters:** - **equations** (List[str]): A list of strings representing the linear equations to be solved. - **variables** (List[str]): A list of strings representing the variables involved in the equations. **Returns:** str: JSON string containing the solution to the system of equations in the `"result"` field. Each solution is represented as a tuple of values corresponding to the variables. If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### solve_nonlinear_system ```python def solve_nonlinear_system(self, sympy_equations: List[str], variables: List[str]): ``` Solves a system of nonlinear equations. **Parameters:** - **sympy_equations** (List[str]): A list of strings representing the nonlinear equations to be solved. The equation to solve, must be compatible with SymPy, provided as a string. - **variables** (List[str]): A list of strings representing the variables involved in the equations. **Returns:** str: JSON string containing the solutions to the system of equations in the `"result"` field. Each solution is represented as a tuple of values corresponding to the variables. If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### solve_univariate_inequality ```python def solve_univariate_inequality(self, inequality: str, variable: str): ``` Solves a single-variable inequality. **Parameters:** - **inequality** (str): A string representing the inequality to be solved. - **variable** (str): The variable in the inequality. **Returns:** str: JSON string containing the solution to the inequality in the `"result"` field. The solution is represented in a symbolic format (e.g., intervals or expressions). If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### reduce_inequalities ```python def reduce_inequalities(self, inequalities: List[str]): ``` Reduces a system of inequalities. **Parameters:** - **inequalities** (List[str]): A list of strings representing the inequalities to be reduced. **Returns:** str: JSON string containing the reduced system of inequalities in the `"result"` field. The solution is represented in a symbolic format (e.g., combined intervals or expressions). If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### polynomial_representation ```python def polynomial_representation(self, expression: str, variable: str): ``` Represents an expression as a polynomial. **Parameters:** - **expression** (str): The mathematical expression to represent as a polynomial, provided as a string. - **variable** (str): The variable with respect to which the polynomial representation will be created. **Returns:** str: JSON string containing the polynomial representation of the expression in the `"result"` field. The polynomial is returned in a symbolic format. If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### polynomial_degree ```python def polynomial_degree(self, expression: str, variable: str): ``` Returns the degree of a polynomial. **Parameters:** - **expression** (str): The polynomial expression for which the degree is to be determined, provided as a string. - **variable** (str): The variable with respect to which the degree of the polynomial is calculated. **Returns:** str: JSON string containing the degree of the polynomial in the `"result"` field. If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### polynomial_coefficients ```python def polynomial_coefficients(self, expression: str, variable: str): ``` Returns the coefficients of a polynomial. **Parameters:** - **expression** (str): The polynomial expression from which the coefficients are to be extracted, provided as a string. - **variable** (str): The variable with respect to which the polynomial coefficients are determined. **Returns:** str: JSON string containing the list of coefficients of the polynomial in the `"result"` field. The coefficients are ordered from the highest degree term to the constant term. If an error occurs, the JSON string will include an `"error" field with the corresponding error message. ### solve_equation ```python def solve_equation(self, sympy_equation: str, variable: Optional[str] = None): ``` Solves an equation for a specific variable. **Parameters:** - **sympy_equation** (str): The equation to solve, must be compatible with SymPy, provided as a string. - **variable** (str, optional): The variable to solve for. If not specified, the function will use the default variable. **Returns:** str: JSON string containing the solutions to the equation in the `"result"` field. Each solution is represented as a string. If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### find_roots ```python def find_roots(self, expression: str): ``` Finds the roots of a polynomial or algebraic equation. **Parameters:** - **expression** (str): The polynomial or algebraic equation for which the roots are to be found, provided as a string. **Returns:** str: JSON string containing the roots of the expression in the `"result"` field. The roots are represented as a list of solutions. If an error occurs, the JSON string will include a `"status"` field set to `"error"` and a `"message"` field with the corresponding error description. ### differentiate ```python def differentiate(self, expression: str, variable: Optional[str] = None): ``` Differentiates an expression with respect to a variable. **Parameters:** - **expression** (str): The mathematical expression to differentiate, provided as a string. - **variable** (str, optional): The variable with respect to which the differentiation is performed. If not specified, the default variable is used. **Returns:** str: JSON string containing the derivative of the expression in the `"result"` field. If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### integrate ```python def integrate(self, expression: str, variable: Optional[str] = None): ``` Integrates an expression with respect to a variable. **Parameters:** - **expression** (str): The mathematical expression to integrate, provided as a string. - **variable** (str, optional): The variable with respect to which the integration is performed. If not specified, the default variable is used. **Returns:** str: JSON string containing the integral of the expression in the `"result"` field. If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### definite_integral ```python def definite_integral( self, expression: str, variable: str, lower: float, upper: float ): ``` Computes the definite integral of an expression within given bounds. **Parameters:** - **expression** (str): The mathematical expression to integrate, provided as a string. - **variable** (str): The variable with respect to which the definite integration is performed. - **lower** (float): The lower limit of the integration. - **upper** (float): The upper limit of the integration. **Returns:** str: JSON string containing the result of the definite integral in the `"result"` field. If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### series_expansion ```python def series_expansion( self, expression: str, variable: str, point: float, order: int ): ``` Expands an expression into a Taylor series around a given point up to a specified order. **Parameters:** - **expression** (str): The mathematical expression to expand, provided as a string. - **variable** (str): The variable with respect to which the series expansion is performed. - **point** (float): The point around which the Taylor series is expanded. - **order** (int): The order up to which the series expansion is computed. **Returns:** str: JSON string containing the Taylor series expansion of the expression in the `"result"` field. If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### compute_limit ```python def compute_limit( self, expression: str, variable: str, point: float ): ``` Computes the limit of an expression as a variable approaches a point. **Parameters:** - **expression** (str): The mathematical expression for which the limit is to be computed, provided as a string. - **variable** (str): The variable with respect to which the limit is computed. - **point** (float): The point that the variable approaches. **Returns:** str: JSON string containing the computed limit of the expression in the `"result"` field. If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### find_critical_points ```python def find_critical_points(self, expression: str, variable: str): ``` Finds the critical points of an expression by setting its derivative to zero. **Parameters:** - **expression** (str): The mathematical expression for which critical points are to be found, provided as a string. - **variable** (str): The variable with respect to which the critical points are determined. **Returns:** str: JSON string containing the critical points of the expression in the `"result"` field. The critical points are returned as a list of values corresponding to the variable. If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### check_continuity ```python def check_continuity( self, expression: str, variable: str, point: float ): ``` Checks if an expression is continuous at a given point. **Parameters:** - **expression** (str): The mathematical expression to check for continuity, provided as a string. - **variable** (str): The variable with respect to which continuity is checked. - **point** (float): The point at which the continuity of the expression is checked. **Returns:** str: JSON string containing the result of the continuity check in the `"result"` field. The result will be `"True"` if the expression is continuous at the given point, otherwise `"False"`. If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### compute_determinant ```python def compute_determinant(self, matrix: List[List[float]]): ``` Computes the determinant of a matrix. **Parameters:** - **matrix** (List[List[float]]): A two-dimensional list representing the matrix for which the determinant is to be computed. **Returns:** str: JSON string containing the determinant of the matrix in the `"result"` field. If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### compute_inverse ```python def compute_inverse(self, matrix: List[List[float]]): ``` Computes the inverse of a matrix. **Parameters:** - **matrix** (List[List[float]]): A two-dimensional list representing the matrix for which the inverse is to be computed. **Returns:** str: JSON string containing the inverse of the matrix in the `"result"` field. The inverse is represented in a symbolic matrix format. If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### compute_eigenvalues ```python def compute_eigenvalues(self, matrix: List[List[float]]): ``` Computes the eigenvalues of a matrix. **Parameters:** - **matrix** (List[List[float]]): A two-dimensional list representing the matrix for which the eigenvalues are to be computed. **Returns:** str: JSON string containing the eigenvalues of the matrix in the `"result"` field. The eigenvalues are represented as a dictionary where keys are the eigenvalues (as strings) and values are their multiplicities (as strings). If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### compute_eigenvectors ```python def compute_eigenvectors(self, matrix: List[List[float]]): ``` Computes the eigenvectors of a matrix. **Parameters:** - **matrix** (List[List[float]]): A two-dimensional list representing the matrix for which the eigenvectors are to be computed. **Returns:** str: JSON string containing the eigenvectors of the matrix in the `"result"` field. Each eigenvalue is represented as a dictionary with the following keys: - `"eigenvalue"`: The eigenvalue (as a string). - `"multiplicity"`: The multiplicity of the eigenvalue (as an integer). - `"eigenvectors"`: A list of eigenvectors (each represented as a string). If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### compute_nullspace ```python def compute_nullspace(self, matrix: List[List[float]]): ``` Computes the null space of a matrix. **Parameters:** - **matrix** (List[List[float]]): A two-dimensional list representing the matrix for which the null space is to be computed. **Returns:** str: JSON string containing the null space of the matrix in the `"result"` field. The null space is represented as a list of basis vectors, where each vector is given as a string in symbolic format. If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### compute_rank ```python def compute_rank(self, matrix: List[List[float]]): ``` Computes the rank of a matrix. **Parameters:** - **matrix** (List[List[float]]): A two-dimensional list representing the matrix for which the rank is to be computed. **Returns:** str: JSON string containing the rank of the matrix in the `"result"` field. The rank is represented as an integer. If an error occurs,the JSON string will include an `"error"` field with the corresponding error message. ### compute_inner_product ```python def compute_inner_product(self, vector1: List[float], vector2: List[float]): ``` Computes the inner (dot) product of two vectors. **Parameters:** - **vector1** (List[float]): The first vector as a list of floats. - **vector2** (List[float]): The second vector as a list of floats. **Returns:** str: JSON string containing the inner product in the `"result"` field. If an error occurs, the JSON string will include an `"error"` field with the corresponding error message. ### handle_exception ```python def handle_exception(self, func_name: str, error: Exception): ``` Handles exceptions by logging and returning error details. **Parameters:** - **func_name** (str): The name of the function where the exception occurred. - **error** (Exception): The exception object containing details about the error. **Returns:** str: JSON string containing the error details. The JSON includes: - `"status"`: Always set to `"error"`. - `"message"`: A string representation of the exception message. ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of `FunctionTool` objects representing the toolkit's methods, making them accessible to the agent. --- ## TaskPlanningToolkit ```python class TaskPlanningToolkit(BaseToolkit): ``` A toolkit for task decomposition and re-planning. ### __init__ ```python def __init__(self, timeout: Optional[float] = None): ``` Initialize the TaskPlanningToolkit. **Parameters:** - **timeout** (Optional[float]): The timeout for the toolkit. (default: :obj:`None`) ### decompose_task ```python def decompose_task( self, original_task_content: str, sub_task_contents: List[str], original_task_id: Optional[str] = None ): ``` Use the tool to decompose an original task into several sub-tasks. It creates new Task objects from the provided original task content, used when the original task is complex and needs to be decomposed. **Parameters:** - **original_task_content** (str): The content of the task to be decomposed. - **sub_task_contents** (List[str]): A list of strings, where each string is the content for a new sub-task. - **original_task_id** (Optional[str]): The id of the task to be decomposed. If not provided, a new id will be generated. (default: :obj:`None`) **Returns:** List[Task]: A list of newly created sub-task objects. ### replan_tasks ```python def replan_tasks( self, original_task_content: str, sub_task_contents: List[str], original_task_id: Optional[str] = None ): ``` Use the tool to re_decompose a task into several subTasks. It creates new Task objects from the provided original task content, used when the decomposed tasks are not good enough to help finish the task. **Parameters:** - **original_task_content** (str): The content of the task to be decomposed. - **sub_task_contents** (List[str]): A list of strings, where each string is the content for a new sub-task. - **original_task_id** (Optional[str]): The id of the task to be decomposed. (default: :obj:`None`) **Returns:** List[Task]: Reordered or modified tasks. ### get_tools ```python def get_tools(self): ``` --- ## TerminalToolkit ```python class TerminalToolkit(BaseToolkit): ``` A toolkit for terminal operations across multiple operating systems. This toolkit provides a set of functions for terminal operations such as searching for files by name or content, executing shell commands, and managing terminal sessions. **Parameters:** - **timeout** (Optional[float]): The timeout for terminal operations. - **shell_sessions** (Optional[Dict[str, Any]]): A dictionary to store shell session information. If None, an empty dictionary will be used. (default: :obj:`{}`) - **working_dir** (str): The working directory for operations. If specified, all execution and write operations will be restricted to this directory. Read operations can access paths outside this directory.(default: :obj:`"./workspace"`) - **need_terminal** (bool): Whether to create a terminal interface. (default: :obj:`True`) - **use_shell_mode** (bool): Whether to use shell mode for command execution. (default: :obj:`True`) - **clone_current_env** (bool): Whether to clone the current Python environment.(default: :obj:`False`) - **safe_mode** (bool): Whether to enable safe mode to restrict operations. (default: :obj:`True`) **Note:** Most functions are compatible with Unix-based systems (macOS, Linux). For Windows compatibility, additional implementation details are needed. ### __init__ ```python def __init__( self, timeout: Optional[float] = None, shell_sessions: Optional[Dict[str, Any]] = None, working_dir: str = './workspace', need_terminal: bool = True, use_shell_mode: bool = True, clone_current_env: bool = False, safe_mode: bool = True ): ``` ### _setup_file_output ```python def _setup_file_output(self): ``` Set up file output to replace GUI, using a fixed file to simulate terminal. ### _clone_current_environment ```python def _clone_current_environment(self): ``` Create a new Python virtual environment. ### _create_terminal ```python def _create_terminal(self): ``` Create a terminal GUI. If GUI creation fails, fallback to file output. ### _update_terminal_output ```python def _update_terminal_output(self, output: str): ``` Update terminal output and send to agent. **Parameters:** - **output** (str): The output to be sent to the agent ### _is_path_within_working_dir ```python def _is_path_within_working_dir(self, path: str): ``` Check if the path is within the working directory. **Parameters:** - **path** (str): The path to check **Returns:** bool: Returns True if the path is within the working directory, otherwise returns False ### _enforce_working_dir_for_execution ```python def _enforce_working_dir_for_execution(self, path: str): ``` Enforce working directory restrictions, return error message if execution path is not within the working directory. **Parameters:** - **path** (str): The path to be used for executing operations **Returns:** Optional[str]: Returns error message if the path is not within the working directory, otherwise returns None ### _copy_external_file_to_workdir ```python def _copy_external_file_to_workdir(self, external_file: str): ``` Copy external file to working directory. **Parameters:** - **external_file** (str): The path of the external file **Returns:** Optional[str]: New path after copying to the working directory, returns None on failure ### file_find_in_content ```python def file_find_in_content( self, file: str, regex: str, sudo: bool = False ): ``` Search for text within a file's content using a regular expression. This function is useful for finding specific patterns or lines of text within a given file. It uses `grep` on Unix-like systems and `findstr` on Windows. **Parameters:** - **file** (str): The absolute path of the file to search within. - **regex** (str): The regular expression pattern to match. - **sudo** (bool, optional): Whether to use sudo privileges for the search. Defaults to False. Note: Using sudo requires the process to have appropriate permissions. (default: :obj:`False`) **Returns:** str: The matching content found in the file. If no matches are found, an empty string is returned. Returns an error message if the file does not exist or another error occurs. ### file_find_by_name ```python def file_find_by_name(self, path: str, glob: str): ``` Find files by name in a specified directory using a glob pattern. This function recursively searches for files matching a given name or pattern within a directory. It uses `find` on Unix-like systems and `dir` on Windows. **Parameters:** - **path** (str): The absolute path of the directory to search in. - **glob** (str): The filename pattern to search for, using glob syntax (e.g., "*.py", "data*"). **Returns:** str: A newline-separated string containing the paths of the files that match the pattern. Returns an error message if the directory does not exist or another error occurs. ### _sanitize_command ```python def _sanitize_command(self, command: str, exec_dir: str): ``` Check and modify command to ensure safety. **Parameters:** - **command** (str): The command to check - **exec_dir** (str): The directory to execute the command in **Returns:** Tuple: (is safe, modified command or error message) ### shell_exec ```python def shell_exec( self, id: str, command: str, interactive: bool = False ): ``` Executes a shell command in a specified session. This function creates and manages shell sessions to execute commands, simulating a real terminal. It can run commands in both non-interactive (capturing output) and interactive modes. Each session is identified by a unique ID. If a session with the given ID does not exist, it will be created. **Parameters:** - **id** (str): A unique identifier for the shell session. This is used to manage multiple concurrent shell processes. - **command** (str): The shell command to be executed. - **interactive** (bool, optional): If `True`, the command runs in interactive mode, connecting it to the terminal's standard input. This is useful for commands that require user input, like `ssh`. Defaults to `False`. Interactive mode is only supported on macOS and Linux. (default: :obj:`False`) **Returns:** str: The standard output and standard error from the command. If an error occurs during execution, a descriptive error message is returned. **Note:** When `interactive` is set to `True`, this function may block if the command requires input. In safe mode, some commands that are considered dangerous are restricted. ### shell_view ```python def shell_view(self, id: str): ``` View the full output history of a specified shell session. Retrieves the accumulated output (both stdout and stderr) generated by commands in the specified session since its creation. This is useful for checking the complete history of a session, especially after a command has finished execution. **Parameters:** - **id** (str): The unique identifier of the shell session to view. **Returns:** str: The complete output history of the shell session. Returns an error message if the session is not found. ### shell_wait ```python def shell_wait(self, id: str, seconds: Optional[int] = None): ``` Wait for a command to finish in a specified shell session. Blocks execution and waits for the running process in a shell session to complete. This is useful for ensuring a long-running command has finished before proceeding. **Parameters:** - **id** (str): The unique identifier of the target shell session. - **seconds** (Optional[int], optional): The maximum time to wait, in seconds. If `None`, it waits indefinitely. (default: :obj:`None`) **Returns:** str: A message indicating that the process has completed, including the final output. If the process times out, it returns a timeout message. ### shell_write_to_process ```python def shell_write_to_process( self, id: str, input: str, press_enter: bool ): ``` Write input to a running process in a specified shell session. Sends a string of text to the standard input of a running process. This is useful for interacting with commands that require input. This function cannot be used with a command that was started in interactive mode. **Parameters:** - **id** (str): The unique identifier of the target shell session. - **input** (str): The text to write to the process's stdin. - **press_enter** (bool): If `True`, a newline character (`\n`) is appended to the input, simulating pressing the Enter key. **Returns:** str: A status message indicating whether the input was sent, or an error message if the operation fails. ### shell_kill_process ```python def shell_kill_process(self, id: str): ``` Terminate a running process in a specified shell session. Forcibly stops a command that is currently running in a shell session. This is useful for ending processes that are stuck, running too long, or need to be cancelled. **Parameters:** - **id** (str): The unique identifier of the shell session containing the process to be terminated. **Returns:** str: A status message indicating that the process has been terminated, or an error message if the operation fails. ### ask_user_for_help ```python def ask_user_for_help(self, id: str): ``` Pause the agent and ask a human for help with a command. This function should be used when the agent is stuck and requires manual intervention, such as solving a CAPTCHA or debugging a complex issue. It pauses the agent's execution and allows a human to take control of a specified shell session. The human can execute one command to resolve the issue, and then control is returned to the agent. **Parameters:** - **id** (str): The identifier of the shell session for the human to interact with. If the session does not exist, it will be created. **Returns:** str: A status message indicating that the human has finished, including the number of commands executed. If the takeover times out or fails, an error message is returned. ### __del__ ```python def __del__(self): ``` Clean up resources when the object is being destroyed. Terminates all running processes and closes any open file handles. ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of FunctionTool objects representing the functions in the toolkit. --- ## ThinkingToolkit ```python class ThinkingToolkit(BaseToolkit): ``` A toolkit for recording thoughts during reasoning processes. ### __init__ ```python def __init__(self, timeout: Optional[float] = None): ``` Initialize the ThinkingToolkit. **Parameters:** - **timeout** (Optional[float]): The timeout for the toolkit. (default: :obj:`None`) ### plan ```python def plan(self, plan: str): ``` Use the tool to create a plan or strategy. This tool is for outlining the approach or steps to be taken before starting the actual thinking process. **Parameters:** - **plan** (str): A forward-looking plan or strategy. **Returns:** str: The recorded plan. ### hypothesize ```python def hypothesize(self, hypothesis: str): ``` Use the tool to form a hypothesis or make a prediction. This tool is for making educated guesses or predictions based on the plan, before detailed thinking. **Parameters:** - **hypothesis** (str): A hypothesis or prediction to test. **Returns:** str: The recorded hypothesis. ### think ```python def think(self, thought: str): ``` Use the tool to think about something. It will not obtain new information or change the database, but just append the thought to the log. Use it for initial thoughts and observations during the execution of the plan. **Parameters:** - **thought** (str): A thought to think about. **Returns:** str: The recorded thought. ### contemplate ```python def contemplate(self, contemplation: str): ``` Use the tool to deeply contemplate an idea or concept. This tool is for deeper, more thorough exploration of thoughts, considering multiple perspectives and implications. It's more comprehensive than basic thinking but more focused than reflection. **Parameters:** - **contemplation** (str): A deeper exploration of thoughts or concepts. **Returns:** str: The recorded contemplation. ### critique ```python def critique(self, critique: str): ``` Use the tool to critically evaluate current thoughts. This tool is for identifying potential flaws, biases, or weaknesses in the current thinking process. **Parameters:** - **critique** (str): A critical evaluation of current thoughts. **Returns:** str: The recorded critique. ### synthesize ```python def synthesize(self, synthesis: str): ``` Use the tool to combine and integrate various thoughts. This tool is for bringing together different thoughts, contemplations, and critiques into a coherent understanding. **Parameters:** - **synthesis** (str): An integration of multiple thoughts and insights. **Returns:** str: The recorded synthesis. ### reflect ```python def reflect(self, reflection: str): ``` Use the tool to reflect on the entire process. This tool is for final evaluation of the entire thinking process, including plans, hypotheses, thoughts, contemplations, critiques, and syntheses. **Parameters:** - **reflection** (str): A comprehensive reflection on the process. **Returns:** str: The recorded reflection. ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of tools. --- ## VideoAnalysisToolkit ```python class VideoAnalysisToolkit(BaseToolkit): ``` A class for analysing videos with vision-language model. **Parameters:** - **working_directory** (Optional[str], optional): The directory where the video will be downloaded to. If not provided, video will be stored in a temporary directory and will be cleaned up after use. (default: :obj:`None`) - **model** (Optional[BaseModelBackend], optional): The model to use for visual analysis. (default: :obj:`None`) - **use_audio_transcription** (bool, optional): Whether to enable audio transcription using OpenAI's audio models. Requires a valid OpenAI API key. When disabled, video analysis will be based solely on visual content. (default: :obj:`False`) - **use_ocr** (bool, optional): Whether to enable OCR for extracting text from video frames. (default: :obj:`False`) - **frame_interval** (float, optional): Interval in seconds between frames to extract from the video. (default: :obj:`4.0`) - **output_language** (str, optional): The language for output responses. (default: :obj:`"English"`) - **cookies_path** (Optional[str]): The path to the cookies file for the video service in Netscape format. (default: :obj:`None`) - **timeout** (Optional[float]): The timeout value for API requests in seconds. If None, no timeout is applied. (default: :obj:`None`) ### __init__ ```python def __init__( self, working_directory: Optional[str] = None, model: Optional[BaseModelBackend] = None, use_audio_transcription: bool = False, use_ocr: bool = False, frame_interval: float = 4.0, output_language: str = 'English', cookies_path: Optional[str] = None, timeout: Optional[float] = None ): ``` ### __del__ ```python def __del__(self): ``` Clean up temporary directories and files when the object is destroyed. ### _extract_text_from_frame ```python def _extract_text_from_frame(self, frame: Image.Image): ``` Extract text from a video frame using OCR. **Parameters:** - **frame** (Image.Image): PIL image frame to process. **Returns:** str: Extracted text from the frame. ### _process_extracted_text ```python def _process_extracted_text(self, text: str): ``` Clean and format OCR-extracted text. **Parameters:** - **text** (str): Raw extracted OCR text. **Returns:** str: Cleaned and formatted text. ### _extract_audio_from_video ```python def _extract_audio_from_video(self, video_path: str, output_format: str = 'mp3'): ``` Extract audio from the video. **Parameters:** - **video_path** (str): The path to the video file. - **output_format** (str): The format of the audio file to be saved. (default: :obj:`"mp3"`) **Returns:** str: The path to the audio file. ### _transcribe_audio ```python def _transcribe_audio(self, audio_path: str): ``` Transcribe the audio of the video. ### _extract_keyframes ```python def _extract_keyframes(self, video_path: str): ``` Extract keyframes from a video based on scene changes and regular intervals,and return them as PIL.Image.Image objects. **Parameters:** - **video_path** (str): Path to the video file. **Returns:** List[Image.Image]: A list of PIL.Image.Image objects representing the extracted keyframes. ### _normalize_frames ```python def _normalize_frames(self, frames: List[Image.Image], target_width: int = 512): ``` Normalize the size of extracted frames. **Parameters:** - **frames** (List[Image.Image]): List of frames to normalize. - **target_width** (int): Target width for normalized frames. **Returns:** List[Image.Image]: List of normalized frames. ### ask_question_about_video ```python def ask_question_about_video(self, video_path: str, question: str): ``` Ask a question about the video. **Parameters:** - **video_path** (str): The path to the video file. It can be a local file or a URL (such as Youtube website). - **question** (str): The question to ask about the video. **Returns:** str: The answer to the question. ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of FunctionTool objects representing the functions in the toolkit. --- ## _capture_screenshot ```python def _capture_screenshot(video_file: str, timestamp: float): ``` Capture a screenshot from a video file at a specific timestamp. **Parameters:** - **video_file** (str): The path to the video file. - **timestamp** (float): The time in seconds from which to capture the screenshot. **Returns:** Image.Image: The captured screenshot in the form of Image.Image. ## VideoDownloaderToolkit ```python class VideoDownloaderToolkit(BaseToolkit): ``` A class for downloading videos and optionally splitting them into chunks. **Parameters:** - **working_directory** (Optional[str], optional): The directory where the video will be downloaded to. If not provided, video will be stored in a temporary directory and will be cleaned up after use. (default: :obj:`None`) - **cookies_path** (Optional[str], optional): The path to the cookies file for the video service in Netscape format. (default: :obj:`None`) ### __init__ ```python def __init__( self, working_directory: Optional[str] = None, cookies_path: Optional[str] = None, timeout: Optional[float] = None ): ``` ### __del__ ```python def __del__(self): ``` Deconstructor for the VideoDownloaderToolkit class. Cleans up the downloaded video if they are stored in a temporary directory. ### download_video ```python def download_video(self, url: str): ``` Download the video and optionally split it into chunks. yt-dlp will detect if the video is downloaded automatically so there is no need to check if the video exists. **Parameters:** - **url** (str): The URL of the video to download. **Returns:** str: The path to the downloaded video file. ### get_video_bytes ```python def get_video_bytes(self, video_path: str): ``` Download video by the path, and return the content in bytes. **Parameters:** - **video_path** (str): The path to the video file. **Returns:** bytes: The video file content in bytes. ### get_video_screenshots ```python def get_video_screenshots(self, video_path: str, amount: int): ``` Capture screenshots from the video at specified timestamps or by dividing the video into equal parts if an integer is provided. **Parameters:** - **video_path** (str): The local path or URL of the video to take screenshots. - **amount** (int): the amount of evenly split screenshots to capture. **Returns:** List[Image.Image]: A list of screenshots as Image.Image. ### get_tools ```python def get_tools(self): ``` **Returns:** List[FunctionTool]: A list of FunctionTool objects representing the functions in the toolkit. --- ## _get_wechat_access_token ```python def _get_wechat_access_token(): ``` **Returns:** str: The valid access token. **Raises:** - **ValueError**: If credentials are missing or token retrieval fails. - **References**: - **https**: //developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html ## _make_wechat_request ```python def _make_wechat_request(method: Literal['GET', 'POST'], endpoint: str, **kwargs): ``` Makes a request to WeChat API with proper error handling. **Parameters:** - **method** (`Literal["GET", "POST"]`): HTTP method ('GET' or 'POST'). - **endpoint** (str): API endpoint path. **kwargs: Additional arguments for requests. **Returns:** Dict[str, Any]: API response data. **Raises:** - **requests.exceptions.RequestException**: If request fails. - **ValueError**: If API returns an error. ## WeChatOfficialToolkit ```python class WeChatOfficialToolkit(BaseToolkit): ``` A toolkit for WeChat Official Account operations. This toolkit provides methods to interact with the WeChat Official Account API, allowing users to send messages, manage users, and handle media files. References: - Documentation: https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html - Test Account: https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login **Note:** Set environment variables: WECHAT_APP_ID, WECHAT_APP_SECRET ### __init__ ```python def __init__(self, timeout: Optional[float] = None): ``` Initializes the WeChatOfficialToolkit. ### send_customer_message ```python def send_customer_message( self, openid: str, content: str, msgtype: Literal['text', 'image', 'voice', 'video'] = 'text' ): ``` Sends a customer service message to a WeChat user. **Parameters:** - **openid** (str): The user's OpenID. - **content** (str): Message content or media_id for non-text messages. - **msgtype** (str): Message type: "text", "image", "voice", "video". **Returns:** str: Success or error message. References: https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Service_Center_messages.html ### get_user_info ```python def get_user_info(self, openid: str, lang: str = 'zh_CN'): ``` Retrieves WeChat user information. **Parameters:** - **openid** (str): The user's OpenID. - **lang** (str): Response language. Common values: "zh_CN", "zh_TW", "en". (default: "zh_CN") **Returns:** Dict[str, Any]: User information as dictionary or error information. References: https://developers.weixin.qq.com/doc/offiaccount/User_Management/ Getting_user_basic_information.html ### get_followers_list ```python def get_followers_list(self, next_openid: str = ''): ``` Retrieves list of followers' OpenIDs. **Parameters:** - **next_openid** (str): Starting OpenID for pagination. (default: "") (default: `""`) **Returns:** Dict[str, Any]: Followers list as dictionary or error information. References: https://developers.weixin.qq.com/doc/offiaccount/User_Management/ Getting_a_list_of_followers.html ### upload_wechat_media ```python def upload_wechat_media( self, media_type: Literal['image', 'voice', 'video', 'thumb'], file_path: str, permanent: bool = False, description: Optional[str] = None ): ``` Uploads media file to WeChat. **Parameters:** - **media_type** (str): Media type: "image", "voice", "video", "thumb". - **file_path** (str): Local file path. - **permanent** (bool): Whether to upload as permanent media. (default: :obj:`False`) - **description** (Optional[str]): Video description in JSON format for permanent upload. (default: :obj:`None`) **Returns:** Dict[str, Any]: Upload result with media_id or error information. References: - Temporary: https://developers.weixin.qq.com/doc/offiaccount/ Asset_Management/Adding_Temporary_Assets.html - Permanent: https://developers.weixin.qq.com/doc/offiaccount/ Asset_Management/Adding_Permanent_Assets.html ### get_media_list ```python def get_media_list( self, media_type: Literal['image', 'voice', 'video', 'news'], offset: int = 0, count: int = 20 ): ``` Gets list of permanent media files. **Parameters:** - **media_type** (str): Media type: "image", "voice", "video", "news". - **offset** (int): Starting position. (default: :obj:`0`) (default: 0) - **count** (int): Number of items (1-20). (default: :obj:`20`) (default: 20) **Returns:** Dict[str, Any]: Media list as dictionary or error information. References: https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/ Get_the_list_of_all_materials.html ### send_mass_message_to_all ```python def send_mass_message_to_all( self, content: str, msgtype: Literal['text', 'image', 'voice', 'video'] = 'text', clientmsgid: Optional[str] = None, send_ignore_reprint: Optional[int] = 0, batch_size: int = 10000 ): ``` Sends a mass message to all followers (by OpenID list). This method paginates all follower OpenIDs and calls the mass-send API in batches. **Parameters:** - **content** (str): For text, the message content; for non-text, the media_id. - **msgtype** (`Literal["text","image","voice","video"]`): Message type. For "video", the mass API expects "mpvideo" internally. - **clientmsgid** (Optional[str]): Idempotency key to avoid duplicate mass jobs. - **send_ignore_reprint** (Optional[int]): Whether to continue when a news article is judged as a reprint (reserved; applies to news/mpnews). - **batch_size** (int): Max OpenIDs per request (WeChat limit is up to 10000 per batch). **Returns:** Dict[str, Any]: Aggregated result including counts and each batch response. References: - Mass send by OpenID list: https://developers.weixin.qq.com/doc/service/api/notify/message/ api_masssend.html ### get_tools ```python def get_tools(self): ``` Returns toolkit functions as tools. --- ## ToolCallingRecord ```python class ToolCallingRecord(BaseModel): ``` Historical records of tools called in the conversation. **Parameters:** - **func_name** (str): The name of the tool being called. - **args** (Dict[str, Any]): The dictionary of arguments passed to the tool. - **result** (Any): The execution result of calling this tool. - **tool_call_id** (str): The ID of the tool call, if available. - **images** (Optional[List[str]]): List of base64-encoded images returned by the tool, if any. ### __str__ ```python def __str__(self): ``` **Returns:** str: Modified string to represent the tool calling. ### as_dict ```python def as_dict(self): ``` **Returns:** dict[str, Any]: The tool calling record as a dictionary. --- ## MessageSummary ```python class MessageSummary(BaseModel): ``` Schema for structured message summaries. **Parameters:** - **summary** (str): A brief, one-sentence summary of the conversation. - **participants** (List[str]): The roles of participants involved. - **key_topics_and_entities** (List[str]): Important topics, concepts, and entities discussed. - **decisions_and_outcomes** (List[str]): Key decisions, conclusions, or outcomes reached. - **action_items** (List[str]): A list of specific tasks or actions to be taken, with assignees if mentioned. - **progress_on_main_task** (str): A summary of progress made on the primary task. ## MessageSummarizer ```python class MessageSummarizer: ``` Utility class for generating structured summaries of chat messages. **Parameters:** - **model_backend** (Optional[BaseModelBackend], optional): The model backend to use for summarization. If not provided, a default model backend will be created. ### __init__ ```python def __init__(self, model_backend: Optional[BaseModelBackend] = None): ``` ### summarize ```python def summarize(self, messages: List[BaseMessage]): ``` Generate a structured summary of the provided messages. **Parameters:** - **messages** (List[BaseMessage]): List of messages to summarize. **Returns:** MessageSummary: Structured summary of the conversation. --- ## ToolResult ```python class ToolResult: ``` Special result type for tools that can return images along with text. This class is used by ChatAgent to detect when a tool returns visual content that should be included in the conversation context. ### __init__ ```python def __init__(self, text: str, images: Optional[List[str]] = None): ``` Initialize a tool result. **Parameters:** - **text** (str): The text description or result of the tool operation. - **images** (Optional[List[str]]): List of base64-encoded images to include in the conversation context. Images should be encoded as "data:image/\{format\};base64,\{data\}" format. ### __str__ ```python def __str__(self): ``` Return the text representation of the result. ### __repr__ ```python def __repr__(self): ``` Return a detailed representation of the result.