fast-agent-mcp 0.2.57__py3-none-any.whl → 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of fast-agent-mcp might be problematic. Click here for more details.
- fast_agent/__init__.py +127 -0
- fast_agent/agents/__init__.py +36 -0
- {mcp_agent/core → fast_agent/agents}/agent_types.py +2 -1
- fast_agent/agents/llm_agent.py +217 -0
- fast_agent/agents/llm_decorator.py +486 -0
- mcp_agent/agents/base_agent.py → fast_agent/agents/mcp_agent.py +377 -385
- fast_agent/agents/tool_agent.py +168 -0
- {mcp_agent → fast_agent}/agents/workflow/chain_agent.py +43 -33
- {mcp_agent → fast_agent}/agents/workflow/evaluator_optimizer.py +31 -35
- {mcp_agent → fast_agent}/agents/workflow/iterative_planner.py +56 -47
- {mcp_agent → fast_agent}/agents/workflow/orchestrator_models.py +4 -4
- {mcp_agent → fast_agent}/agents/workflow/parallel_agent.py +34 -41
- {mcp_agent → fast_agent}/agents/workflow/router_agent.py +54 -39
- {mcp_agent → fast_agent}/cli/__main__.py +5 -3
- {mcp_agent → fast_agent}/cli/commands/check_config.py +95 -66
- {mcp_agent → fast_agent}/cli/commands/go.py +20 -11
- {mcp_agent → fast_agent}/cli/commands/quickstart.py +4 -4
- {mcp_agent → fast_agent}/cli/commands/server_helpers.py +1 -1
- {mcp_agent → fast_agent}/cli/commands/setup.py +64 -134
- {mcp_agent → fast_agent}/cli/commands/url_parser.py +9 -8
- {mcp_agent → fast_agent}/cli/main.py +36 -16
- {mcp_agent → fast_agent}/cli/terminal.py +2 -2
- {mcp_agent → fast_agent}/config.py +13 -2
- fast_agent/constants.py +8 -0
- {mcp_agent → fast_agent}/context.py +24 -19
- {mcp_agent → fast_agent}/context_dependent.py +9 -5
- fast_agent/core/__init__.py +17 -0
- {mcp_agent → fast_agent}/core/agent_app.py +39 -36
- fast_agent/core/core_app.py +135 -0
- {mcp_agent → fast_agent}/core/direct_decorators.py +12 -26
- {mcp_agent → fast_agent}/core/direct_factory.py +95 -73
- {mcp_agent → fast_agent/core}/executor/executor.py +4 -5
- {mcp_agent → fast_agent}/core/fastagent.py +32 -32
- fast_agent/core/logging/__init__.py +5 -0
- {mcp_agent → fast_agent/core}/logging/events.py +3 -3
- {mcp_agent → fast_agent/core}/logging/json_serializer.py +1 -1
- {mcp_agent → fast_agent/core}/logging/listeners.py +85 -7
- {mcp_agent → fast_agent/core}/logging/logger.py +7 -7
- {mcp_agent → fast_agent/core}/logging/transport.py +10 -11
- fast_agent/core/prompt.py +9 -0
- {mcp_agent → fast_agent}/core/validation.py +4 -4
- fast_agent/event_progress.py +61 -0
- fast_agent/history/history_exporter.py +44 -0
- {mcp_agent → fast_agent}/human_input/__init__.py +9 -12
- {mcp_agent → fast_agent}/human_input/elicitation_handler.py +26 -8
- {mcp_agent → fast_agent}/human_input/elicitation_state.py +7 -7
- {mcp_agent → fast_agent}/human_input/simple_form.py +6 -4
- {mcp_agent → fast_agent}/human_input/types.py +1 -18
- fast_agent/interfaces.py +228 -0
- fast_agent/llm/__init__.py +9 -0
- mcp_agent/llm/augmented_llm.py → fast_agent/llm/fastagent_llm.py +128 -218
- fast_agent/llm/internal/passthrough.py +137 -0
- mcp_agent/llm/augmented_llm_playback.py → fast_agent/llm/internal/playback.py +29 -25
- mcp_agent/llm/augmented_llm_silent.py → fast_agent/llm/internal/silent.py +10 -17
- fast_agent/llm/internal/slow.py +38 -0
- {mcp_agent → fast_agent}/llm/memory.py +40 -30
- {mcp_agent → fast_agent}/llm/model_database.py +35 -2
- {mcp_agent → fast_agent}/llm/model_factory.py +103 -77
- fast_agent/llm/model_info.py +126 -0
- {mcp_agent/llm/providers → fast_agent/llm/provider/anthropic}/anthropic_utils.py +7 -7
- fast_agent/llm/provider/anthropic/llm_anthropic.py +603 -0
- {mcp_agent/llm/providers → fast_agent/llm/provider/anthropic}/multipart_converter_anthropic.py +79 -86
- fast_agent/llm/provider/bedrock/bedrock_utils.py +218 -0
- fast_agent/llm/provider/bedrock/llm_bedrock.py +2192 -0
- {mcp_agent/llm/providers → fast_agent/llm/provider/google}/google_converter.py +66 -14
- fast_agent/llm/provider/google/llm_google_native.py +431 -0
- mcp_agent/llm/providers/augmented_llm_aliyun.py → fast_agent/llm/provider/openai/llm_aliyun.py +6 -7
- mcp_agent/llm/providers/augmented_llm_azure.py → fast_agent/llm/provider/openai/llm_azure.py +4 -4
- mcp_agent/llm/providers/augmented_llm_deepseek.py → fast_agent/llm/provider/openai/llm_deepseek.py +10 -11
- mcp_agent/llm/providers/augmented_llm_generic.py → fast_agent/llm/provider/openai/llm_generic.py +4 -4
- mcp_agent/llm/providers/augmented_llm_google_oai.py → fast_agent/llm/provider/openai/llm_google_oai.py +4 -4
- mcp_agent/llm/providers/augmented_llm_groq.py → fast_agent/llm/provider/openai/llm_groq.py +14 -16
- mcp_agent/llm/providers/augmented_llm_openai.py → fast_agent/llm/provider/openai/llm_openai.py +133 -206
- mcp_agent/llm/providers/augmented_llm_openrouter.py → fast_agent/llm/provider/openai/llm_openrouter.py +6 -6
- mcp_agent/llm/providers/augmented_llm_tensorzero_openai.py → fast_agent/llm/provider/openai/llm_tensorzero_openai.py +17 -16
- mcp_agent/llm/providers/augmented_llm_xai.py → fast_agent/llm/provider/openai/llm_xai.py +6 -6
- {mcp_agent/llm/providers → fast_agent/llm/provider/openai}/multipart_converter_openai.py +125 -63
- {mcp_agent/llm/providers → fast_agent/llm/provider/openai}/openai_multipart.py +12 -12
- {mcp_agent/llm/providers → fast_agent/llm/provider/openai}/openai_utils.py +18 -16
- {mcp_agent → fast_agent}/llm/provider_key_manager.py +2 -2
- {mcp_agent → fast_agent}/llm/provider_types.py +2 -0
- {mcp_agent → fast_agent}/llm/sampling_converter.py +15 -12
- {mcp_agent → fast_agent}/llm/usage_tracking.py +23 -5
- fast_agent/mcp/__init__.py +43 -0
- {mcp_agent → fast_agent}/mcp/elicitation_factory.py +3 -3
- {mcp_agent → fast_agent}/mcp/elicitation_handlers.py +19 -10
- {mcp_agent → fast_agent}/mcp/gen_client.py +3 -3
- fast_agent/mcp/helpers/__init__.py +36 -0
- fast_agent/mcp/helpers/content_helpers.py +183 -0
- {mcp_agent → fast_agent}/mcp/helpers/server_config_helpers.py +8 -8
- {mcp_agent → fast_agent}/mcp/hf_auth.py +25 -23
- fast_agent/mcp/interfaces.py +93 -0
- {mcp_agent → fast_agent}/mcp/logger_textio.py +4 -4
- {mcp_agent → fast_agent}/mcp/mcp_agent_client_session.py +49 -44
- {mcp_agent → fast_agent}/mcp/mcp_aggregator.py +66 -115
- {mcp_agent → fast_agent}/mcp/mcp_connection_manager.py +16 -23
- {mcp_agent/core → fast_agent/mcp}/mcp_content.py +23 -15
- {mcp_agent → fast_agent}/mcp/mime_utils.py +39 -0
- fast_agent/mcp/prompt.py +159 -0
- mcp_agent/mcp/prompt_message_multipart.py → fast_agent/mcp/prompt_message_extended.py +27 -20
- {mcp_agent → fast_agent}/mcp/prompt_render.py +21 -19
- {mcp_agent → fast_agent}/mcp/prompt_serialization.py +46 -46
- fast_agent/mcp/prompts/__main__.py +7 -0
- {mcp_agent → fast_agent}/mcp/prompts/prompt_helpers.py +31 -30
- {mcp_agent → fast_agent}/mcp/prompts/prompt_load.py +8 -8
- {mcp_agent → fast_agent}/mcp/prompts/prompt_server.py +11 -19
- {mcp_agent → fast_agent}/mcp/prompts/prompt_template.py +18 -18
- {mcp_agent → fast_agent}/mcp/resource_utils.py +1 -1
- {mcp_agent → fast_agent}/mcp/sampling.py +31 -26
- {mcp_agent/mcp_server → fast_agent/mcp/server}/__init__.py +1 -1
- {mcp_agent/mcp_server → fast_agent/mcp/server}/agent_server.py +5 -6
- fast_agent/mcp/ui_agent.py +48 -0
- fast_agent/mcp/ui_mixin.py +209 -0
- fast_agent/mcp_server_registry.py +90 -0
- {mcp_agent → fast_agent}/resources/examples/data-analysis/analysis-campaign.py +5 -4
- {mcp_agent → fast_agent}/resources/examples/data-analysis/analysis.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/mcp/elicitations/elicitation_forms_server.py +25 -3
- {mcp_agent → fast_agent}/resources/examples/mcp/elicitations/forms_demo.py +3 -3
- {mcp_agent → fast_agent}/resources/examples/mcp/elicitations/game_character.py +2 -2
- {mcp_agent → fast_agent}/resources/examples/mcp/elicitations/game_character_handler.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/mcp/elicitations/tool_call.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/mcp/state-transfer/agent_one.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/mcp/state-transfer/agent_two.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/researcher/researcher-eval.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/researcher/researcher-imp.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/researcher/researcher.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/tensorzero/agent.py +2 -2
- {mcp_agent → fast_agent}/resources/examples/tensorzero/image_demo.py +3 -3
- {mcp_agent → fast_agent}/resources/examples/tensorzero/simple_agent.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/workflows/chaining.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/workflows/evaluator.py +3 -3
- {mcp_agent → fast_agent}/resources/examples/workflows/human_input.py +5 -3
- {mcp_agent → fast_agent}/resources/examples/workflows/orchestrator.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/workflows/parallel.py +2 -2
- {mcp_agent → fast_agent}/resources/examples/workflows/router.py +5 -2
- fast_agent/resources/setup/.gitignore +24 -0
- fast_agent/resources/setup/agent.py +18 -0
- fast_agent/resources/setup/fastagent.config.yaml +44 -0
- fast_agent/resources/setup/fastagent.secrets.yaml.example +38 -0
- fast_agent/tools/elicitation.py +369 -0
- fast_agent/types/__init__.py +32 -0
- fast_agent/types/llm_stop_reason.py +77 -0
- fast_agent/ui/__init__.py +38 -0
- fast_agent/ui/console_display.py +1005 -0
- {mcp_agent/human_input → fast_agent/ui}/elicitation_form.py +56 -39
- mcp_agent/human_input/elicitation_forms.py → fast_agent/ui/elicitation_style.py +1 -1
- {mcp_agent/core → fast_agent/ui}/enhanced_prompt.py +96 -25
- {mcp_agent/core → fast_agent/ui}/interactive_prompt.py +330 -125
- fast_agent/ui/mcp_ui_utils.py +224 -0
- {mcp_agent → fast_agent/ui}/progress_display.py +2 -2
- {mcp_agent/logging → fast_agent/ui}/rich_progress.py +4 -4
- {mcp_agent/core → fast_agent/ui}/usage_display.py +3 -8
- {fast_agent_mcp-0.2.57.dist-info → fast_agent_mcp-0.3.0.dist-info}/METADATA +7 -7
- fast_agent_mcp-0.3.0.dist-info/RECORD +202 -0
- fast_agent_mcp-0.3.0.dist-info/entry_points.txt +5 -0
- fast_agent_mcp-0.2.57.dist-info/RECORD +0 -192
- fast_agent_mcp-0.2.57.dist-info/entry_points.txt +0 -6
- mcp_agent/__init__.py +0 -114
- mcp_agent/agents/agent.py +0 -92
- mcp_agent/agents/workflow/__init__.py +0 -1
- mcp_agent/agents/workflow/orchestrator_agent.py +0 -597
- mcp_agent/app.py +0 -175
- mcp_agent/core/__init__.py +0 -26
- mcp_agent/core/prompt.py +0 -191
- mcp_agent/event_progress.py +0 -134
- mcp_agent/human_input/handler.py +0 -81
- mcp_agent/llm/__init__.py +0 -2
- mcp_agent/llm/augmented_llm_passthrough.py +0 -232
- mcp_agent/llm/augmented_llm_slow.py +0 -53
- mcp_agent/llm/providers/__init__.py +0 -8
- mcp_agent/llm/providers/augmented_llm_anthropic.py +0 -717
- mcp_agent/llm/providers/augmented_llm_bedrock.py +0 -1788
- mcp_agent/llm/providers/augmented_llm_google_native.py +0 -495
- mcp_agent/llm/providers/sampling_converter_anthropic.py +0 -57
- mcp_agent/llm/providers/sampling_converter_openai.py +0 -26
- mcp_agent/llm/sampling_format_converter.py +0 -37
- mcp_agent/logging/__init__.py +0 -0
- mcp_agent/mcp/__init__.py +0 -50
- mcp_agent/mcp/helpers/__init__.py +0 -25
- mcp_agent/mcp/helpers/content_helpers.py +0 -187
- mcp_agent/mcp/interfaces.py +0 -266
- mcp_agent/mcp/prompts/__init__.py +0 -0
- mcp_agent/mcp/prompts/__main__.py +0 -10
- mcp_agent/mcp_server_registry.py +0 -343
- mcp_agent/tools/tool_definition.py +0 -14
- mcp_agent/ui/console_display.py +0 -790
- mcp_agent/ui/console_display_legacy.py +0 -401
- {mcp_agent → fast_agent}/agents/workflow/orchestrator_prompts.py +0 -0
- {mcp_agent/agents → fast_agent/cli}/__init__.py +0 -0
- {mcp_agent → fast_agent}/cli/constants.py +0 -0
- {mcp_agent → fast_agent}/core/error_handling.py +0 -0
- {mcp_agent → fast_agent}/core/exceptions.py +0 -0
- {mcp_agent/cli → fast_agent/core/executor}/__init__.py +0 -0
- {mcp_agent → fast_agent/core}/executor/task_registry.py +0 -0
- {mcp_agent → fast_agent/core}/executor/workflow_signal.py +0 -0
- {mcp_agent → fast_agent}/human_input/form_fields.py +0 -0
- {mcp_agent → fast_agent}/llm/prompt_utils.py +0 -0
- {mcp_agent/core → fast_agent/llm}/request_params.py +0 -0
- {mcp_agent → fast_agent}/mcp/common.py +0 -0
- {mcp_agent/executor → fast_agent/mcp/prompts}/__init__.py +0 -0
- {mcp_agent → fast_agent}/mcp/prompts/prompt_constants.py +0 -0
- {mcp_agent → fast_agent}/py.typed +0 -0
- {mcp_agent → fast_agent}/resources/examples/data-analysis/fastagent.config.yaml +0 -0
- {mcp_agent → fast_agent}/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
- {mcp_agent → fast_agent}/resources/examples/mcp/elicitations/elicitation_account_server.py +0 -0
- {mcp_agent → fast_agent}/resources/examples/mcp/elicitations/elicitation_game_server.py +0 -0
- {mcp_agent → fast_agent}/resources/examples/mcp/elicitations/fastagent.config.yaml +0 -0
- {mcp_agent → fast_agent}/resources/examples/mcp/elicitations/fastagent.secrets.yaml.example +0 -0
- {mcp_agent → fast_agent}/resources/examples/mcp/state-transfer/fastagent.config.yaml +0 -0
- {mcp_agent → fast_agent}/resources/examples/mcp/state-transfer/fastagent.secrets.yaml.example +0 -0
- {mcp_agent → fast_agent}/resources/examples/researcher/fastagent.config.yaml +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/.env.sample +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/Makefile +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/README.md +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/demo_images/clam.jpg +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/demo_images/crab.png +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/demo_images/shrimp.png +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/docker-compose.yml +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/fastagent.config.yaml +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/mcp_server/Dockerfile +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/mcp_server/entrypoint.sh +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/mcp_server/mcp_server.py +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/mcp_server/pyproject.toml +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/tensorzero_config/system_schema.json +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/tensorzero_config/system_template.minijinja +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/tensorzero_config/tensorzero.toml +0 -0
- {mcp_agent → fast_agent}/resources/examples/workflows/fastagent.config.yaml +0 -0
- {mcp_agent → fast_agent}/resources/examples/workflows/graded_report.md +0 -0
- {mcp_agent → fast_agent}/resources/examples/workflows/short_story.md +0 -0
- {mcp_agent → fast_agent}/resources/examples/workflows/short_story.txt +0 -0
- {mcp_agent → fast_agent/ui}/console.py +0 -0
- {mcp_agent/core → fast_agent/ui}/mermaid_utils.py +0 -0
- {fast_agent_mcp-0.2.57.dist-info → fast_agent_mcp-0.3.0.dist-info}/WHEEL +0 -0
- {fast_agent_mcp-0.2.57.dist-info → fast_agent_mcp-0.3.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -7,136 +7,55 @@ from rich.prompt import Confirm
|
|
|
7
7
|
app = typer.Typer()
|
|
8
8
|
console = Console()
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
#
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
#
|
|
59
|
-
# Keys in the configuration file override environment variables.
|
|
60
|
-
|
|
61
|
-
openai:
|
|
62
|
-
api_key: <your-api-key-here>
|
|
63
|
-
anthropic:
|
|
64
|
-
api_key: <your-api-key-here>
|
|
65
|
-
deepseek:
|
|
66
|
-
api_key: <your-api-key-here>
|
|
67
|
-
openrouter:
|
|
68
|
-
api_key: <your-api-key-here>
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
# Example of setting an MCP Server environment variable
|
|
72
|
-
mcp:
|
|
73
|
-
servers:
|
|
74
|
-
brave:
|
|
75
|
-
env:
|
|
76
|
-
BRAVE_API_KEY: <your_api_key_here>
|
|
77
|
-
|
|
78
|
-
"""
|
|
79
|
-
|
|
80
|
-
GITIGNORE_TEMPLATE = """
|
|
81
|
-
# FastAgent secrets file
|
|
82
|
-
fastagent.secrets.yaml
|
|
83
|
-
|
|
84
|
-
# Python
|
|
85
|
-
__pycache__/
|
|
86
|
-
*.py[cod]
|
|
87
|
-
*$py.class
|
|
88
|
-
*.so
|
|
89
|
-
.Python
|
|
90
|
-
build/
|
|
91
|
-
develop-eggs/
|
|
92
|
-
dist/
|
|
93
|
-
downloads/
|
|
94
|
-
eggs/
|
|
95
|
-
.eggs/
|
|
96
|
-
lib/
|
|
97
|
-
lib64/
|
|
98
|
-
parts/
|
|
99
|
-
sdist/
|
|
100
|
-
var/
|
|
101
|
-
wheels/
|
|
102
|
-
*.egg-info/
|
|
103
|
-
.installed.cfg
|
|
104
|
-
*.egg
|
|
105
|
-
|
|
106
|
-
# Virtual Environment
|
|
107
|
-
.env
|
|
108
|
-
.venv
|
|
109
|
-
env/
|
|
110
|
-
venv/
|
|
111
|
-
ENV/
|
|
112
|
-
|
|
113
|
-
# IDE
|
|
114
|
-
.idea/
|
|
115
|
-
.vscode/
|
|
116
|
-
*.swp
|
|
117
|
-
*.swo
|
|
118
|
-
"""
|
|
119
|
-
|
|
120
|
-
AGENT_EXAMPLE_TEMPLATE = """
|
|
121
|
-
import asyncio
|
|
122
|
-
from mcp_agent.core.fastagent import FastAgent
|
|
123
|
-
|
|
124
|
-
# Create the application
|
|
125
|
-
fast = FastAgent("fast-agent example")
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
# Define the agent
|
|
129
|
-
@fast.agent(instruction="You are a helpful AI Agent")
|
|
130
|
-
async def main():
|
|
131
|
-
# use the --model command line switch or agent arguments to change model
|
|
132
|
-
async with fast.run() as agent:
|
|
133
|
-
await agent.interactive()
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
if __name__ == "__main__":
|
|
137
|
-
asyncio.run(main())
|
|
138
|
-
|
|
139
|
-
"""
|
|
10
|
+
|
|
11
|
+
def load_template_text(filename: str) -> str:
|
|
12
|
+
"""Load template text from packaged resources with a development fallback.
|
|
13
|
+
|
|
14
|
+
Special-case: when requesting 'fastagent.secrets.yaml', read the
|
|
15
|
+
'fastagent.secrets.yaml.example' template from resources, but still
|
|
16
|
+
return its contents so we can write out the real secrets file name
|
|
17
|
+
in the destination project.
|
|
18
|
+
"""
|
|
19
|
+
try:
|
|
20
|
+
# Prefer reading from installed package resources
|
|
21
|
+
from importlib.resources import files
|
|
22
|
+
|
|
23
|
+
# Map secrets filename to its '.example' template in resources
|
|
24
|
+
res_name = (
|
|
25
|
+
"fastagent.secrets.yaml.example" if filename == "fastagent.secrets.yaml" else filename
|
|
26
|
+
)
|
|
27
|
+
resource_path = files("fast_agent").joinpath("resources").joinpath("setup").joinpath(res_name)
|
|
28
|
+
if resource_path.is_file():
|
|
29
|
+
return resource_path.read_text()
|
|
30
|
+
# If the path exists but isn't a file, fall back to dev
|
|
31
|
+
raise FileNotFoundError
|
|
32
|
+
except (ImportError, ModuleNotFoundError, FileNotFoundError):
|
|
33
|
+
# Development environment fallback to repo path (project root/examples/setup)
|
|
34
|
+
try:
|
|
35
|
+
repo_root = Path(__file__).resolve().parents[4]
|
|
36
|
+
except IndexError:
|
|
37
|
+
repo_root = Path(__file__).resolve().parent
|
|
38
|
+
# Apply the same secrets mapping for the dev path
|
|
39
|
+
dev_name = (
|
|
40
|
+
"fastagent.secrets.yaml.example" if filename == "fastagent.secrets.yaml" else filename
|
|
41
|
+
)
|
|
42
|
+
dev_path = repo_root / "examples" / "setup" / dev_name
|
|
43
|
+
if dev_path.exists():
|
|
44
|
+
return dev_path.read_text()
|
|
45
|
+
raise RuntimeError(
|
|
46
|
+
"Setup template missing: '"
|
|
47
|
+
+ filename
|
|
48
|
+
+ "'.\n"
|
|
49
|
+
+ "Expected at: "
|
|
50
|
+
+ str(resource_path)
|
|
51
|
+
+ " (package) or "
|
|
52
|
+
+ str(dev_path)
|
|
53
|
+
+ " (dev).\n"
|
|
54
|
+
+ "This indicates a packaging issue. Please rebuild/reinstall fast-agent."
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# (No embedded template defaults; templates are the single source of truth.)
|
|
140
59
|
|
|
141
60
|
|
|
142
61
|
def find_gitignore(path: Path) -> bool:
|
|
@@ -203,21 +122,32 @@ def init(
|
|
|
203
122
|
|
|
204
123
|
# Create configuration files
|
|
205
124
|
created = []
|
|
206
|
-
if create_file(
|
|
125
|
+
if create_file(
|
|
126
|
+
config_path / "fastagent.config.yaml", load_template_text("fastagent.config.yaml"), force
|
|
127
|
+
):
|
|
207
128
|
created.append("fastagent.yaml")
|
|
208
129
|
|
|
209
|
-
if create_file(
|
|
130
|
+
if create_file(
|
|
131
|
+
config_path / "fastagent.secrets.yaml", load_template_text("fastagent.secrets.yaml"), force
|
|
132
|
+
):
|
|
210
133
|
created.append("fastagent.secrets.yaml")
|
|
211
134
|
|
|
212
|
-
if create_file(config_path / "agent.py",
|
|
135
|
+
if create_file(config_path / "agent.py", load_template_text("agent.py"), force):
|
|
213
136
|
created.append("agent.py")
|
|
214
137
|
|
|
215
138
|
# Only create .gitignore if none exists in parent directories
|
|
216
|
-
if needs_gitignore and create_file(
|
|
139
|
+
if needs_gitignore and create_file(
|
|
140
|
+
config_path / ".gitignore", load_template_text(".gitignore"), force
|
|
141
|
+
):
|
|
217
142
|
created.append(".gitignore")
|
|
218
143
|
|
|
219
144
|
if created:
|
|
220
145
|
console.print("\n[green]Setup completed successfully![/green]")
|
|
146
|
+
if not needs_gitignore:
|
|
147
|
+
console.print(
|
|
148
|
+
"[yellow]Note:[/yellow] Found an existing .gitignore in this or a parent directory. "
|
|
149
|
+
"Ensure it ignores 'fastagent.secrets.yaml' to avoid committing secrets."
|
|
150
|
+
)
|
|
221
151
|
if "fastagent.secrets.yaml" in created:
|
|
222
152
|
console.print("\n[yellow]Important:[/yellow] Remember to:")
|
|
223
153
|
console.print(
|
|
@@ -8,7 +8,7 @@ import re
|
|
|
8
8
|
from typing import Dict, List, Literal, Tuple
|
|
9
9
|
from urllib.parse import urlparse
|
|
10
10
|
|
|
11
|
-
from
|
|
11
|
+
from fast_agent.mcp.hf_auth import add_hf_auth_header
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def parse_server_url(
|
|
@@ -46,12 +46,13 @@ def parse_server_url(
|
|
|
46
46
|
|
|
47
47
|
# Determine transport type based on URL path
|
|
48
48
|
transport_type: Literal["http", "sse"] = "http"
|
|
49
|
-
|
|
49
|
+
path = parsed_url.path or ""
|
|
50
|
+
normalized_path = path.rstrip("/")
|
|
51
|
+
if normalized_path.endswith("/sse"):
|
|
50
52
|
transport_type = "sse"
|
|
51
|
-
elif not
|
|
52
|
-
# If path doesn't end with /mcp or /sse, append /mcp
|
|
53
|
-
url = url
|
|
54
|
-
url = f"{url}mcp"
|
|
53
|
+
elif not normalized_path.endswith("/mcp"):
|
|
54
|
+
# If path doesn't end with /mcp or /sse (handling trailing slash), append /mcp once
|
|
55
|
+
url = f"{url.rstrip('/')}" + "/mcp"
|
|
55
56
|
|
|
56
57
|
# Generate a server name based on hostname and port
|
|
57
58
|
server_name = generate_server_name(url)
|
|
@@ -133,10 +134,10 @@ def parse_server_urls(
|
|
|
133
134
|
result = []
|
|
134
135
|
for url in url_list:
|
|
135
136
|
server_name, transport_type, parsed_url = parse_server_url(url)
|
|
136
|
-
|
|
137
|
+
|
|
137
138
|
# Apply HuggingFace authentication if appropriate
|
|
138
139
|
final_headers = add_hf_auth_header(parsed_url, headers)
|
|
139
|
-
|
|
140
|
+
|
|
140
141
|
result.append((server_name, transport_type, parsed_url, final_headers))
|
|
141
142
|
|
|
142
143
|
return result
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"""Main CLI entry point for MCP Agent."""
|
|
2
2
|
|
|
3
3
|
import typer
|
|
4
|
-
from rich.console import Console
|
|
5
4
|
from rich.table import Table
|
|
6
5
|
|
|
7
|
-
from
|
|
8
|
-
from
|
|
6
|
+
from fast_agent.cli.commands import check_config, go, quickstart, setup
|
|
7
|
+
from fast_agent.cli.terminal import Application
|
|
8
|
+
from fast_agent.ui.console import console as shared_console
|
|
9
9
|
|
|
10
10
|
app = typer.Typer(
|
|
11
11
|
help="fast-agent - Build effective agents using Model Context Protocol",
|
|
@@ -21,34 +21,54 @@ app.add_typer(quickstart.app, name="quickstart", help="Create example applicatio
|
|
|
21
21
|
|
|
22
22
|
# Shared application context
|
|
23
23
|
application = Application()
|
|
24
|
-
console
|
|
24
|
+
# Use shared console to match app-wide styling
|
|
25
|
+
console = shared_console
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
def show_welcome() -> None:
|
|
28
|
-
"""Show a welcome message with available commands."""
|
|
29
|
+
"""Show a welcome message with available commands, using new styling."""
|
|
29
30
|
from importlib.metadata import version
|
|
30
31
|
|
|
32
|
+
from rich.text import Text
|
|
33
|
+
|
|
31
34
|
try:
|
|
32
35
|
app_version = version("fast-agent-mcp")
|
|
33
36
|
except: # noqa: E722
|
|
34
37
|
app_version = "unknown"
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
# Header in the same style used by check/console_display
|
|
40
|
+
def _print_section_header(title: str, color: str = "blue") -> None:
|
|
41
|
+
width = console.size.width
|
|
42
|
+
left = f"[{color}]▎[/{color}][dim {color}]▶[/dim {color}] [{color}]{title}[/{color}]"
|
|
43
|
+
left_text = Text.from_markup(left)
|
|
44
|
+
separator_count = max(1, width - left_text.cell_len - 1)
|
|
45
|
+
|
|
46
|
+
combined = Text()
|
|
47
|
+
combined.append_text(left_text)
|
|
48
|
+
combined.append(" ")
|
|
49
|
+
combined.append("─" * separator_count, style="dim")
|
|
50
|
+
|
|
51
|
+
console.print()
|
|
52
|
+
console.print(combined)
|
|
53
|
+
console.print()
|
|
54
|
+
|
|
55
|
+
header_title = f"fast-agent v{app_version}"
|
|
56
|
+
_print_section_header(header_title, color="blue")
|
|
57
|
+
|
|
58
|
+
# Commands list (no boxes), matching updated check styling
|
|
59
|
+
table = Table(show_header=True, box=None)
|
|
60
|
+
table.add_column("Command", style="green", header_style="bold bright_white")
|
|
61
|
+
table.add_column("Description", header_style="bold bright_white")
|
|
62
|
+
|
|
63
|
+
table.add_row("[bold]go[/bold]", "Start an interactive session")
|
|
64
|
+
table.add_row("check", "Show current configuration")
|
|
65
|
+
table.add_row("setup", "Create agent template and configuration")
|
|
46
66
|
table.add_row("quickstart", "Create example applications (workflow, researcher, etc.)")
|
|
47
67
|
|
|
48
68
|
console.print(table)
|
|
49
69
|
|
|
50
70
|
console.print(
|
|
51
|
-
"\
|
|
71
|
+
"\nVisit [cyan][link=https://fast-agent.ai]fast-agent.ai[/link][/cyan] for more information."
|
|
52
72
|
)
|
|
53
73
|
|
|
54
74
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from
|
|
1
|
+
from fast_agent.ui.console import console, error_console
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
class Application:
|
|
@@ -14,7 +14,7 @@ class Application:
|
|
|
14
14
|
self.error_console = error_console
|
|
15
15
|
|
|
16
16
|
def log(self, message: str, level: str = "info") -> None:
|
|
17
|
-
if
|
|
17
|
+
if level == "info" or (level == "debug" and self.verbosity > 0) or level == "error":
|
|
18
18
|
if level == "error":
|
|
19
19
|
self.error_console.print(f"[{level.upper()}] {message}")
|
|
20
20
|
else:
|
|
@@ -84,10 +84,10 @@ class MCPServerSettings(BaseModel):
|
|
|
84
84
|
"""The timeout in seconds for the server connection."""
|
|
85
85
|
|
|
86
86
|
url: str | None = None
|
|
87
|
-
"""The URL for the server (e.g. for SSE transport)."""
|
|
87
|
+
"""The URL for the server (e.g. for SSE/SHTTP transport)."""
|
|
88
88
|
|
|
89
89
|
headers: Dict[str, str] | None = None
|
|
90
|
-
"""Headers dictionary for
|
|
90
|
+
"""Headers dictionary for HTTP connections"""
|
|
91
91
|
|
|
92
92
|
auth: MCPServerAuthSettings | None = None
|
|
93
93
|
"""The authentication configuration for the server."""
|
|
@@ -276,6 +276,9 @@ class BedrockSettings(BaseModel):
|
|
|
276
276
|
profile: str | None = None
|
|
277
277
|
"""AWS profile to use for authentication"""
|
|
278
278
|
|
|
279
|
+
reasoning_effort: Literal["minimal", "low", "medium", "high"] = "minimal"
|
|
280
|
+
"""Default reasoning effort for Bedrock models. Can be overridden in model string (e.g., bedrock.claude-sonnet-4-0.high)"""
|
|
281
|
+
|
|
279
282
|
model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True)
|
|
280
283
|
|
|
281
284
|
|
|
@@ -459,6 +462,14 @@ class Settings(BaseSettings):
|
|
|
459
462
|
logger: LoggerSettings | None = LoggerSettings()
|
|
460
463
|
"""Logger settings for the fast-agent application"""
|
|
461
464
|
|
|
465
|
+
# MCP UI integration mode for handling ui:// embedded resources from MCP tool results
|
|
466
|
+
mcp_ui_mode: Literal["disabled", "enabled", "auto"] = "enabled"
|
|
467
|
+
"""Controls handling of MCP UI embedded resources:
|
|
468
|
+
- "disabled": Do not process ui:// resources
|
|
469
|
+
- "enabled": Always extract ui:// resources into message channels (default)
|
|
470
|
+
- "auto": Extract and automatically open ui:// resources.
|
|
471
|
+
"""
|
|
472
|
+
|
|
462
473
|
@classmethod
|
|
463
474
|
def find_config(cls) -> Path | None:
|
|
464
475
|
"""Find the config file in the current directory or parent directories."""
|
fast_agent/constants.py
ADDED
|
@@ -7,15 +7,11 @@ import concurrent.futures
|
|
|
7
7
|
import uuid
|
|
8
8
|
from typing import TYPE_CHECKING, Any, Optional, Union
|
|
9
9
|
|
|
10
|
-
from mcp import ServerSession
|
|
11
10
|
from opentelemetry import trace
|
|
12
11
|
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
|
|
13
12
|
|
|
14
13
|
# from opentelemetry.instrumentation.anthropic import AnthropicInstrumentor
|
|
15
|
-
from opentelemetry.instrumentation.google_genai import GoogleGenAiSdkInstrumentor
|
|
16
|
-
|
|
17
14
|
# from opentelemetry.instrumentation.mcp import McpInstrumentor
|
|
18
|
-
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
|
|
19
15
|
from opentelemetry.propagate import set_global_textmap
|
|
20
16
|
from opentelemetry.sdk.resources import Resource
|
|
21
17
|
from opentelemetry.sdk.trace import TracerProvider
|
|
@@ -23,20 +19,18 @@ from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExport
|
|
|
23
19
|
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
|
|
24
20
|
from pydantic import BaseModel, ConfigDict
|
|
25
21
|
|
|
26
|
-
from
|
|
27
|
-
from
|
|
28
|
-
from
|
|
29
|
-
from
|
|
30
|
-
from
|
|
31
|
-
from
|
|
32
|
-
from
|
|
22
|
+
from fast_agent.config import Settings, get_settings
|
|
23
|
+
from fast_agent.core.executor.executor import AsyncioExecutor, Executor
|
|
24
|
+
from fast_agent.core.executor.task_registry import ActivityRegistry
|
|
25
|
+
from fast_agent.core.logging.events import EventFilter, StreamingExclusionFilter
|
|
26
|
+
from fast_agent.core.logging.logger import LoggingConfig, get_logger
|
|
27
|
+
from fast_agent.core.logging.transport import create_transport
|
|
28
|
+
from fast_agent.mcp_server_registry import ServerRegistry
|
|
33
29
|
|
|
34
30
|
if TYPE_CHECKING:
|
|
35
|
-
from
|
|
36
|
-
from mcp_agent.human_input.types import HumanInputCallback
|
|
31
|
+
from fast_agent.core.executor.workflow_signal import SignalWaitCallback
|
|
37
32
|
else:
|
|
38
33
|
# Runtime placeholders for the types
|
|
39
|
-
HumanInputCallback = Any
|
|
40
34
|
SignalWaitCallback = Any
|
|
41
35
|
|
|
42
36
|
logger = get_logger(__name__)
|
|
@@ -50,9 +44,8 @@ class Context(BaseModel):
|
|
|
50
44
|
|
|
51
45
|
config: Optional[Settings] = None
|
|
52
46
|
executor: Optional[Executor] = None
|
|
53
|
-
human_input_handler: Optional[
|
|
47
|
+
human_input_handler: Optional[Any] = None
|
|
54
48
|
signal_notification: Optional[SignalWaitCallback] = None
|
|
55
|
-
upstream_session: Optional[ServerSession] = None # TODO: saqadri - figure this out
|
|
56
49
|
|
|
57
50
|
# Registries
|
|
58
51
|
server_registry: Optional[ServerRegistry] = None
|
|
@@ -113,9 +106,21 @@ async def configure_otel(config: "Settings") -> None:
|
|
|
113
106
|
|
|
114
107
|
# Set as global tracer provider
|
|
115
108
|
trace.set_tracer_provider(tracer_provider)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
109
|
+
|
|
110
|
+
# Attempt to instrument optional SDKs if available; continue silently if missing
|
|
111
|
+
try:
|
|
112
|
+
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
|
|
113
|
+
|
|
114
|
+
OpenAIInstrumentor().instrument()
|
|
115
|
+
except Exception: # pragma: no cover - optional instrumentation
|
|
116
|
+
pass
|
|
117
|
+
|
|
118
|
+
try:
|
|
119
|
+
from opentelemetry.instrumentation.google_genai import GoogleGenAiSdkInstrumentor
|
|
120
|
+
|
|
121
|
+
GoogleGenAiSdkInstrumentor().instrument()
|
|
122
|
+
except Exception: # pragma: no cover - optional instrumentation
|
|
123
|
+
pass
|
|
119
124
|
|
|
120
125
|
|
|
121
126
|
# McpInstrumentor().instrument()
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from contextlib import contextmanager
|
|
2
|
-
from typing import TYPE_CHECKING, Any
|
|
2
|
+
from typing import TYPE_CHECKING, Any
|
|
3
3
|
|
|
4
4
|
if TYPE_CHECKING:
|
|
5
|
-
from
|
|
5
|
+
from fast_agent.context import Context
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class ContextDependent:
|
|
@@ -11,7 +11,11 @@ class ContextDependent:
|
|
|
11
11
|
Provides both global fallback and instance-specific context support.
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
# Ensure the attribute always exists even if a subclass
|
|
15
|
+
# does not call this mixin's __init__.
|
|
16
|
+
_context: "Context | None" = None
|
|
17
|
+
|
|
18
|
+
def __init__(self, context: "Context | None" = None, **kwargs: dict[str, Any]) -> None:
|
|
15
19
|
self._context = context
|
|
16
20
|
super().__init__(**kwargs)
|
|
17
21
|
|
|
@@ -27,12 +31,12 @@ class ContextDependent:
|
|
|
27
31
|
|
|
28
32
|
try:
|
|
29
33
|
# Fall back to global context if available
|
|
30
|
-
from
|
|
34
|
+
from fast_agent.context import get_current_context
|
|
31
35
|
|
|
32
36
|
return get_current_context()
|
|
33
37
|
except Exception as e:
|
|
34
38
|
raise RuntimeError(
|
|
35
|
-
f"No context available for {self.__class__.__name__}. Either initialize
|
|
39
|
+
f"No context available for {self.__class__.__name__}. Either initialize Core first or pass context explicitly."
|
|
36
40
|
) from e
|
|
37
41
|
|
|
38
42
|
@contextmanager
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""
|
|
2
|
+
fast_agent.core package
|
|
3
|
+
|
|
4
|
+
Provides core subpackages (executor, logging) and lazily exposes the `Core`
|
|
5
|
+
class to avoid circular imports during initialization.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
__all__ = ["Core"]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def __getattr__(name: str):
|
|
12
|
+
if name == "Core":
|
|
13
|
+
# Lazy import to avoid importing heavy dependencies during package init
|
|
14
|
+
from .core_app import Core
|
|
15
|
+
|
|
16
|
+
return Core
|
|
17
|
+
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|