swarms 7.8.8__tar.gz → 7.8.9__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.
- {swarms-7.8.8 → swarms-7.8.9}/PKG-INFO +1 -1
- {swarms-7.8.8 → swarms-7.8.9}/pyproject.toml +1 -1
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/agent.py +102 -58
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/conversation.py +6 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/csv_to_agent.py +1 -3
- {swarms-7.8.8 → swarms-7.8.9}/swarms/telemetry/__init__.py +0 -4
- {swarms-7.8.8 → swarms-7.8.9}/swarms/telemetry/main.py +24 -122
- {swarms-7.8.8 → swarms-7.8.9}/swarms/tools/__init__.py +10 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/tools/base_tool.py +9 -5
- swarms-7.8.9/swarms/tools/mcp_client_call.py +1015 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/tools/py_func_to_openai_func_str.py +0 -1
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/auto_download_check_packages.py +4 -3
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/history_output_formatter.py +2 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/output_types.py +1 -1
- swarms-7.8.8/swarms/tools/mcp_client_call.py +0 -507
- {swarms-7.8.8 → swarms-7.8.9}/LICENSE +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/README.md +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/__init__.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/agents/__init__.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/agents/agent_judge.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/agents/agent_print.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/agents/ape_agent.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/agents/auto_generate_swarm_config.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/agents/consistency_agent.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/agents/cort_agent.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/agents/create_agents_from_yaml.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/agents/flexion_agent.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/agents/gkp_agent.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/agents/i_agent.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/agents/openai_assistant.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/agents/react_agent.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/agents/reasoning_agents.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/agents/reasoning_duo.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/agents/self_agent_builder.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/agents/tool_agent.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/artifacts/__init__.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/artifacts/main_artifact.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/cli/__init__.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/cli/create_agent.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/cli/main.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/cli/onboarding_process.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/communication/__init__.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/communication/base_communication.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/communication/duckdb_wrap.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/communication/pulsar_struct.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/communication/redis_wrap.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/communication/sqlite_wrap.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/communication/supabase_wrap.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/__init__.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/accountant_swarm_prompts.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/ag_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/aga.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/agent_conversation_aggregator.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/agent_judge_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/agent_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/agent_prompts.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/agent_self_builder_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/agent_system_prompts.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/ai_research_team.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/aot_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/autobloggen.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/autoswarm.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/chat_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/code_interpreter.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/code_spawner.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/debate.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/documentation.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/education.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/finance_agent_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/finance_agent_sys_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/growth_agent_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/idea2img.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/legal_agent_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/logistics.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/max_loop_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/meta_system_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/multi_agent_collab_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/multi_modal_autonomous_instruction_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/multi_modal_prompts.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/multi_modal_visual_prompts.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/operations_agent_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/paper_idea_agent.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/personal_stylist.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/product_agent_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/programming.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/project_manager.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/prompt_generator.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/prompt_generator_optimizer.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/python.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/react.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/react_base_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/reasoning_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/refiner_agent_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/safety_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/sales.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/sales_prompts.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/security_team.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/self_operating_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/sop_generator_agent_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/summaries_prompts.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/support_agent_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/swarm_manager_agent.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/task_assignment_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/tests.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/tools.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/urban_planning.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/visual_cot.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/worker_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/prompts/xray_swarm_prompt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/schemas/__init__.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/schemas/agent_class_schema.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/schemas/agent_completion_response.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/schemas/agent_mcp_errors.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/schemas/agent_rag_schema.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/schemas/agent_step_schemas.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/schemas/agent_tool_schema.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/schemas/base_schemas.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/schemas/conversation_schema.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/schemas/llm_agent_schema.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/schemas/mcp_schemas.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/schemas/swarms_api_schemas.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/schemas/tool_schema_base_model.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/__init__.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/agent_builder.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/agent_rag_handler.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/agent_registry.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/agent_roles.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/agent_router.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/aop.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/auto_swarm_builder.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/base_structure.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/base_swarm.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/base_workflow.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/batch_agent_execution.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/concat.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/concurrent_workflow.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/council_judge.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/de_hallucination_swarm.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/deep_research_swarm.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/dynamic_conversational_swarm.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/graph_workflow.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/groupchat.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/hiearchical_swarm.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/hybrid_hiearchical_peer_swarm.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/image_batch_processor.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/interactive_groupchat.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/long_agent.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/ma_blocks.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/ma_utils.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/majority_voting.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/malt.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/matrix_swarm.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/meme_agent_persona_generator.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/mixture_of_agents.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/model_router.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/multi_agent_exec.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/multi_agent_router.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/multi_model_gpu_manager.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/omni_agent_types.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/rearrange.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/round_robin.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/safe_loading.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/sequential_workflow.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/spreadsheet_swarm.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/stopping_conditions.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/swarm_arange.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/swarm_eval.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/swarm_id_generator.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/swarm_matcher.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/swarm_registry.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/swarm_router.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/swarming_architectures.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/tree_swarm.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/utils.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/structs/various_alt_swarms.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/telemetry/bootup.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/tools/cohere_func_call_schema.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/tools/create_agent_tool.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/tools/func_calling_utils.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/tools/func_to_str.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/tools/function_util.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/tools/json_former.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/tools/json_utils.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/tools/logits_processor.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/tools/openai_func_calling_schema_pydantic.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/tools/openai_tool_creator_decorator.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/tools/pydantic_to_json.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/tools/tool_parse_exec.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/tools/tool_registry.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/tools/tool_utils.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/__init__.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/any_to_str.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/audio_processing.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/calculate_func_metrics.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/check_all_model_max_tokens.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/data_to_text.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/disable_logging.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/file_processing.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/formatter.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/function_caller_model.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/generate_keys.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/index.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/litellm_tokenizer.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/litellm_wrapper.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/loguru_logger.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/parse_code.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/pdf_to_text.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/str_to_dict.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/try_except_wrapper.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/vllm_wrapper.py +0 -0
- {swarms-7.8.8 → swarms-7.8.9}/swarms/utils/xml_utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: swarms
|
3
|
-
Version: 7.8.
|
3
|
+
Version: 7.8.9
|
4
4
|
Summary: Swarms - TGSC
|
5
5
|
License: MIT
|
6
6
|
Keywords: artificial intelligence,deep learning,optimizers,Prompt Engineering,swarms,agents,llms,transformers,multi-agent,swarms of agents,Enterprise-Grade Agents,Production-Grade Agents,Agents,Multi-Grade-Agents,Swarms,Transformers,LLMs,Prompt Engineering,Agents,Generative Agents,Generative AI,Agent Marketplace,Agent Store,quant,finance,algorithmic trading,portfolio optimization,risk management,financial modeling,machine learning for finance,natural language processing for finance
|
@@ -72,8 +72,10 @@ from swarms.prompts.max_loop_prompt import generate_reasoning_prompt
|
|
72
72
|
from swarms.prompts.safety_prompt import SAFETY_PROMPT
|
73
73
|
from swarms.structs.ma_utils import set_random_models_for_agents
|
74
74
|
from swarms.tools.mcp_client_call import (
|
75
|
+
execute_multiple_tools_on_multiple_mcp_servers_sync,
|
75
76
|
execute_tool_call_simple,
|
76
77
|
get_mcp_tools_sync,
|
78
|
+
get_tools_for_multiple_mcp_servers,
|
77
79
|
)
|
78
80
|
from swarms.schemas.mcp_schemas import (
|
79
81
|
MCPConnection,
|
@@ -81,7 +83,6 @@ from swarms.schemas.mcp_schemas import (
|
|
81
83
|
from swarms.utils.index import (
|
82
84
|
exists,
|
83
85
|
format_data_structure,
|
84
|
-
format_dict_to_string,
|
85
86
|
)
|
86
87
|
from swarms.schemas.conversation_schema import ConversationSchema
|
87
88
|
from swarms.utils.output_types import OutputType
|
@@ -417,7 +418,8 @@ class Agent:
|
|
417
418
|
llm_base_url: Optional[str] = None,
|
418
419
|
llm_api_key: Optional[str] = None,
|
419
420
|
rag_config: Optional[RAGConfig] = None,
|
420
|
-
tool_call_summary: bool =
|
421
|
+
tool_call_summary: bool = True,
|
422
|
+
output_raw_json_from_tool_call: bool = False,
|
421
423
|
*args,
|
422
424
|
**kwargs,
|
423
425
|
):
|
@@ -446,7 +448,10 @@ class Agent:
|
|
446
448
|
self.system_prompt = system_prompt
|
447
449
|
self.agent_name = agent_name
|
448
450
|
self.agent_description = agent_description
|
449
|
-
self.saved_state_path = f"{self.agent_name}_{generate_api_key(prefix='agent-')}_state.json"
|
451
|
+
# self.saved_state_path = f"{self.agent_name}_{generate_api_key(prefix='agent-')}_state.json"
|
452
|
+
self.saved_state_path = (
|
453
|
+
f"{generate_api_key(prefix='agent-')}_state.json"
|
454
|
+
)
|
450
455
|
self.autosave = autosave
|
451
456
|
self.response_filters = []
|
452
457
|
self.self_healing_enabled = self_healing_enabled
|
@@ -550,6 +555,9 @@ class Agent:
|
|
550
555
|
self.llm_api_key = llm_api_key
|
551
556
|
self.rag_config = rag_config
|
552
557
|
self.tool_call_summary = tool_call_summary
|
558
|
+
self.output_raw_json_from_tool_call = (
|
559
|
+
output_raw_json_from_tool_call
|
560
|
+
)
|
553
561
|
|
554
562
|
# self.short_memory = self.short_memory_init()
|
555
563
|
|
@@ -623,7 +631,7 @@ class Agent:
|
|
623
631
|
|
624
632
|
self.short_memory.add(
|
625
633
|
role=f"{self.agent_name}",
|
626
|
-
content=
|
634
|
+
content=self.tools_list_dictionary,
|
627
635
|
)
|
628
636
|
|
629
637
|
def short_memory_init(self):
|
@@ -692,6 +700,10 @@ class Agent:
|
|
692
700
|
|
693
701
|
if exists(self.tools) and len(self.tools) >= 2:
|
694
702
|
parallel_tool_calls = True
|
703
|
+
elif exists(self.mcp_url) or exists(self.mcp_urls):
|
704
|
+
parallel_tool_calls = True
|
705
|
+
elif exists(self.mcp_config):
|
706
|
+
parallel_tool_calls = True
|
695
707
|
else:
|
696
708
|
parallel_tool_calls = False
|
697
709
|
|
@@ -714,7 +726,7 @@ class Agent:
|
|
714
726
|
parallel_tool_calls=parallel_tool_calls,
|
715
727
|
)
|
716
728
|
|
717
|
-
elif self.mcp_url
|
729
|
+
elif exists(self.mcp_url) or exists(self.mcp_urls):
|
718
730
|
self.llm = LiteLLM(
|
719
731
|
**common_args,
|
720
732
|
tools_list_dictionary=self.add_mcp_tools_to_memory(),
|
@@ -752,15 +764,27 @@ class Agent:
|
|
752
764
|
tools = get_mcp_tools_sync(server_path=self.mcp_url)
|
753
765
|
elif exists(self.mcp_config):
|
754
766
|
tools = get_mcp_tools_sync(connection=self.mcp_config)
|
755
|
-
logger.info(f"Tools: {tools}")
|
767
|
+
# logger.info(f"Tools: {tools}")
|
768
|
+
elif exists(self.mcp_urls):
|
769
|
+
tools = get_tools_for_multiple_mcp_servers(
|
770
|
+
urls=self.mcp_urls,
|
771
|
+
output_type="str",
|
772
|
+
)
|
773
|
+
# print(f"Tools: {tools} for {self.mcp_urls}")
|
756
774
|
else:
|
757
775
|
raise AgentMCPConnectionError(
|
758
776
|
"mcp_url must be either a string URL or MCPConnection object"
|
759
777
|
)
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
778
|
+
|
779
|
+
if (
|
780
|
+
exists(self.mcp_url)
|
781
|
+
or exists(self.mcp_urls)
|
782
|
+
or exists(self.mcp_config)
|
783
|
+
):
|
784
|
+
self.pretty_print(
|
785
|
+
f"✨ [SYSTEM] Successfully integrated {len(tools)} MCP tools into agent: {self.agent_name} | Status: ONLINE | Time: {time.strftime('%H:%M:%S')} ✨",
|
786
|
+
loop_count=0,
|
787
|
+
)
|
764
788
|
|
765
789
|
return tools
|
766
790
|
except AgentMCPConnectionError as e:
|
@@ -939,7 +963,7 @@ class Agent:
|
|
939
963
|
|
940
964
|
self.short_memory.add(role=self.user_name, content=task)
|
941
965
|
|
942
|
-
if self.plan_enabled:
|
966
|
+
if self.plan_enabled or self.planning_prompt is not None:
|
943
967
|
self.plan(task)
|
944
968
|
|
945
969
|
# Set the loop count
|
@@ -1006,55 +1030,51 @@ class Agent:
|
|
1006
1030
|
)
|
1007
1031
|
self.memory_query(task_prompt)
|
1008
1032
|
|
1009
|
-
# # Generate response using LLM
|
1010
|
-
# response_args = (
|
1011
|
-
# (task_prompt, *args)
|
1012
|
-
# if img is None
|
1013
|
-
# else (task_prompt, img, *args)
|
1014
|
-
# )
|
1015
|
-
|
1016
|
-
# # Call the LLM
|
1017
|
-
# response = self.call_llm(
|
1018
|
-
# *response_args, **kwargs
|
1019
|
-
# )
|
1020
|
-
|
1021
1033
|
response = self.call_llm(
|
1022
1034
|
task=task_prompt, img=img, *args, **kwargs
|
1023
1035
|
)
|
1024
1036
|
|
1037
|
+
print(f"Response: {response}")
|
1038
|
+
|
1025
1039
|
if exists(self.tools_list_dictionary):
|
1026
1040
|
if isinstance(response, BaseModel):
|
1027
1041
|
response = response.model_dump()
|
1028
1042
|
|
1029
|
-
#
|
1030
|
-
# if self.mcp_url is None or self.tools is None:
|
1043
|
+
# Parse the response from the agent with the output type
|
1031
1044
|
response = self.parse_llm_output(response)
|
1032
1045
|
|
1033
1046
|
self.short_memory.add(
|
1034
1047
|
role=self.agent_name,
|
1035
|
-
content=
|
1048
|
+
content=response,
|
1036
1049
|
)
|
1037
1050
|
|
1038
1051
|
# Print
|
1039
1052
|
self.pretty_print(response, loop_count)
|
1040
1053
|
|
1041
|
-
#
|
1042
|
-
# self.output_cleaner_op(response)
|
1043
|
-
|
1044
|
-
# Check and execute tools
|
1054
|
+
# Check and execute callable tools
|
1045
1055
|
if exists(self.tools):
|
1046
1056
|
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
)
|
1057
|
+
if (
|
1058
|
+
self.output_raw_json_from_tool_call
|
1059
|
+
is True
|
1060
|
+
):
|
1061
|
+
print(type(response))
|
1062
|
+
response = response
|
1063
|
+
else:
|
1064
|
+
self.execute_tools(
|
1065
|
+
response=response,
|
1066
|
+
loop_count=loop_count,
|
1067
|
+
)
|
1051
1068
|
|
1052
1069
|
# Handle MCP tools
|
1053
|
-
if
|
1054
|
-
self.
|
1070
|
+
if (
|
1071
|
+
exists(self.mcp_url)
|
1072
|
+
or exists(self.mcp_config)
|
1073
|
+
or exists(self.mcp_urls)
|
1055
1074
|
):
|
1056
1075
|
self.mcp_tool_handling(
|
1057
|
-
response,
|
1076
|
+
response=response,
|
1077
|
+
current_loop=loop_count,
|
1058
1078
|
)
|
1059
1079
|
|
1060
1080
|
self.sentiment_and_evaluator(response)
|
@@ -1298,26 +1318,47 @@ class Agent:
|
|
1298
1318
|
|
1299
1319
|
def plan(self, task: str, *args, **kwargs) -> None:
|
1300
1320
|
"""
|
1301
|
-
|
1321
|
+
Create a strategic plan for executing the given task.
|
1322
|
+
|
1323
|
+
This method generates a step-by-step plan by combining the conversation
|
1324
|
+
history, planning prompt, and current task. The plan is then added to
|
1325
|
+
the agent's short-term memory for reference during execution.
|
1302
1326
|
|
1303
1327
|
Args:
|
1304
|
-
task (str): The task to plan
|
1328
|
+
task (str): The task to create a plan for
|
1329
|
+
*args: Additional positional arguments passed to the LLM
|
1330
|
+
**kwargs: Additional keyword arguments passed to the LLM
|
1331
|
+
|
1332
|
+
Returns:
|
1333
|
+
None: The plan is stored in memory rather than returned
|
1334
|
+
|
1335
|
+
Raises:
|
1336
|
+
Exception: If planning fails, the original exception is re-raised
|
1305
1337
|
"""
|
1306
1338
|
try:
|
1307
|
-
|
1308
|
-
|
1309
|
-
planning_prompt = f"{self.planning_prompt} {task}"
|
1310
|
-
plan = self.llm(planning_prompt, *args, **kwargs)
|
1311
|
-
logger.info(f"Plan: {plan}")
|
1339
|
+
# Get the current conversation history
|
1340
|
+
history = self.short_memory.get_str()
|
1312
1341
|
|
1313
|
-
#
|
1314
|
-
|
1315
|
-
|
1342
|
+
# Construct the planning prompt by combining history, planning prompt, and task
|
1343
|
+
planning_prompt = (
|
1344
|
+
f"{history}\n\n{self.planning_prompt}\n\nTask: {task}"
|
1316
1345
|
)
|
1317
1346
|
|
1347
|
+
# Generate the plan using the LLM
|
1348
|
+
plan = self.llm.run(task=planning_prompt, *args, **kwargs)
|
1349
|
+
|
1350
|
+
# Store the generated plan in short-term memory
|
1351
|
+
self.short_memory.add(role=self.agent_name, content=plan)
|
1352
|
+
|
1353
|
+
logger.info(
|
1354
|
+
f"Successfully created plan for task: {task[:50]}..."
|
1355
|
+
)
|
1318
1356
|
return None
|
1357
|
+
|
1319
1358
|
except Exception as error:
|
1320
|
-
logger.error(
|
1359
|
+
logger.error(
|
1360
|
+
f"Failed to create plan for task '{task}': {error}"
|
1361
|
+
)
|
1321
1362
|
raise error
|
1322
1363
|
|
1323
1364
|
async def run_concurrent(self, task: str, *args, **kwargs):
|
@@ -1440,7 +1481,6 @@ class Agent:
|
|
1440
1481
|
raise AgentInitializationError(
|
1441
1482
|
f"Max tokens is set to {self.max_tokens}, but the model '{self.model_name}' only supports {get_max_tokens(self.model_name)} tokens. Please set max tokens to {get_max_tokens(self.model_name)} or less."
|
1442
1483
|
)
|
1443
|
-
|
1444
1484
|
|
1445
1485
|
if self.model_name not in model_list:
|
1446
1486
|
logger.warning(
|
@@ -2664,7 +2704,7 @@ class Agent:
|
|
2664
2704
|
) # Convert other dicts to string
|
2665
2705
|
|
2666
2706
|
elif isinstance(response, BaseModel):
|
2667
|
-
|
2707
|
+
response = response.model_dump()
|
2668
2708
|
|
2669
2709
|
# Handle List[BaseModel] responses
|
2670
2710
|
elif (
|
@@ -2674,14 +2714,9 @@ class Agent:
|
|
2674
2714
|
):
|
2675
2715
|
return [item.model_dump() for item in response]
|
2676
2716
|
|
2677
|
-
|
2678
|
-
out = format_data_structure(response)
|
2679
|
-
else:
|
2680
|
-
out = str(response)
|
2717
|
+
return response
|
2681
2718
|
|
2682
|
-
|
2683
|
-
|
2684
|
-
except Exception as e:
|
2719
|
+
except AgentChatCompletionResponse as e:
|
2685
2720
|
logger.error(f"Error parsing LLM output: {e}")
|
2686
2721
|
raise ValueError(
|
2687
2722
|
f"Failed to parse LLM output: {type(response)}"
|
@@ -2738,6 +2773,15 @@ class Agent:
|
|
2738
2773
|
connection=self.mcp_config,
|
2739
2774
|
)
|
2740
2775
|
)
|
2776
|
+
elif exists(self.mcp_urls):
|
2777
|
+
tool_response = execute_multiple_tools_on_multiple_mcp_servers_sync(
|
2778
|
+
responses=response,
|
2779
|
+
urls=self.mcp_urls,
|
2780
|
+
output_type="json",
|
2781
|
+
)
|
2782
|
+
# tool_response = format_data_structure(tool_response)
|
2783
|
+
|
2784
|
+
print(f"Multiple MCP Tool Response: {tool_response}")
|
2741
2785
|
else:
|
2742
2786
|
raise AgentMCPConnectionError(
|
2743
2787
|
"mcp_url must be either a string URL or MCPConnection object"
|
@@ -2745,7 +2789,7 @@ class Agent:
|
|
2745
2789
|
|
2746
2790
|
# Get the text content from the tool response
|
2747
2791
|
# execute_tool_call_simple returns a string directly, not an object with content attribute
|
2748
|
-
text_content = f"MCP Tool Response: \n{json.dumps(tool_response, indent=2)}"
|
2792
|
+
text_content = f"MCP Tool Response: \n\n {json.dumps(tool_response, indent=2)}"
|
2749
2793
|
|
2750
2794
|
if self.no_print is False:
|
2751
2795
|
formatter.print_panel(
|
@@ -1326,6 +1326,12 @@ class Conversation(BaseStructure):
|
|
1326
1326
|
self.conversation_history[-1]["content"],
|
1327
1327
|
)
|
1328
1328
|
|
1329
|
+
def return_list_final(self):
|
1330
|
+
"""Return the final message as a list."""
|
1331
|
+
return [
|
1332
|
+
self.conversation_history[-1]["content"],
|
1333
|
+
]
|
1334
|
+
|
1329
1335
|
@classmethod
|
1330
1336
|
def list_conversations(
|
1331
1337
|
cls, conversations_dir: Optional[str] = None
|
@@ -104,9 +104,7 @@ class AgentValidator:
|
|
104
104
|
model_name in model["model_name"]
|
105
105
|
for model in model_list
|
106
106
|
):
|
107
|
-
|
108
|
-
model["model_name"] for model in model_list
|
109
|
-
]
|
107
|
+
[model["model_name"] for model in model_list]
|
110
108
|
raise AgentValidationError(
|
111
109
|
"Invalid model name. Must be one of the supported litellm models",
|
112
110
|
"model_name",
|
@@ -4,11 +4,9 @@ from swarms.telemetry.main import (
|
|
4
4
|
get_cpu_info,
|
5
5
|
get_machine_id,
|
6
6
|
get_os_version,
|
7
|
-
get_package_mismatches,
|
8
7
|
get_pip_version,
|
9
8
|
get_python_version,
|
10
9
|
get_ram_info,
|
11
|
-
get_swarms_verison,
|
12
10
|
get_system_info,
|
13
11
|
get_user_device_data,
|
14
12
|
system_info,
|
@@ -21,11 +19,9 @@ __all__ = [
|
|
21
19
|
"generate_unique_identifier",
|
22
20
|
"get_python_version",
|
23
21
|
"get_pip_version",
|
24
|
-
"get_swarms_verison",
|
25
22
|
"get_os_version",
|
26
23
|
"get_cpu_info",
|
27
24
|
"get_ram_info",
|
28
|
-
"get_package_mismatches",
|
29
25
|
"system_info",
|
30
26
|
"get_user_device_data",
|
31
27
|
]
|
@@ -1,24 +1,16 @@
|
|
1
|
-
import
|
2
|
-
|
3
|
-
|
1
|
+
import os
|
4
2
|
import datetime
|
5
3
|
import hashlib
|
6
4
|
import platform
|
7
5
|
import socket
|
8
6
|
import subprocess
|
9
7
|
import uuid
|
10
|
-
from concurrent.futures import ThreadPoolExecutor
|
11
|
-
from functools import lru_cache
|
12
|
-
from threading import Lock
|
13
8
|
from typing import Dict
|
14
9
|
|
15
|
-
import aiohttp
|
16
10
|
import pkg_resources
|
17
11
|
import psutil
|
12
|
+
import requests
|
18
13
|
import toml
|
19
|
-
from requests import Session
|
20
|
-
from requests.adapters import HTTPAdapter
|
21
|
-
from urllib3.util.retry import Retry
|
22
14
|
|
23
15
|
|
24
16
|
# Helper functions
|
@@ -263,134 +255,44 @@ def capture_system_data() -> Dict[str, str]:
|
|
263
255
|
print(f"Failed to capture system data: {e}")
|
264
256
|
|
265
257
|
|
266
|
-
|
267
|
-
|
268
|
-
_session_lock = Lock()
|
269
|
-
_executor = ThreadPoolExecutor(max_workers=10)
|
270
|
-
_aiohttp_session = None
|
271
|
-
|
272
|
-
|
273
|
-
def get_session() -> Session:
|
274
|
-
"""Thread-safe session getter with optimized connection pooling"""
|
275
|
-
global _session
|
276
|
-
if _session is None:
|
277
|
-
with _session_lock:
|
278
|
-
if _session is None: # Double-check pattern
|
279
|
-
_session = Session()
|
280
|
-
adapter = HTTPAdapter(
|
281
|
-
pool_connections=1000, # Increased pool size
|
282
|
-
pool_maxsize=1000, # Increased max size
|
283
|
-
max_retries=Retry(
|
284
|
-
total=3,
|
285
|
-
backoff_factor=0.1,
|
286
|
-
status_forcelist=[500, 502, 503, 504],
|
287
|
-
),
|
288
|
-
pool_block=False, # Non-blocking pool
|
289
|
-
)
|
290
|
-
_session.mount("http://", adapter)
|
291
|
-
_session.mount("https://", adapter)
|
292
|
-
_session.headers.update(
|
293
|
-
{
|
294
|
-
"Content-Type": "application/json",
|
295
|
-
"Authorization": "Bearer sk-33979fd9a4e8e6b670090e4900a33dbe7452a15ccc705745f4eca2a70c88ea24",
|
296
|
-
"Connection": "keep-alive", # Enable keep-alive
|
297
|
-
}
|
298
|
-
)
|
299
|
-
return _session
|
300
|
-
|
301
|
-
|
302
|
-
@lru_cache(maxsize=2048, typed=True)
|
303
|
-
def get_user_device_data_cached():
|
304
|
-
"""Cached version with increased cache size"""
|
305
|
-
return get_user_device_data()
|
306
|
-
|
307
|
-
|
308
|
-
async def get_aiohttp_session():
|
309
|
-
"""Get or create aiohttp session for async requests"""
|
310
|
-
global _aiohttp_session
|
311
|
-
if _aiohttp_session is None or _aiohttp_session.closed:
|
312
|
-
timeout = aiohttp.ClientTimeout(total=10)
|
313
|
-
connector = aiohttp.TCPConnector(
|
314
|
-
limit=1000, # Connection limit
|
315
|
-
ttl_dns_cache=300, # DNS cache TTL
|
316
|
-
use_dns_cache=True, # Enable DNS caching
|
317
|
-
keepalive_timeout=60, # Keep-alive timeout
|
318
|
-
)
|
319
|
-
_aiohttp_session = aiohttp.ClientSession(
|
320
|
-
timeout=timeout,
|
321
|
-
connector=connector,
|
322
|
-
headers={
|
323
|
-
"Content-Type": "application/json",
|
324
|
-
"Authorization": "Bearer sk-33979fd9a4e8e6b670090e4900a33dbe7452a15ccc705745f4eca2a70c88ea24",
|
325
|
-
},
|
326
|
-
)
|
327
|
-
return _aiohttp_session
|
328
|
-
|
329
|
-
|
330
|
-
async def log_agent_data_async(data_dict: dict):
|
331
|
-
"""Asynchronous version of log_agent_data"""
|
258
|
+
def _log_agent_data(data_dict: dict):
|
259
|
+
"""Simple function to log agent data using requests library"""
|
332
260
|
if not data_dict:
|
333
|
-
return
|
261
|
+
return
|
334
262
|
|
335
263
|
url = "https://swarms.world/api/get-agents/log-agents"
|
336
264
|
payload = {
|
337
265
|
"data": data_dict,
|
338
|
-
"system_data":
|
266
|
+
"system_data": get_user_device_data(),
|
339
267
|
"timestamp": datetime.datetime.now(
|
340
268
|
datetime.timezone.utc
|
341
269
|
).isoformat(),
|
342
270
|
}
|
343
271
|
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
return await response.json()
|
349
|
-
except Exception:
|
350
|
-
return None
|
351
|
-
|
352
|
-
|
353
|
-
def _log_agent_data(data_dict: dict):
|
354
|
-
"""
|
355
|
-
Enhanced log_agent_data with both sync and async capabilities
|
356
|
-
"""
|
357
|
-
if not data_dict:
|
358
|
-
return None
|
359
|
-
|
360
|
-
# If running in an event loop, use async version
|
361
|
-
try:
|
362
|
-
loop = asyncio.get_event_loop()
|
363
|
-
if loop.is_running():
|
364
|
-
return asyncio.create_task(
|
365
|
-
log_agent_data_async(data_dict)
|
366
|
-
)
|
367
|
-
except RuntimeError:
|
368
|
-
pass
|
272
|
+
key = (
|
273
|
+
os.getenv("SWARMS_API_KEY")
|
274
|
+
or "Bearer sk-33979fd9a4e8e6b670090e4900a33dbe7452a15ccc705745f4eca2a70c88ea24"
|
275
|
+
)
|
369
276
|
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
"data": data_dict,
|
374
|
-
"system_data": get_user_device_data_cached(),
|
375
|
-
"timestamp": datetime.datetime.now(
|
376
|
-
datetime.timezone.utc
|
377
|
-
).isoformat(),
|
277
|
+
headers = {
|
278
|
+
"Content-Type": "application/json",
|
279
|
+
"Authorization": key,
|
378
280
|
}
|
379
281
|
|
380
282
|
try:
|
381
|
-
|
382
|
-
|
383
|
-
url,
|
384
|
-
json=payload,
|
385
|
-
timeout=10,
|
386
|
-
stream=False, # Disable streaming for faster response
|
283
|
+
response = requests.post(
|
284
|
+
url, json=payload, headers=headers, timeout=10
|
387
285
|
)
|
388
|
-
if response.
|
389
|
-
return
|
286
|
+
if response.status_code == 200:
|
287
|
+
return
|
390
288
|
except Exception:
|
391
|
-
return
|
289
|
+
return
|
290
|
+
|
291
|
+
return
|
392
292
|
|
393
293
|
|
394
294
|
def log_agent_data(data_dict: dict):
|
395
|
-
|
396
|
-
|
295
|
+
try:
|
296
|
+
_log_agent_data(data_dict)
|
297
|
+
except Exception:
|
298
|
+
pass
|
@@ -33,6 +33,11 @@ from swarms.tools.mcp_client_call import (
|
|
33
33
|
get_tools_for_multiple_mcp_servers,
|
34
34
|
get_mcp_tools_sync,
|
35
35
|
aget_mcp_tools,
|
36
|
+
execute_multiple_tools_on_multiple_mcp_servers,
|
37
|
+
execute_multiple_tools_on_multiple_mcp_servers_sync,
|
38
|
+
_create_server_tool_mapping,
|
39
|
+
_create_server_tool_mapping_async,
|
40
|
+
_execute_tool_on_server,
|
36
41
|
)
|
37
42
|
|
38
43
|
|
@@ -62,4 +67,9 @@ __all__ = [
|
|
62
67
|
"get_tools_for_multiple_mcp_servers",
|
63
68
|
"get_mcp_tools_sync",
|
64
69
|
"aget_mcp_tools",
|
70
|
+
"execute_multiple_tools_on_multiple_mcp_servers",
|
71
|
+
"execute_multiple_tools_on_multiple_mcp_servers_sync",
|
72
|
+
"_create_server_tool_mapping",
|
73
|
+
"_create_server_tool_mapping_async",
|
74
|
+
"_execute_tool_on_server",
|
65
75
|
]
|
@@ -2256,14 +2256,18 @@ class BaseTool(BaseModel):
|
|
2256
2256
|
try:
|
2257
2257
|
api_response = json.loads(api_response)
|
2258
2258
|
except json.JSONDecodeError as e:
|
2259
|
-
|
2260
|
-
|
2261
|
-
|
2259
|
+
self._log_if_verbose(
|
2260
|
+
"error",
|
2261
|
+
f"Failed to parse JSON from API response: {e}. Response: '{api_response[:100]}...'"
|
2262
|
+
)
|
2263
|
+
return []
|
2262
2264
|
|
2263
2265
|
if not isinstance(api_response, dict):
|
2264
|
-
|
2265
|
-
"
|
2266
|
+
self._log_if_verbose(
|
2267
|
+
"warning",
|
2268
|
+
f"API response is not a dictionary (type: {type(api_response)}), returning empty list"
|
2266
2269
|
)
|
2270
|
+
return []
|
2267
2271
|
|
2268
2272
|
# Extract function calls from dictionary response
|
2269
2273
|
function_calls = (
|