fast-agent-mcp 0.3.5__tar.gz → 0.3.6__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.3.5 → fast_agent_mcp-0.3.6}/PKG-INFO +1 -1
- {fast_agent_mcp-0.3.5/src/fast_agent/resources → fast_agent_mcp-0.3.6/examples}/setup/.gitignore +6 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/setup/agent.py +8 -1
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/setup/pyproject.toml.tmpl +6 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/pyproject.toml +1 -1
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/agents/llm_agent.py +15 -1
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/agents/mcp_agent.py +73 -1
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/agents/tool_agent.py +10 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/agents/workflow/router_agent.py +10 -2
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/cli/commands/auth.py +52 -29
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/cli/commands/check_config.py +26 -5
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/cli/commands/go.py +8 -2
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/cli/commands/setup.py +4 -7
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/config.py +4 -1
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/mcp_aggregator.py +30 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/mcp_connection_manager.py +23 -4
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/oauth_client.py +32 -4
- {fast_agent_mcp-0.3.5/examples → fast_agent_mcp-0.3.6/src/fast_agent/resources}/setup/.gitignore +6 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/setup/agent.py +8 -1
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/setup/pyproject.toml.tmpl +6 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/ui/console_display.py +48 -31
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/ui/enhanced_prompt.py +8 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/ui/interactive_prompt.py +54 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/.gitignore +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/LICENSE +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/README.md +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/azure-openai/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/bedrock/fast-agent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/custom-agents/agent.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/custom-agents/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/data-analysis/analysis-campaign.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/data-analysis/analysis.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/data-analysis/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/fastapi/fastapi-advanced.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/fastapi/fastapi-simple.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/fastapi/pyproject.toml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/fastapi/readme.md +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/elicitations/elicitation_account_server.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/elicitations/elicitation_forms_server.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/elicitations/elicitation_game_server.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/elicitations/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/elicitations/fastagent.secrets.yaml.example +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/elicitations/forms_demo.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/elicitations/game_character.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/elicitations/game_character_handler.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/elicitations/tool_call.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/mcp-filtering/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/mcp-filtering/fastagent.secrets.yaml.example +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/mcp-filtering/mcp_server.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/mcp-filtering/test_mcp_filtering.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/state-transfer/agent_one.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/state-transfer/agent_two.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/state-transfer/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/state-transfer/fastagent.secrets.yaml.example +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/vision-examples/cat.png +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/vision-examples/example1.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/vision-examples/example2.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/vision-examples/example3.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/mcp/vision-examples/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/new-api/display_check.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/new-api/simple_llm.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/new-api/simple_llm_advanced.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/new-api/simple_mcp.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/otel/agent.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/otel/agent2.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/otel/docker-compose.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/otel/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/researcher/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/researcher/researcher-eval.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/researcher/researcher-imp.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/researcher/researcher.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/setup/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/setup/fastagent.secrets.yaml.example +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/tensorzero/.env.sample +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/tensorzero/Makefile +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/tensorzero/README.md +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/tensorzero/agent.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/tensorzero/demo_images/clam.jpg +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/tensorzero/demo_images/crab.png +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/tensorzero/demo_images/shrimp.png +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/tensorzero/docker-compose.yml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/tensorzero/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/tensorzero/image_demo.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/tensorzero/mcp_server/Dockerfile +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/tensorzero/mcp_server/entrypoint.sh +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/tensorzero/mcp_server/mcp_server.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/tensorzero/mcp_server/pyproject.toml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/tensorzero/simple_agent.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/tensorzero/tensorzero_config/system_schema.json +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/tensorzero/tensorzero_config/system_template.minijinja +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/tensorzero/tensorzero_config/tensorzero.toml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/workflows/chaining.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/workflows/evaluator.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/workflows/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/workflows/graded_report.md +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/workflows/human_input.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/workflows/orchestrator.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/workflows/parallel.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/workflows/router.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/workflows/short_story.md +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/examples/workflows/short_story.txt +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/hatch_build.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/__init__.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/agents/__init__.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/agents/agent_types.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/agents/llm_decorator.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/agents/workflow/chain_agent.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/agents/workflow/evaluator_optimizer.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/agents/workflow/iterative_planner.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/agents/workflow/orchestrator_models.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/agents/workflow/orchestrator_prompts.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/agents/workflow/parallel_agent.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/cli/__init__.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/cli/__main__.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/cli/commands/quickstart.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/cli/commands/server_helpers.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/cli/commands/url_parser.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/cli/constants.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/cli/main.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/cli/terminal.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/constants.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/context.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/context_dependent.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/__init__.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/agent_app.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/core_app.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/direct_decorators.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/direct_factory.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/error_handling.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/exceptions.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/executor/__init__.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/executor/executor.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/executor/task_registry.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/executor/workflow_signal.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/fastagent.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/logging/__init__.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/logging/events.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/logging/json_serializer.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/logging/listeners.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/logging/logger.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/logging/transport.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/prompt.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/core/validation.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/event_progress.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/history/history_exporter.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/human_input/__init__.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/human_input/elicitation_handler.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/human_input/elicitation_state.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/human_input/form_fields.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/human_input/simple_form.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/human_input/types.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/interfaces.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/__init__.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/fastagent_llm.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/internal/passthrough.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/internal/playback.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/internal/silent.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/internal/slow.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/memory.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/model_database.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/model_factory.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/model_info.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/prompt_utils.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/anthropic/anthropic_utils.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/anthropic/llm_anthropic.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/anthropic/multipart_converter_anthropic.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/bedrock/bedrock_utils.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/bedrock/llm_bedrock.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/google/google_converter.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/google/llm_google_native.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/openai/llm_aliyun.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/openai/llm_azure.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/openai/llm_deepseek.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/openai/llm_generic.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/openai/llm_google_oai.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/openai/llm_groq.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/openai/llm_openai.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/openai/llm_openrouter.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/openai/llm_tensorzero_openai.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/openai/llm_xai.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/openai/multipart_converter_openai.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/openai/openai_multipart.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider/openai/openai_utils.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider_key_manager.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/provider_types.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/request_params.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/sampling_converter.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/llm/usage_tracking.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/__init__.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/common.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/elicitation_factory.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/elicitation_handlers.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/gen_client.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/helpers/__init__.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/helpers/content_helpers.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/helpers/server_config_helpers.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/hf_auth.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/interfaces.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/logger_textio.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/mcp_agent_client_session.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/mcp_content.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/mime_utils.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/prompt.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/prompt_message_extended.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/prompt_render.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/prompt_serialization.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/prompts/__init__.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/prompts/__main__.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/prompts/prompt_constants.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/prompts/prompt_helpers.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/prompts/prompt_load.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/prompts/prompt_server.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/prompts/prompt_template.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/resource_utils.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/sampling.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/server/__init__.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/server/agent_server.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/ui_agent.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp/ui_mixin.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/mcp_server_registry.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/py.typed +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/data-analysis/analysis-campaign.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/data-analysis/analysis.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/data-analysis/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/mcp/elicitations/elicitation_account_server.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/mcp/elicitations/elicitation_forms_server.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/mcp/elicitations/elicitation_game_server.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/mcp/elicitations/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/mcp/elicitations/fastagent.secrets.yaml.example +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/mcp/elicitations/forms_demo.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/mcp/elicitations/game_character.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/mcp/elicitations/game_character_handler.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/mcp/elicitations/tool_call.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/mcp/state-transfer/agent_one.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/mcp/state-transfer/agent_two.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/mcp/state-transfer/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/mcp/state-transfer/fastagent.secrets.yaml.example +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/researcher/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/researcher/researcher-eval.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/researcher/researcher-imp.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/researcher/researcher.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/.env.sample +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/Makefile +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/README.md +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/agent.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/demo_images/clam.jpg +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/demo_images/crab.png +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/demo_images/shrimp.png +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/docker-compose.yml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/image_demo.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/mcp_server/.python-version +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/mcp_server/Dockerfile +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/mcp_server/entrypoint.sh +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/mcp_server/mcp_server.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/mcp_server/pyproject.toml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/simple_agent.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/tensorzero_config/system_schema.json +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/tensorzero_config/system_template.minijinja +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/tensorzero/tensorzero_config/tensorzero.toml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/workflows/chaining.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/workflows/evaluator.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/workflows/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/workflows/graded_report.md +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/workflows/human_input.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/workflows/orchestrator.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/workflows/parallel.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/workflows/router.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/workflows/short_story.md +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/examples/workflows/short_story.txt +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/setup/fastagent.config.yaml +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/resources/setup/fastagent.secrets.yaml.example +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/tools/elicitation.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/types/__init__.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/types/llm_stop_reason.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/ui/__init__.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/ui/console.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/ui/elicitation_form.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/ui/elicitation_style.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/ui/mcp_ui_utils.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/ui/mermaid_utils.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/ui/progress_display.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/ui/rich_progress.py +0 -0
- {fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/ui/usage_display.py +0 -0
|
@@ -6,8 +6,15 @@ from fast_agent import FastAgent
|
|
|
6
6
|
fast = FastAgent("fast-agent example")
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
default_instruction = """You are a helpful AI Agent.
|
|
10
|
+
|
|
11
|
+
{{serverInstructions}}
|
|
12
|
+
|
|
13
|
+
The current date is {{currentDate}}."""
|
|
14
|
+
|
|
15
|
+
|
|
9
16
|
# Define the agent
|
|
10
|
-
@fast.agent(instruction=
|
|
17
|
+
@fast.agent(instruction=default_instruction)
|
|
11
18
|
async def main():
|
|
12
19
|
# use the --model command line switch or agent arguments to change model
|
|
13
20
|
async with fast.run() as agent:
|
|
@@ -137,10 +137,24 @@ class LlmAgent(LlmDecorator):
|
|
|
137
137
|
display_name = name if name is not None else self.name
|
|
138
138
|
display_model = model if model is not None else (self.llm.model_name if self._llm else None)
|
|
139
139
|
|
|
140
|
+
# Convert highlight_items to highlight_index
|
|
141
|
+
highlight_index = None
|
|
142
|
+
if highlight_items and bottom_items:
|
|
143
|
+
if isinstance(highlight_items, str):
|
|
144
|
+
try:
|
|
145
|
+
highlight_index = bottom_items.index(highlight_items)
|
|
146
|
+
except ValueError:
|
|
147
|
+
pass
|
|
148
|
+
elif isinstance(highlight_items, list) and len(highlight_items) > 0:
|
|
149
|
+
try:
|
|
150
|
+
highlight_index = bottom_items.index(highlight_items[0])
|
|
151
|
+
except ValueError:
|
|
152
|
+
pass
|
|
153
|
+
|
|
140
154
|
await self.display.show_assistant_message(
|
|
141
155
|
message_text,
|
|
142
156
|
bottom_items=bottom_items,
|
|
143
|
-
|
|
157
|
+
highlight_index=highlight_index,
|
|
144
158
|
max_item_length=max_item_length,
|
|
145
159
|
name=display_name,
|
|
146
160
|
model=display_model,
|
|
@@ -156,6 +156,9 @@ class McpAgent(ABC, ToolAgent):
|
|
|
156
156
|
"""
|
|
157
157
|
await self.__aenter__()
|
|
158
158
|
|
|
159
|
+
# Apply template substitution to the instruction with server instructions
|
|
160
|
+
await self._apply_instruction_templates()
|
|
161
|
+
|
|
159
162
|
async def shutdown(self) -> None:
|
|
160
163
|
"""
|
|
161
164
|
Shutdown the agent and close all MCP server connections.
|
|
@@ -174,6 +177,67 @@ class McpAgent(ABC, ToolAgent):
|
|
|
174
177
|
self._initialized = value
|
|
175
178
|
self._aggregator.initialized = value
|
|
176
179
|
|
|
180
|
+
async def _apply_instruction_templates(self) -> None:
|
|
181
|
+
"""
|
|
182
|
+
Apply template substitution to the instruction, including server instructions.
|
|
183
|
+
This is called during initialization after servers are connected.
|
|
184
|
+
"""
|
|
185
|
+
if not self.instruction:
|
|
186
|
+
return
|
|
187
|
+
|
|
188
|
+
# Gather server instructions if the template includes {{serverInstructions}}
|
|
189
|
+
if "{{serverInstructions}}" in self.instruction:
|
|
190
|
+
try:
|
|
191
|
+
instructions_data = await self._aggregator.get_server_instructions()
|
|
192
|
+
server_instructions = self._format_server_instructions(instructions_data)
|
|
193
|
+
except Exception as e:
|
|
194
|
+
self.logger.warning(f"Failed to get server instructions: {e}")
|
|
195
|
+
server_instructions = ""
|
|
196
|
+
|
|
197
|
+
# Replace the template variable
|
|
198
|
+
self.instruction = self.instruction.replace("{{serverInstructions}}", server_instructions)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
# Update default request params to match
|
|
202
|
+
if self._default_request_params:
|
|
203
|
+
self._default_request_params.systemPrompt = self.instruction
|
|
204
|
+
|
|
205
|
+
self.logger.debug(f"Applied instruction templates for agent {self._name}")
|
|
206
|
+
|
|
207
|
+
def _format_server_instructions(self, instructions_data: Dict[str, tuple[str | None, List[str]]]) -> str:
|
|
208
|
+
"""
|
|
209
|
+
Format server instructions with XML tags and tool lists.
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
instructions_data: Dict mapping server name to (instructions, tool_names)
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
Formatted string with server instructions
|
|
216
|
+
"""
|
|
217
|
+
if not instructions_data:
|
|
218
|
+
return ""
|
|
219
|
+
|
|
220
|
+
formatted_parts = []
|
|
221
|
+
for server_name, (instructions, tool_names) in instructions_data.items():
|
|
222
|
+
# Skip servers with no instructions
|
|
223
|
+
if instructions is None:
|
|
224
|
+
continue
|
|
225
|
+
|
|
226
|
+
# Format tool names with server prefix
|
|
227
|
+
prefixed_tools = [f"{server_name}-{tool}" for tool in tool_names]
|
|
228
|
+
tools_list = ", ".join(prefixed_tools) if prefixed_tools else "No tools available"
|
|
229
|
+
|
|
230
|
+
formatted_parts.append(
|
|
231
|
+
f"<mcp-server name=\"{server_name}\">\n"
|
|
232
|
+
f"<tools>{tools_list}</tools>\n"
|
|
233
|
+
f"<instructions>\n{instructions}\n</instructions>\n"
|
|
234
|
+
f"</mcp-server>"
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
if formatted_parts:
|
|
238
|
+
return "\n\n".join(formatted_parts)
|
|
239
|
+
return ""
|
|
240
|
+
|
|
177
241
|
async def __call__(
|
|
178
242
|
self,
|
|
179
243
|
message: Union[
|
|
@@ -549,12 +613,20 @@ class McpAgent(ABC, ToolAgent):
|
|
|
549
613
|
namespaced_tool = self._aggregator._namespaced_tool_map.get(tool_name)
|
|
550
614
|
display_tool_name = namespaced_tool.tool.name if namespaced_tool else tool_name
|
|
551
615
|
|
|
616
|
+
# Find the index of the current tool in available_tools for highlighting
|
|
617
|
+
highlight_index = None
|
|
618
|
+
try:
|
|
619
|
+
highlight_index = available_tools.index(display_tool_name)
|
|
620
|
+
except ValueError:
|
|
621
|
+
# Tool not found in list, no highlighting
|
|
622
|
+
pass
|
|
623
|
+
|
|
552
624
|
self.display.show_tool_call(
|
|
553
625
|
name=self._name,
|
|
554
626
|
tool_args=tool_args,
|
|
555
627
|
bottom_items=available_tools,
|
|
556
628
|
tool_name=display_tool_name,
|
|
557
|
-
|
|
629
|
+
highlight_index=highlight_index,
|
|
558
630
|
max_item_length=12,
|
|
559
631
|
)
|
|
560
632
|
|
|
@@ -128,11 +128,21 @@ class ToolAgent(LlmAgent):
|
|
|
128
128
|
for correlation_id, tool_request in request.tool_calls.items():
|
|
129
129
|
tool_name = tool_request.params.name
|
|
130
130
|
tool_args = tool_request.params.arguments or {}
|
|
131
|
+
|
|
132
|
+
# Find the index of the current tool in available_tools for highlighting
|
|
133
|
+
highlight_index = None
|
|
134
|
+
try:
|
|
135
|
+
highlight_index = available_tools.index(tool_name)
|
|
136
|
+
except ValueError:
|
|
137
|
+
# Tool not found in list, no highlighting
|
|
138
|
+
pass
|
|
139
|
+
|
|
131
140
|
self.display.show_tool_call(
|
|
132
141
|
name=self.name,
|
|
133
142
|
tool_args=tool_args,
|
|
134
143
|
bottom_items=available_tools,
|
|
135
144
|
tool_name=tool_name,
|
|
145
|
+
highlight_index=highlight_index,
|
|
136
146
|
max_item_length=12,
|
|
137
147
|
)
|
|
138
148
|
|
{fast_agent_mcp-0.3.5 → fast_agent_mcp-0.3.6}/src/fast_agent/agents/workflow/router_agent.py
RENAMED
|
@@ -300,10 +300,18 @@ class RouterAgent(LlmAgent):
|
|
|
300
300
|
if response.reasoning:
|
|
301
301
|
routing_message += f" ({response.reasoning})"
|
|
302
302
|
|
|
303
|
+
# Convert highlight_items to highlight_index
|
|
304
|
+
agent_keys = list(self.agent_map.keys())
|
|
305
|
+
highlight_index = None
|
|
306
|
+
try:
|
|
307
|
+
highlight_index = agent_keys.index(response.agent)
|
|
308
|
+
except ValueError:
|
|
309
|
+
pass
|
|
310
|
+
|
|
303
311
|
await self.display.show_assistant_message(
|
|
304
312
|
routing_message,
|
|
305
|
-
bottom_items=
|
|
306
|
-
|
|
313
|
+
bottom_items=agent_keys,
|
|
314
|
+
highlight_index=highlight_index,
|
|
307
315
|
name=self.name,
|
|
308
316
|
)
|
|
309
317
|
|
|
@@ -22,14 +22,28 @@ from fast_agent.ui.console import console
|
|
|
22
22
|
app = typer.Typer(help="Manage OAuth authentication state for MCP servers")
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
def
|
|
25
|
+
def _get_keyring_status() -> tuple[str, bool]:
|
|
26
|
+
"""Return (backend_name, usable) where usable=False for the fail backend or missing keyring."""
|
|
26
27
|
try:
|
|
27
28
|
import keyring
|
|
28
29
|
|
|
29
30
|
kr = keyring.get_keyring()
|
|
30
|
-
|
|
31
|
+
name = getattr(kr, "name", kr.__class__.__name__)
|
|
32
|
+
try:
|
|
33
|
+
from keyring.backends.fail import Keyring as FailKeyring # type: ignore
|
|
34
|
+
|
|
35
|
+
return name, not isinstance(kr, FailKeyring)
|
|
36
|
+
except Exception:
|
|
37
|
+
# If fail backend marker cannot be imported, assume usable
|
|
38
|
+
return name, True
|
|
31
39
|
except Exception:
|
|
32
|
-
return "unavailable"
|
|
40
|
+
return "unavailable", False
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _get_keyring_backend_name() -> str:
|
|
44
|
+
# Backwards-compat helper; prefer _get_keyring_status in new code
|
|
45
|
+
name, _ = _get_keyring_status()
|
|
46
|
+
return name
|
|
33
47
|
|
|
34
48
|
|
|
35
49
|
def _keyring_get_password(service: str, username: str) -> str | None:
|
|
@@ -106,7 +120,7 @@ def status(
|
|
|
106
120
|
) -> None:
|
|
107
121
|
"""Show keyring backend and token status for configured MCP servers."""
|
|
108
122
|
settings = get_settings(config_path)
|
|
109
|
-
backend =
|
|
123
|
+
backend, backend_usable = _get_keyring_status()
|
|
110
124
|
|
|
111
125
|
# Single-target view if target provided
|
|
112
126
|
if target:
|
|
@@ -123,12 +137,15 @@ def status(
|
|
|
123
137
|
|
|
124
138
|
# Direct presence check
|
|
125
139
|
present = False
|
|
126
|
-
|
|
127
|
-
|
|
140
|
+
if backend_usable:
|
|
141
|
+
try:
|
|
142
|
+
import keyring
|
|
128
143
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
144
|
+
present = (
|
|
145
|
+
keyring.get_password("fast-agent-mcp", f"oauth:tokens:{identity}") is not None
|
|
146
|
+
)
|
|
147
|
+
except Exception:
|
|
148
|
+
present = False
|
|
132
149
|
|
|
133
150
|
table = Table(show_header=True, box=None)
|
|
134
151
|
table.add_column("Identity", header_style="bold")
|
|
@@ -139,7 +156,10 @@ def status(
|
|
|
139
156
|
token_disp = "[bold green]✓[/bold green]" if present else "[dim]✗[/dim]"
|
|
140
157
|
table.add_row(identity, token_disp, servers_for_id)
|
|
141
158
|
|
|
142
|
-
|
|
159
|
+
if backend_usable and backend != "unavailable":
|
|
160
|
+
console.print(f"Keyring backend: [green]{backend}[/green]")
|
|
161
|
+
else:
|
|
162
|
+
console.print("Keyring backend: [red]not available[/red]")
|
|
143
163
|
console.print(table)
|
|
144
164
|
console.print(
|
|
145
165
|
"\n[dim]Run 'fast-agent auth clear --identity "
|
|
@@ -148,7 +168,10 @@ def status(
|
|
|
148
168
|
return
|
|
149
169
|
|
|
150
170
|
# Full status view
|
|
151
|
-
|
|
171
|
+
if backend_usable and backend != "unavailable":
|
|
172
|
+
console.print(f"Keyring backend: [green]{backend}[/green]")
|
|
173
|
+
else:
|
|
174
|
+
console.print("Keyring backend: [red]not available[/red]")
|
|
152
175
|
|
|
153
176
|
tokens = list_keyring_tokens()
|
|
154
177
|
token_table = Table(show_header=True, box=None)
|
|
@@ -181,25 +204,25 @@ def status(
|
|
|
181
204
|
)
|
|
182
205
|
# Direct presence check for each identity so status works even without index
|
|
183
206
|
has_token = False
|
|
207
|
+
token_disp = "[dim]✗[/dim]"
|
|
184
208
|
if persist == "keyring" and row["oauth"]:
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
)
|
|
209
|
+
if backend_usable:
|
|
210
|
+
try:
|
|
211
|
+
import keyring
|
|
212
|
+
|
|
213
|
+
has_token = (
|
|
214
|
+
keyring.get_password(
|
|
215
|
+
"fast-agent-mcp", f"oauth:tokens:{row['identity']}"
|
|
216
|
+
)
|
|
217
|
+
is not None
|
|
218
|
+
)
|
|
219
|
+
except Exception:
|
|
220
|
+
has_token = False
|
|
221
|
+
token_disp = "[bold green]✓[/bold green]" if has_token else "[dim]✗[/dim]"
|
|
222
|
+
else:
|
|
223
|
+
token_disp = "[red]not available[/red]"
|
|
224
|
+
elif persist == "memory" and row["oauth"]:
|
|
225
|
+
token_disp = "[yellow]memory[/yellow]"
|
|
203
226
|
map_table.add_row(
|
|
204
227
|
row["name"],
|
|
205
228
|
row["transport"].upper(),
|
|
@@ -305,14 +305,25 @@ def show_check_summary() -> None:
|
|
|
305
305
|
env_table.add_column("Value")
|
|
306
306
|
|
|
307
307
|
# Determine keyring backend early so it can appear in the top section
|
|
308
|
+
# Also detect whether the backend is actually usable (not the fail backend)
|
|
309
|
+
keyring_usable = False
|
|
308
310
|
try:
|
|
309
311
|
import keyring # type: ignore
|
|
310
312
|
|
|
311
313
|
keyring_backend = keyring.get_keyring()
|
|
312
314
|
keyring_name = getattr(keyring_backend, "name", keyring_backend.__class__.__name__)
|
|
315
|
+
try:
|
|
316
|
+
# Detect the "fail" backend explicitly; it's present but unusable
|
|
317
|
+
from keyring.backends.fail import Keyring as FailKeyring # type: ignore
|
|
318
|
+
|
|
319
|
+
keyring_usable = not isinstance(keyring_backend, FailKeyring)
|
|
320
|
+
except Exception:
|
|
321
|
+
# If we can't import the fail backend marker, assume usable
|
|
322
|
+
keyring_usable = True
|
|
313
323
|
except Exception:
|
|
314
324
|
keyring = None # type: ignore
|
|
315
325
|
keyring_name = "unavailable"
|
|
326
|
+
keyring_usable = False
|
|
316
327
|
|
|
317
328
|
# Python info (highlight version and path in green)
|
|
318
329
|
env_table.add_row(
|
|
@@ -345,11 +356,14 @@ def show_check_summary() -> None:
|
|
|
345
356
|
)
|
|
346
357
|
else: # parsed successfully
|
|
347
358
|
env_table.add_row("Config File", f"[green]Found[/green] ({config_path})")
|
|
348
|
-
default_model_value = config_summary.get("default_model", "
|
|
359
|
+
default_model_value = config_summary.get("default_model", "gpt-5-mini.low (system default)")
|
|
349
360
|
env_table.add_row("Default Model", f"[green]{default_model_value}[/green]")
|
|
350
361
|
|
|
351
362
|
# Keyring backend (always shown in application-level settings)
|
|
352
|
-
|
|
363
|
+
if keyring_usable and keyring_name != "unavailable":
|
|
364
|
+
env_table.add_row("Keyring Backend", f"[green]{keyring_name}[/green]")
|
|
365
|
+
else:
|
|
366
|
+
env_table.add_row("Keyring Backend", "[red]not available[/red]")
|
|
353
367
|
|
|
354
368
|
console.print(env_table)
|
|
355
369
|
|
|
@@ -514,7 +528,9 @@ def show_check_summary() -> None:
|
|
|
514
528
|
try:
|
|
515
529
|
cfg = MCPServerSettings(
|
|
516
530
|
name=name,
|
|
517
|
-
transport="sse"
|
|
531
|
+
transport="sse"
|
|
532
|
+
if transport == "SSE"
|
|
533
|
+
else ("stdio" if transport == "STDIO" else "http"),
|
|
518
534
|
url=(server.get("url") or None),
|
|
519
535
|
auth=server.get("auth") if isinstance(server.get("auth"), dict) else None,
|
|
520
536
|
)
|
|
@@ -532,11 +548,16 @@ def show_check_summary() -> None:
|
|
|
532
548
|
persist = "keyring"
|
|
533
549
|
if cfg.auth is not None and hasattr(cfg.auth, "persist"):
|
|
534
550
|
persist = getattr(cfg.auth, "persist") or "keyring"
|
|
535
|
-
if keyring and persist == "keyring" and oauth_enabled:
|
|
551
|
+
if keyring and keyring_usable and persist == "keyring" and oauth_enabled:
|
|
536
552
|
identity = compute_server_identity(cfg)
|
|
537
553
|
tkey = f"oauth:tokens:{identity}"
|
|
538
|
-
|
|
554
|
+
try:
|
|
555
|
+
has = keyring.get_password("fast-agent-mcp", tkey) is not None
|
|
556
|
+
except Exception:
|
|
557
|
+
has = False
|
|
539
558
|
token_status = "[bold green]✓[/bold green]" if has else "[dim]✗[/dim]"
|
|
559
|
+
elif persist == "keyring" and not keyring_usable and oauth_enabled:
|
|
560
|
+
token_status = "[red]not available[/red]"
|
|
540
561
|
elif persist == "memory" and oauth_enabled:
|
|
541
562
|
token_status = "[yellow]memory[/yellow]"
|
|
542
563
|
|
|
@@ -18,10 +18,16 @@ app = typer.Typer(
|
|
|
18
18
|
context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
|
|
19
19
|
)
|
|
20
20
|
|
|
21
|
+
default_instruction = """You are a helpful AI Agent.
|
|
22
|
+
|
|
23
|
+
{{serverInstructions}}
|
|
24
|
+
|
|
25
|
+
The current date is {{currentDate}}."""
|
|
26
|
+
|
|
21
27
|
|
|
22
28
|
async def _run_agent(
|
|
23
29
|
name: str = "fast-agent cli",
|
|
24
|
-
instruction: str =
|
|
30
|
+
instruction: str = default_instruction,
|
|
25
31
|
config_path: Optional[str] = None,
|
|
26
32
|
server_list: Optional[List[str]] = None,
|
|
27
33
|
model: Optional[str] = None,
|
|
@@ -352,7 +358,7 @@ def go(
|
|
|
352
358
|
stdio_commands.append(stdio)
|
|
353
359
|
|
|
354
360
|
# Resolve instruction from file/URL or use default
|
|
355
|
-
resolved_instruction =
|
|
361
|
+
resolved_instruction = default_instruction # Default
|
|
356
362
|
agent_name = "agent"
|
|
357
363
|
|
|
358
364
|
if instruction:
|
|
@@ -26,9 +26,7 @@ def load_template_text(filename: str) -> str:
|
|
|
26
26
|
res_name = "pyproject.toml.tmpl"
|
|
27
27
|
else:
|
|
28
28
|
res_name = filename
|
|
29
|
-
resource_path = (
|
|
30
|
-
files("fast_agent").joinpath("resources").joinpath("setup").joinpath(res_name)
|
|
31
|
-
)
|
|
29
|
+
resource_path = files("fast_agent").joinpath("resources").joinpath("setup").joinpath(res_name)
|
|
32
30
|
if resource_path.is_file():
|
|
33
31
|
return resource_path.read_text()
|
|
34
32
|
|
|
@@ -137,9 +135,8 @@ def init(
|
|
|
137
135
|
# Always use latest fast-agent-mcp (no version pin)
|
|
138
136
|
fast_agent_dep = '"fast-agent-mcp"'
|
|
139
137
|
|
|
140
|
-
return (
|
|
141
|
-
|
|
142
|
-
.replace("{{fast_agent_dep}}", fast_agent_dep)
|
|
138
|
+
return template_text.replace("{{python_requires}}", py_req).replace(
|
|
139
|
+
"{{fast_agent_dep}}", fast_agent_dep
|
|
143
140
|
)
|
|
144
141
|
|
|
145
142
|
pyproject_template = load_template_text("pyproject.toml")
|
|
@@ -169,7 +166,7 @@ def init(
|
|
|
169
166
|
"2. Keep fastagent.secrets.yaml secure and never commit it to version control"
|
|
170
167
|
)
|
|
171
168
|
console.print(
|
|
172
|
-
"3. Update fastagent.config.yaml to set a default model (currently system default is '
|
|
169
|
+
"3. Update fastagent.config.yaml to set a default model (currently system default is 'gpt-5-mini.low')"
|
|
173
170
|
)
|
|
174
171
|
console.print("\nTo get started, run:")
|
|
175
172
|
console.print(" uv run agent.py")
|
|
@@ -37,7 +37,7 @@ class MCPServerAuthSettings(BaseModel):
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
class MCPSamplingSettings(BaseModel):
|
|
40
|
-
model: str = "
|
|
40
|
+
model: str = "gpt-5-mini.low"
|
|
41
41
|
|
|
42
42
|
model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True)
|
|
43
43
|
|
|
@@ -122,6 +122,9 @@ class MCPServerSettings(BaseModel):
|
|
|
122
122
|
cwd: str | None = None
|
|
123
123
|
"""Working directory for the executed server command."""
|
|
124
124
|
|
|
125
|
+
include_instructions: bool = True
|
|
126
|
+
"""Whether to include this server's instructions in the system prompt (default: True)."""
|
|
127
|
+
|
|
125
128
|
implementation: Implementation | None = None
|
|
126
129
|
|
|
127
130
|
@model_validator(mode="before")
|
|
@@ -461,6 +461,36 @@ class MCPAggregator(ContextDependent):
|
|
|
461
461
|
for server_name in self.server_names:
|
|
462
462
|
await self._refresh_server_tools(server_name)
|
|
463
463
|
|
|
464
|
+
async def get_server_instructions(self) -> Dict[str, tuple[str, List[str]]]:
|
|
465
|
+
"""
|
|
466
|
+
Get instructions from all connected servers along with their tool names.
|
|
467
|
+
|
|
468
|
+
Returns:
|
|
469
|
+
Dict mapping server name to tuple of (instructions, list of tool names)
|
|
470
|
+
"""
|
|
471
|
+
instructions = {}
|
|
472
|
+
|
|
473
|
+
if self.connection_persistence and hasattr(self, '_persistent_connection_manager'):
|
|
474
|
+
# Get instructions from persistent connections
|
|
475
|
+
for server_name in self.server_names:
|
|
476
|
+
try:
|
|
477
|
+
server_conn = await self._persistent_connection_manager.get_server(
|
|
478
|
+
server_name, client_session_factory=self._create_session_factory(server_name)
|
|
479
|
+
)
|
|
480
|
+
# Always include server, even if no instructions
|
|
481
|
+
# Get tool names for this server
|
|
482
|
+
tool_names = [
|
|
483
|
+
namespaced_tool.tool.name
|
|
484
|
+
for namespaced_tool_name, namespaced_tool in self._namespaced_tool_map.items()
|
|
485
|
+
if namespaced_tool.server_name == server_name
|
|
486
|
+
]
|
|
487
|
+
# Include server even if instructions is None
|
|
488
|
+
instructions[server_name] = (server_conn.server_instructions, tool_names)
|
|
489
|
+
except Exception as e:
|
|
490
|
+
logger.debug(f"Failed to get instructions from server {server_name}: {e}")
|
|
491
|
+
|
|
492
|
+
return instructions
|
|
493
|
+
|
|
464
494
|
async def _execute_on_server(
|
|
465
495
|
self,
|
|
466
496
|
server_name: str,
|
|
@@ -105,6 +105,9 @@ class ServerConnection:
|
|
|
105
105
|
self._error_occurred = False
|
|
106
106
|
self._error_message = None
|
|
107
107
|
|
|
108
|
+
# Server instructions from initialization
|
|
109
|
+
self.server_instructions: str | None = None
|
|
110
|
+
|
|
108
111
|
def is_healthy(self) -> bool:
|
|
109
112
|
"""Check if the server connection is healthy and ready to use."""
|
|
110
113
|
return self.session is not None and not self._error_occurred
|
|
@@ -131,10 +134,20 @@ class ServerConnection:
|
|
|
131
134
|
Initializes the server connection and session.
|
|
132
135
|
Must be called within an async context.
|
|
133
136
|
"""
|
|
134
|
-
|
|
137
|
+
assert self.session, "Session must be created before initialization"
|
|
135
138
|
result = await self.session.initialize()
|
|
136
139
|
|
|
137
140
|
self.server_capabilities = result.capabilities
|
|
141
|
+
|
|
142
|
+
# Store instructions if provided by the server and enabled in config
|
|
143
|
+
if self.server_config.include_instructions:
|
|
144
|
+
self.server_instructions = getattr(result, 'instructions', None)
|
|
145
|
+
if self.server_instructions:
|
|
146
|
+
logger.debug(f"{self.server_name}: Received server instructions", data={"instructions": self.server_instructions})
|
|
147
|
+
else:
|
|
148
|
+
self.server_instructions = None
|
|
149
|
+
logger.debug(f"{self.server_name}: Server instructions disabled by configuration")
|
|
150
|
+
|
|
138
151
|
# If there's an init hook, run it
|
|
139
152
|
|
|
140
153
|
# Now the session is ready for use
|
|
@@ -343,7 +356,9 @@ class MCPConnectionManager(ContextDependent):
|
|
|
343
356
|
def transport_context_factory():
|
|
344
357
|
if config.transport == "stdio":
|
|
345
358
|
if not config.command:
|
|
346
|
-
raise ValueError(
|
|
359
|
+
raise ValueError(
|
|
360
|
+
f"Server '{server_name}' uses stdio transport but no command is specified"
|
|
361
|
+
)
|
|
347
362
|
server_params = StdioServerParameters(
|
|
348
363
|
command=config.command,
|
|
349
364
|
args=config.args if config.args is not None else [],
|
|
@@ -357,7 +372,9 @@ class MCPConnectionManager(ContextDependent):
|
|
|
357
372
|
return _add_none_to_context(stdio_client(server_params, errlog=error_handler))
|
|
358
373
|
elif config.transport == "sse":
|
|
359
374
|
if not config.url:
|
|
360
|
-
raise ValueError(
|
|
375
|
+
raise ValueError(
|
|
376
|
+
f"Server '{server_name}' uses sse transport but no url is specified"
|
|
377
|
+
)
|
|
361
378
|
# Suppress MCP library error spam
|
|
362
379
|
self._suppress_mcp_sse_errors()
|
|
363
380
|
oauth_auth = build_oauth_provider(config)
|
|
@@ -376,7 +393,9 @@ class MCPConnectionManager(ContextDependent):
|
|
|
376
393
|
)
|
|
377
394
|
elif config.transport == "http":
|
|
378
395
|
if not config.url:
|
|
379
|
-
raise ValueError(
|
|
396
|
+
raise ValueError(
|
|
397
|
+
f"Server '{server_name}' uses http transport but no url is specified"
|
|
398
|
+
)
|
|
380
399
|
oauth_auth = build_oauth_provider(config)
|
|
381
400
|
headers = dict(config.headers or {})
|
|
382
401
|
if oauth_auth is not None:
|