camel-ai 0.2.59__py3-none-any.whl → 0.2.82__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of camel-ai might be problematic. Click here for more details.
- camel/__init__.py +3 -3
- camel/agents/__init__.py +2 -2
- camel/agents/_types.py +9 -4
- camel/agents/_utils.py +40 -2
- camel/agents/base.py +2 -2
- camel/agents/chat_agent.py +5012 -902
- camel/agents/critic_agent.py +2 -2
- camel/agents/deductive_reasoner_agent.py +56 -56
- camel/agents/embodied_agent.py +2 -2
- camel/agents/knowledge_graph_agent.py +20 -20
- camel/agents/mcp_agent.py +39 -36
- camel/agents/multi_hop_generator_agent.py +3 -3
- camel/agents/programmed_agent_instruction.py +2 -2
- camel/agents/repo_agent.py +4 -3
- camel/agents/role_assignment_agent.py +2 -2
- camel/agents/search_agent.py +2 -2
- camel/agents/task_agent.py +2 -2
- camel/agents/tool_agents/__init__.py +2 -2
- camel/agents/tool_agents/base.py +2 -2
- camel/agents/tool_agents/hugging_face_tool_agent.py +3 -3
- camel/benchmarks/__init__.py +2 -2
- camel/benchmarks/apibank.py +5 -5
- camel/benchmarks/apibench.py +2 -2
- camel/benchmarks/base.py +2 -2
- camel/benchmarks/browsecomp.py +44 -33
- camel/benchmarks/gaia.py +17 -13
- camel/benchmarks/mock_website/README.md +94 -0
- camel/benchmarks/mock_website/mock_web.py +299 -0
- camel/benchmarks/mock_website/requirements.txt +3 -0
- camel/benchmarks/mock_website/shopping_mall/app.py +465 -0
- camel/benchmarks/mock_website/task.json +104 -0
- camel/benchmarks/nexus.py +3 -3
- camel/benchmarks/ragbench.py +2 -2
- camel/bots/__init__.py +2 -2
- camel/bots/discord/__init__.py +2 -2
- camel/bots/discord/discord_app.py +2 -2
- camel/bots/discord/discord_installation.py +2 -2
- camel/bots/discord/discord_store.py +3 -3
- camel/bots/slack/__init__.py +2 -2
- camel/bots/slack/models.py +4 -4
- camel/bots/slack/slack_app.py +2 -2
- camel/bots/telegram_bot.py +2 -2
- camel/configs/__init__.py +26 -2
- camel/configs/aihubmix_config.py +90 -0
- camel/configs/aiml_config.py +2 -2
- camel/configs/amd_config.py +70 -0
- camel/configs/anthropic_config.py +8 -7
- camel/configs/base_config.py +2 -2
- camel/configs/bedrock_config.py +5 -3
- camel/configs/cerebras_config.py +98 -0
- camel/configs/cohere_config.py +3 -3
- camel/configs/cometapi_config.py +106 -0
- camel/configs/crynux_config.py +94 -0
- camel/configs/deepseek_config.py +9 -8
- camel/configs/gemini_config.py +6 -4
- camel/configs/groq_config.py +6 -4
- camel/configs/internlm_config.py +6 -4
- camel/configs/litellm_config.py +2 -2
- camel/configs/lmstudio_config.py +6 -4
- camel/configs/minimax_config.py +95 -0
- camel/configs/mistral_config.py +3 -3
- camel/configs/modelscope_config.py +5 -3
- camel/configs/moonshot_config.py +2 -2
- camel/configs/nebius_config.py +105 -0
- camel/configs/netmind_config.py +2 -2
- camel/configs/novita_config.py +2 -2
- camel/configs/nvidia_config.py +2 -2
- camel/configs/ollama_config.py +2 -2
- camel/configs/openai_config.py +8 -3
- camel/configs/openrouter_config.py +6 -4
- camel/configs/ppio_config.py +2 -2
- camel/configs/qianfan_config.py +85 -0
- camel/configs/qwen_config.py +2 -2
- camel/configs/reka_config.py +3 -3
- camel/configs/samba_config.py +8 -6
- camel/configs/sglang_config.py +2 -2
- camel/configs/siliconflow_config.py +2 -2
- camel/configs/togetherai_config.py +2 -2
- camel/configs/vllm_config.py +4 -2
- camel/configs/watsonx_config.py +2 -2
- camel/configs/yi_config.py +6 -4
- camel/configs/zhipuai_config.py +6 -4
- camel/{data_collector → data_collectors}/__init__.py +2 -2
- camel/{data_collector → data_collectors}/alpaca_collector.py +19 -10
- camel/{data_collector → data_collectors}/base.py +2 -2
- camel/{data_collector → data_collectors}/sharegpt_collector.py +3 -3
- camel/datagen/__init__.py +2 -2
- camel/datagen/cot_datagen.py +32 -37
- camel/datagen/evol_instruct/__init__.py +2 -2
- camel/datagen/evol_instruct/evol_instruct.py +2 -2
- camel/datagen/evol_instruct/scorer.py +24 -25
- camel/datagen/evol_instruct/templates.py +48 -48
- camel/datagen/self_improving_cot.py +5 -5
- camel/datagen/self_instruct/__init__.py +2 -2
- camel/datagen/self_instruct/filter/__init__.py +2 -2
- camel/datagen/self_instruct/filter/filter_function.py +2 -2
- camel/datagen/self_instruct/filter/filter_registry.py +2 -2
- camel/datagen/self_instruct/filter/instruction_filter.py +2 -2
- camel/datagen/self_instruct/self_instruct.py +2 -2
- camel/datagen/self_instruct/templates.py +47 -47
- camel/datagen/source2synth/__init__.py +2 -2
- camel/datagen/source2synth/data_processor.py +2 -2
- camel/datagen/source2synth/models.py +2 -2
- camel/datagen/source2synth/user_data_processor_config.py +2 -2
- camel/datahubs/__init__.py +2 -2
- camel/datahubs/base.py +2 -2
- camel/datahubs/huggingface.py +2 -2
- camel/datahubs/models.py +2 -2
- camel/datasets/__init__.py +2 -2
- camel/datasets/base_generator.py +41 -12
- camel/datasets/few_shot_generator.py +18 -18
- camel/datasets/models.py +3 -3
- camel/datasets/self_instruct_generator.py +2 -2
- camel/datasets/static_dataset.py +152 -2
- camel/embeddings/__init__.py +2 -2
- camel/embeddings/azure_embedding.py +2 -2
- camel/embeddings/base.py +2 -2
- camel/embeddings/gemini_embedding.py +2 -2
- camel/embeddings/jina_embedding.py +10 -3
- camel/embeddings/mistral_embedding.py +2 -2
- camel/embeddings/openai_compatible_embedding.py +2 -2
- camel/embeddings/openai_embedding.py +2 -2
- camel/embeddings/sentence_transformers_embeddings.py +4 -4
- camel/embeddings/together_embedding.py +2 -2
- camel/embeddings/vlm_embedding.py +11 -4
- camel/environments/__init__.py +14 -2
- camel/environments/models.py +2 -2
- camel/environments/multi_step.py +2 -2
- camel/environments/rlcards_env.py +860 -0
- camel/environments/single_step.py +30 -5
- camel/environments/tic_tac_toe.py +3 -3
- camel/extractors/__init__.py +2 -2
- camel/extractors/base.py +2 -2
- camel/extractors/python_strategies.py +2 -2
- camel/generators.py +2 -2
- camel/human.py +2 -2
- camel/interpreters/__init__.py +4 -2
- camel/interpreters/base.py +16 -3
- camel/interpreters/docker/Dockerfile +53 -7
- camel/interpreters/docker_interpreter.py +70 -11
- camel/interpreters/e2b_interpreter.py +59 -11
- camel/interpreters/internal_python_interpreter.py +81 -4
- camel/interpreters/interpreter_error.py +2 -2
- camel/interpreters/ipython_interpreter.py +23 -5
- camel/interpreters/microsandbox_interpreter.py +395 -0
- camel/interpreters/subprocess_interpreter.py +36 -4
- camel/loaders/__init__.py +17 -5
- camel/loaders/apify_reader.py +2 -2
- camel/loaders/base_io.py +2 -2
- camel/loaders/base_loader.py +85 -0
- camel/loaders/chunkr_reader.py +128 -93
- camel/loaders/crawl4ai_reader.py +2 -2
- camel/loaders/firecrawl_reader.py +6 -6
- camel/loaders/jina_url_reader.py +2 -2
- camel/loaders/markitdown.py +2 -2
- camel/loaders/mineru_extractor.py +2 -2
- camel/loaders/mistral_reader.py +148 -0
- camel/loaders/scrapegraph_reader.py +2 -2
- camel/loaders/unstructured_io.py +2 -2
- camel/logger.py +5 -5
- camel/memories/__init__.py +2 -2
- camel/memories/agent_memories.py +86 -3
- camel/memories/base.py +36 -2
- camel/memories/blocks/__init__.py +2 -2
- camel/memories/blocks/chat_history_block.py +126 -9
- camel/memories/blocks/vectordb_block.py +10 -3
- camel/memories/context_creators/__init__.py +2 -2
- camel/memories/context_creators/score_based.py +31 -239
- camel/memories/records.py +98 -13
- camel/messages/__init__.py +2 -2
- camel/messages/base.py +193 -46
- camel/messages/conversion/__init__.py +2 -2
- camel/messages/conversion/alpaca.py +2 -2
- camel/messages/conversion/conversation_models.py +2 -2
- camel/messages/conversion/sharegpt/__init__.py +2 -2
- camel/messages/conversion/sharegpt/function_call_formatter.py +2 -2
- camel/messages/conversion/sharegpt/hermes/__init__.py +2 -2
- camel/messages/conversion/sharegpt/hermes/hermes_function_formatter.py +2 -2
- camel/messages/func_message.py +54 -17
- camel/models/__init__.py +18 -2
- camel/models/_utils.py +3 -3
- camel/models/aihubmix_model.py +83 -0
- camel/models/aiml_model.py +11 -18
- camel/models/amd_model.py +101 -0
- camel/models/anthropic_model.py +127 -20
- camel/models/aws_bedrock_model.py +12 -35
- camel/models/azure_openai_model.py +263 -63
- camel/models/base_audio_model.py +5 -3
- camel/models/base_model.py +195 -26
- camel/models/cerebras_model.py +83 -0
- camel/models/cohere_model.py +81 -21
- camel/models/cometapi_model.py +83 -0
- camel/models/crynux_model.py +87 -0
- camel/models/deepseek_model.py +61 -59
- camel/models/fish_audio_model.py +8 -2
- camel/models/gemini_model.py +439 -30
- camel/models/groq_model.py +11 -19
- camel/models/internlm_model.py +11 -18
- camel/models/litellm_model.py +94 -34
- camel/models/lmstudio_model.py +17 -20
- camel/models/minimax_model.py +83 -0
- camel/models/mistral_model.py +84 -19
- camel/models/model_factory.py +49 -6
- camel/models/model_manager.py +33 -11
- camel/models/modelscope_model.py +13 -193
- camel/models/moonshot_model.py +195 -21
- camel/models/nebius_model.py +83 -0
- camel/models/nemotron_model.py +19 -9
- camel/models/netmind_model.py +11 -18
- camel/models/novita_model.py +11 -18
- camel/models/nvidia_model.py +11 -18
- camel/models/ollama_model.py +14 -21
- camel/models/openai_audio_models.py +2 -2
- camel/models/openai_compatible_model.py +234 -27
- camel/models/openai_model.py +255 -39
- camel/models/openrouter_model.py +11 -19
- camel/models/ppio_model.py +11 -18
- camel/models/qianfan_model.py +89 -0
- camel/models/qwen_model.py +13 -193
- camel/models/reka_model.py +90 -21
- camel/models/reward/__init__.py +2 -2
- camel/models/reward/base_reward_model.py +2 -2
- camel/models/reward/evaluator.py +2 -2
- camel/models/reward/nemotron_model.py +2 -2
- camel/models/reward/skywork_model.py +2 -2
- camel/models/samba_model.py +117 -49
- camel/models/sglang_model.py +162 -42
- camel/models/siliconflow_model.py +12 -35
- camel/models/stub_model.py +10 -7
- camel/models/togetherai_model.py +11 -18
- camel/models/vllm_model.py +10 -18
- camel/models/volcano_model.py +16 -20
- camel/models/watsonx_model.py +69 -19
- camel/models/yi_model.py +11 -18
- camel/models/zhipuai_model.py +70 -18
- camel/parsers/__init__.py +18 -0
- camel/parsers/mcp_tool_call_parser.py +176 -0
- camel/personas/__init__.py +2 -2
- camel/personas/persona.py +2 -2
- camel/personas/persona_hub.py +2 -2
- camel/prompts/__init__.py +2 -2
- camel/prompts/ai_society.py +2 -2
- camel/prompts/base.py +2 -2
- camel/prompts/code.py +2 -2
- camel/prompts/evaluation.py +2 -2
- camel/prompts/generate_text_embedding_data.py +2 -2
- camel/prompts/image_craft.py +2 -2
- camel/prompts/misalignment.py +2 -2
- camel/prompts/multi_condition_image_craft.py +2 -2
- camel/prompts/object_recognition.py +2 -2
- camel/prompts/persona_hub.py +3 -3
- camel/prompts/prompt_templates.py +2 -2
- camel/prompts/role_description_prompt_template.py +2 -2
- camel/prompts/solution_extraction.py +8 -8
- camel/prompts/task_prompt_template.py +2 -2
- camel/prompts/translation.py +2 -2
- camel/prompts/video_description_prompt.py +3 -3
- camel/responses/__init__.py +2 -2
- camel/responses/agent_responses.py +2 -2
- camel/retrievers/__init__.py +2 -2
- camel/retrievers/auto_retriever.py +23 -3
- camel/retrievers/base.py +2 -2
- camel/retrievers/bm25_retriever.py +3 -4
- camel/retrievers/cohere_rerank_retriever.py +2 -2
- camel/retrievers/hybrid_retrival.py +4 -4
- camel/retrievers/vector_retriever.py +2 -2
- camel/runtimes/Dockerfile.multi-toolkit +90 -0
- camel/{runtime → runtimes}/__init__.py +2 -2
- camel/runtimes/api.py +153 -0
- camel/{runtime → runtimes}/base.py +2 -2
- camel/{runtime → runtimes}/configs.py +13 -13
- camel/{runtime → runtimes}/daytona_runtime.py +18 -19
- camel/{runtime → runtimes}/docker_runtime.py +13 -13
- camel/{runtime → runtimes}/llm_guard_runtime.py +28 -28
- camel/{runtime → runtimes}/remote_http_runtime.py +12 -12
- camel/{runtime → runtimes}/ubuntu_docker_runtime.py +3 -3
- camel/{runtime → runtimes}/utils/__init__.py +2 -2
- camel/{runtime → runtimes}/utils/function_risk_toolkit.py +2 -2
- camel/{runtime → runtimes}/utils/ignore_risk_toolkit.py +2 -2
- camel/schemas/__init__.py +2 -2
- camel/schemas/base.py +2 -2
- camel/schemas/openai_converter.py +3 -3
- camel/schemas/outlines_converter.py +2 -2
- camel/services/agent_openapi_server.py +380 -0
- camel/societies/__init__.py +4 -2
- camel/societies/babyagi_playing.py +2 -2
- camel/societies/role_playing.py +201 -80
- camel/societies/workforce/__init__.py +10 -3
- camel/societies/workforce/base.py +9 -5
- camel/societies/workforce/events.py +143 -0
- camel/societies/workforce/prompts.py +258 -33
- camel/societies/workforce/role_playing_worker.py +95 -30
- camel/societies/workforce/single_agent_worker.py +659 -30
- camel/societies/workforce/structured_output_handler.py +512 -0
- camel/societies/workforce/task_channel.py +182 -38
- camel/societies/workforce/utils.py +784 -18
- camel/societies/workforce/worker.py +96 -28
- camel/societies/workforce/workflow_memory_manager.py +1746 -0
- camel/societies/workforce/workforce.py +5730 -366
- camel/societies/workforce/workforce_callback.py +103 -0
- camel/societies/workforce/workforce_logger.py +647 -0
- camel/societies/workforce/workforce_metrics.py +33 -0
- camel/storages/__init__.py +10 -2
- camel/storages/graph_storages/__init__.py +2 -2
- camel/storages/graph_storages/base.py +2 -2
- camel/storages/graph_storages/graph_element.py +2 -2
- camel/storages/graph_storages/nebula_graph.py +4 -4
- camel/storages/graph_storages/neo4j_graph.py +7 -7
- camel/storages/key_value_storages/__init__.py +2 -2
- camel/storages/key_value_storages/base.py +2 -2
- camel/storages/key_value_storages/in_memory.py +2 -2
- camel/storages/key_value_storages/json.py +17 -4
- camel/storages/key_value_storages/mem0_cloud.py +50 -49
- camel/storages/key_value_storages/redis.py +2 -2
- camel/storages/object_storages/__init__.py +2 -2
- camel/storages/object_storages/amazon_s3.py +2 -2
- camel/storages/object_storages/azure_blob.py +2 -2
- camel/storages/object_storages/base.py +2 -2
- camel/storages/object_storages/google_cloud.py +3 -3
- camel/storages/vectordb_storages/__init__.py +12 -2
- camel/storages/vectordb_storages/base.py +2 -2
- camel/storages/vectordb_storages/chroma.py +731 -0
- camel/storages/vectordb_storages/faiss.py +712 -0
- camel/storages/vectordb_storages/milvus.py +2 -2
- camel/storages/vectordb_storages/oceanbase.py +16 -17
- camel/storages/vectordb_storages/pgvector.py +349 -0
- camel/storages/vectordb_storages/qdrant.py +6 -6
- camel/storages/vectordb_storages/surreal.py +372 -0
- camel/storages/vectordb_storages/tidb.py +11 -8
- camel/storages/vectordb_storages/weaviate.py +714 -0
- camel/tasks/__init__.py +2 -2
- camel/tasks/task.py +366 -27
- camel/tasks/task_prompt.py +3 -3
- camel/terminators/__init__.py +2 -2
- camel/terminators/base.py +2 -2
- camel/terminators/response_terminator.py +2 -2
- camel/terminators/token_limit_terminator.py +2 -2
- camel/toolkits/__init__.py +58 -10
- camel/toolkits/aci_toolkit.py +66 -21
- camel/toolkits/arxiv_toolkit.py +8 -8
- camel/toolkits/ask_news_toolkit.py +2 -2
- camel/toolkits/async_browser_toolkit.py +174 -575
- camel/toolkits/audio_analysis_toolkit.py +3 -3
- camel/toolkits/base.py +65 -7
- camel/toolkits/bohrium_toolkit.py +318 -0
- camel/toolkits/browser_toolkit.py +306 -566
- camel/toolkits/browser_toolkit_commons.py +568 -0
- camel/toolkits/code_execution.py +67 -11
- camel/toolkits/context_summarizer_toolkit.py +684 -0
- camel/toolkits/craw4ai_toolkit.py +93 -0
- camel/toolkits/dappier_toolkit.py +12 -8
- camel/toolkits/data_commons_toolkit.py +2 -2
- camel/toolkits/dingtalk.py +1135 -0
- camel/toolkits/earth_science_toolkit.py +5367 -0
- camel/toolkits/edgeone_pages_mcp_toolkit.py +49 -0
- camel/toolkits/excel_toolkit.py +910 -70
- camel/toolkits/file_toolkit.py +1402 -0
- camel/toolkits/function_tool.py +128 -20
- camel/toolkits/github_toolkit.py +148 -43
- camel/toolkits/gmail_toolkit.py +1839 -0
- camel/toolkits/google_calendar_toolkit.py +40 -6
- camel/toolkits/google_drive_mcp_toolkit.py +54 -0
- camel/toolkits/google_maps_toolkit.py +2 -2
- camel/toolkits/google_scholar_toolkit.py +2 -2
- camel/toolkits/human_toolkit.py +36 -12
- camel/toolkits/hybrid_browser_toolkit/__init__.py +18 -0
- camel/toolkits/hybrid_browser_toolkit/config_loader.py +185 -0
- camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit.py +246 -0
- camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit_ts.py +1973 -0
- camel/toolkits/hybrid_browser_toolkit/installer.py +203 -0
- camel/toolkits/hybrid_browser_toolkit/ts/package-lock.json +4589 -0
- camel/toolkits/hybrid_browser_toolkit/ts/package.json +33 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/browser-scripts.js +125 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/browser-session.ts +1929 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/config-loader.ts +233 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/hybrid-browser-toolkit.ts +589 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/index.ts +7 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/parent-child-filter.ts +226 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/snapshot-parser.ts +219 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/som-screenshot-injected.ts +543 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/types.ts +129 -0
- camel/toolkits/hybrid_browser_toolkit/ts/tsconfig.json +27 -0
- camel/toolkits/hybrid_browser_toolkit/ts/websocket-server.js +319 -0
- camel/toolkits/hybrid_browser_toolkit/ws_wrapper.py +1037 -0
- camel/toolkits/hybrid_browser_toolkit_py/__init__.py +17 -0
- camel/toolkits/hybrid_browser_toolkit_py/actions.py +575 -0
- camel/toolkits/hybrid_browser_toolkit_py/agent.py +311 -0
- camel/toolkits/hybrid_browser_toolkit_py/browser_session.py +787 -0
- camel/toolkits/hybrid_browser_toolkit_py/config_loader.py +490 -0
- camel/toolkits/hybrid_browser_toolkit_py/hybrid_browser_toolkit.py +2390 -0
- camel/toolkits/hybrid_browser_toolkit_py/snapshot.py +233 -0
- camel/toolkits/hybrid_browser_toolkit_py/stealth_script.js +0 -0
- camel/toolkits/hybrid_browser_toolkit_py/unified_analyzer.js +1043 -0
- camel/toolkits/image_analysis_toolkit.py +3 -3
- camel/toolkits/image_generation_toolkit.py +390 -0
- camel/toolkits/jina_reranker_toolkit.py +195 -79
- camel/toolkits/klavis_toolkit.py +7 -3
- camel/toolkits/linkedin_toolkit.py +2 -2
- camel/toolkits/markitdown_toolkit.py +104 -0
- camel/toolkits/math_toolkit.py +66 -12
- camel/toolkits/mcp_toolkit.py +841 -600
- camel/toolkits/memory_toolkit.py +7 -3
- camel/toolkits/meshy_toolkit.py +2 -2
- camel/toolkits/message_agent_toolkit.py +608 -0
- camel/toolkits/message_integration.py +724 -0
- camel/toolkits/mineru_toolkit.py +2 -2
- camel/toolkits/minimax_mcp_toolkit.py +195 -0
- camel/toolkits/networkx_toolkit.py +2 -2
- camel/toolkits/note_taking_toolkit.py +277 -0
- camel/toolkits/notion_mcp_toolkit.py +224 -0
- camel/toolkits/notion_toolkit.py +2 -2
- camel/toolkits/open_api_specs/biztoc/__init__.py +2 -2
- camel/toolkits/open_api_specs/biztoc/ai-plugin.json +1 -1
- camel/toolkits/open_api_specs/coursera/__init__.py +2 -2
- camel/toolkits/open_api_specs/create_qr_code/__init__.py +2 -2
- camel/toolkits/open_api_specs/klarna/__init__.py +2 -2
- camel/toolkits/open_api_specs/nasa_apod/__init__.py +2 -2
- camel/toolkits/open_api_specs/outschool/__init__.py +2 -2
- camel/toolkits/open_api_specs/outschool/ai-plugin.json +1 -1
- camel/toolkits/open_api_specs/outschool/openapi.yaml +1 -1
- camel/toolkits/open_api_specs/outschool/paths/__init__.py +2 -2
- camel/toolkits/open_api_specs/outschool/paths/get_classes.py +2 -2
- camel/toolkits/open_api_specs/outschool/paths/search_teachers.py +2 -2
- camel/toolkits/open_api_specs/security_config.py +2 -2
- camel/toolkits/open_api_specs/speak/__init__.py +2 -2
- camel/toolkits/open_api_specs/web_scraper/__init__.py +2 -2
- camel/toolkits/open_api_specs/web_scraper/ai-plugin.json +1 -1
- camel/toolkits/open_api_specs/web_scraper/paths/__init__.py +2 -2
- camel/toolkits/open_api_specs/web_scraper/paths/scraper.py +2 -2
- camel/toolkits/open_api_toolkit.py +2 -2
- camel/toolkits/openbb_toolkit.py +7 -3
- camel/toolkits/origene_mcp_toolkit.py +56 -0
- camel/toolkits/page_script.js +86 -74
- camel/toolkits/playwright_mcp_toolkit.py +27 -32
- camel/toolkits/pptx_toolkit.py +790 -0
- camel/toolkits/pubmed_toolkit.py +2 -2
- camel/toolkits/pulse_mcp_search_toolkit.py +2 -2
- camel/toolkits/pyautogui_toolkit.py +2 -2
- camel/toolkits/reddit_toolkit.py +2 -2
- camel/toolkits/resend_toolkit.py +168 -0
- camel/toolkits/retrieval_toolkit.py +2 -2
- camel/toolkits/screenshot_toolkit.py +213 -0
- camel/toolkits/search_toolkit.py +539 -146
- camel/toolkits/searxng_toolkit.py +2 -2
- camel/toolkits/semantic_scholar_toolkit.py +2 -2
- camel/toolkits/slack_toolkit.py +108 -58
- camel/toolkits/sql_toolkit.py +712 -0
- camel/toolkits/stripe_toolkit.py +2 -2
- camel/toolkits/sympy_toolkit.py +3 -3
- camel/toolkits/task_planning_toolkit.py +134 -0
- camel/toolkits/terminal_toolkit/__init__.py +18 -0
- camel/toolkits/terminal_toolkit/terminal_toolkit.py +1070 -0
- camel/toolkits/terminal_toolkit/utils.py +532 -0
- camel/toolkits/thinking_toolkit.py +3 -3
- camel/toolkits/twitter_toolkit.py +8 -3
- camel/toolkits/vertex_ai_veo_toolkit.py +590 -0
- camel/toolkits/video_analysis_toolkit.py +112 -29
- camel/toolkits/video_download_toolkit.py +22 -16
- camel/toolkits/weather_toolkit.py +2 -2
- camel/toolkits/web_deploy_toolkit.py +1219 -0
- camel/toolkits/wechat_official_toolkit.py +483 -0
- camel/toolkits/whatsapp_toolkit.py +2 -2
- camel/toolkits/wolfram_alpha_toolkit.py +53 -25
- camel/toolkits/zapier_toolkit.py +7 -3
- camel/types/__init__.py +4 -4
- camel/types/agents/__init__.py +2 -2
- camel/types/agents/tool_calling_record.py +6 -3
- camel/types/enums.py +454 -35
- camel/types/mcp_registries.py +2 -2
- camel/types/openai_types.py +4 -4
- camel/types/unified_model_type.py +43 -6
- camel/utils/__init__.py +20 -2
- camel/utils/async_func.py +2 -2
- camel/utils/chunker/__init__.py +2 -2
- camel/utils/chunker/base.py +2 -2
- camel/utils/chunker/code_chunker.py +2 -2
- camel/utils/chunker/uio_chunker.py +2 -2
- camel/utils/commons.py +65 -7
- camel/utils/constants.py +5 -2
- camel/utils/context_utils.py +1134 -0
- camel/utils/deduplication.py +2 -2
- camel/utils/filename.py +2 -2
- camel/utils/langfuse.py +258 -0
- camel/utils/mcp.py +140 -6
- camel/utils/mcp_client.py +1056 -0
- camel/utils/message_summarizer.py +148 -0
- camel/utils/response_format.py +2 -2
- camel/utils/token_counting.py +45 -22
- camel/utils/tool_result.py +44 -0
- camel/verifiers/__init__.py +2 -2
- camel/verifiers/base.py +2 -2
- camel/verifiers/math_verifier.py +2 -2
- camel/verifiers/models.py +2 -2
- camel/verifiers/physics_verifier.py +2 -2
- camel/verifiers/python_verifier.py +2 -2
- {camel_ai-0.2.59.dist-info → camel_ai-0.2.82.dist-info}/METADATA +349 -108
- camel_ai-0.2.82.dist-info/RECORD +507 -0
- {camel_ai-0.2.59.dist-info → camel_ai-0.2.82.dist-info}/WHEEL +1 -1
- {camel_ai-0.2.59.dist-info → camel_ai-0.2.82.dist-info}/licenses/LICENSE +1 -1
- camel/loaders/pandas_reader.py +0 -368
- camel/runtime/api.py +0 -97
- camel/toolkits/dalle_toolkit.py +0 -171
- camel/toolkits/file_write_toolkit.py +0 -395
- camel/toolkits/openai_agent_toolkit.py +0 -135
- camel/toolkits/terminal_toolkit.py +0 -1037
- camel_ai-0.2.59.dist-info/RECORD +0 -410
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
# ========= Copyright 2023-2025 @ CAMEL-AI.org. All Rights Reserved. =========
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
# ========= Copyright 2023-2025 @ CAMEL-AI.org. All Rights Reserved. =========
|
|
14
|
+
import json
|
|
15
|
+
import re
|
|
16
|
+
from typing import Any, ClassVar, Dict, List, Optional, Type, Union
|
|
17
|
+
|
|
18
|
+
from pydantic import BaseModel, ValidationError
|
|
19
|
+
|
|
20
|
+
from camel.logger import get_logger
|
|
21
|
+
from camel.societies.workforce.utils import (
|
|
22
|
+
RecoveryStrategy,
|
|
23
|
+
TaskAnalysisResult,
|
|
24
|
+
TaskAssignResult,
|
|
25
|
+
WorkerConf,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
logger = get_logger(__name__)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class StructuredOutputHandler:
|
|
32
|
+
r"""Handler for generating prompts and extracting structured output from
|
|
33
|
+
agent responses.
|
|
34
|
+
|
|
35
|
+
This handler provides functionality to:
|
|
36
|
+
- Generate prompts that guide agents to produce structured output
|
|
37
|
+
- Extract structured data from agent responses using regex patterns
|
|
38
|
+
- Provide fallback mechanisms when extraction fails
|
|
39
|
+
- Support the existing structured output schemas used in workforce.py
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
# Common JSON extraction patterns
|
|
43
|
+
JSON_PATTERNS: ClassVar[List[str]] = [
|
|
44
|
+
# Pattern 1: Standard JSON block
|
|
45
|
+
r'```json\s*\n(.*?)\n```',
|
|
46
|
+
# Pattern 2: JSON without code block
|
|
47
|
+
r'(\{[^{}]*(?:\{[^{}]*\}[^{}]*)*\})',
|
|
48
|
+
# Pattern 3: JSON with potential nested objects
|
|
49
|
+
r'(\{(?:[^{}]|(?:\{[^{}]*\}))*\})',
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
# Schema-specific patterns for more targeted extraction
|
|
53
|
+
SCHEMA_PATTERNS: ClassVar[Dict[str, List[str]]] = {
|
|
54
|
+
'TaskAssignResult': [
|
|
55
|
+
r'"assignments"\s*:\s*\[(.*?)\]',
|
|
56
|
+
r'assignments.*?:\s*\[(.*?)\]',
|
|
57
|
+
],
|
|
58
|
+
'WorkerConf': [
|
|
59
|
+
(
|
|
60
|
+
r'"role"\s*:\s*"([^"]+)".*?"sys_msg"\s*:\s*"([^"]+)".*?'
|
|
61
|
+
r'"description"\s*:\s*"([^"]+)"'
|
|
62
|
+
),
|
|
63
|
+
(
|
|
64
|
+
r'role.*?:\s*"([^"]+)".*?sys_msg.*?:\s*"([^"]+)".*?'
|
|
65
|
+
r'description.*?:\s*"([^"]+)"'
|
|
66
|
+
),
|
|
67
|
+
],
|
|
68
|
+
'TaskAnalysisResult': [
|
|
69
|
+
r'"recovery_strategy"\s*:\s*"([^"]+)".*?"reasoning"\s*:\s*"([^"]+)"',
|
|
70
|
+
r'recovery_strategy.*?:\s*"([^"]+)".*?reasoning.*?:\s*"([^"]+)"',
|
|
71
|
+
],
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@staticmethod
|
|
75
|
+
def generate_structured_prompt(
|
|
76
|
+
base_prompt: str,
|
|
77
|
+
schema: Type[BaseModel],
|
|
78
|
+
examples: Optional[List[Dict[str, Any]]] = None,
|
|
79
|
+
additional_instructions: Optional[str] = None,
|
|
80
|
+
) -> str:
|
|
81
|
+
r"""Generate a prompt that guides agents to produce structured output.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
base_prompt (str): The base prompt content.
|
|
85
|
+
schema (Type[BaseModel]): The Pydantic model schema for the
|
|
86
|
+
expected output.
|
|
87
|
+
examples (Optional[List[Dict[str, Any]]]): Optional examples of
|
|
88
|
+
valid output.
|
|
89
|
+
additional_instructions (Optional[str]): Additional instructions
|
|
90
|
+
for output formatting.
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
str: The enhanced prompt with structured output instructions.
|
|
94
|
+
"""
|
|
95
|
+
# Get schema information
|
|
96
|
+
schema_name = schema.__name__
|
|
97
|
+
schema_json = schema.model_json_schema()
|
|
98
|
+
required_fields = schema_json.get('required', [])
|
|
99
|
+
properties = schema_json.get('properties', {})
|
|
100
|
+
|
|
101
|
+
# Build field descriptions
|
|
102
|
+
field_descriptions = []
|
|
103
|
+
for field_name, field_info in properties.items():
|
|
104
|
+
description = field_info.get('description', 'No description')
|
|
105
|
+
field_type = field_info.get('type', 'unknown')
|
|
106
|
+
required = field_name in required_fields
|
|
107
|
+
field_descriptions.append(
|
|
108
|
+
f"- {field_name} ({field_type}{'*' if required else ''}): "
|
|
109
|
+
f"{description}"
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# Build structured output section
|
|
113
|
+
structured_section = f"""
|
|
114
|
+
**STRUCTURED OUTPUT REQUIREMENTS:**
|
|
115
|
+
|
|
116
|
+
You must return a valid JSON object that conforms to the {schema_name} schema.
|
|
117
|
+
|
|
118
|
+
Required fields:
|
|
119
|
+
{chr(10).join(field_descriptions)}
|
|
120
|
+
|
|
121
|
+
Fields marked with * are required and must be present in your response.
|
|
122
|
+
|
|
123
|
+
**FORMAT YOUR RESPONSE AS:**
|
|
124
|
+
```json
|
|
125
|
+
{{
|
|
126
|
+
// Your JSON response here following the schema
|
|
127
|
+
}}
|
|
128
|
+
```
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
# Add examples if provided
|
|
132
|
+
if examples:
|
|
133
|
+
examples_section = "\n**VALID EXAMPLES:**\n"
|
|
134
|
+
for i, example in enumerate(examples, 1):
|
|
135
|
+
examples_section += f"\nExample {i}:\n```json\n"
|
|
136
|
+
examples_section += json.dumps(example, indent=2)
|
|
137
|
+
examples_section += "\n```\n"
|
|
138
|
+
structured_section += examples_section
|
|
139
|
+
|
|
140
|
+
# Add additional instructions if provided
|
|
141
|
+
if additional_instructions:
|
|
142
|
+
structured_section += "\n**ADDITIONAL INSTRUCTIONS:**\n"
|
|
143
|
+
structured_section += additional_instructions + "\n"
|
|
144
|
+
|
|
145
|
+
# Add critical reminder
|
|
146
|
+
structured_section += """
|
|
147
|
+
**CRITICAL**: Your response must contain ONLY the JSON object within the code
|
|
148
|
+
block.
|
|
149
|
+
Do not include any explanatory text, comments, or content outside the JSON
|
|
150
|
+
structure.
|
|
151
|
+
Ensure the JSON is valid and properly formatted.
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
# Combine with base prompt
|
|
155
|
+
return base_prompt + "\n\n" + structured_section
|
|
156
|
+
|
|
157
|
+
@staticmethod
|
|
158
|
+
def extract_json(
|
|
159
|
+
text: str,
|
|
160
|
+
schema: Optional[Type[BaseModel]] = None,
|
|
161
|
+
) -> Optional[Dict[str, Any]]:
|
|
162
|
+
r"""Extract JSON data from text using multiple patterns.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
text (str): The text containing JSON data.
|
|
166
|
+
schema (Optional[Type[BaseModel]]): Optional schema for targeted
|
|
167
|
+
extraction.
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
Optional[Dict[str, Any]]: Extracted JSON data or None if extraction
|
|
171
|
+
fails.
|
|
172
|
+
"""
|
|
173
|
+
if not text:
|
|
174
|
+
return None
|
|
175
|
+
|
|
176
|
+
# Try standard JSON patterns first
|
|
177
|
+
for pattern in StructuredOutputHandler.JSON_PATTERNS:
|
|
178
|
+
matches = re.findall(pattern, text, re.DOTALL | re.IGNORECASE)
|
|
179
|
+
for match in matches:
|
|
180
|
+
try:
|
|
181
|
+
# Clean up the match
|
|
182
|
+
json_str = match.strip()
|
|
183
|
+
# Remove any trailing commas
|
|
184
|
+
json_str = re.sub(r',\s*}', '}', json_str)
|
|
185
|
+
json_str = re.sub(r',\s*]', ']', json_str)
|
|
186
|
+
|
|
187
|
+
data = json.loads(json_str)
|
|
188
|
+
if isinstance(data, dict):
|
|
189
|
+
return data
|
|
190
|
+
except json.JSONDecodeError:
|
|
191
|
+
continue
|
|
192
|
+
|
|
193
|
+
# Try direct JSON parsing of the entire text
|
|
194
|
+
try:
|
|
195
|
+
data = json.loads(text.strip())
|
|
196
|
+
if isinstance(data, dict):
|
|
197
|
+
return data
|
|
198
|
+
except json.JSONDecodeError:
|
|
199
|
+
pass
|
|
200
|
+
|
|
201
|
+
# Try schema-specific patterns if schema is provided
|
|
202
|
+
if (
|
|
203
|
+
schema
|
|
204
|
+
and schema.__name__ in StructuredOutputHandler.SCHEMA_PATTERNS
|
|
205
|
+
):
|
|
206
|
+
return StructuredOutputHandler._extract_with_schema_patterns(
|
|
207
|
+
text, schema
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
return None
|
|
211
|
+
|
|
212
|
+
@staticmethod
|
|
213
|
+
def _extract_with_schema_patterns(
|
|
214
|
+
text: str,
|
|
215
|
+
schema: Type[BaseModel],
|
|
216
|
+
) -> Optional[Dict[str, Any]]:
|
|
217
|
+
r"""Extract data using schema-specific patterns.
|
|
218
|
+
|
|
219
|
+
Args:
|
|
220
|
+
text (str): The text to extract from.
|
|
221
|
+
schema (Type[BaseModel]): The schema to use for extraction.
|
|
222
|
+
|
|
223
|
+
Returns:
|
|
224
|
+
Optional[Dict[str, Any]]: Extracted data or None.
|
|
225
|
+
"""
|
|
226
|
+
schema_name = schema.__name__
|
|
227
|
+
patterns = StructuredOutputHandler.SCHEMA_PATTERNS.get(schema_name, [])
|
|
228
|
+
|
|
229
|
+
if schema_name == 'WorkerConf':
|
|
230
|
+
for pattern in patterns:
|
|
231
|
+
match = re.search(pattern, text, re.DOTALL | re.IGNORECASE)
|
|
232
|
+
if match:
|
|
233
|
+
try:
|
|
234
|
+
return {
|
|
235
|
+
'role': match.group(1),
|
|
236
|
+
'sys_msg': match.group(2),
|
|
237
|
+
'description': match.group(3),
|
|
238
|
+
}
|
|
239
|
+
except (IndexError, AttributeError):
|
|
240
|
+
continue
|
|
241
|
+
|
|
242
|
+
elif schema_name == 'TaskAnalysisResult':
|
|
243
|
+
for pattern in patterns:
|
|
244
|
+
match = re.search(pattern, text, re.DOTALL | re.IGNORECASE)
|
|
245
|
+
if match:
|
|
246
|
+
try:
|
|
247
|
+
recovery_strategy = match.group(1)
|
|
248
|
+
reasoning = match.group(2)
|
|
249
|
+
# Look for modified_task_content
|
|
250
|
+
content_match = re.search(
|
|
251
|
+
r'"modified_task_content"\s*:\s*"([^"]*)"',
|
|
252
|
+
text,
|
|
253
|
+
re.IGNORECASE,
|
|
254
|
+
)
|
|
255
|
+
# Look for quality_score (for quality evaluation)
|
|
256
|
+
score_match = re.search(
|
|
257
|
+
r'"quality_score"\s*:\s*(\d+)',
|
|
258
|
+
text,
|
|
259
|
+
re.IGNORECASE,
|
|
260
|
+
)
|
|
261
|
+
return {
|
|
262
|
+
'recovery_strategy': recovery_strategy,
|
|
263
|
+
'reasoning': reasoning,
|
|
264
|
+
'modified_task_content': (
|
|
265
|
+
content_match.group(1)
|
|
266
|
+
if content_match
|
|
267
|
+
else None
|
|
268
|
+
),
|
|
269
|
+
'quality_score': (
|
|
270
|
+
int(score_match.group(1))
|
|
271
|
+
if score_match
|
|
272
|
+
else None
|
|
273
|
+
),
|
|
274
|
+
}
|
|
275
|
+
except (IndexError, AttributeError):
|
|
276
|
+
continue
|
|
277
|
+
|
|
278
|
+
return None
|
|
279
|
+
|
|
280
|
+
@staticmethod
|
|
281
|
+
def parse_structured_response(
|
|
282
|
+
response_text: str,
|
|
283
|
+
schema: Type[BaseModel],
|
|
284
|
+
fallback_values: Optional[Dict[str, Any]] = None,
|
|
285
|
+
) -> Union[BaseModel, Dict[str, Any]]:
|
|
286
|
+
r"""Parse agent response into structured data with fallback support.
|
|
287
|
+
|
|
288
|
+
Args:
|
|
289
|
+
response_text (str): The agent's response text.
|
|
290
|
+
schema (Type[BaseModel]): The expected schema.
|
|
291
|
+
fallback_values (Optional[Dict[str, Any]]): Fallback values to use
|
|
292
|
+
if parsing fails.
|
|
293
|
+
|
|
294
|
+
Returns:
|
|
295
|
+
Union[BaseModel, Dict[str, Any]]: Parsed data as schema instance
|
|
296
|
+
or fallback dictionary.
|
|
297
|
+
"""
|
|
298
|
+
# Try to extract JSON
|
|
299
|
+
extracted_data = StructuredOutputHandler.extract_json(
|
|
300
|
+
response_text, schema
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
if extracted_data:
|
|
304
|
+
try:
|
|
305
|
+
# Validate against schema
|
|
306
|
+
return schema(**extracted_data)
|
|
307
|
+
except ValidationError as e:
|
|
308
|
+
logger.warning(
|
|
309
|
+
f"Validation error for {schema.__name__}: {e}. "
|
|
310
|
+
f"Attempting to fix common issues."
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
# Try to fix common validation issues
|
|
314
|
+
fixed_data = StructuredOutputHandler._fix_common_issues(
|
|
315
|
+
extracted_data, schema
|
|
316
|
+
)
|
|
317
|
+
if fixed_data:
|
|
318
|
+
try:
|
|
319
|
+
return schema(**fixed_data)
|
|
320
|
+
except ValidationError:
|
|
321
|
+
pass
|
|
322
|
+
|
|
323
|
+
# Use fallback values if provided
|
|
324
|
+
if fallback_values:
|
|
325
|
+
logger.warning(
|
|
326
|
+
f"Failed to parse {schema.__name__} from response. "
|
|
327
|
+
f"Using fallback values."
|
|
328
|
+
)
|
|
329
|
+
try:
|
|
330
|
+
return schema(**fallback_values)
|
|
331
|
+
except ValidationError:
|
|
332
|
+
return fallback_values
|
|
333
|
+
|
|
334
|
+
# Return default instance if possible
|
|
335
|
+
try:
|
|
336
|
+
logger.warning(f"Creating default {schema.__name__} instance.")
|
|
337
|
+
return StructuredOutputHandler._create_default_instance(schema)
|
|
338
|
+
except Exception:
|
|
339
|
+
logger.error(
|
|
340
|
+
f"Failed to create default instance for {schema.__name__}"
|
|
341
|
+
)
|
|
342
|
+
return {}
|
|
343
|
+
|
|
344
|
+
@staticmethod
|
|
345
|
+
def _fix_common_issues(
|
|
346
|
+
data: Dict[str, Any],
|
|
347
|
+
schema: Type[BaseModel],
|
|
348
|
+
) -> Optional[Dict[str, Any]]:
|
|
349
|
+
r"""Attempt to fix common validation issues in extracted data.
|
|
350
|
+
|
|
351
|
+
Args:
|
|
352
|
+
data (Dict[str, Any]): The extracted data.
|
|
353
|
+
schema (Type[BaseModel]): The target schema.
|
|
354
|
+
|
|
355
|
+
Returns:
|
|
356
|
+
Optional[Dict[str, Any]]: Fixed data or None if unfixable.
|
|
357
|
+
"""
|
|
358
|
+
fixed_data = data.copy()
|
|
359
|
+
schema_name = schema.__name__
|
|
360
|
+
|
|
361
|
+
if schema_name == 'TaskAssignResult':
|
|
362
|
+
# Ensure assignments is a list
|
|
363
|
+
if 'assignments' not in fixed_data:
|
|
364
|
+
fixed_data['assignments'] = []
|
|
365
|
+
elif not isinstance(fixed_data['assignments'], list):
|
|
366
|
+
fixed_data['assignments'] = [fixed_data['assignments']]
|
|
367
|
+
|
|
368
|
+
# Fix each assignment
|
|
369
|
+
for _i, assignment in enumerate(fixed_data['assignments']):
|
|
370
|
+
if isinstance(assignment, dict):
|
|
371
|
+
# Ensure dependencies is a list
|
|
372
|
+
if 'dependencies' not in assignment:
|
|
373
|
+
assignment['dependencies'] = []
|
|
374
|
+
elif isinstance(assignment['dependencies'], str):
|
|
375
|
+
# Handle comma-separated string
|
|
376
|
+
deps = assignment['dependencies'].strip()
|
|
377
|
+
if deps:
|
|
378
|
+
assignment['dependencies'] = [
|
|
379
|
+
d.strip() for d in deps.split(',')
|
|
380
|
+
]
|
|
381
|
+
else:
|
|
382
|
+
assignment['dependencies'] = []
|
|
383
|
+
|
|
384
|
+
elif schema_name == 'TaskAnalysisResult':
|
|
385
|
+
# Ensure recovery_strategy is valid
|
|
386
|
+
if 'recovery_strategy' in fixed_data:
|
|
387
|
+
strategy = fixed_data['recovery_strategy'].lower()
|
|
388
|
+
valid_strategies = [
|
|
389
|
+
'retry',
|
|
390
|
+
'replan',
|
|
391
|
+
'decompose',
|
|
392
|
+
'create_worker',
|
|
393
|
+
'reassign',
|
|
394
|
+
]
|
|
395
|
+
if strategy not in valid_strategies:
|
|
396
|
+
# Try to match partial
|
|
397
|
+
for valid in valid_strategies:
|
|
398
|
+
if valid.startswith(strategy) or strategy in valid:
|
|
399
|
+
fixed_data['recovery_strategy'] = valid
|
|
400
|
+
break
|
|
401
|
+
|
|
402
|
+
return fixed_data
|
|
403
|
+
|
|
404
|
+
@staticmethod
|
|
405
|
+
def _create_default_instance(schema: Type[BaseModel]) -> BaseModel:
|
|
406
|
+
r"""Create a default instance of the schema with minimal required
|
|
407
|
+
fields.
|
|
408
|
+
|
|
409
|
+
Args:
|
|
410
|
+
schema (Type[BaseModel]): The schema to instantiate.
|
|
411
|
+
|
|
412
|
+
Returns:
|
|
413
|
+
BaseModel: Default instance of the schema.
|
|
414
|
+
"""
|
|
415
|
+
schema_name = schema.__name__
|
|
416
|
+
|
|
417
|
+
if schema_name == 'TaskAssignResult':
|
|
418
|
+
return TaskAssignResult(assignments=[])
|
|
419
|
+
elif schema_name == 'WorkerConf':
|
|
420
|
+
return WorkerConf(
|
|
421
|
+
role="General Assistant",
|
|
422
|
+
sys_msg="You are a helpful assistant.",
|
|
423
|
+
description="A general-purpose worker",
|
|
424
|
+
)
|
|
425
|
+
elif schema_name == 'TaskAnalysisResult':
|
|
426
|
+
return TaskAnalysisResult(
|
|
427
|
+
reasoning="Unable to parse response, defaulting to retry",
|
|
428
|
+
recovery_strategy=RecoveryStrategy.RETRY,
|
|
429
|
+
modified_task_content=None,
|
|
430
|
+
)
|
|
431
|
+
else:
|
|
432
|
+
# Try to create with empty dict and let defaults handle it
|
|
433
|
+
return schema()
|
|
434
|
+
|
|
435
|
+
@staticmethod
|
|
436
|
+
def validate_response(
|
|
437
|
+
response: Union[BaseModel, Dict[str, Any]],
|
|
438
|
+
schema: Type[BaseModel],
|
|
439
|
+
) -> bool:
|
|
440
|
+
r"""Validate that a response conforms to the expected schema.
|
|
441
|
+
|
|
442
|
+
Args:
|
|
443
|
+
response: The response to validate.
|
|
444
|
+
schema (Type[BaseModel]): The expected schema.
|
|
445
|
+
|
|
446
|
+
Returns:
|
|
447
|
+
bool: True if valid, False otherwise.
|
|
448
|
+
"""
|
|
449
|
+
if isinstance(response, schema):
|
|
450
|
+
return True
|
|
451
|
+
|
|
452
|
+
if isinstance(response, dict):
|
|
453
|
+
try:
|
|
454
|
+
schema(**response)
|
|
455
|
+
return True
|
|
456
|
+
except ValidationError:
|
|
457
|
+
return False
|
|
458
|
+
|
|
459
|
+
return False
|
|
460
|
+
|
|
461
|
+
@staticmethod
|
|
462
|
+
def create_fallback_response(
|
|
463
|
+
schema: Type[BaseModel],
|
|
464
|
+
error_message: str,
|
|
465
|
+
context: Optional[Dict[str, Any]] = None,
|
|
466
|
+
) -> BaseModel:
|
|
467
|
+
r"""Create a fallback response for a given schema with error context.
|
|
468
|
+
|
|
469
|
+
Args:
|
|
470
|
+
schema (Type[BaseModel]): The schema to create a response for.
|
|
471
|
+
error_message (str): The error message to include.
|
|
472
|
+
context (Optional[Dict[str, Any]]): Additional context for the
|
|
473
|
+
fallback.
|
|
474
|
+
|
|
475
|
+
Returns:
|
|
476
|
+
BaseModel: A valid instance of the schema with fallback values.
|
|
477
|
+
"""
|
|
478
|
+
schema_name = schema.__name__
|
|
479
|
+
|
|
480
|
+
if schema_name == 'TaskAssignResult':
|
|
481
|
+
# Return empty assignments
|
|
482
|
+
return TaskAssignResult(assignments=[])
|
|
483
|
+
|
|
484
|
+
elif schema_name == 'WorkerConf':
|
|
485
|
+
# Create a generic worker config
|
|
486
|
+
task_content = ""
|
|
487
|
+
if context and 'task_content' in context:
|
|
488
|
+
task_content = context['task_content'][:50]
|
|
489
|
+
|
|
490
|
+
return WorkerConf(
|
|
491
|
+
role="General Assistant",
|
|
492
|
+
sys_msg=f"You are a general assistant. Error during "
|
|
493
|
+
f"configuration: {error_message}",
|
|
494
|
+
description=f"Fallback worker for task: {task_content}...",
|
|
495
|
+
)
|
|
496
|
+
|
|
497
|
+
elif schema_name == 'TaskAnalysisResult':
|
|
498
|
+
# Default to retry strategy
|
|
499
|
+
return TaskAnalysisResult(
|
|
500
|
+
reasoning=f"Fallback decision due to: {error_message}",
|
|
501
|
+
recovery_strategy=RecoveryStrategy.RETRY,
|
|
502
|
+
modified_task_content=None,
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
else:
|
|
506
|
+
# Generic fallback
|
|
507
|
+
try:
|
|
508
|
+
return schema()
|
|
509
|
+
except Exception as e:
|
|
510
|
+
raise ValueError(
|
|
511
|
+
f"Cannot create fallback for unknown schema: {schema_name}"
|
|
512
|
+
) from e
|