camel-ai 0.2.70__tar.gz → 0.2.71a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of camel-ai might be problematic. Click here for more details.
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/PKG-INFO +1 -1
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/__init__.py +1 -1
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/societies/workforce/role_playing_worker.py +4 -4
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/societies/workforce/single_agent_worker.py +4 -4
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/societies/workforce/workforce.py +236 -41
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/societies/workforce/workforce_logger.py +0 -1
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/tasks/task.py +83 -7
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/human_toolkit.py +23 -8
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/non_visual_browser_toolkit/browser_non_visual_toolkit.py +23 -2
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/non_visual_browser_toolkit/nv_browser_session.py +53 -11
- camel_ai-0.2.71a1/camel/toolkits/non_visual_browser_toolkit/snapshot.js +268 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/non_visual_browser_toolkit/snapshot.py +9 -8
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/terminal_toolkit.py +17 -16
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/video_download_toolkit.py +5 -1
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/pyproject.toml +1 -1
- camel_ai-0.2.70/camel/toolkits/non_visual_browser_toolkit/snapshot.js +0 -188
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/.gitignore +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/LICENSE +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/README.md +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/_types.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/_utils.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/chat_agent.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/critic_agent.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/deductive_reasoner_agent.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/embodied_agent.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/knowledge_graph_agent.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/mcp_agent.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/multi_hop_generator_agent.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/programmed_agent_instruction.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/repo_agent.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/role_assignment_agent.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/search_agent.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/task_agent.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/tool_agents/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/tool_agents/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/agents/tool_agents/hugging_face_tool_agent.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/benchmarks/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/benchmarks/apibank.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/benchmarks/apibench.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/benchmarks/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/benchmarks/browsecomp.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/benchmarks/gaia.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/benchmarks/mock_website/README.md +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/benchmarks/mock_website/mock_web.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/benchmarks/mock_website/requirements.txt +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/benchmarks/mock_website/shopping_mall/app.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/benchmarks/mock_website/task.json +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/benchmarks/nexus.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/benchmarks/ragbench.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/bots/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/bots/discord/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/bots/discord/discord_app.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/bots/discord/discord_installation.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/bots/discord/discord_store.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/bots/slack/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/bots/slack/models.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/bots/slack/slack_app.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/bots/telegram_bot.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/aiml_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/anthropic_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/base_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/bedrock_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/cohere_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/crynux_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/deepseek_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/gemini_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/groq_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/internlm_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/litellm_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/lmstudio_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/mistral_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/modelscope_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/moonshot_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/netmind_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/novita_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/nvidia_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/ollama_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/openai_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/openrouter_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/ppio_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/qianfan_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/qwen_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/reka_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/samba_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/sglang_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/siliconflow_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/togetherai_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/vllm_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/watsonx_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/yi_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/configs/zhipuai_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/data_collectors/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/data_collectors/alpaca_collector.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/data_collectors/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/data_collectors/sharegpt_collector.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datagen/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datagen/cot_datagen.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datagen/evol_instruct/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datagen/evol_instruct/evol_instruct.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datagen/evol_instruct/scorer.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datagen/evol_instruct/templates.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datagen/self_improving_cot.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datagen/self_instruct/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datagen/self_instruct/filter/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datagen/self_instruct/filter/filter_function.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datagen/self_instruct/filter/filter_registry.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datagen/self_instruct/filter/instruction_filter.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datagen/self_instruct/self_instruct.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datagen/self_instruct/templates.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datagen/source2synth/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datagen/source2synth/data_processor.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datagen/source2synth/models.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datagen/source2synth/user_data_processor_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datahubs/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datahubs/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datahubs/huggingface.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datahubs/models.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datasets/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datasets/base_generator.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datasets/few_shot_generator.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datasets/models.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datasets/self_instruct_generator.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/datasets/static_dataset.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/embeddings/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/embeddings/azure_embedding.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/embeddings/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/embeddings/gemini_embedding.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/embeddings/jina_embedding.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/embeddings/mistral_embedding.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/embeddings/openai_compatible_embedding.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/embeddings/openai_embedding.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/embeddings/sentence_transformers_embeddings.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/embeddings/together_embedding.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/embeddings/vlm_embedding.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/environments/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/environments/models.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/environments/multi_step.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/environments/rlcards_env.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/environments/single_step.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/environments/tic_tac_toe.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/extractors/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/extractors/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/extractors/python_strategies.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/generators.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/human.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/interpreters/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/interpreters/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/interpreters/docker/Dockerfile +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/interpreters/docker_interpreter.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/interpreters/e2b_interpreter.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/interpreters/internal_python_interpreter.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/interpreters/interpreter_error.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/interpreters/ipython_interpreter.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/interpreters/subprocess_interpreter.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/loaders/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/loaders/apify_reader.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/loaders/base_io.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/loaders/chunkr_reader.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/loaders/crawl4ai_reader.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/loaders/firecrawl_reader.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/loaders/jina_url_reader.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/loaders/markitdown.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/loaders/mineru_extractor.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/loaders/mistral_reader.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/loaders/pandas_reader.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/loaders/scrapegraph_reader.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/loaders/unstructured_io.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/logger.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/memories/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/memories/agent_memories.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/memories/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/memories/blocks/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/memories/blocks/chat_history_block.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/memories/blocks/vectordb_block.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/memories/context_creators/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/memories/context_creators/score_based.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/memories/records.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/messages/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/messages/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/messages/conversion/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/messages/conversion/alpaca.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/messages/conversion/conversation_models.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/messages/conversion/sharegpt/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/messages/conversion/sharegpt/function_call_formatter.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/messages/conversion/sharegpt/hermes/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/messages/conversion/sharegpt/hermes/hermes_function_formatter.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/messages/func_message.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/_utils.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/aiml_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/anthropic_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/aws_bedrock_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/azure_openai_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/base_audio_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/base_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/cohere_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/crynux_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/deepseek_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/fish_audio_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/gemini_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/groq_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/internlm_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/litellm_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/lmstudio_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/mistral_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/model_factory.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/model_manager.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/modelscope_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/moonshot_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/nemotron_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/netmind_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/novita_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/nvidia_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/ollama_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/openai_audio_models.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/openai_compatible_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/openai_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/openrouter_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/ppio_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/qianfan_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/qwen_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/reka_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/reward/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/reward/base_reward_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/reward/evaluator.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/reward/nemotron_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/reward/skywork_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/samba_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/sglang_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/siliconflow_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/stub_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/togetherai_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/vllm_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/volcano_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/watsonx_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/yi_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/models/zhipuai_model.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/personas/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/personas/persona.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/personas/persona_hub.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/prompts/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/prompts/ai_society.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/prompts/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/prompts/code.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/prompts/evaluation.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/prompts/generate_text_embedding_data.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/prompts/image_craft.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/prompts/misalignment.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/prompts/multi_condition_image_craft.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/prompts/object_recognition.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/prompts/persona_hub.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/prompts/prompt_templates.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/prompts/role_description_prompt_template.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/prompts/solution_extraction.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/prompts/task_prompt_template.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/prompts/translation.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/prompts/video_description_prompt.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/py.typed +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/responses/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/responses/agent_responses.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/retrievers/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/retrievers/auto_retriever.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/retrievers/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/retrievers/bm25_retriever.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/retrievers/cohere_rerank_retriever.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/retrievers/hybrid_retrival.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/retrievers/vector_retriever.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/runtimes/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/runtimes/api.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/runtimes/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/runtimes/configs.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/runtimes/daytona_runtime.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/runtimes/docker_runtime.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/runtimes/llm_guard_runtime.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/runtimes/remote_http_runtime.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/runtimes/ubuntu_docker_runtime.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/runtimes/utils/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/runtimes/utils/function_risk_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/runtimes/utils/ignore_risk_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/schemas/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/schemas/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/schemas/openai_converter.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/schemas/outlines_converter.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/societies/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/societies/babyagi_playing.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/societies/role_playing.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/societies/workforce/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/societies/workforce/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/societies/workforce/prompts.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/societies/workforce/task_channel.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/societies/workforce/utils.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/societies/workforce/worker.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/graph_storages/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/graph_storages/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/graph_storages/graph_element.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/graph_storages/nebula_graph.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/graph_storages/neo4j_graph.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/key_value_storages/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/key_value_storages/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/key_value_storages/in_memory.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/key_value_storages/json.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/key_value_storages/mem0_cloud.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/key_value_storages/redis.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/object_storages/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/object_storages/amazon_s3.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/object_storages/azure_blob.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/object_storages/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/object_storages/google_cloud.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/vectordb_storages/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/vectordb_storages/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/vectordb_storages/chroma.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/vectordb_storages/faiss.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/vectordb_storages/milvus.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/vectordb_storages/oceanbase.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/vectordb_storages/pgvector.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/vectordb_storages/qdrant.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/vectordb_storages/tidb.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/storages/vectordb_storages/weaviate.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/tasks/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/tasks/task_prompt.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/terminators/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/terminators/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/terminators/response_terminator.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/terminators/token_limit_terminator.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/aci_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/arxiv_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/ask_news_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/async_browser_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/audio_analysis_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/bohrium_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/browser_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/browser_toolkit_commons.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/code_execution.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/craw4ai_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/dalle_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/dappier_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/data_commons_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/edgeone_pages_mcp_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/excel_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/file_write_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/function_tool.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/github_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/google_calendar_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/google_drive_mcp_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/google_maps_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/google_scholar_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/image_analysis_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/jina_reranker_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/klavis_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/linkedin_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/markitdown_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/math_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/mcp_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/memory_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/meshy_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/mineru_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/networkx_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/non_visual_browser_toolkit/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/non_visual_browser_toolkit/actions.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/non_visual_browser_toolkit/agent.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/notion_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/biztoc/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/biztoc/ai-plugin.json +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/biztoc/openapi.yaml +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/coursera/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/coursera/openapi.yaml +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/create_qr_code/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/create_qr_code/openapi.yaml +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/klarna/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/klarna/openapi.yaml +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/nasa_apod/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/nasa_apod/openapi.yaml +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/outschool/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/outschool/ai-plugin.json +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/outschool/openapi.yaml +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/outschool/paths/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/outschool/paths/get_classes.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/outschool/paths/search_teachers.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/security_config.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/speak/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/speak/openapi.yaml +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/web_scraper/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/web_scraper/ai-plugin.json +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/web_scraper/openapi.yaml +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/web_scraper/paths/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_specs/web_scraper/paths/scraper.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/open_api_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/openai_agent_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/openbb_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/page_script.js +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/playwright_mcp_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/pptx_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/pubmed_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/pulse_mcp_search_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/pyautogui_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/reddit_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/retrieval_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/search_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/searxng_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/semantic_scholar_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/slack_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/stripe_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/sympy_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/task_planning_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/thinking_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/twitter_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/video_analysis_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/weather_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/whatsapp_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/wolfram_alpha_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/toolkits/zapier_toolkit.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/types/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/types/agents/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/types/agents/tool_calling_record.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/types/enums.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/types/mcp_registries.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/types/openai_types.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/types/unified_model_type.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/utils/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/utils/async_func.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/utils/chunker/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/utils/chunker/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/utils/chunker/code_chunker.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/utils/chunker/uio_chunker.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/utils/commons.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/utils/constants.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/utils/deduplication.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/utils/filename.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/utils/langfuse.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/utils/mcp.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/utils/mcp_client.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/utils/response_format.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/utils/token_counting.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/verifiers/__init__.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/verifiers/base.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/verifiers/math_verifier.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/verifiers/models.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/verifiers/physics_verifier.py +0 -0
- {camel_ai-0.2.70 → camel_ai-0.2.71a1}/camel/verifiers/python_verifier.py +0 -0
|
@@ -27,7 +27,7 @@ from camel.societies.workforce.prompts import (
|
|
|
27
27
|
)
|
|
28
28
|
from camel.societies.workforce.utils import TaskResult
|
|
29
29
|
from camel.societies.workforce.worker import Worker
|
|
30
|
-
from camel.tasks.task import Task, TaskState,
|
|
30
|
+
from camel.tasks.task import Task, TaskState, is_task_result_insufficient
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
class RolePlayingWorker(Worker):
|
|
@@ -178,14 +178,14 @@ class RolePlayingWorker(Worker):
|
|
|
178
178
|
result_dict = json.loads(response.msg.content)
|
|
179
179
|
task_result = TaskResult(**result_dict)
|
|
180
180
|
|
|
181
|
-
|
|
181
|
+
task.result = task_result.content
|
|
182
|
+
|
|
183
|
+
if is_task_result_insufficient(task):
|
|
182
184
|
print(
|
|
183
185
|
f"{Fore.RED}Task {task.id}: Content validation failed - "
|
|
184
186
|
f"task marked as failed{Fore.RESET}"
|
|
185
187
|
)
|
|
186
188
|
return TaskState.FAILED
|
|
187
189
|
|
|
188
|
-
task.result = task_result.content
|
|
189
|
-
|
|
190
190
|
print(f"Task result: {task.result}\n")
|
|
191
191
|
return TaskState.DONE
|
|
@@ -26,7 +26,7 @@ from camel.agents import ChatAgent
|
|
|
26
26
|
from camel.societies.workforce.prompts import PROCESS_TASK_PROMPT
|
|
27
27
|
from camel.societies.workforce.utils import TaskResult
|
|
28
28
|
from camel.societies.workforce.worker import Worker
|
|
29
|
-
from camel.tasks.task import Task, TaskState,
|
|
29
|
+
from camel.tasks.task import Task, TaskState, is_task_result_insufficient
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
class AgentPool:
|
|
@@ -352,14 +352,14 @@ class SingleAgentWorker(Worker):
|
|
|
352
352
|
if task_result.failed:
|
|
353
353
|
return TaskState.FAILED
|
|
354
354
|
|
|
355
|
-
|
|
355
|
+
task.result = task_result.content
|
|
356
|
+
|
|
357
|
+
if is_task_result_insufficient(task):
|
|
356
358
|
print(
|
|
357
359
|
f"{Fore.RED}Task {task.id}: Content validation failed - "
|
|
358
360
|
f"task marked as failed{Fore.RESET}"
|
|
359
361
|
)
|
|
360
362
|
return TaskState.FAILED
|
|
361
|
-
|
|
362
|
-
task.result = task_result.content
|
|
363
363
|
return TaskState.DONE
|
|
364
364
|
|
|
365
365
|
async def _listen_to_channel(self):
|
|
@@ -43,7 +43,12 @@ from camel.societies.workforce.utils import (
|
|
|
43
43
|
check_if_running,
|
|
44
44
|
)
|
|
45
45
|
from camel.societies.workforce.worker import Worker
|
|
46
|
-
from camel.tasks.task import
|
|
46
|
+
from camel.tasks.task import (
|
|
47
|
+
Task,
|
|
48
|
+
TaskState,
|
|
49
|
+
is_task_result_insufficient,
|
|
50
|
+
validate_task_content,
|
|
51
|
+
)
|
|
47
52
|
from camel.toolkits import (
|
|
48
53
|
CodeExecutionToolkit,
|
|
49
54
|
SearchToolkit,
|
|
@@ -57,6 +62,12 @@ from .workforce_logger import WorkforceLogger
|
|
|
57
62
|
|
|
58
63
|
logger = get_logger(__name__)
|
|
59
64
|
|
|
65
|
+
# Constants for configuration values
|
|
66
|
+
MAX_TASK_RETRIES = 3
|
|
67
|
+
MAX_PENDING_TASKS_LIMIT = 20
|
|
68
|
+
TASK_TIMEOUT_SECONDS = 180.0
|
|
69
|
+
DEFAULT_WORKER_POOL_SIZE = 10
|
|
70
|
+
|
|
60
71
|
|
|
61
72
|
class WorkforceState(Enum):
|
|
62
73
|
r"""Workforce execution state for human intervention support."""
|
|
@@ -216,6 +227,7 @@ class Workforce(BaseNode):
|
|
|
216
227
|
self._completed_tasks: List[Task] = []
|
|
217
228
|
self._loop: Optional[asyncio.AbstractEventLoop] = None
|
|
218
229
|
self._main_task_future: Optional[asyncio.Future] = None
|
|
230
|
+
self._cleanup_task: Optional[asyncio.Task] = None
|
|
219
231
|
# Snapshot throttle support
|
|
220
232
|
self._last_snapshot_time: float = 0.0
|
|
221
233
|
# Minimum seconds between automatic snapshots
|
|
@@ -517,6 +529,15 @@ class Workforce(BaseNode):
|
|
|
517
529
|
except Exception as e:
|
|
518
530
|
logger.warning(f"Error synchronizing shared memory: {e}")
|
|
519
531
|
|
|
532
|
+
def _cleanup_task_tracking(self, task_id: str) -> None:
|
|
533
|
+
r"""Clean up tracking data for a task to prevent memory leaks.
|
|
534
|
+
|
|
535
|
+
Args:
|
|
536
|
+
task_id (str): The ID of the task to clean up.
|
|
537
|
+
"""
|
|
538
|
+
if task_id in self._task_start_times:
|
|
539
|
+
del self._task_start_times[task_id]
|
|
540
|
+
|
|
520
541
|
def _decompose_task(self, task: Task) -> List[Task]:
|
|
521
542
|
r"""Decompose the task into subtasks. This method will also set the
|
|
522
543
|
relationship between the task and its subtasks.
|
|
@@ -1104,7 +1125,7 @@ class Workforce(BaseNode):
|
|
|
1104
1125
|
self,
|
|
1105
1126
|
description: str,
|
|
1106
1127
|
worker: ChatAgent,
|
|
1107
|
-
pool_max_size: int =
|
|
1128
|
+
pool_max_size: int = DEFAULT_WORKER_POOL_SIZE,
|
|
1108
1129
|
) -> Workforce:
|
|
1109
1130
|
r"""Add a worker node to the workforce that uses a single agent.
|
|
1110
1131
|
|
|
@@ -1233,7 +1254,7 @@ class Workforce(BaseNode):
|
|
|
1233
1254
|
except RuntimeError:
|
|
1234
1255
|
asyncio.run(self._async_reset())
|
|
1235
1256
|
|
|
1236
|
-
if hasattr(self, '
|
|
1257
|
+
if hasattr(self, 'metrics_logger') and self.metrics_logger is not None:
|
|
1237
1258
|
self.metrics_logger.reset_task_data()
|
|
1238
1259
|
else:
|
|
1239
1260
|
self.metrics_logger = WorkforceLogger(workforce_id=self.node_id)
|
|
@@ -1516,12 +1537,26 @@ class Workforce(BaseNode):
|
|
|
1516
1537
|
# Record the start time when a task is posted
|
|
1517
1538
|
self._task_start_times[task.id] = time.time()
|
|
1518
1539
|
|
|
1540
|
+
task.assigned_worker_id = assignee_id
|
|
1541
|
+
|
|
1519
1542
|
if self.metrics_logger:
|
|
1520
1543
|
self.metrics_logger.log_task_started(
|
|
1521
1544
|
task_id=task.id, worker_id=assignee_id
|
|
1522
1545
|
)
|
|
1523
|
-
|
|
1524
|
-
|
|
1546
|
+
|
|
1547
|
+
try:
|
|
1548
|
+
self._in_flight_tasks += 1
|
|
1549
|
+
await self._channel.post_task(task, self.node_id, assignee_id)
|
|
1550
|
+
logger.debug(
|
|
1551
|
+
f"Posted task {task.id} to {assignee_id}. "
|
|
1552
|
+
f"In-flight tasks: {self._in_flight_tasks}"
|
|
1553
|
+
)
|
|
1554
|
+
except Exception as e:
|
|
1555
|
+
# Decrement counter if posting failed
|
|
1556
|
+
self._in_flight_tasks -= 1
|
|
1557
|
+
logger.error(
|
|
1558
|
+
f"Failed to post task {task.id} to {assignee_id}: {e}"
|
|
1559
|
+
)
|
|
1525
1560
|
|
|
1526
1561
|
async def _post_dependency(self, dependency: Task) -> None:
|
|
1527
1562
|
await self._channel.post_dependency(dependency, self.node_id)
|
|
@@ -1580,7 +1615,7 @@ class Workforce(BaseNode):
|
|
|
1580
1615
|
new_node = SingleAgentWorker(
|
|
1581
1616
|
description=new_node_conf.description,
|
|
1582
1617
|
worker=new_agent,
|
|
1583
|
-
pool_max_size=
|
|
1618
|
+
pool_max_size=DEFAULT_WORKER_POOL_SIZE,
|
|
1584
1619
|
)
|
|
1585
1620
|
new_node.set_channel(self._channel)
|
|
1586
1621
|
|
|
@@ -1623,7 +1658,7 @@ class Workforce(BaseNode):
|
|
|
1623
1658
|
|
|
1624
1659
|
return ChatAgent(worker_sys_msg, model=model, tools=function_list) # type: ignore[arg-type]
|
|
1625
1660
|
|
|
1626
|
-
async def _get_returned_task(self) -> Task:
|
|
1661
|
+
async def _get_returned_task(self) -> Optional[Task]:
|
|
1627
1662
|
r"""Get the task that's published by this node and just get returned
|
|
1628
1663
|
from the assignee. Includes timeout handling to prevent indefinite
|
|
1629
1664
|
waiting.
|
|
@@ -1632,17 +1667,28 @@ class Workforce(BaseNode):
|
|
|
1632
1667
|
# Add timeout to prevent indefinite waiting
|
|
1633
1668
|
return await asyncio.wait_for(
|
|
1634
1669
|
self._channel.get_returned_task_by_publisher(self.node_id),
|
|
1635
|
-
timeout=
|
|
1670
|
+
timeout=TASK_TIMEOUT_SECONDS,
|
|
1636
1671
|
)
|
|
1637
|
-
except
|
|
1638
|
-
|
|
1639
|
-
|
|
1672
|
+
except Exception as e:
|
|
1673
|
+
# Decrement in-flight counter to prevent hanging
|
|
1674
|
+
if self._in_flight_tasks > 0:
|
|
1675
|
+
self._in_flight_tasks -= 1
|
|
1676
|
+
|
|
1677
|
+
error_msg = (
|
|
1678
|
+
f"Error getting returned task {e} in "
|
|
1640
1679
|
f"workforce {self.node_id}. "
|
|
1641
|
-
f"This may indicate an issue with async tool execution. "
|
|
1642
1680
|
f"Current pending tasks: {len(self._pending_tasks)}, "
|
|
1643
1681
|
f"In-flight tasks: {self._in_flight_tasks}"
|
|
1644
1682
|
)
|
|
1645
|
-
|
|
1683
|
+
logger.warning(error_msg)
|
|
1684
|
+
|
|
1685
|
+
if self._pending_tasks and self._assignees:
|
|
1686
|
+
for task in self._pending_tasks:
|
|
1687
|
+
if task.id in self._assignees:
|
|
1688
|
+
# Mark this real task as failed
|
|
1689
|
+
task.set_state(TaskState.FAILED)
|
|
1690
|
+
return task
|
|
1691
|
+
return None
|
|
1646
1692
|
|
|
1647
1693
|
async def _post_ready_tasks(self) -> None:
|
|
1648
1694
|
r"""Checks for unassigned tasks, assigns them, and then posts any
|
|
@@ -1682,6 +1728,9 @@ class Workforce(BaseNode):
|
|
|
1682
1728
|
# Step 2: Iterate through all pending tasks and post those that are
|
|
1683
1729
|
# ready
|
|
1684
1730
|
posted_tasks = []
|
|
1731
|
+
# Pre-compute completed task IDs set for O(1) lookups
|
|
1732
|
+
completed_task_ids = {t.id for t in self._completed_tasks}
|
|
1733
|
+
|
|
1685
1734
|
for task in self._pending_tasks:
|
|
1686
1735
|
# A task must be assigned to be considered for posting
|
|
1687
1736
|
if task.id in self._task_dependencies:
|
|
@@ -1689,8 +1738,7 @@ class Workforce(BaseNode):
|
|
|
1689
1738
|
# Check if all dependencies for this task are in the completed
|
|
1690
1739
|
# set
|
|
1691
1740
|
if all(
|
|
1692
|
-
dep_id in
|
|
1693
|
-
for dep_id in dependencies
|
|
1741
|
+
dep_id in completed_task_ids for dep_id in dependencies
|
|
1694
1742
|
):
|
|
1695
1743
|
assignee_id = self._assignees[task.id]
|
|
1696
1744
|
logger.debug(
|
|
@@ -1712,17 +1760,67 @@ class Workforce(BaseNode):
|
|
|
1712
1760
|
async def _handle_failed_task(self, task: Task) -> bool:
|
|
1713
1761
|
task.failure_count += 1
|
|
1714
1762
|
|
|
1763
|
+
# Determine detailed failure information
|
|
1764
|
+
if is_task_result_insufficient(task):
|
|
1765
|
+
failure_reason = "Worker returned unhelpful "
|
|
1766
|
+
f"response: {task.result[:100] if task.result else ''}..."
|
|
1767
|
+
else:
|
|
1768
|
+
failure_reason = "Task marked as failed despite "
|
|
1769
|
+
f"having result: {(task.result or '')[:100]}..."
|
|
1770
|
+
|
|
1771
|
+
# Add context about the worker and task
|
|
1772
|
+
worker_id = task.assigned_worker_id or "unknown"
|
|
1773
|
+
worker_info = f" (assigned to worker: {worker_id})"
|
|
1774
|
+
|
|
1775
|
+
detailed_error = f"{failure_reason}{worker_info}"
|
|
1776
|
+
|
|
1777
|
+
logger.error(
|
|
1778
|
+
f"Task {task.id} failed (attempt "
|
|
1779
|
+
f"{task.failure_count}/3): {detailed_error}"
|
|
1780
|
+
)
|
|
1781
|
+
|
|
1715
1782
|
if self.metrics_logger:
|
|
1716
|
-
worker_id = self._assignees.get(task.id)
|
|
1717
1783
|
self.metrics_logger.log_task_failed(
|
|
1718
1784
|
task_id=task.id,
|
|
1719
1785
|
worker_id=worker_id,
|
|
1720
|
-
error_message=
|
|
1786
|
+
error_message=detailed_error,
|
|
1721
1787
|
error_type="TaskFailure",
|
|
1722
|
-
metadata={
|
|
1788
|
+
metadata={
|
|
1789
|
+
'failure_count': task.failure_count,
|
|
1790
|
+
'task_content': task.content,
|
|
1791
|
+
'result_length': len(task.result) if task.result else 0,
|
|
1792
|
+
},
|
|
1723
1793
|
)
|
|
1724
1794
|
|
|
1725
|
-
|
|
1795
|
+
# Check for immediate halt conditions - return immediately if we
|
|
1796
|
+
# should halt
|
|
1797
|
+
if task.failure_count >= MAX_TASK_RETRIES:
|
|
1798
|
+
logger.error(
|
|
1799
|
+
f"Task {task.id} has exceeded maximum retry attempts "
|
|
1800
|
+
f"({MAX_TASK_RETRIES}). Final failure "
|
|
1801
|
+
f"reason: {detailed_error}. "
|
|
1802
|
+
f"Task content: '{task.content[:100]}...'"
|
|
1803
|
+
)
|
|
1804
|
+
self._cleanup_task_tracking(task.id)
|
|
1805
|
+
# Mark task as completed for dependency tracking before halting
|
|
1806
|
+
self._completed_tasks.append(task)
|
|
1807
|
+
if task.id in self._assignees:
|
|
1808
|
+
await self._channel.archive_task(task.id)
|
|
1809
|
+
return True
|
|
1810
|
+
|
|
1811
|
+
# If too many tasks are failing rapidly, also halt to prevent infinite
|
|
1812
|
+
# loops
|
|
1813
|
+
if len(self._pending_tasks) > MAX_PENDING_TASKS_LIMIT:
|
|
1814
|
+
logger.error(
|
|
1815
|
+
f"Too many pending tasks ({len(self._pending_tasks)} > "
|
|
1816
|
+
f"{MAX_PENDING_TASKS_LIMIT}). Halting to prevent task "
|
|
1817
|
+
f"explosion. Last failed task: {task.id}"
|
|
1818
|
+
)
|
|
1819
|
+
self._cleanup_task_tracking(task.id)
|
|
1820
|
+
# Mark task as completed for dependency tracking before halting
|
|
1821
|
+
self._completed_tasks.append(task)
|
|
1822
|
+
if task.id in self._assignees:
|
|
1823
|
+
await self._channel.archive_task(task.id)
|
|
1726
1824
|
return True
|
|
1727
1825
|
|
|
1728
1826
|
if task.get_depth() > 3:
|
|
@@ -1777,8 +1875,6 @@ class Workforce(BaseNode):
|
|
|
1777
1875
|
# Mark task as completed for dependency tracking
|
|
1778
1876
|
self._completed_tasks.append(task)
|
|
1779
1877
|
|
|
1780
|
-
# Post next ready tasks
|
|
1781
|
-
|
|
1782
1878
|
# Sync shared memory after task completion to share knowledge
|
|
1783
1879
|
if self.share_memory:
|
|
1784
1880
|
logger.info(
|
|
@@ -1792,7 +1888,7 @@ class Workforce(BaseNode):
|
|
|
1792
1888
|
|
|
1793
1889
|
async def _handle_completed_task(self, task: Task) -> None:
|
|
1794
1890
|
if self.metrics_logger:
|
|
1795
|
-
worker_id =
|
|
1891
|
+
worker_id = task.assigned_worker_id or "unknown"
|
|
1796
1892
|
processing_time_seconds = None
|
|
1797
1893
|
token_usage = None
|
|
1798
1894
|
|
|
@@ -1801,7 +1897,7 @@ class Workforce(BaseNode):
|
|
|
1801
1897
|
processing_time_seconds = (
|
|
1802
1898
|
time.time() - self._task_start_times[task.id]
|
|
1803
1899
|
)
|
|
1804
|
-
|
|
1900
|
+
self._cleanup_task_tracking(task.id)
|
|
1805
1901
|
elif (
|
|
1806
1902
|
task.additional_info is not None
|
|
1807
1903
|
and 'processing_time_seconds' in task.additional_info
|
|
@@ -1995,8 +2091,19 @@ class Workforce(BaseNode):
|
|
|
1995
2091
|
)
|
|
1996
2092
|
self._last_snapshot_time = time.time()
|
|
1997
2093
|
|
|
1998
|
-
# Get returned task
|
|
2094
|
+
# Get returned task
|
|
1999
2095
|
returned_task = await self._get_returned_task()
|
|
2096
|
+
|
|
2097
|
+
# If no task was returned, continue
|
|
2098
|
+
if returned_task is None:
|
|
2099
|
+
logger.debug(
|
|
2100
|
+
f"No task returned in workforce {self.node_id}. "
|
|
2101
|
+
f"Pending: {len(self._pending_tasks)}, "
|
|
2102
|
+
f"In-flight: {self._in_flight_tasks}"
|
|
2103
|
+
)
|
|
2104
|
+
await self._post_ready_tasks()
|
|
2105
|
+
continue
|
|
2106
|
+
|
|
2000
2107
|
self._in_flight_tasks -= 1
|
|
2001
2108
|
|
|
2002
2109
|
# Check for stop request after getting task
|
|
@@ -2006,22 +2113,72 @@ class Workforce(BaseNode):
|
|
|
2006
2113
|
|
|
2007
2114
|
# Process the returned task based on its state
|
|
2008
2115
|
if returned_task.state == TaskState.DONE:
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2116
|
+
# Check if the "completed" task actually failed to provide
|
|
2117
|
+
# useful results
|
|
2118
|
+
if is_task_result_insufficient(returned_task):
|
|
2119
|
+
result_preview = (
|
|
2120
|
+
returned_task.result[:100] + "..."
|
|
2121
|
+
if returned_task.result
|
|
2122
|
+
else "No result"
|
|
2123
|
+
)
|
|
2124
|
+
logger.warning(
|
|
2125
|
+
f"Task {returned_task.id} marked as DONE but "
|
|
2126
|
+
f"result is insufficient. "
|
|
2127
|
+
f"Treating as failed. Result: '{result_preview}'"
|
|
2128
|
+
)
|
|
2129
|
+
returned_task.state = TaskState.FAILED
|
|
2130
|
+
try:
|
|
2131
|
+
halt = await self._handle_failed_task(
|
|
2132
|
+
returned_task
|
|
2133
|
+
)
|
|
2134
|
+
if not halt:
|
|
2135
|
+
continue
|
|
2136
|
+
print(
|
|
2137
|
+
f"{Fore.RED}Task {returned_task.id} has "
|
|
2138
|
+
f"failed for {MAX_TASK_RETRIES} times after "
|
|
2139
|
+
f"insufficient results, halting the "
|
|
2140
|
+
f"workforce. Final error: "
|
|
2141
|
+
f"{returned_task.result or 'Unknown error'}"
|
|
2142
|
+
f"{Fore.RESET}"
|
|
2143
|
+
)
|
|
2144
|
+
await self._graceful_shutdown(returned_task)
|
|
2145
|
+
break
|
|
2146
|
+
except Exception as e:
|
|
2147
|
+
logger.error(
|
|
2148
|
+
f"Error handling insufficient task result "
|
|
2149
|
+
f"{returned_task.id}: {e}",
|
|
2150
|
+
exc_info=True,
|
|
2151
|
+
)
|
|
2152
|
+
continue
|
|
2153
|
+
else:
|
|
2154
|
+
print(
|
|
2155
|
+
f"{Fore.CYAN}🎯 Task {returned_task.id} completed "
|
|
2156
|
+
f"successfully.{Fore.RESET}"
|
|
2157
|
+
)
|
|
2158
|
+
await self._handle_completed_task(returned_task)
|
|
2014
2159
|
elif returned_task.state == TaskState.FAILED:
|
|
2015
|
-
|
|
2016
|
-
|
|
2160
|
+
try:
|
|
2161
|
+
halt = await self._handle_failed_task(returned_task)
|
|
2162
|
+
if not halt:
|
|
2163
|
+
continue
|
|
2164
|
+
print(
|
|
2165
|
+
f"{Fore.RED}Task {returned_task.id} has failed "
|
|
2166
|
+
f"for {MAX_TASK_RETRIES} times, halting "
|
|
2167
|
+
f"the workforce. Final error: "
|
|
2168
|
+
f"{returned_task.result or 'Unknown error'}"
|
|
2169
|
+
f"{Fore.RESET}"
|
|
2170
|
+
)
|
|
2171
|
+
# Graceful shutdown instead of immediate break
|
|
2172
|
+
await self._graceful_shutdown(returned_task)
|
|
2173
|
+
break
|
|
2174
|
+
except Exception as e:
|
|
2175
|
+
logger.error(
|
|
2176
|
+
f"Error handling failed task "
|
|
2177
|
+
f"{returned_task.id}: {e}",
|
|
2178
|
+
exc_info=True,
|
|
2179
|
+
)
|
|
2180
|
+
# Continue to prevent hanging
|
|
2017
2181
|
continue
|
|
2018
|
-
print(
|
|
2019
|
-
f"{Fore.RED}Task {returned_task.id} has failed "
|
|
2020
|
-
f"for 3 times, halting the workforce.{Fore.RESET}"
|
|
2021
|
-
)
|
|
2022
|
-
# Graceful shutdown instead of immediate break
|
|
2023
|
-
await self._graceful_shutdown(returned_task)
|
|
2024
|
-
break
|
|
2025
2182
|
elif returned_task.state == TaskState.OPEN:
|
|
2026
2183
|
# TODO: Add logic for OPEN
|
|
2027
2184
|
pass
|
|
@@ -2031,7 +2188,18 @@ class Workforce(BaseNode):
|
|
|
2031
2188
|
)
|
|
2032
2189
|
|
|
2033
2190
|
except Exception as e:
|
|
2034
|
-
|
|
2191
|
+
# Decrement in-flight counter to prevent hanging
|
|
2192
|
+
if self._in_flight_tasks > 0:
|
|
2193
|
+
self._in_flight_tasks -= 1
|
|
2194
|
+
|
|
2195
|
+
logger.error(
|
|
2196
|
+
f"Error processing task in workforce {self.node_id}: {e}"
|
|
2197
|
+
f"Workforce state - Pending tasks: "
|
|
2198
|
+
f"{len(self._pending_tasks)}, "
|
|
2199
|
+
f"In-flight tasks: {self._in_flight_tasks}, "
|
|
2200
|
+
f"Completed tasks: {len(self._completed_tasks)}"
|
|
2201
|
+
)
|
|
2202
|
+
|
|
2035
2203
|
if self._stop_requested:
|
|
2036
2204
|
break
|
|
2037
2205
|
# Continue with next iteration unless stop is requested
|
|
@@ -2085,11 +2253,38 @@ class Workforce(BaseNode):
|
|
|
2085
2253
|
r"""Stop all the child nodes under it. The node itself will be stopped
|
|
2086
2254
|
by its parent node.
|
|
2087
2255
|
"""
|
|
2256
|
+
# Stop all child nodes first
|
|
2088
2257
|
for child in self._children:
|
|
2089
2258
|
if child._running:
|
|
2090
2259
|
child.stop()
|
|
2091
|
-
|
|
2092
|
-
|
|
2260
|
+
|
|
2261
|
+
# Cancel child listening tasks
|
|
2262
|
+
if self._child_listening_tasks:
|
|
2263
|
+
try:
|
|
2264
|
+
loop = asyncio.get_running_loop()
|
|
2265
|
+
if loop and not loop.is_closed():
|
|
2266
|
+
# Create graceful cleanup task
|
|
2267
|
+
async def cleanup():
|
|
2268
|
+
await asyncio.sleep(0.1) # Brief grace period
|
|
2269
|
+
for task in self._child_listening_tasks:
|
|
2270
|
+
if not task.done():
|
|
2271
|
+
task.cancel()
|
|
2272
|
+
await asyncio.gather(
|
|
2273
|
+
*self._child_listening_tasks,
|
|
2274
|
+
return_exceptions=True,
|
|
2275
|
+
)
|
|
2276
|
+
|
|
2277
|
+
self._cleanup_task = loop.create_task(cleanup())
|
|
2278
|
+
else:
|
|
2279
|
+
# No active loop, cancel immediately
|
|
2280
|
+
for task in self._child_listening_tasks:
|
|
2281
|
+
task.cancel()
|
|
2282
|
+
except (RuntimeError, Exception) as e:
|
|
2283
|
+
# Fallback: cancel immediately
|
|
2284
|
+
logger.debug(f"Exception during task cleanup: {e}")
|
|
2285
|
+
for task in self._child_listening_tasks:
|
|
2286
|
+
task.cancel()
|
|
2287
|
+
|
|
2093
2288
|
self._running = False
|
|
2094
2289
|
|
|
2095
2290
|
def clone(self, with_memory: bool = False) -> 'Workforce':
|
|
@@ -46,19 +46,35 @@ from .task_prompt import (
|
|
|
46
46
|
logger = get_logger(__name__)
|
|
47
47
|
|
|
48
48
|
|
|
49
|
+
class TaskValidationMode(Enum):
|
|
50
|
+
r"""Validation modes for different use cases."""
|
|
51
|
+
|
|
52
|
+
INPUT = "input" # For validating task content before processing
|
|
53
|
+
OUTPUT = "output" # For validating task results after completion
|
|
54
|
+
|
|
55
|
+
|
|
49
56
|
def validate_task_content(
|
|
50
|
-
content: str,
|
|
57
|
+
content: str,
|
|
58
|
+
task_id: str = "unknown",
|
|
59
|
+
min_length: int = 5,
|
|
60
|
+
mode: TaskValidationMode = TaskValidationMode.INPUT,
|
|
61
|
+
check_failure_patterns: bool = True,
|
|
51
62
|
) -> bool:
|
|
52
|
-
r"""
|
|
53
|
-
|
|
54
|
-
|
|
63
|
+
r"""Unified validation for task content and results to avoid silent
|
|
64
|
+
failures. Performs comprehensive checks to ensure content meets quality
|
|
65
|
+
standards.
|
|
55
66
|
|
|
56
67
|
Args:
|
|
57
|
-
content (str): The task result
|
|
68
|
+
content (str): The task content or result to validate.
|
|
58
69
|
task_id (str): Task ID for logging purposes.
|
|
59
70
|
(default: :obj:`"unknown"`)
|
|
60
71
|
min_length (int): Minimum content length after stripping whitespace.
|
|
61
|
-
(default: :obj:`
|
|
72
|
+
(default: :obj:`5`)
|
|
73
|
+
mode (TaskValidationMode): Validation mode - INPUT for task content,
|
|
74
|
+
OUTPUT for task results. (default: :obj:`TaskValidationMode.INPUT`)
|
|
75
|
+
check_failure_patterns (bool): Whether to check for failure indicators
|
|
76
|
+
in the content. Only effective in OUTPUT mode.
|
|
77
|
+
(default: :obj:`True`)
|
|
62
78
|
|
|
63
79
|
Returns:
|
|
64
80
|
bool: True if content passes validation, False otherwise.
|
|
@@ -85,14 +101,70 @@ def validate_task_content(
|
|
|
85
101
|
)
|
|
86
102
|
return False
|
|
87
103
|
|
|
104
|
+
# 4: For OUTPUT mode, check for failure patterns if enabled
|
|
105
|
+
if mode == TaskValidationMode.OUTPUT and check_failure_patterns:
|
|
106
|
+
content_lower = stripped_content.lower()
|
|
107
|
+
|
|
108
|
+
# Check for explicit failure indicators
|
|
109
|
+
failure_indicators = [
|
|
110
|
+
"i cannot complete",
|
|
111
|
+
"i cannot do",
|
|
112
|
+
"task failed",
|
|
113
|
+
"unable to complete",
|
|
114
|
+
"cannot be completed",
|
|
115
|
+
"failed to complete",
|
|
116
|
+
"i cannot",
|
|
117
|
+
"not possible",
|
|
118
|
+
"impossible to",
|
|
119
|
+
"cannot perform",
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
if any(indicator in content_lower for indicator in failure_indicators):
|
|
123
|
+
logger.warning(
|
|
124
|
+
f"Task {task_id}: Failure indicator detected in result. "
|
|
125
|
+
f"Content preview: '{stripped_content[:100]}...'"
|
|
126
|
+
)
|
|
127
|
+
return False
|
|
128
|
+
|
|
129
|
+
# Check for responses that are just error messages or refusals
|
|
130
|
+
if content_lower.startswith(("error", "failed", "cannot", "unable")):
|
|
131
|
+
logger.warning(
|
|
132
|
+
f"Task {task_id}: Error/refusal pattern detected at start. "
|
|
133
|
+
f"Content preview: '{stripped_content[:100]}...'"
|
|
134
|
+
)
|
|
135
|
+
return False
|
|
136
|
+
|
|
88
137
|
# All validation checks passed
|
|
89
138
|
logger.debug(
|
|
90
|
-
f"Task {task_id}:
|
|
139
|
+
f"Task {task_id}: {mode.value} validation passed "
|
|
91
140
|
f"({len(stripped_content)} chars)"
|
|
92
141
|
)
|
|
93
142
|
return True
|
|
94
143
|
|
|
95
144
|
|
|
145
|
+
def is_task_result_insufficient(task: "Task") -> bool:
|
|
146
|
+
r"""Check if a task result is insufficient and should be treated as failed.
|
|
147
|
+
|
|
148
|
+
This is a convenience wrapper around validate_task_content for backward
|
|
149
|
+
compatibility and semantic clarity when checking task results.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
task (Task): The task to check.
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
bool: True if the result is insufficient, False otherwise.
|
|
156
|
+
"""
|
|
157
|
+
if not hasattr(task, 'result') or task.result is None:
|
|
158
|
+
return True
|
|
159
|
+
|
|
160
|
+
return not validate_task_content(
|
|
161
|
+
content=task.result,
|
|
162
|
+
task_id=task.id,
|
|
163
|
+
mode=TaskValidationMode.OUTPUT,
|
|
164
|
+
check_failure_patterns=True,
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
|
|
96
168
|
def parse_response(
|
|
97
169
|
response: str, task_id: Optional[str] = None
|
|
98
170
|
) -> List["Task"]:
|
|
@@ -157,6 +229,8 @@ class Task(BaseModel):
|
|
|
157
229
|
(default: :obj:`""`)
|
|
158
230
|
failure_count (int): The failure count for the task.
|
|
159
231
|
(default: :obj:`0`)
|
|
232
|
+
assigned_worker_id (Optional[str]): The ID of the worker assigned to
|
|
233
|
+
this task. (default: :obj:`None`)
|
|
160
234
|
additional_info (Optional[Dict[str, Any]]): Additional information for
|
|
161
235
|
the task. (default: :obj:`None`)
|
|
162
236
|
image_list (Optional[List[Image.Image]]): Optional list of PIL Image
|
|
@@ -187,6 +261,8 @@ class Task(BaseModel):
|
|
|
187
261
|
|
|
188
262
|
failure_count: int = 0
|
|
189
263
|
|
|
264
|
+
assigned_worker_id: Optional[str] = None
|
|
265
|
+
|
|
190
266
|
additional_info: Optional[Dict[str, Any]] = None
|
|
191
267
|
|
|
192
268
|
image_list: Optional[List[Image.Image]] = None
|