fast-agent-mcp 0.0.15__tar.gz → 0.0.16__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.
Files changed (124) hide show
  1. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/PKG-INFO +116 -17
  2. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/README.md +115 -16
  3. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/pyproject.toml +1 -1
  4. fast_agent_mcp-0.0.16/src/mcp_agent/cli/__main__.py +7 -0
  5. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/config.py +19 -11
  6. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/core/enhanced_prompt.py +10 -2
  7. fast_agent_mcp-0.0.16/src/mcp_agent/resources/examples/data-analysis/analysis.py +61 -0
  8. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/resources/examples/workflows/evaluator.py +0 -2
  9. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/resources/examples/workflows/parallel.py +0 -4
  10. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/evaluator_optimizer/evaluator_optimizer.py +112 -31
  11. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/llm/augmented_llm_anthropic.py +16 -2
  12. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/llm/augmented_llm_openai.py +13 -1
  13. fast_agent_mcp-0.0.16/src/mcp_agent/workflows/llm/prompt_utils.py +137 -0
  14. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/orchestrator/orchestrator.py +206 -52
  15. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/orchestrator/orchestrator_models.py +81 -9
  16. fast_agent_mcp-0.0.16/src/mcp_agent/workflows/orchestrator/orchestrator_prompts.py +188 -0
  17. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/router/router_base.py +113 -21
  18. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/router/router_llm.py +19 -5
  19. fast_agent_mcp-0.0.15/src/mcp_agent/cli/__main__.py +0 -4
  20. fast_agent_mcp-0.0.15/src/mcp_agent/resources/examples/data-analysis/analysis.py +0 -35
  21. fast_agent_mcp-0.0.15/src/mcp_agent/workflows/orchestrator/orchestrator_prompts.py +0 -118
  22. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/.gitignore +0 -0
  23. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/LICENSE +0 -0
  24. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/__init__.py +0 -0
  25. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/agents/__init__.py +0 -0
  26. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/agents/agent.py +0 -0
  27. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/app.py +0 -0
  28. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/cli/__init__.py +0 -0
  29. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/cli/commands/bootstrap.py +0 -0
  30. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/cli/commands/config.py +0 -0
  31. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/cli/commands/setup.py +0 -0
  32. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/cli/main.py +0 -0
  33. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/cli/terminal.py +0 -0
  34. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/console.py +0 -0
  35. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/context.py +0 -0
  36. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/context_dependent.py +0 -0
  37. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/core/__init__.py +0 -0
  38. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/core/agent_app.py +0 -0
  39. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/core/agent_types.py +0 -0
  40. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/core/agent_utils.py +0 -0
  41. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/core/error_handling.py +0 -0
  42. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/core/exceptions.py +0 -0
  43. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/core/fastagent.py +0 -0
  44. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/core/proxies.py +0 -0
  45. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/core/server_validation.py +0 -0
  46. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/core/types.py +0 -0
  47. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/eval/__init__.py +0 -0
  48. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/event_progress.py +0 -0
  49. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/executor/__init__.py +0 -0
  50. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/executor/decorator_registry.py +0 -0
  51. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/executor/executor.py +0 -0
  52. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/executor/task_registry.py +0 -0
  53. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/executor/temporal.py +0 -0
  54. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/executor/workflow.py +0 -0
  55. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/executor/workflow_signal.py +0 -0
  56. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/human_input/__init__.py +0 -0
  57. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/human_input/handler.py +0 -0
  58. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/human_input/types.py +0 -0
  59. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/logging/__init__.py +0 -0
  60. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/logging/events.py +0 -0
  61. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/logging/json_serializer.py +0 -0
  62. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/logging/listeners.py +0 -0
  63. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/logging/logger.py +0 -0
  64. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/logging/rich_progress.py +0 -0
  65. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/logging/tracing.py +0 -0
  66. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/logging/transport.py +0 -0
  67. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/mcp/__init__.py +0 -0
  68. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/mcp/gen_client.py +0 -0
  69. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/mcp/mcp_activity.py +0 -0
  70. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/mcp/mcp_agent_client_session.py +0 -0
  71. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/mcp/mcp_agent_server.py +0 -0
  72. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/mcp/mcp_aggregator.py +0 -0
  73. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/mcp/mcp_connection_manager.py +0 -0
  74. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/mcp/stdio.py +0 -0
  75. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/mcp_server_registry.py +0 -0
  76. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/progress_display.py +0 -0
  77. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/resources/examples/data-analysis/fastagent.config.yaml +0 -0
  78. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
  79. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/resources/examples/internal/agent.py +0 -0
  80. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/resources/examples/internal/job.py +0 -0
  81. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/resources/examples/internal/social.py +0 -0
  82. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/resources/examples/mcp_researcher/researcher-eval.py +0 -0
  83. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/resources/examples/researcher/fastagent.config.yaml +0 -0
  84. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/resources/examples/researcher/researcher-eval.py +0 -0
  85. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/resources/examples/researcher/researcher.py +0 -0
  86. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/resources/examples/workflows/agent_build.py +0 -0
  87. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/resources/examples/workflows/chaining.py +0 -0
  88. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/resources/examples/workflows/fastagent.config.yaml +0 -0
  89. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/resources/examples/workflows/human_input.py +0 -0
  90. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/resources/examples/workflows/orchestrator.py +0 -0
  91. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/resources/examples/workflows/router.py +0 -0
  92. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/telemetry/__init__.py +0 -0
  93. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/telemetry/usage_tracking.py +0 -0
  94. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/__init__.py +0 -0
  95. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/embedding/__init__.py +0 -0
  96. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/embedding/embedding_base.py +0 -0
  97. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/embedding/embedding_cohere.py +0 -0
  98. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/embedding/embedding_openai.py +0 -0
  99. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/evaluator_optimizer/__init__.py +0 -0
  100. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/intent_classifier/__init__.py +0 -0
  101. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/intent_classifier/intent_classifier_base.py +0 -0
  102. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/intent_classifier/intent_classifier_embedding.py +0 -0
  103. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/intent_classifier/intent_classifier_embedding_cohere.py +0 -0
  104. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/intent_classifier/intent_classifier_embedding_openai.py +0 -0
  105. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/intent_classifier/intent_classifier_llm.py +0 -0
  106. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/intent_classifier/intent_classifier_llm_anthropic.py +0 -0
  107. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/intent_classifier/intent_classifier_llm_openai.py +0 -0
  108. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/llm/__init__.py +0 -0
  109. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/llm/augmented_llm.py +0 -0
  110. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/llm/llm_selector.py +0 -0
  111. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/llm/model_factory.py +0 -0
  112. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/orchestrator/__init__.py +0 -0
  113. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/parallel/__init__.py +0 -0
  114. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/parallel/fan_in.py +0 -0
  115. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/parallel/fan_out.py +0 -0
  116. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/parallel/parallel_llm.py +0 -0
  117. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/router/__init__.py +0 -0
  118. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/router/router_embedding.py +0 -0
  119. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/router/router_embedding_cohere.py +0 -0
  120. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/router/router_embedding_openai.py +0 -0
  121. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/swarm/__init__.py +0 -0
  122. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/swarm/swarm.py +0 -0
  123. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/swarm/swarm_anthropic.py +0 -0
  124. {fast_agent_mcp-0.0.15 → fast_agent_mcp-0.0.16}/src/mcp_agent/workflows/swarm/swarm_openai.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fast-agent-mcp
