fast-agent-mcp 0.1.12__py3-none-any.whl → 0.2.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.
- {fast_agent_mcp-0.1.12.dist-info → fast_agent_mcp-0.2.0.dist-info}/METADATA +3 -4
- fast_agent_mcp-0.2.0.dist-info/RECORD +123 -0
- mcp_agent/__init__.py +75 -0
- mcp_agent/agents/agent.py +61 -415
- mcp_agent/agents/base_agent.py +522 -0
- mcp_agent/agents/workflow/__init__.py +1 -0
- mcp_agent/agents/workflow/chain_agent.py +173 -0
- mcp_agent/agents/workflow/evaluator_optimizer.py +362 -0
- mcp_agent/agents/workflow/orchestrator_agent.py +591 -0
- mcp_agent/{workflows/orchestrator → agents/workflow}/orchestrator_models.py +11 -21
- mcp_agent/agents/workflow/parallel_agent.py +182 -0
- mcp_agent/agents/workflow/router_agent.py +307 -0
- mcp_agent/app.py +15 -19
- mcp_agent/cli/commands/bootstrap.py +19 -38
- mcp_agent/cli/commands/config.py +4 -4
- mcp_agent/cli/commands/setup.py +7 -14
- mcp_agent/cli/main.py +7 -10
- mcp_agent/cli/terminal.py +3 -3
- mcp_agent/config.py +25 -40
- mcp_agent/context.py +12 -21
- mcp_agent/context_dependent.py +3 -5
- mcp_agent/core/agent_types.py +10 -7
- mcp_agent/core/direct_agent_app.py +179 -0
- mcp_agent/core/direct_decorators.py +443 -0
- mcp_agent/core/direct_factory.py +476 -0
- mcp_agent/core/enhanced_prompt.py +23 -55
- mcp_agent/core/exceptions.py +8 -8
- mcp_agent/core/fastagent.py +145 -371
- mcp_agent/core/interactive_prompt.py +424 -0
- mcp_agent/core/mcp_content.py +17 -17
- mcp_agent/core/prompt.py +6 -9
- mcp_agent/core/request_params.py +6 -3
- mcp_agent/core/validation.py +92 -18
- mcp_agent/executor/decorator_registry.py +9 -17
- mcp_agent/executor/executor.py +8 -17
- mcp_agent/executor/task_registry.py +2 -4
- mcp_agent/executor/temporal.py +19 -41
- mcp_agent/executor/workflow.py +3 -5
- mcp_agent/executor/workflow_signal.py +15 -21
- mcp_agent/human_input/handler.py +4 -7
- mcp_agent/human_input/types.py +2 -3
- mcp_agent/llm/__init__.py +2 -0
- mcp_agent/llm/augmented_llm.py +450 -0
- mcp_agent/llm/augmented_llm_passthrough.py +162 -0
- mcp_agent/llm/augmented_llm_playback.py +83 -0
- mcp_agent/llm/memory.py +103 -0
- mcp_agent/{workflows/llm → llm}/model_factory.py +22 -16
- mcp_agent/{workflows/llm → llm}/prompt_utils.py +1 -3
- mcp_agent/llm/providers/__init__.py +8 -0
- mcp_agent/{workflows/llm → llm/providers}/anthropic_utils.py +8 -25
- mcp_agent/{workflows/llm → llm/providers}/augmented_llm_anthropic.py +56 -194
- mcp_agent/llm/providers/augmented_llm_deepseek.py +53 -0
- mcp_agent/{workflows/llm → llm/providers}/augmented_llm_openai.py +99 -190
- mcp_agent/{workflows/llm → llm}/providers/multipart_converter_anthropic.py +72 -71
- mcp_agent/{workflows/llm → llm}/providers/multipart_converter_openai.py +65 -71
- mcp_agent/{workflows/llm → llm}/providers/openai_multipart.py +16 -44
- mcp_agent/{workflows/llm → llm/providers}/openai_utils.py +4 -4
- mcp_agent/{workflows/llm → llm}/providers/sampling_converter_anthropic.py +9 -11
- mcp_agent/{workflows/llm → llm}/providers/sampling_converter_openai.py +8 -12
- mcp_agent/{workflows/llm → llm}/sampling_converter.py +3 -31
- mcp_agent/llm/sampling_format_converter.py +37 -0
- mcp_agent/logging/events.py +1 -5
- mcp_agent/logging/json_serializer.py +7 -6
- mcp_agent/logging/listeners.py +20 -23
- mcp_agent/logging/logger.py +17 -19
- mcp_agent/logging/rich_progress.py +10 -8
- mcp_agent/logging/tracing.py +4 -6
- mcp_agent/logging/transport.py +22 -22
- mcp_agent/mcp/gen_client.py +1 -3
- mcp_agent/mcp/interfaces.py +117 -110
- mcp_agent/mcp/logger_textio.py +97 -0
- mcp_agent/mcp/mcp_agent_client_session.py +7 -7
- mcp_agent/mcp/mcp_agent_server.py +8 -8
- mcp_agent/mcp/mcp_aggregator.py +102 -143
- mcp_agent/mcp/mcp_connection_manager.py +20 -27
- mcp_agent/mcp/prompt_message_multipart.py +68 -16
- mcp_agent/mcp/prompt_render.py +77 -0
- mcp_agent/mcp/prompt_serialization.py +30 -48
- mcp_agent/mcp/prompts/prompt_constants.py +18 -0
- mcp_agent/mcp/prompts/prompt_helpers.py +327 -0
- mcp_agent/mcp/prompts/prompt_load.py +109 -0
- mcp_agent/mcp/prompts/prompt_server.py +155 -195
- mcp_agent/mcp/prompts/prompt_template.py +35 -66
- mcp_agent/mcp/resource_utils.py +7 -14
- mcp_agent/mcp/sampling.py +17 -17
- mcp_agent/mcp_server/agent_server.py +13 -17
- mcp_agent/mcp_server_registry.py +13 -22
- mcp_agent/resources/examples/{workflows → in_dev}/agent_build.py +3 -2
- mcp_agent/resources/examples/in_dev/slides.py +110 -0
- mcp_agent/resources/examples/internal/agent.py +6 -3
- mcp_agent/resources/examples/internal/fastagent.config.yaml +8 -2
- mcp_agent/resources/examples/internal/job.py +2 -1
- mcp_agent/resources/examples/internal/prompt_category.py +1 -1
- mcp_agent/resources/examples/internal/prompt_sizing.py +3 -5
- mcp_agent/resources/examples/internal/sizer.py +2 -1
- mcp_agent/resources/examples/internal/social.py +2 -1
- mcp_agent/resources/examples/prompting/agent.py +2 -1
- mcp_agent/resources/examples/prompting/image_server.py +4 -8
- mcp_agent/resources/examples/prompting/work_with_image.py +19 -0
- mcp_agent/ui/console_display.py +16 -20
- fast_agent_mcp-0.1.12.dist-info/RECORD +0 -161
- mcp_agent/core/agent_app.py +0 -646
- mcp_agent/core/agent_utils.py +0 -71
- mcp_agent/core/decorators.py +0 -455
- mcp_agent/core/factory.py +0 -463
- mcp_agent/core/proxies.py +0 -269
- mcp_agent/core/types.py +0 -24
- mcp_agent/eval/__init__.py +0 -0
- mcp_agent/mcp/stdio.py +0 -111
- mcp_agent/resources/examples/data-analysis/analysis-campaign.py +0 -188
- mcp_agent/resources/examples/data-analysis/analysis.py +0 -65
- mcp_agent/resources/examples/data-analysis/fastagent.config.yaml +0 -41
- mcp_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -1471
- mcp_agent/resources/examples/mcp_researcher/researcher-eval.py +0 -53
- mcp_agent/resources/examples/researcher/fastagent.config.yaml +0 -66
- mcp_agent/resources/examples/researcher/researcher-eval.py +0 -53
- mcp_agent/resources/examples/researcher/researcher-imp.py +0 -190
- mcp_agent/resources/examples/researcher/researcher.py +0 -38
- mcp_agent/resources/examples/workflows/chaining.py +0 -44
- mcp_agent/resources/examples/workflows/evaluator.py +0 -78
- mcp_agent/resources/examples/workflows/fastagent.config.yaml +0 -24
- mcp_agent/resources/examples/workflows/human_input.py +0 -25
- mcp_agent/resources/examples/workflows/orchestrator.py +0 -73
- mcp_agent/resources/examples/workflows/parallel.py +0 -78
- mcp_agent/resources/examples/workflows/router.py +0 -53
- mcp_agent/resources/examples/workflows/sse.py +0 -23
- mcp_agent/telemetry/__init__.py +0 -0
- mcp_agent/telemetry/usage_tracking.py +0 -18
- mcp_agent/workflows/__init__.py +0 -0
- mcp_agent/workflows/embedding/__init__.py +0 -0
- mcp_agent/workflows/embedding/embedding_base.py +0 -61
- mcp_agent/workflows/embedding/embedding_cohere.py +0 -49
- mcp_agent/workflows/embedding/embedding_openai.py +0 -46
- mcp_agent/workflows/evaluator_optimizer/__init__.py +0 -0
- mcp_agent/workflows/evaluator_optimizer/evaluator_optimizer.py +0 -481
- mcp_agent/workflows/intent_classifier/__init__.py +0 -0
- mcp_agent/workflows/intent_classifier/intent_classifier_base.py +0 -120
- mcp_agent/workflows/intent_classifier/intent_classifier_embedding.py +0 -134
- mcp_agent/workflows/intent_classifier/intent_classifier_embedding_cohere.py +0 -45
- mcp_agent/workflows/intent_classifier/intent_classifier_embedding_openai.py +0 -45
- mcp_agent/workflows/intent_classifier/intent_classifier_llm.py +0 -161
- mcp_agent/workflows/intent_classifier/intent_classifier_llm_anthropic.py +0 -60
- mcp_agent/workflows/intent_classifier/intent_classifier_llm_openai.py +0 -60
- mcp_agent/workflows/llm/__init__.py +0 -0
- mcp_agent/workflows/llm/augmented_llm.py +0 -753
- mcp_agent/workflows/llm/augmented_llm_passthrough.py +0 -241
- mcp_agent/workflows/llm/augmented_llm_playback.py +0 -109
- mcp_agent/workflows/llm/providers/__init__.py +0 -8
- mcp_agent/workflows/llm/sampling_format_converter.py +0 -22
- mcp_agent/workflows/orchestrator/__init__.py +0 -0
- mcp_agent/workflows/orchestrator/orchestrator.py +0 -578
- mcp_agent/workflows/parallel/__init__.py +0 -0
- mcp_agent/workflows/parallel/fan_in.py +0 -350
- mcp_agent/workflows/parallel/fan_out.py +0 -187
- mcp_agent/workflows/parallel/parallel_llm.py +0 -166
- mcp_agent/workflows/router/__init__.py +0 -0
- mcp_agent/workflows/router/router_base.py +0 -368
- mcp_agent/workflows/router/router_embedding.py +0 -240
- mcp_agent/workflows/router/router_embedding_cohere.py +0 -59
- mcp_agent/workflows/router/router_embedding_openai.py +0 -59
- mcp_agent/workflows/router/router_llm.py +0 -320
- mcp_agent/workflows/swarm/__init__.py +0 -0
- mcp_agent/workflows/swarm/swarm.py +0 -320
- mcp_agent/workflows/swarm/swarm_anthropic.py +0 -42
- mcp_agent/workflows/swarm/swarm_openai.py +0 -41
- {fast_agent_mcp-0.1.12.dist-info → fast_agent_mcp-0.2.0.dist-info}/WHEEL +0 -0
- {fast_agent_mcp-0.1.12.dist-info → fast_agent_mcp-0.2.0.dist-info}/entry_points.txt +0 -0
- {fast_agent_mcp-0.1.12.dist-info → fast_agent_mcp-0.2.0.dist-info}/licenses/LICENSE +0 -0
- /mcp_agent/{workflows/orchestrator → agents/workflow}/orchestrator_prompts.py +0 -0
@@ -2,10 +2,11 @@
|
|
2
2
|
|
3
3
|
import shutil
|
4
4
|
from pathlib import Path
|
5
|
+
|
5
6
|
import typer
|
6
7
|
from rich.console import Console
|
7
|
-
from rich.table import Table
|
8
8
|
from rich.panel import Panel
|
9
|
+
from rich.table import Table
|
9
10
|
|
10
11
|
app = typer.Typer(
|
11
12
|
help="Create example applications",
|
@@ -49,9 +50,7 @@ EXAMPLE_TYPES = {
|
|
49
50
|
}
|
50
51
|
|
51
52
|
|
52
|
-
def copy_example_files(
|
53
|
-
example_type: str, target_dir: Path, force: bool = False
|
54
|
-
) -> list[str]:
|
53
|
+
def copy_example_files(example_type: str, target_dir: Path, force: bool = False) -> list[str]:
|
55
54
|
"""Copy example files from resources to target directory."""
|
56
55
|
created = []
|
57
56
|
|
@@ -71,13 +70,9 @@ def copy_example_files(
|
|
71
70
|
mount_point_dir.mkdir(parents=True)
|
72
71
|
console.print(f"Created mount-point directory: {mount_point_dir}")
|
73
72
|
|
74
|
-
# Use
|
75
|
-
|
76
|
-
|
77
|
-
/ "resources"
|
78
|
-
/ "examples"
|
79
|
-
/ ("workflows" if example_type == "workflow" else f"{example_type}")
|
80
|
-
)
|
73
|
+
# Use examples from top-level directory
|
74
|
+
package_dir = Path(__file__).parent.parent.parent.parent.parent
|
75
|
+
source_dir = package_dir / "examples" / ("workflows" if example_type == "workflow" else f"{example_type}")
|
81
76
|
|
82
77
|
if not source_dir.exists():
|
83
78
|
console.print(f"[red]Error: Source directory not found: {source_dir}[/red]")
|
@@ -126,22 +121,18 @@ def copy_example_files(
|
|
126
121
|
console.print(f"[green]Created[/green] mount-point/{filename}")
|
127
122
|
|
128
123
|
except Exception as e:
|
129
|
-
console.print(
|
130
|
-
f"[red]Error copying mount-point/{filename}: {str(e)}[/red]"
|
131
|
-
)
|
124
|
+
console.print(f"[red]Error copying mount-point/{filename}: {str(e)}[/red]")
|
132
125
|
|
133
126
|
return created
|
134
127
|
|
135
128
|
|
136
|
-
def show_overview():
|
129
|
+
def show_overview() -> None:
|
137
130
|
"""Display an overview of available examples in a nicely formatted table."""
|
138
131
|
console.print("\n[bold cyan]fast-agent Example Applications[/bold cyan]")
|
139
132
|
console.print("Build agents and compose workflows through practical examples\n")
|
140
133
|
|
141
134
|
# Create a table for better organization
|
142
|
-
table = Table(
|
143
|
-
show_header=True, header_style="bold magenta", box=None, padding=(0, 2)
|
144
|
-
)
|
135
|
+
table = Table(show_header=True, header_style="bold magenta", box=None, padding=(0, 2))
|
145
136
|
table.add_column("Example")
|
146
137
|
table.add_column("Description")
|
147
138
|
table.add_column("Files")
|
@@ -178,10 +169,8 @@ def workflow(
|
|
178
169
|
Path("."),
|
179
170
|
help="Directory where workflow examples will be created",
|
180
171
|
),
|
181
|
-
force: bool = typer.Option(
|
182
|
-
|
183
|
-
),
|
184
|
-
):
|
172
|
+
force: bool = typer.Option(False, "--force", "-f", help="Force overwrite existing files"),
|
173
|
+
) -> None:
|
185
174
|
"""Create workflow pattern examples."""
|
186
175
|
target_dir = directory.resolve()
|
187
176
|
if not target_dir.exists():
|
@@ -198,10 +187,8 @@ def researcher(
|
|
198
187
|
Path("."),
|
199
188
|
help="Directory where researcher examples will be created (in 'researcher' subdirectory)",
|
200
189
|
),
|
201
|
-
force: bool = typer.Option(
|
202
|
-
|
203
|
-
),
|
204
|
-
):
|
190
|
+
force: bool = typer.Option(False, "--force", "-f", help="Force overwrite existing files"),
|
191
|
+
) -> None:
|
205
192
|
"""Create researcher pattern examples."""
|
206
193
|
target_dir = directory.resolve()
|
207
194
|
if not target_dir.exists():
|
@@ -218,10 +205,8 @@ def data_analysis(
|
|
218
205
|
Path("."),
|
219
206
|
help="Directory where data analysis examples will be created (creates 'data-analysis' subdirectory with mount-point)",
|
220
207
|
),
|
221
|
-
force: bool = typer.Option(
|
222
|
-
|
223
|
-
),
|
224
|
-
):
|
208
|
+
force: bool = typer.Option(False, "--force", "-f", help="Force overwrite existing files"),
|
209
|
+
) -> None:
|
225
210
|
"""Create data analysis examples with sample dataset."""
|
226
211
|
target_dir = directory.resolve()
|
227
212
|
if not target_dir.exists():
|
@@ -232,7 +217,7 @@ def data_analysis(
|
|
232
217
|
_show_completion_message("data-analysis", created)
|
233
218
|
|
234
219
|
|
235
|
-
def _show_completion_message(example_type: str, created: list[str]):
|
220
|
+
def _show_completion_message(example_type: str, created: list[str]) -> None:
|
236
221
|
"""Show completion message and next steps."""
|
237
222
|
if created:
|
238
223
|
console.print("\n[green]Setup completed successfully![/green]")
|
@@ -258,13 +243,9 @@ def _show_completion_message(example_type: str, created: list[str]):
|
|
258
243
|
"1. Set up the Brave MCP Server (get an API key from https://brave.com/search/api/)"
|
259
244
|
)
|
260
245
|
console.print("2. Try `uv run researcher.py` for the basic version")
|
261
|
-
console.print(
|
262
|
-
"3. Try `uv run researcher-eval.py` for the eval/optimize version"
|
263
|
-
)
|
246
|
+
console.print("3. Try `uv run researcher-eval.py` for the eval/optimize version")
|
264
247
|
elif example_type == "data-analysis":
|
265
|
-
console.print(
|
266
|
-
"1. Run uv `analysis.py` to perform data analysis and visualization"
|
267
|
-
)
|
248
|
+
console.print("1. Run uv `analysis.py` to perform data analysis and visualization")
|
268
249
|
console.print("2. The dataset is available in the mount-point directory:")
|
269
250
|
console.print(" - mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv")
|
270
251
|
console.print(
|
@@ -275,7 +256,7 @@ def _show_completion_message(example_type: str, created: list[str]):
|
|
275
256
|
|
276
257
|
|
277
258
|
@app.callback(invoke_without_command=True)
|
278
|
-
def main(ctx: typer.Context):
|
259
|
+
def main(ctx: typer.Context) -> None:
|
279
260
|
"""Create example applications and learn FastAgent patterns."""
|
280
261
|
if ctx.invoked_subcommand is None:
|
281
262
|
show_overview()
|
mcp_agent/cli/commands/config.py
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
+
from typing import NoReturn
|
2
|
+
|
1
3
|
import typer
|
2
4
|
|
3
5
|
app = typer.Typer()
|
4
6
|
|
5
7
|
|
6
8
|
@app.command()
|
7
|
-
def show():
|
9
|
+
def show() -> NoReturn:
|
8
10
|
"""Show the configuration."""
|
9
|
-
raise NotImplementedError(
|
10
|
-
"The show configuration command has not been implemented yet"
|
11
|
-
)
|
11
|
+
raise NotImplementedError("The show configuration command has not been implemented yet")
|
mcp_agent/cli/commands/setup.py
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
from pathlib import Path
|
2
|
+
|
2
3
|
import typer
|
3
|
-
from rich.prompt import Confirm
|
4
4
|
from rich.console import Console
|
5
|
+
from rich.prompt import Confirm
|
5
6
|
|
6
7
|
app = typer.Typer()
|
7
8
|
console = Console()
|
@@ -166,10 +167,8 @@ def init(
|
|
166
167
|
"-c",
|
167
168
|
help="Directory where configuration files will be created",
|
168
169
|
),
|
169
|
-
force: bool = typer.Option(
|
170
|
-
|
171
|
-
),
|
172
|
-
):
|
170
|
+
force: bool = typer.Option(False, "--force", "-f", help="Force overwrite existing files"),
|
171
|
+
) -> None:
|
173
172
|
"""Initialize a new FastAgent project with configuration files and example agent."""
|
174
173
|
|
175
174
|
config_path = Path(config_dir).resolve()
|
@@ -198,23 +197,17 @@ def init(
|
|
198
197
|
|
199
198
|
# Create configuration files
|
200
199
|
created = []
|
201
|
-
if create_file(
|
202
|
-
config_path / "fastagent.config.yaml", FASTAGENT_CONFIG_TEMPLATE, force
|
203
|
-
):
|
200
|
+
if create_file(config_path / "fastagent.config.yaml", FASTAGENT_CONFIG_TEMPLATE, force):
|
204
201
|
created.append("fastagent.yaml")
|
205
202
|
|
206
|
-
if create_file(
|
207
|
-
config_path / "fastagent.secrets.yaml", FASTAGENT_SECRETS_TEMPLATE, force
|
208
|
-
):
|
203
|
+
if create_file(config_path / "fastagent.secrets.yaml", FASTAGENT_SECRETS_TEMPLATE, force):
|
209
204
|
created.append("fastagent.secrets.yaml")
|
210
205
|
|
211
206
|
if create_file(config_path / "agent.py", AGENT_EXAMPLE_TEMPLATE, force):
|
212
207
|
created.append("agent.py")
|
213
208
|
|
214
209
|
# Only create .gitignore if none exists in parent directories
|
215
|
-
if needs_gitignore and create_file(
|
216
|
-
config_path / ".gitignore", GITIGNORE_TEMPLATE, force
|
217
|
-
):
|
210
|
+
if needs_gitignore and create_file(config_path / ".gitignore", GITIGNORE_TEMPLATE, force):
|
218
211
|
created.append(".gitignore")
|
219
212
|
|
220
213
|
if created:
|
mcp_agent/cli/main.py
CHANGED
@@ -3,11 +3,12 @@
|
|
3
3
|
import typer
|
4
4
|
from rich.console import Console
|
5
5
|
from rich.table import Table
|
6
|
+
|
7
|
+
from mcp_agent.cli.commands import bootstrap, setup
|
6
8
|
from mcp_agent.cli.terminal import Application
|
7
|
-
from mcp_agent.cli.commands import setup, bootstrap
|
8
9
|
|
9
10
|
app = typer.Typer(
|
10
|
-
help="
|
11
|
+
help="FastAgent CLI - Build effective agents using Model Context Protocol",
|
11
12
|
add_completion=False, # We'll add this later when we have more commands
|
12
13
|
)
|
13
14
|
|
@@ -20,7 +21,7 @@ application = Application()
|
|
20
21
|
console = Console()
|
21
22
|
|
22
23
|
|
23
|
-
def show_welcome():
|
24
|
+
def show_welcome() -> None:
|
24
25
|
"""Show a welcome message with available commands."""
|
25
26
|
from importlib.metadata import version
|
26
27
|
|
@@ -38,9 +39,7 @@ def show_welcome():
|
|
38
39
|
table.add_column("Description")
|
39
40
|
|
40
41
|
table.add_row("setup", "Set up a new agent project with configuration files")
|
41
|
-
table.add_row(
|
42
|
-
"bootstrap", "Create example applications (workflow, researcher, etc.)"
|
43
|
-
)
|
42
|
+
table.add_row("bootstrap", "Create example applications (workflow, researcher, etc.)")
|
44
43
|
# table.add_row("config", "Manage agent configuration settings")
|
45
44
|
|
46
45
|
console.print(table)
|
@@ -62,10 +61,8 @@ def main(
|
|
62
61
|
ctx: typer.Context,
|
63
62
|
verbose: bool = typer.Option(False, "--verbose", "-v", help="Enable verbose mode"),
|
64
63
|
quiet: bool = typer.Option(False, "--quiet", "-q", help="Disable output"),
|
65
|
-
color: bool = typer.Option(
|
66
|
-
|
67
|
-
),
|
68
|
-
):
|
64
|
+
color: bool = typer.Option(True, "--color/--no-color", help="Enable/disable color output"),
|
65
|
+
) -> None:
|
69
66
|
"""FastAgent CLI - Build effective agents using Model Context Protocol (MCP).
|
70
67
|
|
71
68
|
Use --help with any command for detailed usage information.
|
mcp_agent/cli/terminal.py
CHANGED
@@ -2,7 +2,7 @@ from mcp_agent.console import console, error_console
|
|
2
2
|
|
3
3
|
|
4
4
|
class Application:
|
5
|
-
def __init__(self, verbosity: int = 0, enable_color: bool = True):
|
5
|
+
def __init__(self, verbosity: int = 0, enable_color: bool = True) -> None:
|
6
6
|
self.verbosity = verbosity
|
7
7
|
# Use the central console instances, respecting color setting
|
8
8
|
if not enable_color:
|
@@ -13,8 +13,8 @@ class Application:
|
|
13
13
|
self.console = console
|
14
14
|
self.error_console = error_console
|
15
15
|
|
16
|
-
def log(self, message: str, level: str = "info"):
|
17
|
-
if level == "info" or (level == "debug" and self.verbosity > 0):
|
16
|
+
def log(self, message: str, level: str = "info") -> None:
|
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:
|
mcp_agent/config.py
CHANGED
@@ -100,31 +100,36 @@ class MCPSettings(BaseModel):
|
|
100
100
|
|
101
101
|
class AnthropicSettings(BaseModel):
|
102
102
|
"""
|
103
|
-
Settings for using Anthropic models in the
|
103
|
+
Settings for using Anthropic models in the fast-agent application.
|
104
104
|
"""
|
105
105
|
|
106
106
|
api_key: str | None = None
|
107
107
|
|
108
|
+
base_url: str | None = None
|
109
|
+
|
108
110
|
model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True)
|
109
111
|
|
110
112
|
|
111
|
-
class
|
113
|
+
class OpenAISettings(BaseModel):
|
112
114
|
"""
|
113
|
-
Settings for using
|
115
|
+
Settings for using OpenAI models in the fast-agent application.
|
114
116
|
"""
|
115
117
|
|
116
118
|
api_key: str | None = None
|
119
|
+
reasoning_effort: Literal["low", "medium", "high"] = "medium"
|
120
|
+
|
121
|
+
base_url: str | None = None
|
117
122
|
|
118
123
|
model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True)
|
119
124
|
|
120
125
|
|
121
|
-
class
|
126
|
+
class DeepSeekSettings(BaseModel):
|
122
127
|
"""
|
123
|
-
Settings for using OpenAI models in the
|
128
|
+
Settings for using OpenAI models in the fast-agent application.
|
124
129
|
"""
|
125
130
|
|
126
131
|
api_key: str | None = None
|
127
|
-
reasoning_effort: Literal["low", "medium", "high"] = "medium"
|
132
|
+
# reasoning_effort: Literal["low", "medium", "high"] = "medium"
|
128
133
|
|
129
134
|
base_url: str | None = None
|
130
135
|
|
@@ -133,7 +138,7 @@ class OpenAISettings(BaseModel):
|
|
133
138
|
|
134
139
|
class TemporalSettings(BaseModel):
|
135
140
|
"""
|
136
|
-
Temporal settings for the
|
141
|
+
Temporal settings for the fast-agent application.
|
137
142
|
"""
|
138
143
|
|
139
144
|
host: str
|
@@ -142,27 +147,14 @@ class TemporalSettings(BaseModel):
|
|
142
147
|
api_key: str | None = None
|
143
148
|
|
144
149
|
|
145
|
-
class UsageTelemetrySettings(BaseModel):
|
146
|
-
"""
|
147
|
-
Settings for usage telemetry in the MCP Agent application.
|
148
|
-
Anonymized usage metrics are sent to a telemetry server to help improve the product.
|
149
|
-
"""
|
150
|
-
|
151
|
-
enabled: bool = True
|
152
|
-
"""Enable usage telemetry in the MCP Agent application."""
|
153
|
-
|
154
|
-
enable_detailed_telemetry: bool = False
|
155
|
-
"""If enabled, detailed telemetry data, including prompts and agents, will be sent to the telemetry server."""
|
156
|
-
|
157
|
-
|
158
150
|
class OpenTelemetrySettings(BaseModel):
|
159
151
|
"""
|
160
|
-
OTEL settings for the
|
152
|
+
OTEL settings for the fast-agent application.
|
161
153
|
"""
|
162
154
|
|
163
155
|
enabled: bool = True
|
164
156
|
|
165
|
-
service_name: str = "
|
157
|
+
service_name: str = "fast-agent"
|
166
158
|
service_instance_id: str | None = None
|
167
159
|
service_version: str | None = None
|
168
160
|
|
@@ -178,7 +170,7 @@ class OpenTelemetrySettings(BaseModel):
|
|
178
170
|
|
179
171
|
class LoggerSettings(BaseModel):
|
180
172
|
"""
|
181
|
-
Logger settings for the
|
173
|
+
Logger settings for the fast-agent application.
|
182
174
|
"""
|
183
175
|
|
184
176
|
type: Literal["none", "console", "file", "http"] = "file"
|
@@ -221,7 +213,7 @@ class LoggerSettings(BaseModel):
|
|
221
213
|
|
222
214
|
class Settings(BaseSettings):
|
223
215
|
"""
|
224
|
-
Settings class for the
|
216
|
+
Settings class for the fast-agent application.
|
225
217
|
"""
|
226
218
|
|
227
219
|
model_config = SettingsConfigDict(
|
@@ -236,7 +228,7 @@ class Settings(BaseSettings):
|
|
236
228
|
"""MCP config, such as MCP servers"""
|
237
229
|
|
238
230
|
execution_engine: Literal["asyncio", "temporal"] = "asyncio"
|
239
|
-
"""Execution engine for the
|
231
|
+
"""Execution engine for the fast-agent application"""
|
240
232
|
|
241
233
|
default_model: str | None = "haiku"
|
242
234
|
"""
|
@@ -247,22 +239,19 @@ class Settings(BaseSettings):
|
|
247
239
|
"""Settings for Temporal workflow orchestration"""
|
248
240
|
|
249
241
|
anthropic: AnthropicSettings | None = None
|
250
|
-
"""Settings for using Anthropic models in the
|
242
|
+
"""Settings for using Anthropic models in the fast-agent application"""
|
251
243
|
|
252
|
-
|
253
|
-
"""
|
244
|
+
otel: OpenTelemetrySettings | None = OpenTelemetrySettings()
|
245
|
+
"""OpenTelemetry logging settings for the fast-agent application"""
|
254
246
|
|
255
247
|
openai: OpenAISettings | None = None
|
256
|
-
"""Settings for using OpenAI models in the
|
248
|
+
"""Settings for using OpenAI models in the fast-agent application"""
|
257
249
|
|
258
|
-
|
259
|
-
"""
|
250
|
+
deepseek: DeepSeekSettings | None = None
|
251
|
+
"""Settings for using DeepSeek models in the fast-agent application"""
|
260
252
|
|
261
253
|
logger: LoggerSettings | None = LoggerSettings()
|
262
|
-
"""Logger settings for the
|
263
|
-
|
264
|
-
usage_telemetry: UsageTelemetrySettings | None = UsageTelemetrySettings()
|
265
|
-
"""Usage tracking settings for the MCP Agent application"""
|
254
|
+
"""Logger settings for the fast-agent application"""
|
266
255
|
|
267
256
|
@classmethod
|
268
257
|
def find_config(cls) -> Path | None:
|
@@ -295,11 +284,7 @@ def get_settings(config_path: str | None = None) -> Settings:
|
|
295
284
|
"""Recursively merge two dictionaries, preserving nested structures."""
|
296
285
|
merged = base.copy()
|
297
286
|
for key, value in update.items():
|
298
|
-
if (
|
299
|
-
key in merged
|
300
|
-
and isinstance(merged[key], dict)
|
301
|
-
and isinstance(value, dict)
|
302
|
-
):
|
287
|
+
if key in merged and isinstance(merged[key], dict) and isinstance(value, dict):
|
303
288
|
merged[key] = deep_merge(merged[key], value)
|
304
289
|
else:
|
305
290
|
merged[key] = value
|
mcp_agent/context.py
CHANGED
@@ -4,40 +4,33 @@ A central context object to store global state that is shared across the applica
|
|
4
4
|
|
5
5
|
import asyncio
|
6
6
|
import concurrent.futures
|
7
|
-
from typing import Any, Optional, Union
|
8
|
-
|
9
|
-
from pydantic import BaseModel, ConfigDict
|
7
|
+
from typing import TYPE_CHECKING, Any, Optional, Union
|
10
8
|
|
11
9
|
from mcp import ServerSession
|
12
|
-
|
13
10
|
from opentelemetry import trace
|
11
|
+
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
|
14
12
|
from opentelemetry.propagate import set_global_textmap
|
15
13
|
from opentelemetry.sdk.resources import Resource
|
16
14
|
from opentelemetry.sdk.trace import TracerProvider
|
17
15
|
from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter
|
18
16
|
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
|
19
|
-
from
|
17
|
+
from pydantic import BaseModel, ConfigDict
|
20
18
|
|
21
|
-
from mcp_agent.config import get_settings
|
22
|
-
from mcp_agent.config import Settings
|
23
|
-
from mcp_agent.executor.executor import Executor
|
19
|
+
from mcp_agent.config import Settings, get_settings
|
24
20
|
from mcp_agent.executor.decorator_registry import (
|
25
21
|
DecoratorRegistry,
|
26
22
|
register_asyncio_decorators,
|
27
23
|
)
|
24
|
+
from mcp_agent.executor.executor import AsyncioExecutor, Executor
|
28
25
|
from mcp_agent.executor.task_registry import ActivityRegistry
|
29
|
-
from mcp_agent.executor.executor import AsyncioExecutor
|
30
|
-
|
31
26
|
from mcp_agent.logging.events import EventFilter
|
32
|
-
from mcp_agent.logging.logger import LoggingConfig
|
27
|
+
from mcp_agent.logging.logger import LoggingConfig, get_logger
|
33
28
|
from mcp_agent.logging.transport import create_transport
|
34
29
|
from mcp_agent.mcp_server_registry import ServerRegistry
|
35
|
-
from mcp_agent.logging.logger import get_logger
|
36
|
-
|
37
30
|
|
38
31
|
if TYPE_CHECKING:
|
39
|
-
from mcp_agent.human_input.types import HumanInputCallback
|
40
32
|
from mcp_agent.executor.workflow_signal import SignalWaitCallback
|
33
|
+
from mcp_agent.human_input.types import HumanInputCallback
|
41
34
|
else:
|
42
35
|
# Runtime placeholders for the types
|
43
36
|
HumanInputCallback = Any
|
@@ -71,7 +64,7 @@ class Context(BaseModel):
|
|
71
64
|
)
|
72
65
|
|
73
66
|
|
74
|
-
async def configure_otel(config: "Settings"):
|
67
|
+
async def configure_otel(config: "Settings") -> None:
|
75
68
|
"""
|
76
69
|
Configure OpenTelemetry based on the application config.
|
77
70
|
"""
|
@@ -112,9 +105,7 @@ async def configure_otel(config: "Settings"):
|
|
112
105
|
tracer_provider.add_span_processor(BatchSpanProcessor(exporter))
|
113
106
|
|
114
107
|
if config.otel.console_debug:
|
115
|
-
tracer_provider.add_span_processor(
|
116
|
-
BatchSpanProcessor(ConsoleSpanExporter())
|
117
|
-
)
|
108
|
+
tracer_provider.add_span_processor(BatchSpanProcessor(ConsoleSpanExporter()))
|
118
109
|
else:
|
119
110
|
# Default to console exporter in development
|
120
111
|
tracer_provider.add_span_processor(BatchSpanProcessor(ConsoleSpanExporter()))
|
@@ -123,7 +114,7 @@ async def configure_otel(config: "Settings"):
|
|
123
114
|
trace.set_tracer_provider(tracer_provider)
|
124
115
|
|
125
116
|
|
126
|
-
async def configure_logger(config: "Settings"):
|
117
|
+
async def configure_logger(config: "Settings") -> None:
|
127
118
|
"""
|
128
119
|
Configure logging and tracing based on the application config.
|
129
120
|
"""
|
@@ -139,7 +130,7 @@ async def configure_logger(config: "Settings"):
|
|
139
130
|
)
|
140
131
|
|
141
132
|
|
142
|
-
async def configure_usage_telemetry(_config: "Settings"):
|
133
|
+
async def configure_usage_telemetry(_config: "Settings") -> None:
|
143
134
|
"""
|
144
135
|
Configure usage telemetry based on the application config.
|
145
136
|
TODO: saqadri - implement usage tracking
|
@@ -202,7 +193,7 @@ async def initialize_context(
|
|
202
193
|
return context
|
203
194
|
|
204
195
|
|
205
|
-
async def cleanup_context():
|
196
|
+
async def cleanup_context() -> None:
|
206
197
|
"""
|
207
198
|
Cleanup the global application context.
|
208
199
|
"""
|
mcp_agent/context_dependent.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
from contextlib import contextmanager
|
2
|
-
from typing import
|
3
|
-
|
2
|
+
from typing import TYPE_CHECKING, Any, Optional
|
4
3
|
|
5
4
|
if TYPE_CHECKING:
|
6
5
|
from mcp_agent.context import Context
|
@@ -12,7 +11,7 @@ class ContextDependent:
|
|
12
11
|
Provides both global fallback and instance-specific context support.
|
13
12
|
"""
|
14
13
|
|
15
|
-
def __init__(self, context: Optional["Context"] = None, **kwargs):
|
14
|
+
def __init__(self, context: Optional["Context"] = None, **kwargs: dict[str, Any]) -> None:
|
16
15
|
self._context = context
|
17
16
|
super().__init__(**kwargs)
|
18
17
|
|
@@ -33,8 +32,7 @@ class ContextDependent:
|
|
33
32
|
return get_current_context()
|
34
33
|
except Exception as e:
|
35
34
|
raise RuntimeError(
|
36
|
-
f"No context available for {self.__class__.__name__}. "
|
37
|
-
"Either initialize MCPApp first or pass context explicitly."
|
35
|
+
f"No context available for {self.__class__.__name__}. Either initialize MCPApp first or pass context explicitly."
|
38
36
|
) from e
|
39
37
|
|
40
38
|
@contextmanager
|
mcp_agent/core/agent_types.py
CHANGED
@@ -2,9 +2,10 @@
|
|
2
2
|
Type definitions for agents and agent configurations.
|
3
3
|
"""
|
4
4
|
|
5
|
+
import dataclasses
|
5
6
|
from dataclasses import dataclass
|
6
7
|
from enum import Enum
|
7
|
-
from typing import
|
8
|
+
from typing import List
|
8
9
|
|
9
10
|
# Forward imports to avoid circular dependencies
|
10
11
|
from mcp_agent.core.request_params import RequestParams
|
@@ -26,18 +27,20 @@ class AgentConfig:
|
|
26
27
|
"""Configuration for an Agent instance"""
|
27
28
|
|
28
29
|
name: str
|
29
|
-
instruction:
|
30
|
-
servers: List[str]
|
31
|
-
model:
|
30
|
+
instruction: str = "You are a helpful agent."
|
31
|
+
servers: List[str] = dataclasses.field(default_factory=list)
|
32
|
+
model: str | None = None
|
32
33
|
use_history: bool = True
|
33
|
-
default_request_params:
|
34
|
+
default_request_params: RequestParams | None = None
|
34
35
|
human_input: bool = False
|
35
36
|
|
36
|
-
def __post_init__(self):
|
37
|
+
def __post_init__(self) -> None:
|
37
38
|
"""Ensure default_request_params exists with proper history setting"""
|
38
39
|
|
39
40
|
if self.default_request_params is None:
|
40
|
-
self.default_request_params = RequestParams(
|
41
|
+
self.default_request_params = RequestParams(
|
42
|
+
use_history=self.use_history, systemPrompt=self.instruction
|
43
|
+
)
|
41
44
|
else:
|
42
45
|
# Override the request params history setting if explicitly configured
|
43
46
|
self.default_request_params.use_history = self.use_history
|