fast-agent-mcp 0.2.16__tar.gz → 0.2.17__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 fast-agent-mcp might be problematic. Click here for more details.
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/PKG-INFO +4 -6
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/README.md +3 -3
- {fast_agent_mcp-0.2.16/src/mcp_agent/resources → fast_agent_mcp-0.2.17}/examples/data-analysis/analysis-campaign.py +2 -2
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/examples/mcp/state-transfer/fastagent.config.yaml +1 -1
- {fast_agent_mcp-0.2.16/src/mcp_agent/resources → fast_agent_mcp-0.2.17}/examples/researcher/fastagent.config.yaml +1 -6
- {fast_agent_mcp-0.2.16/src/mcp_agent/resources → fast_agent_mcp-0.2.17}/examples/workflows/evaluator.py +1 -1
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/examples/workflows/fastagent.config.yaml +0 -1
- {fast_agent_mcp-0.2.16/src/mcp_agent/resources → fast_agent_mcp-0.2.17}/examples/workflows/orchestrator.py +7 -9
- {fast_agent_mcp-0.2.16/src/mcp_agent/resources → fast_agent_mcp-0.2.17}/examples/workflows/parallel.py +1 -1
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/pyproject.toml +1 -4
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/agents/base_agent.py +50 -6
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/agents/workflow/orchestrator_agent.py +6 -7
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/agents/workflow/router_agent.py +70 -136
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/app.py +1 -124
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/cli/commands/setup.py +1 -1
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/config.py +16 -13
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/context.py +4 -22
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/core/agent_types.py +2 -2
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/core/direct_decorators.py +2 -2
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/core/direct_factory.py +2 -1
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/core/fastagent.py +1 -1
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/core/request_params.py +5 -1
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/executor/workflow_signal.py +0 -2
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/augmented_llm.py +183 -57
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/augmented_llm_passthrough.py +1 -1
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/augmented_llm_playback.py +21 -1
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/memory.py +3 -3
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/model_factory.py +3 -1
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/provider_key_manager.py +1 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/provider_types.py +2 -1
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/providers/augmented_llm_anthropic.py +49 -10
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/providers/augmented_llm_deepseek.py +0 -2
- fast_agent_mcp-0.2.17/src/mcp_agent/llm/providers/augmented_llm_google.py +30 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/providers/augmented_llm_openai.py +95 -158
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/providers/multipart_converter_openai.py +10 -27
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/providers/sampling_converter_openai.py +5 -6
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/interfaces.py +6 -1
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/mcp_aggregator.py +2 -8
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/prompt_message_multipart.py +25 -2
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17/src/mcp_agent/resources}/examples/data-analysis/analysis-campaign.py +2 -2
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/in_dev/agent_build.py +1 -1
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/internal/job.py +1 -1
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/mcp/state-transfer/fastagent.config.yaml +1 -1
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/prompting/agent.py +0 -2
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/prompting/fastagent.config.yaml +2 -3
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17/src/mcp_agent/resources}/examples/researcher/fastagent.config.yaml +1 -6
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/workflows/fastagent.config.yaml +0 -1
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17/src/mcp_agent/resources}/examples/workflows/parallel.py +1 -1
- fast_agent_mcp-0.2.16/src/mcp_agent/executor/decorator_registry.py +0 -112
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/.gitignore +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/LICENSE +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/examples/data-analysis/analysis.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/examples/data-analysis/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/examples/mcp/state-transfer/agent_one.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/examples/mcp/state-transfer/agent_two.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/examples/researcher/researcher-eval.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/examples/researcher/researcher-imp.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/examples/researcher/researcher.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/examples/workflows/chaining.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/examples/workflows/graded_report.md +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/examples/workflows/human_input.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/examples/workflows/router.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/examples/workflows/short_story.md +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/examples/workflows/short_story.txt +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/__init__.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/agents/__init__.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/agents/agent.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/agents/workflow/__init__.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/agents/workflow/chain_agent.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/agents/workflow/evaluator_optimizer.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/agents/workflow/orchestrator_models.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/agents/workflow/orchestrator_prompts.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/agents/workflow/parallel_agent.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/cli/__init__.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/cli/__main__.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/cli/commands/check_config.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/cli/commands/quickstart.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/cli/main.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/cli/terminal.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/console.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/context_dependent.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/core/__init__.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/core/agent_app.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/core/enhanced_prompt.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/core/error_handling.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/core/exceptions.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/core/interactive_prompt.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/core/mcp_content.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/core/prompt.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/core/validation.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/event_progress.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/executor/__init__.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/executor/executor.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/executor/task_registry.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/human_input/__init__.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/human_input/handler.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/human_input/types.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/__init__.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/prompt_utils.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/providers/__init__.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/providers/anthropic_utils.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/providers/augmented_llm_generic.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/providers/augmented_llm_openrouter.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/providers/multipart_converter_anthropic.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/providers/openai_multipart.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/providers/openai_utils.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/providers/sampling_converter_anthropic.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/sampling_converter.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/llm/sampling_format_converter.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/logging/__init__.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/logging/events.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/logging/json_serializer.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/logging/listeners.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/logging/logger.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/logging/rich_progress.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/logging/tracing.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/logging/transport.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/__init__.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/gen_client.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/helpers/__init__.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/helpers/content_helpers.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/logger_textio.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/mcp_agent_client_session.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/mcp_connection_manager.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/mime_utils.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/prompt_render.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/prompt_serialization.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/prompts/__init__.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/prompts/__main__.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/prompts/prompt_constants.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/prompts/prompt_helpers.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/prompts/prompt_load.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/prompts/prompt_server.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/prompts/prompt_template.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/resource_utils.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp/sampling.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp_server/__init__.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp_server/agent_server.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/mcp_server_registry.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/progress_display.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/data-analysis/analysis.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/data-analysis/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/in_dev/css-LICENSE.txt +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/in_dev/slides.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/internal/agent.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/internal/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/internal/history_transfer.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/internal/prompt_category.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/internal/prompt_sizing.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/internal/simple.txt +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/internal/sizer.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/internal/social.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/mcp/state-transfer/agent_one.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/mcp/state-transfer/agent_two.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/mcp/state-transfer/fastagent.secrets.yaml.example +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/prompting/__init__.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/prompting/delimited_prompt.txt +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/prompting/image_server.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/prompting/prompt1.txt +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/prompting/work_with_image.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/researcher/researcher-eval.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/researcher/researcher-imp.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/researcher/researcher.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/workflows/chaining.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17/src/mcp_agent/resources}/examples/workflows/evaluator.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/workflows/human_input.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17/src/mcp_agent/resources}/examples/workflows/orchestrator.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/workflows/router.py +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/resources/examples/workflows/short_story.txt +0 -0
- {fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/ui/console_display.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: fast-agent-mcp
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.17
|
4
4
|
Summary: Define, Prompt and Test MCP enabled Agents and Workflows
|
5
5
|
Author-email: Shaun Smith <fastagent@llmindset.co.uk>, Sarmad Qadri <sarmad@lastmileai.dev>
|
6
6
|
License: Apache License
|
@@ -237,8 +237,6 @@ Requires-Dist: ruff>=0.8.4; extra == 'dev'
|
|
237
237
|
Requires-Dist: tomli>=2.2.1; extra == 'dev'
|
238
238
|
Provides-Extra: openai
|
239
239
|
Requires-Dist: openai>=1.58.1; extra == 'openai'
|
240
|
-
Provides-Extra: temporal
|
241
|
-
Requires-Dist: temporalio>=1.8.0; extra == 'temporal'
|
242
240
|
Description-Content-Type: text/markdown
|
243
241
|
|
244
242
|
<p align="center">
|
@@ -255,7 +253,7 @@ Description-Content-Type: text/markdown
|
|
255
253
|
> [!TIP]
|
256
254
|
> Documentation site is in production here : https://fast-agent.ai. Feel free to feed back what's helpful and what's not. llms.txt link is here: https://fast-agent.ai/llms.txt
|
257
255
|
|
258
|
-
**`fast-agent`** enables you to create and interact with sophisticated Agents and Workflows in minutes. It is the first framework with complete, end-to-end tested MCP Feature support including Sampling. Both Anthropic (Haiku, Sonnet, Opus) and OpenAI models (gpt-4o family, o1/o3 family) are supported.
|
256
|
+
**`fast-agent`** enables you to create and interact with sophisticated Agents and Workflows in minutes. It is the first framework with complete, end-to-end tested MCP Feature support including Sampling. Both Anthropic (Haiku, Sonnet, Opus) and OpenAI models (gpt-4o/gpt-4.1 family, o1/o3 family) are supported.
|
259
257
|
|
260
258
|
The simple declarative syntax lets you concentrate on composing your Prompts and MCP Servers to [build effective agents](https://www.anthropic.com/research/building-effective-agents).
|
261
259
|
|
@@ -313,7 +311,7 @@ Or start an interactive chat with the Agent:
|
|
313
311
|
|
314
312
|
```python
|
315
313
|
async with fast.run() as agent:
|
316
|
-
await agent()
|
314
|
+
await agent.interactive()
|
317
315
|
```
|
318
316
|
|
319
317
|
Here is the complete `sizer.py` Agent application, with boilerplate code:
|
@@ -330,7 +328,7 @@ fast = FastAgent("Agent Example")
|
|
330
328
|
)
|
331
329
|
async def main():
|
332
330
|
async with fast.run() as agent:
|
333
|
-
await agent()
|
331
|
+
await agent.interactive()
|
334
332
|
|
335
333
|
if __name__ == "__main__":
|
336
334
|
asyncio.run(main())
|
@@ -12,7 +12,7 @@
|
|
12
12
|
> [!TIP]
|
13
13
|
> Documentation site is in production here : https://fast-agent.ai. Feel free to feed back what's helpful and what's not. llms.txt link is here: https://fast-agent.ai/llms.txt
|
14
14
|
|
15
|
-
**`fast-agent`** enables you to create and interact with sophisticated Agents and Workflows in minutes. It is the first framework with complete, end-to-end tested MCP Feature support including Sampling. Both Anthropic (Haiku, Sonnet, Opus) and OpenAI models (gpt-4o family, o1/o3 family) are supported.
|
15
|
+
**`fast-agent`** enables you to create and interact with sophisticated Agents and Workflows in minutes. It is the first framework with complete, end-to-end tested MCP Feature support including Sampling. Both Anthropic (Haiku, Sonnet, Opus) and OpenAI models (gpt-4o/gpt-4.1 family, o1/o3 family) are supported.
|
16
16
|
|
17
17
|
The simple declarative syntax lets you concentrate on composing your Prompts and MCP Servers to [build effective agents](https://www.anthropic.com/research/building-effective-agents).
|
18
18
|
|
@@ -70,7 +70,7 @@ Or start an interactive chat with the Agent:
|
|
70
70
|
|
71
71
|
```python
|
72
72
|
async with fast.run() as agent:
|
73
|
-
await agent()
|
73
|
+
await agent.interactive()
|
74
74
|
```
|
75
75
|
|
76
76
|
Here is the complete `sizer.py` Agent application, with boilerplate code:
|
@@ -87,7 +87,7 @@ fast = FastAgent("Agent Example")
|
|
87
87
|
)
|
88
88
|
async def main():
|
89
89
|
async with fast.run() as agent:
|
90
|
-
await agent()
|
90
|
+
await agent.interactive()
|
91
91
|
|
92
92
|
if __name__ == "__main__":
|
93
93
|
asyncio.run(main())
|
@@ -33,7 +33,7 @@ Extract key insights that would be compelling for a social media campaign.
|
|
33
33
|
- Extracted compelling insights suitable for social media promotion
|
34
34
|
""",
|
35
35
|
request_params=RequestParams(maxTokens=8192),
|
36
|
-
model="gpt-
|
36
|
+
model="gpt-4.1",
|
37
37
|
)
|
38
38
|
@fast.evaluator_optimizer(
|
39
39
|
"analysis_tool",
|
@@ -55,7 +55,7 @@ Extract key insights that would be compelling for a social media campaign.
|
|
55
55
|
""",
|
56
56
|
servers=["fetch", "brave"], # Using the fetch MCP server for Brave search
|
57
57
|
request_params=RequestParams(temperature=0.3),
|
58
|
-
model="gpt-
|
58
|
+
model="gpt-4.1",
|
59
59
|
)
|
60
60
|
# Social media content generator
|
61
61
|
@fast.agent(
|
@@ -4,7 +4,6 @@
|
|
4
4
|
#
|
5
5
|
#
|
6
6
|
|
7
|
-
execution_engine: asyncio
|
8
7
|
logger:
|
9
8
|
type: console
|
10
9
|
level: error
|
@@ -53,14 +52,10 @@ mcp:
|
|
53
52
|
args: ["mcp-server-fetch"]
|
54
53
|
sequential:
|
55
54
|
command: "npx"
|
56
|
-
args: ["-y","@modelcontextprotocol/server-sequential-thinking"]
|
57
|
-
|
55
|
+
args: ["-y", "@modelcontextprotocol/server-sequential-thinking"]
|
58
56
|
# webmcp:
|
59
57
|
# command: "node"
|
60
58
|
# args: ["/home/ssmith/.webmcp/server.cjs"]
|
61
59
|
# env:
|
62
60
|
# WEBMCP_SERVER_TOKEN: 96e22896d8143fc1d61fec09208fc5ed
|
63
61
|
|
64
|
-
|
65
|
-
|
66
|
-
|
@@ -40,7 +40,7 @@ fast = FastAgent("Evaluator-Optimizer")
|
|
40
40
|
Summarize your evaluation as a structured response with:
|
41
41
|
- Overall quality rating.
|
42
42
|
- Specific feedback and areas for improvement.""",
|
43
|
-
model="gpt-
|
43
|
+
model="gpt-4.1",
|
44
44
|
)
|
45
45
|
# Define the evaluator-optimizer workflow
|
46
46
|
@fast.evaluator_optimizer(
|
@@ -13,7 +13,7 @@ fast = FastAgent("Orchestrator-Workers")
|
|
13
13
|
@fast.agent(
|
14
14
|
"author",
|
15
15
|
instruction="""You are to role play a poorly skilled writer,
|
16
|
-
who makes frequent grammar,
|
16
|
+
who makes frequent grammar, punctuation and spelling errors. You enjoy
|
17
17
|
writing short stories, but the narrative doesn't always make sense""",
|
18
18
|
servers=["filesystem"],
|
19
19
|
)
|
@@ -25,7 +25,7 @@ fast = FastAgent("Orchestrator-Workers")
|
|
25
25
|
the closest match to a user's request, make the appropriate tool calls,
|
26
26
|
and return the URI and CONTENTS of the closest match.""",
|
27
27
|
servers=["fetch", "filesystem"],
|
28
|
-
model="gpt-
|
28
|
+
model="gpt-4.1",
|
29
29
|
)
|
30
30
|
@fast.agent(
|
31
31
|
name="writer",
|
@@ -40,19 +40,17 @@ fast = FastAgent("Orchestrator-Workers")
|
|
40
40
|
Identify any awkward phrasing or structural issues that could improve clarity.
|
41
41
|
Provide detailed feedback on corrections.""",
|
42
42
|
servers=["fetch"],
|
43
|
-
model="gpt-
|
43
|
+
model="gpt-4.1",
|
44
44
|
)
|
45
45
|
# Define the orchestrator to coordinate the other agents
|
46
46
|
@fast.orchestrator(
|
47
|
-
name="orchestrate",
|
48
|
-
agents=["finder", "writer", "proofreader"],
|
49
|
-
plan_type="full",
|
47
|
+
name="orchestrate", agents=["finder", "writer", "proofreader"], plan_type="full", model="sonnet"
|
50
48
|
)
|
51
49
|
async def main() -> None:
|
52
50
|
async with fast.run() as agent:
|
53
|
-
await agent.author(
|
54
|
-
|
55
|
-
)
|
51
|
+
# await agent.author(
|
52
|
+
# "write a 250 word short story about kittens discovering a castle, and save it to short_story.md"
|
53
|
+
# )
|
56
54
|
|
57
55
|
# The orchestrator can be used just like any other agent
|
58
56
|
task = """Load the student's short story from short_story.md,
|
@@ -25,7 +25,7 @@ fast = FastAgent(
|
|
25
25
|
instruction="""Verify the factual consistency within the story. Identify any contradictions,
|
26
26
|
logical inconsistencies, or inaccuracies in the plot, character actions, or setting.
|
27
27
|
Highlight potential issues with reasoning or coherence.""",
|
28
|
-
model="gpt-
|
28
|
+
model="gpt-4.1",
|
29
29
|
)
|
30
30
|
@fast.agent(
|
31
31
|
name="style_enforcer",
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "fast-agent-mcp"
|
3
|
-
version = "0.2.
|
3
|
+
version = "0.2.17"
|
4
4
|
description = "Define, Prompt and Test MCP enabled Agents and Workflows"
|
5
5
|
readme = "README.md"
|
6
6
|
license = { file = "LICENSE" }
|
@@ -34,9 +34,6 @@ dependencies = [
|
|
34
34
|
]
|
35
35
|
|
36
36
|
[project.optional-dependencies]
|
37
|
-
temporal = [
|
38
|
-
"temporalio>=1.8.0",
|
39
|
-
]
|
40
37
|
openai = [
|
41
38
|
"openai>=1.58.1",
|
42
39
|
]
|
@@ -20,6 +20,7 @@ from typing import (
|
|
20
20
|
Union,
|
21
21
|
)
|
22
22
|
|
23
|
+
from a2a_types.types import AgentCapabilities, AgentCard, AgentSkill
|
23
24
|
from mcp.types import (
|
24
25
|
CallToolResult,
|
25
26
|
EmbeddedResource,
|
@@ -58,6 +59,11 @@ if TYPE_CHECKING:
|
|
58
59
|
from mcp_agent.context import Context
|
59
60
|
|
60
61
|
|
62
|
+
DEFAULT_CAPABILITIES = AgentCapabilities(
|
63
|
+
streaming=False, pushNotifications=False, stateTransitionHistory=False
|
64
|
+
)
|
65
|
+
|
66
|
+
|
61
67
|
class BaseAgent(MCPAggregator, AgentProtocol):
|
62
68
|
"""
|
63
69
|
A base Agent class that implements the AgentProtocol interface.
|
@@ -586,7 +592,7 @@ class BaseAgent(MCPAggregator, AgentProtocol):
|
|
586
592
|
|
587
593
|
async def structured(
|
588
594
|
self,
|
589
|
-
|
595
|
+
multipart_messages: List[PromptMessageMultipart],
|
590
596
|
model: Type[ModelT],
|
591
597
|
request_params: RequestParams | None = None,
|
592
598
|
) -> Tuple[ModelT | None, PromptMessageMultipart]:
|
@@ -603,7 +609,7 @@ class BaseAgent(MCPAggregator, AgentProtocol):
|
|
603
609
|
An instance of the specified model, or None if coercion fails
|
604
610
|
"""
|
605
611
|
assert self._llm
|
606
|
-
return await self._llm.structured(
|
612
|
+
return await self._llm.structured(multipart_messages, model, request_params)
|
607
613
|
|
608
614
|
async def apply_prompt_messages(
|
609
615
|
self, prompts: List[PromptMessageMultipart], request_params: RequestParams | None = None
|
@@ -626,13 +632,51 @@ class BaseAgent(MCPAggregator, AgentProtocol):
|
|
626
632
|
def agent_type(self) -> AgentType:
|
627
633
|
"""
|
628
634
|
Return the type of this agent.
|
635
|
+
"""
|
636
|
+
return AgentType.BASIC
|
637
|
+
|
638
|
+
async def agent_card(self) -> AgentCard:
|
639
|
+
"""
|
640
|
+
Return an A2A card describing this Agent
|
641
|
+
"""
|
629
642
|
|
630
|
-
|
643
|
+
skills: List[AgentSkill] = []
|
644
|
+
tools: ListToolsResult = await self.list_tools()
|
645
|
+
for tool in tools.tools:
|
646
|
+
skills.append(await self.convert(tool))
|
631
647
|
|
632
|
-
|
633
|
-
|
648
|
+
return AgentCard(
|
649
|
+
name=self.name,
|
650
|
+
description=self.instruction,
|
651
|
+
url=f"fast-agent://agents/{self.name}/",
|
652
|
+
version="0.1",
|
653
|
+
capabilities=DEFAULT_CAPABILITIES,
|
654
|
+
defaultInputModes=["text/plain"],
|
655
|
+
defaultOutputModes=["text/plain"],
|
656
|
+
provider=None,
|
657
|
+
documentationUrl=None,
|
658
|
+
authentication=None,
|
659
|
+
skills=skills,
|
660
|
+
)
|
661
|
+
|
662
|
+
async def convert(self, tool: Tool) -> AgentSkill:
|
634
663
|
"""
|
635
|
-
|
664
|
+
Convert a Tool to an AgentSkill.
|
665
|
+
"""
|
666
|
+
|
667
|
+
_, tool_without_namespace = await self._parse_resource_name(tool.name, "tool")
|
668
|
+
return AgentSkill(
|
669
|
+
id=tool.name,
|
670
|
+
name=tool_without_namespace,
|
671
|
+
description=tool.description,
|
672
|
+
tags=["tool"],
|
673
|
+
examples=None,
|
674
|
+
inputModes=None, # ["text/plain"],
|
675
|
+
# cover TextContent | ImageContent ->
|
676
|
+
# https://github.com/modelcontextprotocol/modelcontextprotocol/pull/223
|
677
|
+
# https://github.com/modelcontextprotocol/modelcontextprotocol/pull/93
|
678
|
+
outputModes=None, # ,["text/plain", "image/*"],
|
679
|
+
)
|
636
680
|
|
637
681
|
@property
|
638
682
|
def message_history(self) -> List[PromptMessageMultipart]:
|
{fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/agents/workflow/orchestrator_agent.py
RENAMED
@@ -57,6 +57,7 @@ class OrchestratorAgent(BaseAgent):
|
|
57
57
|
config: AgentConfig,
|
58
58
|
agents: List[Agent],
|
59
59
|
plan_type: Literal["full", "iterative"] = "full",
|
60
|
+
plan_iterations: int = 5,
|
60
61
|
context: Optional[Any] = None,
|
61
62
|
**kwargs,
|
62
63
|
) -> None:
|
@@ -83,7 +84,7 @@ class OrchestratorAgent(BaseAgent):
|
|
83
84
|
agent_name = agent.name
|
84
85
|
self.logger.info(f"Adding agent '{agent_name}' to orchestrator")
|
85
86
|
self.agents[agent_name] = agent
|
86
|
-
|
87
|
+
self.plan_iterations = plan_iterations
|
87
88
|
# For tracking state during execution
|
88
89
|
self.plan_result: Optional[PlanResult] = None
|
89
90
|
|
@@ -186,8 +187,8 @@ class OrchestratorAgent(BaseAgent):
|
|
186
187
|
"""
|
187
188
|
iterations = 0
|
188
189
|
total_steps_executed = 0
|
189
|
-
max_iterations =
|
190
|
-
max_steps = getattr(request_params, "max_steps", max_iterations *
|
190
|
+
max_iterations = self.plan_iterations
|
191
|
+
max_steps = getattr(request_params, "max_steps", max_iterations * 3)
|
191
192
|
|
192
193
|
# Initialize plan result
|
193
194
|
plan_result = PlanResult(objective=objective, step_results=[])
|
@@ -414,7 +415,7 @@ class OrchestratorAgent(BaseAgent):
|
|
414
415
|
plan_status = "Plan Status: Not Started"
|
415
416
|
|
416
417
|
# Calculate iteration information
|
417
|
-
max_iterations =
|
418
|
+
max_iterations = self.plan_iterations
|
418
419
|
current_iteration = len(plan_result.step_results)
|
419
420
|
current_iteration = min(current_iteration, max_iterations - 1)
|
420
421
|
iterations_remaining = max(0, max_iterations - current_iteration - 1)
|
@@ -536,9 +537,7 @@ class OrchestratorAgent(BaseAgent):
|
|
536
537
|
return ""
|
537
538
|
|
538
539
|
# Get agent instruction or default description
|
539
|
-
instruction =
|
540
|
-
agent.instruction if hasattr(agent, "instruction") else f"Agent '{agent_name}'"
|
541
|
-
)
|
540
|
+
instruction = agent.instruction if agent.instruction else f"Agent '{agent_name}'"
|
542
541
|
|
543
542
|
# Format with XML tags
|
544
543
|
return f'<fastagent:agent name="{agent_name}">{instruction}</fastagent:agent>'
|
{fast_agent_mcp-0.2.16 → fast_agent_mcp-0.2.17}/src/mcp_agent/agents/workflow/router_agent.py
RENAMED
@@ -5,9 +5,8 @@ This provides a simplified implementation that routes messages to agents
|
|
5
5
|
by determining the best agent for a request and dispatching to it.
|
6
6
|
"""
|
7
7
|
|
8
|
-
from typing import TYPE_CHECKING, List, Optional, Tuple, Type
|
8
|
+
from typing import TYPE_CHECKING, Callable, List, Optional, Tuple, Type
|
9
9
|
|
10
|
-
from mcp.types import TextContent
|
11
10
|
from pydantic import BaseModel
|
12
11
|
|
13
12
|
from mcp_agent.agents.agent import Agent
|
@@ -17,10 +16,12 @@ from mcp_agent.core.exceptions import AgentConfigError
|
|
17
16
|
from mcp_agent.core.prompt import Prompt
|
18
17
|
from mcp_agent.core.request_params import RequestParams
|
19
18
|
from mcp_agent.logging.logger import get_logger
|
20
|
-
from mcp_agent.mcp.interfaces import ModelT
|
19
|
+
from mcp_agent.mcp.interfaces import AugmentedLLMProtocol, ModelT
|
21
20
|
from mcp_agent.mcp.prompt_message_multipart import PromptMessageMultipart
|
22
21
|
|
23
22
|
if TYPE_CHECKING:
|
23
|
+
from a2a_types.types import AgentCard
|
24
|
+
|
24
25
|
from mcp_agent.context import Context
|
25
26
|
|
26
27
|
logger = get_logger(__name__)
|
@@ -36,47 +37,17 @@ Follow these guidelines:
|
|
36
37
|
- Provide your confidence level (high, medium, low) and brief reasoning for your selection
|
37
38
|
"""
|
38
39
|
|
39
|
-
# Default routing instruction with placeholders for context
|
40
|
+
# Default routing instruction with placeholders for context (AgentCard JSON)
|
40
41
|
DEFAULT_ROUTING_INSTRUCTION = """
|
41
|
-
|
42
|
-
|
43
|
-
<fastagent:data>
|
42
|
+
Select from the following agents to handle the request:
|
44
43
|
<fastagent:agents>
|
44
|
+
[
|
45
45
|
{context}
|
46
|
+
]
|
46
47
|
</fastagent:agents>
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
</fastagent:request>
|
51
|
-
</fastagent:data>
|
52
|
-
|
53
|
-
Your task is to analyze the request and determine the most appropriate agent from the options above.
|
54
|
-
|
55
|
-
<fastagent:instruction>
|
56
|
-
Respond with JSON following the schema below:
|
57
|
-
{{
|
58
|
-
"type": "object",
|
59
|
-
"required": ["agent", "confidence", "reasoning"],
|
60
|
-
"properties": {{
|
61
|
-
"agent": {{
|
62
|
-
"type": "string",
|
63
|
-
"description": "The exact name of the selected agent"
|
64
|
-
}},
|
65
|
-
"confidence": {{
|
66
|
-
"type": "string",
|
67
|
-
"enum": ["high", "medium", "low"],
|
68
|
-
"description": "Your confidence level in this selection"
|
69
|
-
}},
|
70
|
-
"reasoning": {{
|
71
|
-
"type": "string",
|
72
|
-
"description": "Brief explanation for your selection"
|
73
|
-
}}
|
74
|
-
}}
|
75
|
-
}}
|
76
|
-
|
77
|
-
Supply only the JSON with no preamble. Use "reasoning" field to describe actions. NEVER EMIT CODE FENCES.
|
78
|
-
|
79
|
-
</fastagent:instruction>
|
49
|
+
You must respond with the 'name' of one of the agents listed above.
|
50
|
+
|
80
51
|
"""
|
81
52
|
|
82
53
|
|
@@ -85,18 +56,7 @@ class RoutingResponse(BaseModel):
|
|
85
56
|
|
86
57
|
agent: str
|
87
58
|
confidence: str
|
88
|
-
reasoning:
|
89
|
-
|
90
|
-
|
91
|
-
class RouterResult(BaseModel):
|
92
|
-
"""Router result with agent reference and confidence rating."""
|
93
|
-
|
94
|
-
result: BaseAgent
|
95
|
-
confidence: str
|
96
|
-
reasoning: Optional[str] = None
|
97
|
-
|
98
|
-
# Allow Agent objects to be stored without serialization
|
99
|
-
model_config = {"arbitrary_types_allowed": True}
|
59
|
+
reasoning: str | None = None
|
100
60
|
|
101
61
|
|
102
62
|
class RouterAgent(BaseAgent):
|
@@ -142,9 +102,7 @@ class RouterAgent(BaseAgent):
|
|
142
102
|
# Set up base router request parameters
|
143
103
|
base_params = {"systemPrompt": ROUTING_SYSTEM_INSTRUCTION, "use_history": False}
|
144
104
|
|
145
|
-
# Merge with provided defaults if any
|
146
105
|
if default_request_params:
|
147
|
-
# Start with defaults and override with router-specific settings
|
148
106
|
merged_params = default_request_params.model_copy(update=base_params)
|
149
107
|
else:
|
150
108
|
merged_params = RequestParams(**base_params)
|
@@ -174,32 +132,16 @@ class RouterAgent(BaseAgent):
|
|
174
132
|
except Exception as e:
|
175
133
|
logger.warning(f"Error shutting down agent: {str(e)}")
|
176
134
|
|
177
|
-
async def
|
135
|
+
async def attach_llm(
|
178
136
|
self,
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
Returns:
|
188
|
-
RouterResult containing the selected agent, or None if no suitable agent found
|
189
|
-
"""
|
190
|
-
if not self.initialized:
|
191
|
-
await self.initialize()
|
192
|
-
|
193
|
-
# Extract the request text from the last message
|
194
|
-
request = messages[-1].all_text() if messages else ""
|
195
|
-
|
196
|
-
# Determine which agent to route to
|
197
|
-
routing_result = await self._route_request(request)
|
198
|
-
|
199
|
-
if not routing_result:
|
200
|
-
logger.warning("Could not determine appropriate agent for this request")
|
201
|
-
|
202
|
-
return routing_result
|
137
|
+
llm_factory: type[AugmentedLLMProtocol] | Callable[..., AugmentedLLMProtocol],
|
138
|
+
model: str | None = None,
|
139
|
+
request_params: RequestParams | None = None,
|
140
|
+
**additional_kwargs,
|
141
|
+
) -> AugmentedLLMProtocol:
|
142
|
+
return await super().attach_llm(
|
143
|
+
llm_factory, model, request_params, verb="Routing", **additional_kwargs
|
144
|
+
)
|
203
145
|
|
204
146
|
async def generate(
|
205
147
|
self,
|
@@ -216,32 +158,21 @@ class RouterAgent(BaseAgent):
|
|
216
158
|
Returns:
|
217
159
|
The response from the selected agent
|
218
160
|
"""
|
219
|
-
routing_result = await self._get_routing_result(multipart_messages)
|
220
|
-
|
221
|
-
if not routing_result:
|
222
|
-
return PromptMessageMultipart(
|
223
|
-
role="assistant",
|
224
|
-
content=[
|
225
|
-
TextContent(
|
226
|
-
type="text", text="Could not determine appropriate agent for this request."
|
227
|
-
)
|
228
|
-
],
|
229
|
-
)
|
230
161
|
|
231
|
-
|
232
|
-
selected_agent = routing_result.result
|
162
|
+
route, warn = await self._route_request(multipart_messages[-1])
|
233
163
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
164
|
+
if not route:
|
165
|
+
return Prompt.assistant(warn or "No routing result or warning received")
|
166
|
+
|
167
|
+
# Get the selected agent
|
168
|
+
agent: Agent = self.agent_map[route.agent]
|
238
169
|
|
239
170
|
# Dispatch the request to the selected agent
|
240
|
-
return await
|
171
|
+
return await agent.generate(multipart_messages, request_params)
|
241
172
|
|
242
173
|
async def structured(
|
243
174
|
self,
|
244
|
-
|
175
|
+
multipart_messages: List[PromptMessageMultipart],
|
245
176
|
model: Type[ModelT],
|
246
177
|
request_params: Optional[RequestParams] = None,
|
247
178
|
) -> Tuple[ModelT | None, PromptMessageMultipart]:
|
@@ -256,23 +187,22 @@ class RouterAgent(BaseAgent):
|
|
256
187
|
Returns:
|
257
188
|
The parsed response from the selected agent, or None if parsing fails
|
258
189
|
"""
|
259
|
-
|
190
|
+
route, warn = await self._route_request(multipart_messages[-1])
|
260
191
|
|
261
|
-
if not
|
262
|
-
return None, Prompt.assistant(
|
192
|
+
if not route:
|
193
|
+
return None, Prompt.assistant(
|
194
|
+
warn or "No routing result or warning received (structured)"
|
195
|
+
)
|
263
196
|
|
264
197
|
# Get the selected agent
|
265
|
-
|
266
|
-
|
267
|
-
# Log the routing decision
|
268
|
-
logger.info(
|
269
|
-
f"Routing structured request to agent: {selected_agent.name} (confidence: {routing_result.confidence})"
|
270
|
-
)
|
198
|
+
agent: Agent = self.agent_map[route.agent]
|
271
199
|
|
272
200
|
# Dispatch the request to the selected agent
|
273
|
-
return await
|
201
|
+
return await agent.structured(multipart_messages, model, request_params)
|
274
202
|
|
275
|
-
async def _route_request(
|
203
|
+
async def _route_request(
|
204
|
+
self, message: PromptMessageMultipart
|
205
|
+
) -> Tuple[RoutingResponse | None, str | None]:
|
276
206
|
"""
|
277
207
|
Determine which agent to route the request to.
|
278
208
|
|
@@ -283,49 +213,53 @@ class RouterAgent(BaseAgent):
|
|
283
213
|
RouterResult containing the selected agent, or None if no suitable agent was found
|
284
214
|
"""
|
285
215
|
if not self.agents:
|
286
|
-
logger.
|
287
|
-
|
216
|
+
logger.error("No agents available for routing")
|
217
|
+
raise AgentConfigError("No agents available for routing - fatal error")
|
288
218
|
|
289
219
|
# If only one agent is available, use it directly
|
290
220
|
if len(self.agents) == 1:
|
291
|
-
return
|
292
|
-
|
293
|
-
)
|
221
|
+
return RoutingResponse(
|
222
|
+
agent=self.agents[0].name, confidence="high", reasoning="Only one agent available"
|
223
|
+
), None
|
294
224
|
|
295
225
|
# Generate agent descriptions for the context
|
296
226
|
agent_descriptions = []
|
297
|
-
for
|
298
|
-
|
299
|
-
agent_descriptions.append(
|
227
|
+
for agent in self.agents:
|
228
|
+
agent_card: AgentCard = await agent.agent_card()
|
229
|
+
agent_descriptions.append(
|
230
|
+
agent_card.model_dump_json(
|
231
|
+
include={"name", "description", "skills"}, exclude_none=True
|
232
|
+
)
|
233
|
+
)
|
300
234
|
|
301
|
-
context = "
|
235
|
+
context = ",\n".join(agent_descriptions)
|
302
236
|
|
303
237
|
# Format the routing prompt
|
304
238
|
routing_instruction = self.routing_instruction or DEFAULT_ROUTING_INSTRUCTION
|
305
|
-
|
306
|
-
|
307
|
-
# Create multipart message for the router
|
308
|
-
prompt = PromptMessageMultipart(
|
309
|
-
role="user", content=[TextContent(type="text", text=prompt_text)]
|
310
|
-
)
|
239
|
+
routing_instruction = routing_instruction.format(context=context)
|
311
240
|
|
312
|
-
# Get structured response from LLM
|
313
241
|
assert self._llm
|
242
|
+
mutated = message.model_copy(deep=True)
|
243
|
+
mutated.add_text(routing_instruction)
|
314
244
|
response, _ = await self._llm.structured(
|
315
|
-
[
|
245
|
+
[mutated],
|
246
|
+
RoutingResponse,
|
247
|
+
self._default_request_params,
|
316
248
|
)
|
317
249
|
|
250
|
+
warn: str | None = None
|
318
251
|
if not response:
|
319
|
-
|
320
|
-
|
252
|
+
warn = "No routing response received from LLM"
|
253
|
+
elif response.agent not in self.agent_map:
|
254
|
+
warn = f"A response was received, but the agent {response.agent} was not known to the Router"
|
321
255
|
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
256
|
+
if warn:
|
257
|
+
logger.warning(warn)
|
258
|
+
return None, warn
|
259
|
+
else:
|
260
|
+
assert response
|
261
|
+
logger.info(
|
262
|
+
f"Routing structured request to agent: {response.agent or 'error'} (confidence: {response.confidence or ''})"
|
263
|
+
)
|
328
264
|
|
329
|
-
|
330
|
-
result=selected_agent, confidence=response.confidence, reasoning=response.reasoning
|
331
|
-
)
|
265
|
+
return response, None
|