3
- Version: 0.0.15
3
+ Version: 0.0.16
4
4
  Summary: Define, Prompt and Test MCP enabled Agents and Workflows
5
5
  Author-email: Shaun Smith <fastagent@llmindset.co.uk>, Sarmad Qadri <sarmad@lastmileai.dev>
6
6
  License: Apache License
@@ -259,14 +259,17 @@ Prompts and configurations that define your Agent Applications are stored in sim
259
259
 
260
260
  Chat with individual Agents and Components before, during and after workflow execution to tune and diagnose your application.
261
261
 
262
- Simple model selection makes testing Model <-> MCP Server interaction painless.
262
+ Simple model selection makes testing Model <-> MCP Server interaction painless. You can read more about the motivation behind this project [here](https://llmindset.co.uk/resources/fast-agent/)
263
+
264
+ ![fast-agent](https://github.com/user-attachments/assets/3e692103-bf97-489a-b519-2d0fee036369)
263
265
 
264
266
  ## Get started:
265
267
 
266
268
  Start by installing the [uv package manager](https://docs.astral.sh/uv/) for Python. Then:
267
269
 
268
270
  ```bash
269
- uv pip install fast-agent-mcp # install fast-agent
271
+ uv pip install fast-agent-mcp # install fast-agent!
272
+
270
273
  fast-agent setup # create an example agent and config files
271
274
  uv run agent.py # run your first agent
272
275
  uv run agent.py --model=o3-mini.low # specify a model
@@ -275,6 +278,7 @@ fast-agent bootstrap workflow # create "building effective agents" example
275
278
 
276
279
  Other bootstrap examples include a Researcher Agent (with Evaluator-Optimizer workflow) and Data Analysis Agent (similar to the ChatGPT experience), demonstrating MCP Roots support.
277
280
 
281
+ > [!TIP]
278
282
  > Windows Users - there are a couple of configuration changes needed for the Filesystem and Docker MCP Servers - necessary changes are detailed within the configuration files.
279
283
 
280
284
  ### Basic Agents
@@ -354,7 +358,7 @@ async def main():
354
358
  )
355
359
  ```
356
360
 
357
- All Agents and Workflows respond to `.send("message")` and `.prompt()` to begin a chat session.
361
+ All Agents and Workflows respond to `.send("message")` or `.prompt()` to begin a chat session.
358
362
 
359
363
  Saved as `social.py` we can now run this workflow from the command line with:
360
364
 
@@ -362,7 +366,7 @@ Saved as `social.py` we can now run this workflow from the command line with:
362
366
  uv run social.py --agent social_media --message "<url>"
363
367
  ```
364
368
 
365
- Add the `--quiet` switch to only return the final response.
369
+ Add the `--quiet` switch to only return the final response, which is useful for simple automations.
366
370
 
367
371
  ## Workflows
368
372
 
@@ -383,7 +387,7 @@ async with fast.run() as agent:
383
387
 
384
388
  ```
385
389
 
386
- This starts an interactive session, which produces a short social media post for a given URL. If a _chain_ is prompted, by default it returns to a chat with last Agent in the chain.
390
+ This starts an interactive session, which produces a short social media post for a given URL. If a _chain_ is prompted it returns to a chat with last Agent in the chain. You can switch the agent to prompt by typing `@agent-name`.
387
391
 
388
392
  Chains can be incorporated in other workflows, or contain other workflow elements (including other Chains). You can set an `instruction` to precisely describe it's capabilities to other workflow steps if needed.
389
393
 
@@ -407,9 +411,9 @@ The Parallel Workflow sends the same message to multiple Agents simultaneously (
407
411
  )
408
412
  ```
409
413
 
410
- Look at the `parallel.py` workflow example for more examples. If you don't specify a `fan-in` agent, the `parallel` returns Agent results verbatim.
414
+ Look at the `parallel.py` workflow example for more examples. If you don't specify a `fan-in` agent, the `parallel` returns the combined Agent results verbatim.
411
415
 
412
- The Parallel is also useful to ensemble ideas from different LLMs.
416
+ `parallel` is also useful to ensemble ideas from different LLMs.
413
417
 
414
418
  ### Evaluator-Optimizer
415
419
 
@@ -458,20 +462,107 @@ See `orchestrator.py` in the workflow examples.
458
462
 
459
463
  ## Agent Features
460
464
 
465
+ ### Calling Agents
466
+
467
+ All definitions allow omitting the name and instructions arguments for brevity:
468
+
469
+ ```python
470
+ @fast.agent("You are a helpful agent") # Create an agent with a default name.
471
+ @fast.agent("greeter","Respond cheerfully!") # Create an agent with the name "greeter"
472
+
473
+ moon_size = await agent("the moon") # Call the default (first defined agent) with a message
474
+
475
+ result = await agent.greeter("Good morning!") # Send a message to an agent by name using dot notation
476
+ result = await agent.greeter.send("Hello!") # You can call 'send' explicitly
477
+
478
+ await agent.greeter() # If no message is specified, a chat session will open
479
+ await agent.greeter.prompt() # that can be made more explicit
480
+ await agent.greeter.prompt(default_prompt="OK") # and supports setting a default prompt
481
+
482
+ agent["greeter"].send("Good Evening!") # Dictionary access is supported if preferred
483
+ ```
484
+
485
+ ### Defining Agents
486
+
487
+ #### Basic Agent
488
+
461
489
  ```python
462
490
  @fast.agent(
463
- name="agent",
464
- instructions="instructions",
465
- servers=["filesystem"], # list of MCP Servers for the agent, configured in fastagent.config.yaml
466
- model="o3-mini.high", # specify a model for the agent
467
- use_history=True, # agent can maintain chat history
468
- human_input=True, # agent can request human input
491
+ name="agent", # name of the agent
492
+ instruction="You are a helpful Agent", # base instruction for the agent
493
+ servers=["filesystem"], # list of MCP Servers for the agent
494
+ model="o3-mini.high", # specify a model for the agent
495
+ use_history=True, # agent maintains chat history
496
+ request_params={"temperature": 0.7}, # additional parameters for the LLM (or RequestParams())
497
+ human_input=True, # agent can request human input
498
+ )
499
+ ```
500
+
501
+ #### Chain
502
+
503
+ ```python
504
+ @fast.chain(
505
+ name="chain", # name of the chain
506
+ sequence=["agent1", "agent2", ...], # list of agents in execution order
507
+ instruction="instruction", # instruction to describe the chain for other workflows
508
+ continue_with_final=True, # open chat with agent at end of chain after prompting
469
509
  )
470
510
  ```
471
511
 
472
- ### Human Input
512
+ #### Parallel
513
+
514
+ ```python
515
+ @fast.parallel(
516
+ name="parallel", # name of the parallel workflow
517
+ fan_out=["agent1", "agent2"], # list of agents to run in parallel
518
+ fan_in="aggregator", # name of agent that combines results (optional)
519
+ instruction="instruction", # instruction to describe the parallel for other workflows
520
+ include_request=True, # include original request in fan-in message
521
+ )
522
+ ```
473
523
 
474
- When `human_input` is set to true for an Agent, it is presented with the option to prompt the User for input.
524
+ #### Evaluator-Optimizer
525
+
526
+ ```python
527
+ @fast.evaluator_optimizer(
528
+ name="researcher", # name of the workflow
529
+ generator="web_searcher", # name of the content generator agent
530
+ evaluator="quality_assurance", # name of the evaluator agent
531
+ min_rating="GOOD", # minimum acceptable quality (EXCELLENT, GOOD, FAIR, POOR)
532
+ max_refinements=3, # maximum number of refinement iterations
533
+ )
534
+ ```
535
+
536
+ #### Router
537
+
538
+ ```python
539
+ @fast.router(
540
+ name="route", # name of the router
541
+ agents=["agent1", "agent2", "agent3"], # list of agent names router can delegate to
542
+ model="o3-mini.high", # specify routing model
543
+ use_history=True, # router maintains chat history
544
+ human_input=False, # whether router can request human input
545
+ )
546
+ ```
547
+
548
+ #### Orchestrator
549
+
550
+ ```python
551
+ @fast.orchestrator(
552
+ name="orchestrator", # name of the orchestrator
553
+ instruction="instruction", # base instruction for the orchestrator
554
+ agents=["agent1", "agent2"], # list of agent names this orchestrator can use
555
+ model="o3-mini.high", # specify orchestrator planning model
556
+ use_history=False, # orchestrator doesn't maintain chat history by default
557
+ human_input=False, # whether orchestrator can request human input
558
+ plan_type="full", # planning approach: "full" or "iterative"
559
+ )
560
+ ```
561
+
562
+ ### Secrets File
563
+
564
+ > [!TIP]
565
+ > fast-agent will look recursively for a fastagent.secrets.yaml file, so you only need to manage this at the root folder of your agent definitions.
475
566
 
476
567
  ## Project Notes
477
568
 
@@ -479,8 +570,11 @@ When `human_input` is set to true for an Agent, it is presented with the option
479
570
 
480
571
  ### llmindset.co.uk fork:
481
572
 
573
+ - Remove instructor use for Orchestrator
574
+ - Improved handling of Parallel/Fan-In and respose option
575
+ - XML based generated prompts
482
576
  - "FastAgent" style prototyping, with per-agent models
483
- - Api keys through Environment Variables
577
+ - API keys through Environment Variables
484
578
  - Warm-up / Post-Workflow Agent Interactions
485
579
  - Quick Setup
486
580
  - Interactive Prompt Mode
@@ -493,7 +587,12 @@ When `human_input` is set to true for an Agent, it is presented with the option
493
587
  - OpenAI o1/o3-mini support with reasoning level
494
588
  - Enhanced Human Input Messaging and Handling
495
589
  - Declarative workflows
590
+ - Numerous defect fixes
496
591
 
497
592
  ### Features to add.
498
593
 
499
594
  - Chat History Clear.
595
+
596
+ ```
597
+
598
+ ```
@@ -22,14 +22,17 @@ Prompts and configurations that define your Agent Applications are stored in sim
22
22
 
23
23
  Chat with individual Agents and Components before, during and after workflow execution to tune and diagnose your application.
24
24
 
25
- Simple model selection makes testing Model <-> MCP Server interaction painless.
25
+ Simple model selection makes testing Model <-> MCP Server interaction painless. You can read more about the motivation behind this project [here](https://llmindset.co.uk/resources/fast-agent/)
26
+
27
+ ![fast-agent](https://github.com/user-attachments/assets/3e692103-bf97-489a-b519-2d0fee036369)
26
28
 
27
29
  ## Get started:
28
30
 
29
31
  Start by installing the [uv package manager](https://docs.astral.sh/uv/) for Python. Then:
30
32
 
31
33
  ```bash
32
- uv pip install fast-agent-mcp # install fast-agent
34
+ uv pip install fast-agent-mcp # install fast-agent!
35
+
33
36
  fast-agent setup # create an example agent and config files
34
37
  uv run agent.py # run your first agent
35
38
  uv run agent.py --model=o3-mini.low # specify a model
@@ -38,6 +41,7 @@ fast-agent bootstrap workflow # create "building effective agents" example
38
41
 
39
42
  Other bootstrap examples include a Researcher Agent (with Evaluator-Optimizer workflow) and Data Analysis Agent (similar to the ChatGPT experience), demonstrating MCP Roots support.
40
43
 
44
+ > [!TIP]
41
45
  > Windows Users - there are a couple of configuration changes needed for the Filesystem and Docker MCP Servers - necessary changes are detailed within the configuration files.
42
46
 
43
47
  ### Basic Agents
@@ -117,7 +121,7 @@ async def main():
117
121
  )
118
122
  ```
119
123
 
120
- All Agents and Workflows respond to `.send("message")` and `.prompt()` to begin a chat session.
124
+ All Agents and Workflows respond to `.send("message")` or `.prompt()` to begin a chat session.
121
125
 
122
126
  Saved as `social.py` we can now run this workflow from the command line with:
123
127
 
@@ -125,7 +129,7 @@ Saved as `social.py` we can now run this workflow from the command line with:
125
129
  uv run social.py --agent social_media --message "<url>"
126
130
  ```
127
131
 
128
- Add the `--quiet` switch to only return the final response.
132
+ Add the `--quiet` switch to only return the final response, which is useful for simple automations.
129
133
 
130
134
  ## Workflows
131
135
 
@@ -146,7 +150,7 @@ async with fast.run() as agent:
146
150
 
147
151
  ```
148
152
 
149
- This starts an interactive session, which produces a short social media post for a given URL. If a _chain_ is prompted, by default it returns to a chat with last Agent in the chain.
153
+ This starts an interactive session, which produces a short social media post for a given URL. If a _chain_ is prompted it returns to a chat with last Agent in the chain. You can switch the agent to prompt by typing `@agent-name`.
150
154
 
151
155
  Chains can be incorporated in other workflows, or contain other workflow elements (including other Chains). You can set an `instruction` to precisely describe it's capabilities to other workflow steps if needed.
152
156
 
@@ -170,9 +174,9 @@ The Parallel Workflow sends the same message to multiple Agents simultaneously (
170
174
  )
171
175
  ```
172
176
 
173
- Look at the `parallel.py` workflow example for more examples. If you don't specify a `fan-in` agent, the `parallel` returns Agent results verbatim.
177
+ Look at the `parallel.py` workflow example for more examples. If you don't specify a `fan-in` agent, the `parallel` returns the combined Agent results verbatim.
174
178
 
175
- The Parallel is also useful to ensemble ideas from different LLMs.
179
+ `parallel` is also useful to ensemble ideas from different LLMs.
176
180
 
177
181
  ### Evaluator-Optimizer
178
182
 
@@ -221,20 +225,107 @@ See `orchestrator.py` in the workflow examples.
221
225
 
222
226
  ## Agent Features
223
227
 
228
+ ### Calling Agents
229
+
230
+ All definitions allow omitting the name and instructions arguments for brevity:
231
+
232
+ ```python
233
+ @fast.agent("You are a helpful agent") # Create an agent with a default name.
234
+ @fast.agent("greeter","Respond cheerfully!") # Create an agent with the name "greeter"
235
+
236
+ moon_size = await agent("the moon") # Call the default (first defined agent) with a message
237
+
238
+ result = await agent.greeter("Good morning!") # Send a message to an agent by name using dot notation
239
+ result = await agent.greeter.send("Hello!") # You can call 'send' explicitly
240
+
241
+ await agent.greeter() # If no message is specified, a chat session will open
242
+ await agent.greeter.prompt() # that can be made more explicit
243
+ await agent.greeter.prompt(default_prompt="OK") # and supports setting a default prompt
244
+
245
+ agent["greeter"].send("Good Evening!") # Dictionary access is supported if preferred
246
+ ```
247
+
248
+ ### Defining Agents
249
+
250
+ #### Basic Agent
251
+
224
252
  ```python
225
253
  @fast.agent(
226
- name="agent",
227
- instructions="instructions",
228
- servers=["filesystem"], # list of MCP Servers for the agent, configured in fastagent.config.yaml
229
- model="o3-mini.high", # specify a model for the agent
230
- use_history=True, # agent can maintain chat history
231
- human_input=True, # agent can request human input
254
+ name="agent", # name of the agent
255
+ instruction="You are a helpful Agent", # base instruction for the agent
256
+ servers=["filesystem"], # list of MCP Servers for the agent
257
+ model="o3-mini.high", # specify a model for the agent
258
+ use_history=True, # agent maintains chat history
259
+ request_params={"temperature": 0.7}, # additional parameters for the LLM (or RequestParams())
260
+ human_input=True, # agent can request human input
261
+ )
262
+ ```
263
+
264
+ #### Chain
265
+
266
+ ```python
267
+ @fast.chain(
268
+ name="chain", # name of the chain
269
+ sequence=["agent1", "agent2", ...], # list of agents in execution order
270
+ instruction="instruction", # instruction to describe the chain for other workflows
271
+ continue_with_final=True, # open chat with agent at end of chain after prompting
232
272
  )
233
273
  ```
234
274
 
235
- ### Human Input
275
+ #### Parallel
276
+
277
+ ```python
278
+ @fast.parallel(
279
+ name="parallel", # name of the parallel workflow
280
+ fan_out=["agent1", "agent2"], # list of agents to run in parallel
281
+ fan_in="aggregator", # name of agent that combines results (optional)
282
+ instruction="instruction", # instruction to describe the parallel for other workflows
283
+ include_request=True, # include original request in fan-in message
284
+ )
285
+ ```
236
286
 
237
- When `human_input` is set to true for an Agent, it is presented with the option to prompt the User for input.
287
+ #### Evaluator-Optimizer
288
+
289
+ ```python
290
+ @fast.evaluator_optimizer(
291
+ name="researcher", # name of the workflow
292
+ generator="web_searcher", # name of the content generator agent
293
+ evaluator="quality_assurance", # name of the evaluator agent
294
+ min_rating="GOOD", # minimum acceptable quality (EXCELLENT, GOOD, FAIR, POOR)
295
+ max_refinements=3, # maximum number of refinement iterations
296
+ )
297
+ ```
298
+
299
+ #### Router
300
+
301
+ ```python
302
+ @fast.router(
303
+ name="route", # name of the router
304
+ agents=["agent1", "agent2", "agent3"], # list of agent names router can delegate to
305
+ model="o3-mini.high", # specify routing model
306
+ use_history=True, # router maintains chat history
307
+ human_input=False, # whether router can request human input
308
+ )
309
+ ```
310
+
311
+ #### Orchestrator
312
+
313
+ ```python
314
+ @fast.orchestrator(
315
+ name="orchestrator", # name of the orchestrator
316
+ instruction="instruction", # base instruction for the orchestrator
317
+ agents=["agent1", "agent2"], # list of agent names this orchestrator can use
318
+ model="o3-mini.high", # specify orchestrator planning model
319
+ use_history=False, # orchestrator doesn't maintain chat history by default
320
+ human_input=False, # whether orchestrator can request human input
321
+ plan_type="full", # planning approach: "full" or "iterative"
322
+ )
323
+ ```
324
+
325
+ ### Secrets File
326
+
327
+ > [!TIP]
328
+ > fast-agent will look recursively for a fastagent.secrets.yaml file, so you only need to manage this at the root folder of your agent definitions.
238
329
 
239
330
  ## Project Notes
240
331
 
@@ -242,8 +333,11 @@ When `human_input` is set to true for an Agent, it is presented with the option
242
333
 
243
334
  ### llmindset.co.uk fork:
244
335
 
336
+ - Remove instructor use for Orchestrator
337
+ - Improved handling of Parallel/Fan-In and respose option
338
+ - XML based generated prompts
245
339
  - "FastAgent" style prototyping, with per-agent models
246
- - Api keys through Environment Variables
340
+ - API keys through Environment Variables
247
341
  - Warm-up / Post-Workflow Agent Interactions
248
342
  - Quick Setup
249
343
  - Interactive Prompt Mode
@@ -256,7 +350,12 @@ When `human_input` is set to true for an Agent, it is presented with the option
256
350
  - OpenAI o1/o3-mini support with reasoning level
257
351
  - Enhanced Human Input Messaging and Handling
258
352
  - Declarative workflows
353
+ - Numerous defect fixes
259
354
 
260
355
  ### Features to add.
261
356
 
262
357
  - Chat History Clear.
358
+
359
+ ```
360
+
361
+ ```
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fast-agent-mcp"
3
- version = "0.0.15"
3
+ version = "0.0.16"
4
4
  description = "Define, Prompt and Test MCP enabled Agents and Workflows"
5
5
  readme = "README.md"
6
6
  license = { file = "LICENSE" }
@@ -0,0 +1,7 @@
1
+ from mcp_agent.cli.main import app
2
+
3
+ # This must be here for the console entry points defined in pyproject.toml
4
+ # DO NOT REMOVE!
5
+
6
+ if __name__ == "__main__":
7
+ app()
@@ -313,17 +313,25 @@ def get_settings(config_path: str | None = None) -> Settings:
313
313
  with open(config_file, "r", encoding="utf-8") as f:
314
314
  yaml_settings = yaml.safe_load(f) or {}
315
315
  merged_settings = yaml_settings
316
-
317
- # Look for secrets file in the same directory
318
- for secrets_file in [
319
- config_file.parent / "mcp-agent.secrets.yaml",
320
- config_file.parent / "mcp_agent.secrets.yaml",
321
- config_file.parent / "fastagent.secrets.yaml",
322
- ]:
323
- if secrets_file.exists():
324
- with open(secrets_file, "r", encoding="utf-8") as f:
325
- yaml_secrets = yaml.safe_load(f) or {}
326
- merged_settings = deep_merge(merged_settings, yaml_secrets)
316
+ # Look for secrets files recursively up the directory tree
317
+ # but stop after finding the first one
318
+ current_dir = config_file.parent
319
+ found_secrets = False
320
+ while current_dir != current_dir.parent and not found_secrets:
321
+ for secrets_filename in [
322
+ "mcp-agent.secrets.yaml",
323
+ "mcp_agent.secrets.yaml",
324
+ "fastagent.secrets.yaml",
325
+ ]:
326
+ secrets_file = current_dir / secrets_filename
327
+ if secrets_file.exists():
328
+ with open(secrets_file, "r", encoding="utf-8") as f:
329
+ yaml_secrets = yaml.safe_load(f) or {}
330
+ merged_settings = deep_merge(merged_settings, yaml_secrets)
331
+ found_secrets = True
332
+ break
333
+ if not found_secrets:
334
+ current_dir = current_dir.parent
327
335
 
328
336
  _settings = Settings(**merged_settings)
329
337
  return _settings
@@ -3,6 +3,7 @@ Enhanced prompt functionality with advanced prompt_toolkit features.
3
3
  """
4
4
 
5
5
  from typing import List
6
+ from importlib.metadata import version
6
7
  from prompt_toolkit import PromptSession
7
8
  from prompt_toolkit.formatted_text import HTML
8
9
  from prompt_toolkit.history import InMemoryHistory
@@ -15,6 +16,12 @@ from rich import print as rich_print
15
16
 
16
17
  from mcp_agent.core.exceptions import PromptExitError
17
18
 
19
+ # Get the application version
20
+ try:
21
+ app_version = version("fast-agent-mcp")
22
+ except: # noqa: E722
23
+ app_version = "unknown"
24
+
18
25
  # Map of agent names to their history
19
26
  agent_histories = {}
20
27
 
@@ -204,7 +211,7 @@ async def get_enhanced_input(
204
211
 
205
212
  shortcut_text = " | ".join(f"{key}:{action}" for key, action in shortcuts)
206
213
  return HTML(
207
- f" <{toolbar_color}> {agent_name} </{toolbar_color}> | <b>Mode:</b> <{mode_style}> {mode_text} </{mode_style}> {newline} | {shortcut_text}"
214
+ f" <{toolbar_color}> {agent_name} </{toolbar_color}> | <b>Mode:</b> <{mode_style}> {mode_text} </{mode_style}> {newline} | {shortcut_text} | <dim>v{app_version}</dim>"
208
215
  )
209
216
 
210
217
  # Create session with history and completions
@@ -318,7 +325,8 @@ async def handle_special_commands(command, agent_app=None):
318
325
  rich_print(
319
326
  " Enter - Submit (normal mode) / New line (multiline mode)"
320
327
  )
321
- rich_print(" Ctrl+Enter - Always submit (even in multiline mode)")
328
+ rich_print(" \\ + Enter - Insert new line in normal mode")
329
+ rich_print(" Ctrl+Enter - Always submit (in any mode)")
322
330
  rich_print(" Ctrl+T - Toggle multiline mode")
323
331
  rich_print(" Ctrl+L - Clear input")
324
332
  rich_print(" Up/Down - Navigate history")
@@ -0,0 +1,61 @@
1
+ import asyncio
2
+
3
+ from mcp_agent.core.fastagent import FastAgent
4
+ from mcp_agent.workflows.llm.augmented_llm import RequestParams
5
+
6
+ # Create the application
7
+ fast = FastAgent("Data Analysis (Roots)")
8
+
9
+
10
+ @fast.agent(
11
+ name="data_analysis",
12
+ instruction="""
13
+ You have access to a Python 3.12 interpreter and you can use this to analyse and process data.
14
+ Common analysis packages such as Pandas, Seaborn and Matplotlib are already installed.
15
+ You can add further packages if needed.
16
+ Data files are accessible from the /mnt/data/ directory (this is the current working directory).
17
+ Visualisations should be saved as .png files in the current working directory.
18
+ """,
19
+ servers=["interpreter"],
20
+ request_params=RequestParams(maxTokens=8192),
21
+ )
22
+ @fast.agent(
23
+ "evaluator",
24
+ """You are collaborating with a Data Analysis tool that has the capability to analyse data and produce visualisations.
25
+ You must make sure that the tool has:
26
+ - Considered the best way for a Human to interpret the data
27
+ - Produced insightful visualasions.
28
+ - Provided a high level summary report for the Human.
29
+ - Has had its findings challenged, and justified
30
+ """,
31
+ request_params=RequestParams(maxTokens=8192),
32
+ )
33
+ @fast.evaluator_optimizer(
34
+ "analysis_tool",
35
+ generator="data_analysis",
36
+ evaluator="evaluator",
37
+ max_refinements=3,
38
+ min_rating="EXCELLENT",
39
+ )
40
+ @fast.passthrough(
41
+ "sample",
42
+ )
43
+ async def main():
44
+ # Use the app's context manager
45
+ async with fast.run() as agent:
46
+ # await agent(
47
+ # "There is a csv file in the current directory. "
48
+ # "Analyse the file, produce a detailed description of the data, and any patterns it contains.",
49
+ # )
50
+ # await agent(
51
+ # "Consider the data, and how to usefully group it for presentation to a Human. Find insights, using the Python Interpreter as needed.\n"
52
+ # "Use MatPlotLib to produce insightful visualisations. Save them as '.png' files in the current directory. Be sure to run the code and save the files.\n"
53
+ # "Produce a summary with major insights to the data",
54
+ # )
55
+ await agent.analysis_tool.prompt(
56
+ "Analyse the CSV File in the working directory"
57
+ )
58
+
59
+
60
+ if __name__ == "__main__":
61
+ asyncio.run(main())
@@ -38,8 +38,6 @@ fast = FastAgent("Evaluator-Optimizer")
38
38
  Summarize your evaluation as a structured response with:
39
39
  - Overall quality rating.
40
40
  - Specific feedback and areas for improvement.""",
41
- # instructor doesn't seem to work for sonnet37
42
- # model="sonnet35",
43
41
  )
44
42
  # Define the evaluator-optimizer workflow
45
43
  @fast.evaluator_optimizer(
@@ -60,10 +60,6 @@ and whispers of a hidden agenda linger among the villagers.
60
60
  and give an overall grade based on the feedback.""",
61
61
  model="o3-mini.low",
62
62
  )
63
- @fast.agent(
64
- name="cats-to-dogs",
65
- instruction="you should take any text, and change references about cats to dogs",
66
- )
67
63
  @fast.parallel(
68
64
  fan_out=["proofreader", "fact_checker", "style_enforcer"],
69
65
  fan_in="grader",