fast-agent-mcp 0.2.27__tar.gz → 0.2.28__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.27 → fast_agent_mcp-0.2.28}/.gitignore +1 -1
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/PKG-INFO +3 -1
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/pyproject.toml +6 -2
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/agents/agent.py +1 -17
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/agents/base_agent.py +2 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/config.py +3 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/context.py +2 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/core/agent_app.py +7 -2
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/core/interactive_prompt.py +58 -51
- fast_agent_mcp-0.2.28/src/mcp_agent/llm/augmented_llm_slow.py +42 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/model_factory.py +74 -37
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/provider_types.py +4 -3
- fast_agent_mcp-0.2.28/src/mcp_agent/llm/providers/augmented_llm_google_native.py +459 -0
- fast_agent_mcp-0.2.27/src/mcp_agent/llm/providers/augmented_llm_google.py → fast_agent_mcp-0.2.28/src/mcp_agent/llm/providers/augmented_llm_google_oai.py +2 -2
- fast_agent_mcp-0.2.28/src/mcp_agent/llm/providers/google_converter.py +361 -0
- fast_agent_mcp-0.2.28/src/mcp_agent/mcp/helpers/server_config_helpers.py +23 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/mcp_agent_client_session.py +51 -24
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/mcp_aggregator.py +18 -3
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/mcp_connection_manager.py +6 -5
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/sampling.py +40 -10
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp_server_registry.py +15 -4
- fast_agent_mcp-0.2.28/src/mcp_agent/tools/tool_definition.py +14 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/LICENSE +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/README.md +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/azure-openai/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/data-analysis/analysis-campaign.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/data-analysis/analysis.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/data-analysis/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/mcp/state-transfer/agent_one.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/mcp/state-transfer/agent_two.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/mcp/state-transfer/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/mcp/vision-examples/example1.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/mcp/vision-examples/example2.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/mcp/vision-examples/example3.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/mcp/vision-examples/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/otel/agent.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/otel/agent2.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/otel/docker-compose.yaml +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/otel/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/researcher/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/researcher/researcher-eval.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/researcher/researcher-imp.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/researcher/researcher.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/tensorzero/README.md +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/tensorzero/agent.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/tensorzero/docker-compose.yml +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/tensorzero/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/tensorzero/image_demo.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/tensorzero/mcp_server/mcp_server.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/tensorzero/simple_agent.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/workflows/chaining.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/workflows/evaluator.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/workflows/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/workflows/graded_report.md +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/workflows/human_input.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/workflows/orchestrator.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/workflows/parallel.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/workflows/router.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/workflows/short_story.md +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/examples/workflows/short_story.txt +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/__init__.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/agents/__init__.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/agents/workflow/__init__.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/agents/workflow/chain_agent.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/agents/workflow/evaluator_optimizer.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/agents/workflow/orchestrator_agent.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/agents/workflow/orchestrator_models.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/agents/workflow/orchestrator_prompts.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/agents/workflow/parallel_agent.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/agents/workflow/router_agent.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/app.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/cli/__init__.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/cli/__main__.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/cli/commands/check_config.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/cli/commands/go.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/cli/commands/quickstart.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/cli/commands/setup.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/cli/commands/url_parser.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/cli/main.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/cli/terminal.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/console.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/context_dependent.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/core/__init__.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/core/agent_types.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/core/direct_decorators.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/core/direct_factory.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/core/enhanced_prompt.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/core/error_handling.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/core/exceptions.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/core/fastagent.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/core/mcp_content.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/core/prompt.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/core/request_params.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/core/validation.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/event_progress.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/executor/__init__.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/executor/executor.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/executor/task_registry.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/executor/workflow_signal.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/human_input/__init__.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/human_input/handler.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/human_input/types.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/__init__.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/augmented_llm.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/augmented_llm_passthrough.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/augmented_llm_playback.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/memory.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/prompt_utils.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/provider_key_manager.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/providers/__init__.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/providers/anthropic_utils.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/providers/augmented_llm_anthropic.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/providers/augmented_llm_azure.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/providers/augmented_llm_deepseek.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/providers/augmented_llm_generic.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/providers/augmented_llm_openai.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/providers/augmented_llm_openrouter.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/providers/augmented_llm_tensorzero.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/providers/multipart_converter_anthropic.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/providers/multipart_converter_openai.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/providers/multipart_converter_tensorzero.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/providers/openai_multipart.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/providers/openai_utils.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/providers/sampling_converter_anthropic.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/providers/sampling_converter_openai.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/sampling_converter.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/llm/sampling_format_converter.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/logging/__init__.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/logging/events.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/logging/json_serializer.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/logging/listeners.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/logging/logger.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/logging/rich_progress.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/logging/transport.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/__init__.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/common.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/gen_client.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/helpers/__init__.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/helpers/content_helpers.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/interfaces.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/logger_textio.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/mime_utils.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/prompt_message_multipart.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/prompt_render.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/prompt_serialization.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/prompts/__init__.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/prompts/__main__.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/prompts/prompt_constants.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/prompts/prompt_helpers.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/prompts/prompt_load.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/prompts/prompt_server.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/prompts/prompt_template.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp/resource_utils.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp_server/__init__.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/mcp_server/agent_server.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/progress_display.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/data-analysis/analysis-campaign.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/data-analysis/analysis.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/data-analysis/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/in_dev/agent_build.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/in_dev/css-LICENSE.txt +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/in_dev/slides.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/internal/agent.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/internal/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/internal/history_transfer.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/internal/job.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/internal/prompt_category.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/internal/prompt_sizing.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/internal/simple.txt +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/internal/sizer.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/internal/social.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/mcp/state-transfer/agent_one.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/mcp/state-transfer/agent_two.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/mcp/state-transfer/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/mcp/state-transfer/fastagent.secrets.yaml.example +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/prompting/__init__.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/prompting/agent.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/prompting/delimited_prompt.txt +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/prompting/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/prompting/image_server.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/prompting/prompt1.txt +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/prompting/work_with_image.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/researcher/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/researcher/researcher-eval.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/researcher/researcher-imp.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/researcher/researcher.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/workflows/chaining.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/workflows/evaluator.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/workflows/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/workflows/human_input.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/workflows/orchestrator.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/workflows/parallel.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/workflows/router.py +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/src/mcp_agent/resources/examples/workflows/short_story.txt +0 -0
- {fast_agent_mcp-0.2.27 → fast_agent_mcp-0.2.28}/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.28
|
4
4
|
Summary: Define, Prompt and Test MCP enabled Agents and Workflows
|
5
5
|
Author-email: Shaun Smith <fastagent@llmindset.co.uk>
|
6
6
|
License: Apache License
|
@@ -214,11 +214,13 @@ Requires-Dist: aiohttp>=3.11.13
|
|
214
214
|
Requires-Dist: anthropic>=0.49.0
|
215
215
|
Requires-Dist: azure-identity>=1.14.0
|
216
216
|
Requires-Dist: fastapi>=0.115.6
|
217
|
+
Requires-Dist: google-genai
|
217
218
|
Requires-Dist: mcp==1.9.1
|
218
219
|
Requires-Dist: openai>=1.63.2
|
219
220
|
Requires-Dist: opentelemetry-distro>=0.50b0
|
220
221
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.29.0
|
221
222
|
Requires-Dist: opentelemetry-instrumentation-anthropic>=0.39.3; python_version >= '3.10' and python_version < '4.0'
|
223
|
+
Requires-Dist: opentelemetry-instrumentation-google-genai>=0.2b0
|
222
224
|
Requires-Dist: opentelemetry-instrumentation-mcp>=0.40.3; python_version >= '3.10' and python_version < '4.0'
|
223
225
|
Requires-Dist: opentelemetry-instrumentation-openai>=0.39.3; python_version >= '3.10' and python_version < '4.0'
|
224
226
|
Requires-Dist: prompt-toolkit>=3.0.50
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "fast-agent-mcp"
|
3
|
-
version = "0.2.
|
3
|
+
version = "0.2.28"
|
4
4
|
description = "Define, Prompt and Test MCP enabled Agents and Workflows"
|
5
5
|
readme = "README.md"
|
6
6
|
license = { file = "LICENSE" }
|
@@ -31,8 +31,12 @@ dependencies = [
|
|
31
31
|
"a2a-types>=0.1.0",
|
32
32
|
"opentelemetry-instrumentation-openai>=0.39.3; python_version >= '3.10' and python_version < '4.0'",
|
33
33
|
"opentelemetry-instrumentation-anthropic>=0.39.3; python_version >= '3.10' and python_version < '4.0'",
|
34
|
-
"tensorzero>=2025.4.7",
|
35
34
|
"opentelemetry-instrumentation-mcp>=0.40.3; python_version >= '3.10' and python_version < '4.0'",
|
35
|
+
"google-genai",
|
36
|
+
"opentelemetry-instrumentation-google-genai>=0.2b0",
|
37
|
+
"tensorzero>=2025.4.7",
|
38
|
+
"google-genai",
|
39
|
+
"opentelemetry-instrumentation-google-genai>=0.2b0",
|
36
40
|
]
|
37
41
|
|
38
42
|
[project.optional-dependencies]
|
@@ -75,27 +75,11 @@ class Agent(BaseAgent):
|
|
75
75
|
async def send_wrapper(message, agent_name):
|
76
76
|
return await self.send(message)
|
77
77
|
|
78
|
-
# Define wrapper for apply_prompt function
|
79
|
-
async def apply_prompt_wrapper(prompt_name, args, agent_name):
|
80
|
-
# Just apply the prompt directly
|
81
|
-
return await self.apply_prompt(prompt_name, args)
|
82
|
-
|
83
|
-
# Define wrapper for list_prompts function
|
84
|
-
async def list_prompts_wrapper(agent_name):
|
85
|
-
# Always call list_prompts on this agent regardless of agent_name
|
86
|
-
return await self.list_prompts()
|
87
|
-
|
88
|
-
# Define wrapper for list_resources function
|
89
|
-
async def list_resources_wrapper(agent_name):
|
90
|
-
# Always call list_resources on this agent regardless of agent_name
|
91
|
-
return await self.list_resources()
|
92
|
-
|
93
78
|
# Start the prompt loop with just this agent
|
94
79
|
return await prompt.prompt_loop(
|
95
80
|
send_func=send_wrapper,
|
96
81
|
default_agent=agent_name_str,
|
97
82
|
available_agents=[agent_name_str], # Only this agent
|
98
|
-
|
99
|
-
list_prompts_func=list_prompts_wrapper,
|
83
|
+
prompt_provider=self, # Pass self as the prompt provider since we implement the protocol
|
100
84
|
default=default_prompt,
|
101
85
|
)
|
@@ -456,6 +456,7 @@ class BaseAgent(MCPAggregator, AgentProtocol):
|
|
456
456
|
self,
|
457
457
|
prompt_name: str,
|
458
458
|
arguments: Dict[str, str] | None = None,
|
459
|
+
agent_name: str | None = None,
|
459
460
|
server_name: str | None = None,
|
460
461
|
) -> str:
|
461
462
|
"""
|
@@ -468,6 +469,7 @@ class BaseAgent(MCPAggregator, AgentProtocol):
|
|
468
469
|
Args:
|
469
470
|
prompt_name: The name of the prompt to apply
|
470
471
|
arguments: Optional dictionary of string arguments to pass to the prompt template
|
472
|
+
agent_name: Optional agent name (ignored at this level, used by multi-agent apps)
|
471
473
|
server_name: Optional name of the server to get the prompt from
|
472
474
|
|
473
475
|
Returns:
|
@@ -291,6 +291,9 @@ class Settings(BaseSettings):
|
|
291
291
|
Default model for agents. Format is provider.model_name.<reasoning_effort>, for example openai.o3-mini.low
|
292
292
|
Aliases are provided for common models e.g. sonnet, haiku, gpt-4.1, o3-mini etc.
|
293
293
|
"""
|
294
|
+
|
295
|
+
auto_sampling: bool = True
|
296
|
+
"""Enable automatic sampling model selection if not explicitly configured"""
|
294
297
|
|
295
298
|
anthropic: AnthropicSettings | None = None
|
296
299
|
"""Settings for using Anthropic models in the fast-agent application"""
|
@@ -11,6 +11,7 @@ from mcp import ServerSession
|
|
11
11
|
from opentelemetry import trace
|
12
12
|
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
|
13
13
|
from opentelemetry.instrumentation.anthropic import AnthropicInstrumentor
|
14
|
+
from opentelemetry.instrumentation.google_genai import GoogleGenAiSdkInstrumentor
|
14
15
|
from opentelemetry.instrumentation.mcp import McpInstrumentor
|
15
16
|
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
|
16
17
|
from opentelemetry.propagate import set_global_textmap
|
@@ -112,6 +113,7 @@ async def configure_otel(config: "Settings") -> None:
|
|
112
113
|
trace.set_tracer_provider(tracer_provider)
|
113
114
|
AnthropicInstrumentor().instrument()
|
114
115
|
OpenAIInstrumentor().instrument()
|
116
|
+
GoogleGenAiSdkInstrumentor().instrument()
|
115
117
|
McpInstrumentor().instrument()
|
116
118
|
|
117
119
|
|
@@ -129,6 +129,12 @@ class AgentApp:
|
|
129
129
|
Returns:
|
130
130
|
Dictionary mapping server names to lists of available prompts
|
131
131
|
"""
|
132
|
+
if not agent_name:
|
133
|
+
results = {}
|
134
|
+
for agent in self._agents.values():
|
135
|
+
curr_prompts = await agent.list_prompts(server_name=server_name)
|
136
|
+
results.update(curr_prompts)
|
137
|
+
return results
|
132
138
|
return await self._agent(agent_name).list_prompts(server_name=server_name)
|
133
139
|
|
134
140
|
async def get_prompt(
|
@@ -262,7 +268,6 @@ class AgentApp:
|
|
262
268
|
send_func=send_wrapper,
|
263
269
|
default_agent=target_name, # Pass the agent name, not the agent object
|
264
270
|
available_agents=list(self._agents.keys()),
|
265
|
-
|
266
|
-
list_prompts_func=self.list_prompts,
|
271
|
+
prompt_provider=self, # Pass self as the prompt provider
|
267
272
|
default=default_prompt,
|
268
273
|
)
|
@@ -10,12 +10,13 @@ Usage:
|
|
10
10
|
send_func=agent_app.send,
|
11
11
|
default_agent="default_agent",
|
12
12
|
available_agents=["agent1", "agent2"],
|
13
|
-
|
13
|
+
prompt_provider=agent_app
|
14
14
|
)
|
15
15
|
"""
|
16
16
|
|
17
|
-
from typing import Dict, List, Optional
|
17
|
+
from typing import Awaitable, Callable, Dict, List, Mapping, Optional, Protocol, Union
|
18
18
|
|
19
|
+
from mcp.types import Prompt, PromptMessage
|
19
20
|
from rich import print as rich_print
|
20
21
|
from rich.console import Console
|
21
22
|
from rich.table import Table
|
@@ -28,8 +29,24 @@ from mcp_agent.core.enhanced_prompt import (
|
|
28
29
|
handle_special_commands,
|
29
30
|
)
|
30
31
|
from mcp_agent.mcp.mcp_aggregator import SEP # Import SEP once at the top
|
32
|
+
from mcp_agent.mcp.prompt_message_multipart import PromptMessageMultipart
|
31
33
|
from mcp_agent.progress_display import progress_display
|
32
34
|
|
35
|
+
# Type alias for the send function
|
36
|
+
SendFunc = Callable[[Union[str, PromptMessage, PromptMessageMultipart], str], Awaitable[str]]
|
37
|
+
|
38
|
+
|
39
|
+
class PromptProvider(Protocol):
|
40
|
+
"""Protocol for objects that can provide prompt functionality."""
|
41
|
+
|
42
|
+
async def list_prompts(self, server_name: Optional[str] = None, agent_name: Optional[str] = None) -> Mapping[str, List[Prompt]]:
|
43
|
+
"""List available prompts."""
|
44
|
+
...
|
45
|
+
|
46
|
+
async def apply_prompt(self, prompt_name: str, arguments: Optional[Dict[str, str]] = None, agent_name: Optional[str] = None, **kwargs) -> str:
|
47
|
+
"""Apply a prompt."""
|
48
|
+
...
|
49
|
+
|
33
50
|
|
34
51
|
class InteractivePrompt:
|
35
52
|
"""
|
@@ -48,22 +65,20 @@ class InteractivePrompt:
|
|
48
65
|
|
49
66
|
async def prompt_loop(
|
50
67
|
self,
|
51
|
-
send_func,
|
68
|
+
send_func: SendFunc,
|
52
69
|
default_agent: str,
|
53
70
|
available_agents: List[str],
|
54
|
-
|
55
|
-
list_prompts_func=None,
|
71
|
+
prompt_provider: Optional[PromptProvider] = None,
|
56
72
|
default: str = "",
|
57
73
|
) -> str:
|
58
74
|
"""
|
59
75
|
Start an interactive prompt session.
|
60
76
|
|
61
77
|
Args:
|
62
|
-
send_func: Function to send messages to agents
|
78
|
+
send_func: Function to send messages to agents
|
63
79
|
default_agent: Name of the default agent to use
|
64
80
|
available_agents: List of available agent names
|
65
|
-
|
66
|
-
list_prompts_func: Optional function to list available prompts (signature: async (agent_name))
|
81
|
+
prompt_provider: Optional provider that implements list_prompts and apply_prompt
|
67
82
|
default: Default message to use when user presses enter
|
68
83
|
|
69
84
|
Returns:
|
@@ -110,13 +125,11 @@ class InteractivePrompt:
|
|
110
125
|
rich_print(f"[red]Agent '{new_agent}' not found[/red]")
|
111
126
|
continue
|
112
127
|
# Keep the existing list_prompts handler for backward compatibility
|
113
|
-
elif "list_prompts" in command_result and
|
114
|
-
# Use the
|
115
|
-
await self._list_prompts(
|
128
|
+
elif "list_prompts" in command_result and prompt_provider:
|
129
|
+
# Use the prompt_provider directly
|
130
|
+
await self._list_prompts(prompt_provider, agent)
|
116
131
|
continue
|
117
|
-
elif "select_prompt" in command_result and
|
118
|
-
list_prompts_func and apply_prompt_func
|
119
|
-
):
|
132
|
+
elif "select_prompt" in command_result and prompt_provider:
|
120
133
|
# Handle prompt selection, using both list_prompts and apply_prompt
|
121
134
|
prompt_name = command_result.get("prompt_name")
|
122
135
|
prompt_index = command_result.get("prompt_index")
|
@@ -124,7 +137,7 @@ class InteractivePrompt:
|
|
124
137
|
# If a specific index was provided (from /prompt <number>)
|
125
138
|
if prompt_index is not None:
|
126
139
|
# First get a list of all prompts to look up the index
|
127
|
-
all_prompts = await self._get_all_prompts(
|
140
|
+
all_prompts = await self._get_all_prompts(prompt_provider, agent)
|
128
141
|
if not all_prompts:
|
129
142
|
rich_print("[yellow]No prompts available[/yellow]")
|
130
143
|
continue
|
@@ -135,8 +148,7 @@ class InteractivePrompt:
|
|
135
148
|
selected_prompt = all_prompts[prompt_index - 1]
|
136
149
|
# Use the already created namespaced_name to ensure consistency
|
137
150
|
await self._select_prompt(
|
138
|
-
|
139
|
-
apply_prompt_func,
|
151
|
+
prompt_provider,
|
140
152
|
agent,
|
141
153
|
selected_prompt["namespaced_name"],
|
142
154
|
)
|
@@ -145,11 +157,11 @@ class InteractivePrompt:
|
|
145
157
|
f"[red]Invalid prompt number: {prompt_index}. Valid range is 1-{len(all_prompts)}[/red]"
|
146
158
|
)
|
147
159
|
# Show the prompt list for convenience
|
148
|
-
await self._list_prompts(
|
160
|
+
await self._list_prompts(prompt_provider, agent)
|
149
161
|
else:
|
150
162
|
# Use the name-based selection
|
151
163
|
await self._select_prompt(
|
152
|
-
|
164
|
+
prompt_provider, agent, prompt_name
|
153
165
|
)
|
154
166
|
continue
|
155
167
|
|
@@ -171,21 +183,21 @@ class InteractivePrompt:
|
|
171
183
|
|
172
184
|
return result
|
173
185
|
|
174
|
-
async def _get_all_prompts(self,
|
186
|
+
async def _get_all_prompts(self, prompt_provider: PromptProvider, agent_name: Optional[str] = None):
|
175
187
|
"""
|
176
188
|
Get a list of all available prompts.
|
177
189
|
|
178
190
|
Args:
|
179
|
-
|
180
|
-
agent_name:
|
191
|
+
prompt_provider: Provider that implements list_prompts
|
192
|
+
agent_name: Optional agent name (for multi-agent apps)
|
181
193
|
|
182
194
|
Returns:
|
183
195
|
List of prompt info dictionaries, sorted by server and name
|
184
196
|
"""
|
185
197
|
try:
|
186
|
-
#
|
187
|
-
|
188
|
-
|
198
|
+
# Call list_prompts on the provider
|
199
|
+
prompt_servers = await prompt_provider.list_prompts(server_name=None, agent_name=agent_name)
|
200
|
+
|
189
201
|
all_prompts = []
|
190
202
|
|
191
203
|
# Process the returned prompt servers
|
@@ -219,14 +231,18 @@ class InteractivePrompt:
|
|
219
231
|
}
|
220
232
|
)
|
221
233
|
else:
|
234
|
+
# Handle Prompt objects from mcp.types
|
235
|
+
prompt_name = getattr(prompt, "name", str(prompt))
|
236
|
+
description = getattr(prompt, "description", "No description")
|
237
|
+
arguments = getattr(prompt, "arguments", [])
|
222
238
|
all_prompts.append(
|
223
239
|
{
|
224
240
|
"server": server_name,
|
225
|
-
"name":
|
226
|
-
"namespaced_name": f"{server_name}{SEP}{
|
227
|
-
"description":
|
228
|
-
"arg_count":
|
229
|
-
"arguments":
|
241
|
+
"name": prompt_name,
|
242
|
+
"namespaced_name": f"{server_name}{SEP}{prompt_name}",
|
243
|
+
"description": description,
|
244
|
+
"arg_count": len(arguments),
|
245
|
+
"arguments": arguments,
|
230
246
|
}
|
231
247
|
)
|
232
248
|
|
@@ -244,27 +260,22 @@ class InteractivePrompt:
|
|
244
260
|
rich_print(f"[dim]{traceback.format_exc()}[/dim]")
|
245
261
|
return []
|
246
262
|
|
247
|
-
async def _list_prompts(self,
|
263
|
+
async def _list_prompts(self, prompt_provider: PromptProvider, agent_name: str) -> None:
|
248
264
|
"""
|
249
265
|
List available prompts for an agent.
|
250
266
|
|
251
267
|
Args:
|
252
|
-
|
268
|
+
prompt_provider: Provider that implements list_prompts
|
253
269
|
agent_name: Name of the agent
|
254
270
|
"""
|
255
|
-
from rich import print as rich_print
|
256
|
-
from rich.console import Console
|
257
|
-
from rich.table import Table
|
258
|
-
|
259
271
|
console = Console()
|
260
272
|
|
261
273
|
try:
|
262
274
|
# Directly call the list_prompts function for this agent
|
263
275
|
rich_print(f"\n[bold]Fetching prompts for agent [cyan]{agent_name}[/cyan]...[/bold]")
|
264
276
|
|
265
|
-
# Get all prompts using the helper function
|
266
|
-
|
267
|
-
all_prompts = await self._get_all_prompts(list_prompts_func, None)
|
277
|
+
# Get all prompts using the helper function
|
278
|
+
all_prompts = await self._get_all_prompts(prompt_provider, agent_name)
|
268
279
|
|
269
280
|
if all_prompts:
|
270
281
|
# Create a table for better display
|
@@ -300,28 +311,24 @@ class InteractivePrompt:
|
|
300
311
|
rich_print(f"[dim]{traceback.format_exc()}[/dim]")
|
301
312
|
|
302
313
|
async def _select_prompt(
|
303
|
-
self,
|
314
|
+
self, prompt_provider: PromptProvider, agent_name: str, requested_name: Optional[str] = None
|
304
315
|
) -> None:
|
305
316
|
"""
|
306
317
|
Select and apply a prompt.
|
307
318
|
|
308
319
|
Args:
|
309
|
-
|
310
|
-
apply_prompt_func: Function to apply prompts
|
320
|
+
prompt_provider: Provider that implements list_prompts and apply_prompt
|
311
321
|
agent_name: Name of the agent
|
312
322
|
requested_name: Optional name of the prompt to apply
|
313
323
|
"""
|
314
|
-
# We already imported these at the top
|
315
|
-
from rich import print as rich_print
|
316
|
-
|
317
324
|
console = Console()
|
318
325
|
|
319
326
|
try:
|
320
|
-
# Get all available prompts directly from the
|
327
|
+
# Get all available prompts directly from the prompt provider
|
321
328
|
rich_print(f"\n[bold]Fetching prompts for agent [cyan]{agent_name}[/cyan]...[/bold]")
|
322
|
-
|
323
|
-
#
|
324
|
-
prompt_servers = await
|
329
|
+
|
330
|
+
# Call list_prompts on the provider
|
331
|
+
prompt_servers = await prompt_provider.list_prompts(server_name=None, agent_name=agent_name)
|
325
332
|
|
326
333
|
if not prompt_servers:
|
327
334
|
rich_print("[yellow]No prompts available for this agent[/yellow]")
|
@@ -542,8 +549,8 @@ class InteractivePrompt:
|
|
542
549
|
namespaced_name = selected_prompt["namespaced_name"]
|
543
550
|
rich_print(f"\n[bold]Applying prompt [cyan]{namespaced_name}[/cyan]...[/bold]")
|
544
551
|
|
545
|
-
# Call apply_prompt
|
546
|
-
await
|
552
|
+
# Call apply_prompt on the provider with the prompt name and arguments
|
553
|
+
await prompt_provider.apply_prompt(namespaced_name, arg_values, agent_name)
|
547
554
|
|
548
555
|
except Exception as e:
|
549
556
|
import traceback
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import asyncio
|
2
|
+
from typing import Any, List, Optional, Union
|
3
|
+
|
4
|
+
from mcp_agent.llm.augmented_llm import (
|
5
|
+
MessageParamT,
|
6
|
+
RequestParams,
|
7
|
+
)
|
8
|
+
from mcp_agent.llm.augmented_llm_passthrough import PassthroughLLM
|
9
|
+
from mcp_agent.llm.provider_types import Provider
|
10
|
+
from mcp_agent.mcp.prompt_message_multipart import PromptMessageMultipart
|
11
|
+
|
12
|
+
|
13
|
+
class SlowLLM(PassthroughLLM):
|
14
|
+
"""
|
15
|
+
A specialized LLM implementation that sleeps for 3 seconds before responding like PassthroughLLM.
|
16
|
+
|
17
|
+
This is useful for testing scenarios where you want to simulate slow responses
|
18
|
+
or for debugging timing-related issues in parallel workflows.
|
19
|
+
"""
|
20
|
+
|
21
|
+
def __init__(
|
22
|
+
self, provider=Provider.FAST_AGENT, name: str = "Slow", **kwargs: dict[str, Any]
|
23
|
+
) -> None:
|
24
|
+
super().__init__(name=name, provider=provider, **kwargs)
|
25
|
+
|
26
|
+
async def generate_str(
|
27
|
+
self,
|
28
|
+
message: Union[str, MessageParamT, List[MessageParamT]],
|
29
|
+
request_params: Optional[RequestParams] = None,
|
30
|
+
) -> str:
|
31
|
+
"""Sleep for 3 seconds then return the input message as a string."""
|
32
|
+
await asyncio.sleep(3)
|
33
|
+
return await super().generate_str(message, request_params)
|
34
|
+
|
35
|
+
async def _apply_prompt_provider_specific(
|
36
|
+
self,
|
37
|
+
multipart_messages: List["PromptMessageMultipart"],
|
38
|
+
request_params: RequestParams | None = None,
|
39
|
+
) -> PromptMessageMultipart:
|
40
|
+
"""Sleep for 3 seconds then apply prompt like PassthroughLLM."""
|
41
|
+
await asyncio.sleep(3)
|
42
|
+
return await super()._apply_prompt_provider_specific(multipart_messages, request_params)
|
@@ -8,12 +8,14 @@ from mcp_agent.core.exceptions import ModelConfigError
|
|
8
8
|
from mcp_agent.core.request_params import RequestParams
|
9
9
|
from mcp_agent.llm.augmented_llm_passthrough import PassthroughLLM
|
10
10
|
from mcp_agent.llm.augmented_llm_playback import PlaybackLLM
|
11
|
+
from mcp_agent.llm.augmented_llm_slow import SlowLLM
|
11
12
|
from mcp_agent.llm.provider_types import Provider
|
12
13
|
from mcp_agent.llm.providers.augmented_llm_anthropic import AnthropicAugmentedLLM
|
13
14
|
from mcp_agent.llm.providers.augmented_llm_azure import AzureOpenAIAugmentedLLM
|
14
15
|
from mcp_agent.llm.providers.augmented_llm_deepseek import DeepSeekAugmentedLLM
|
15
16
|
from mcp_agent.llm.providers.augmented_llm_generic import GenericAugmentedLLM
|
16
|
-
from mcp_agent.llm.providers.
|
17
|
+
from mcp_agent.llm.providers.augmented_llm_google_native import GoogleNativeAugmentedLLM
|
18
|
+
from mcp_agent.llm.providers.augmented_llm_google_oai import GoogleOaiAugmentedLLM
|
17
19
|
from mcp_agent.llm.providers.augmented_llm_openai import OpenAIAugmentedLLM
|
18
20
|
from mcp_agent.llm.providers.augmented_llm_openrouter import OpenRouterAugmentedLLM
|
19
21
|
from mcp_agent.llm.providers.augmented_llm_tensorzero import TensorZeroAugmentedLLM
|
@@ -28,9 +30,13 @@ LLMClass = Union[
|
|
28
30
|
Type[OpenAIAugmentedLLM],
|
29
31
|
Type[PassthroughLLM],
|
30
32
|
Type[PlaybackLLM],
|
33
|
+
Type[SlowLLM],
|
31
34
|
Type[DeepSeekAugmentedLLM],
|
32
35
|
Type[OpenRouterAugmentedLLM],
|
33
36
|
Type[TensorZeroAugmentedLLM],
|
37
|
+
Type[GoogleNativeAugmentedLLM],
|
38
|
+
Type[GenericAugmentedLLM],
|
39
|
+
Type[AzureOpenAIAugmentedLLM],
|
34
40
|
]
|
35
41
|
|
36
42
|
|
@@ -60,13 +66,16 @@ class ModelFactory:
|
|
60
66
|
"high": ReasoningEffort.HIGH,
|
61
67
|
}
|
62
68
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
69
|
+
"""
|
70
|
+
TODO -- add context window size information for display/management
|
71
|
+
TODO -- add audio supporting got-4o-audio-preview
|
72
|
+
TODO -- bring model parameter configuration here
|
73
|
+
Mapping of model names to their default providers
|
74
|
+
"""
|
67
75
|
DEFAULT_PROVIDERS = {
|
68
76
|
"passthrough": Provider.FAST_AGENT,
|
69
77
|
"playback": Provider.FAST_AGENT,
|
78
|
+
"slow": Provider.FAST_AGENT,
|
70
79
|
"gpt-4o": Provider.OPENAI,
|
71
80
|
"gpt-4o-mini": Provider.OPENAI,
|
72
81
|
"gpt-4.1": Provider.OPENAI,
|
@@ -91,7 +100,9 @@ class ModelFactory:
|
|
91
100
|
"claude-sonnet-4-20250514": Provider.ANTHROPIC,
|
92
101
|
"claude-sonnet-4-0": Provider.ANTHROPIC,
|
93
102
|
"deepseek-chat": Provider.DEEPSEEK,
|
94
|
-
|
103
|
+
"gemini-2.0-flash": Provider.GOOGLE,
|
104
|
+
"gemini-2.5-flash-preview-05-20": Provider.GOOGLE,
|
105
|
+
"gemini-2.5-pro-preview-05-06": Provider.GOOGLE,
|
95
106
|
}
|
96
107
|
|
97
108
|
MODEL_ALIASES = {
|
@@ -108,6 +119,9 @@ class ModelFactory:
|
|
108
119
|
"opus3": "claude-3-opus-latest",
|
109
120
|
"deepseekv3": "deepseek-chat",
|
110
121
|
"deepseek": "deepseek-chat",
|
122
|
+
"gemini2": "gemini-2.0-flash",
|
123
|
+
"gemini25": "gemini-2.5-flash-preview-05-20",
|
124
|
+
"gemini25pro": "gemini-2.5-pro-preview-05-06",
|
111
125
|
}
|
112
126
|
|
113
127
|
# Mapping of providers to their LLM classes
|
@@ -117,7 +131,8 @@ class ModelFactory:
|
|
117
131
|
Provider.FAST_AGENT: PassthroughLLM,
|
118
132
|
Provider.DEEPSEEK: DeepSeekAugmentedLLM,
|
119
133
|
Provider.GENERIC: GenericAugmentedLLM,
|
120
|
-
Provider.
|
134
|
+
Provider.GOOGLE_OAI: GoogleOaiAugmentedLLM,
|
135
|
+
Provider.GOOGLE: GoogleNativeAugmentedLLM,
|
121
136
|
Provider.OPENROUTER: OpenRouterAugmentedLLM,
|
122
137
|
Provider.TENSORZERO: TensorZeroAugmentedLLM,
|
123
138
|
Provider.AZURE: AzureOpenAIAugmentedLLM,
|
@@ -127,48 +142,66 @@ class ModelFactory:
|
|
127
142
|
# This overrides the provider-based class selection
|
128
143
|
MODEL_SPECIFIC_CLASSES: Dict[str, LLMClass] = {
|
129
144
|
"playback": PlaybackLLM,
|
145
|
+
"slow": SlowLLM,
|
130
146
|
}
|
131
147
|
|
132
148
|
@classmethod
|
133
149
|
def parse_model_string(cls, model_string: str) -> ModelConfig:
|
134
150
|
"""Parse a model string into a ModelConfig object"""
|
135
|
-
# Check if model string is an alias
|
136
151
|
model_string = cls.MODEL_ALIASES.get(model_string, model_string)
|
137
152
|
parts = model_string.split(".")
|
138
153
|
|
139
|
-
#
|
140
|
-
model_parts = parts.copy()
|
154
|
+
model_name_str = model_string # Default full string as model name initially
|
141
155
|
provider = None
|
142
156
|
reasoning_effort = None
|
157
|
+
parts_for_provider_model = []
|
143
158
|
|
144
|
-
# Check
|
159
|
+
# Check for reasoning effort first (last part)
|
145
160
|
if len(parts) > 1 and parts[-1].lower() in cls.EFFORT_MAP:
|
146
161
|
reasoning_effort = cls.EFFORT_MAP[parts[-1].lower()]
|
147
|
-
|
162
|
+
# Remove effort from parts list for provider/model name determination
|
163
|
+
parts_for_provider_model = parts[:-1]
|
164
|
+
else:
|
165
|
+
parts_for_provider_model = parts[:]
|
166
|
+
|
167
|
+
# Try to match longest possible provider string
|
168
|
+
identified_provider_parts = 0 # How many parts belong to the provider string
|
169
|
+
|
170
|
+
if len(parts_for_provider_model) >= 2:
|
171
|
+
potential_provider_str = f"{parts_for_provider_model[0]}.{parts_for_provider_model[1]}"
|
172
|
+
if any(p.value == potential_provider_str for p in Provider):
|
173
|
+
provider = Provider(potential_provider_str)
|
174
|
+
identified_provider_parts = 2
|
175
|
+
|
176
|
+
if provider is None and len(parts_for_provider_model) >= 1:
|
177
|
+
potential_provider_str = parts_for_provider_model[0]
|
178
|
+
if any(p.value == potential_provider_str for p in Provider):
|
179
|
+
provider = Provider(potential_provider_str)
|
180
|
+
identified_provider_parts = 1
|
181
|
+
|
182
|
+
# Construct model_name from remaining parts
|
183
|
+
if identified_provider_parts > 0:
|
184
|
+
model_name_str = ".".join(parts_for_provider_model[identified_provider_parts:])
|
185
|
+
else:
|
186
|
+
# If no provider prefix was matched, the whole string (after effort removal) is the model name
|
187
|
+
model_name_str = ".".join(parts_for_provider_model)
|
148
188
|
|
149
|
-
#
|
150
|
-
if
|
151
|
-
|
152
|
-
if
|
153
|
-
|
154
|
-
|
189
|
+
# If provider still None, try to get from DEFAULT_PROVIDERS using the model_name_str
|
190
|
+
if provider is None:
|
191
|
+
provider = cls.DEFAULT_PROVIDERS.get(model_name_str)
|
192
|
+
if provider is None:
|
193
|
+
raise ModelConfigError(
|
194
|
+
f"Unknown model or provider for: {model_string}. Model name parsed as '{model_name_str}'"
|
195
|
+
)
|
155
196
|
|
156
|
-
if provider == Provider.TENSORZERO and not
|
197
|
+
if provider == Provider.TENSORZERO and not model_name_str:
|
157
198
|
raise ModelConfigError(
|
158
199
|
f"TensorZero provider requires a function name after the provider "
|
159
200
|
f"(e.g., tensorzero.my-function), got: {model_string}"
|
160
201
|
)
|
161
|
-
# Join remaining parts as model name
|
162
|
-
model_name = ".".join(model_parts)
|
163
|
-
|
164
|
-
# If no provider was found in the string, look it up in defaults
|
165
|
-
if provider is None:
|
166
|
-
provider = cls.DEFAULT_PROVIDERS.get(model_name)
|
167
|
-
if provider is None:
|
168
|
-
raise ModelConfigError(f"Unknown model: {model_name}")
|
169
202
|
|
170
203
|
return ModelConfig(
|
171
|
-
provider=provider, model_name=
|
204
|
+
provider=provider, model_name=model_name_str, reasoning_effort=reasoning_effort
|
172
205
|
)
|
173
206
|
|
174
207
|
@classmethod
|
@@ -185,33 +218,37 @@ class ModelFactory:
|
|
185
218
|
Returns:
|
186
219
|
A callable that takes an agent parameter and returns an LLM instance
|
187
220
|
"""
|
188
|
-
# Parse configuration up front
|
189
221
|
config = cls.parse_model_string(model_string)
|
222
|
+
|
223
|
+
# Ensure provider is valid before trying to access PROVIDER_CLASSES with it
|
224
|
+
if (
|
225
|
+
config.provider not in cls.PROVIDER_CLASSES
|
226
|
+
and config.model_name not in cls.MODEL_SPECIFIC_CLASSES
|
227
|
+
):
|
228
|
+
# This check is important if a provider (like old GOOGLE) is commented out from PROVIDER_CLASSES
|
229
|
+
raise ModelConfigError(
|
230
|
+
f"Provider '{config.provider}' not configured in PROVIDER_CLASSES and model '{config.model_name}' not in MODEL_SPECIFIC_CLASSES."
|
231
|
+
)
|
232
|
+
|
190
233
|
if config.model_name in cls.MODEL_SPECIFIC_CLASSES:
|
191
234
|
llm_class = cls.MODEL_SPECIFIC_CLASSES[config.model_name]
|
192
235
|
else:
|
236
|
+
# This line is now safer due to the check above
|
193
237
|
llm_class = cls.PROVIDER_CLASSES[config.provider]
|
194
238
|
|
195
|
-
# Create a factory function matching the updated attach_llm protocol
|
196
239
|
def factory(
|
197
240
|
agent: Agent, request_params: Optional[RequestParams] = None, **kwargs
|
198
241
|
) -> AugmentedLLMProtocol:
|
199
|
-
# Create base params with parsed model name
|
200
242
|
base_params = RequestParams()
|
201
|
-
base_params.model = config.model_name
|
202
|
-
|
203
|
-
# Add reasoning effort if available
|
243
|
+
base_params.model = config.model_name
|
204
244
|
if config.reasoning_effort:
|
205
245
|
kwargs["reasoning_effort"] = config.reasoning_effort.value
|
206
|
-
|
207
|
-
# Forward all arguments to LLM constructor
|
208
246
|
llm_args = {
|
209
247
|
"agent": agent,
|
210
248
|
"model": config.model_name,
|
211
249
|
"request_params": request_params,
|
212
250
|
**kwargs,
|
213
251
|
}
|
214
|
-
|
215
252
|
llm: AugmentedLLMProtocol = llm_class(**llm_args)
|
216
253
|
return llm
|
217
254
|
|