fast-agent-mcp 0.1.11__tar.gz → 0.1.13__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 (174) hide show
  1. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/PKG-INFO +1 -1
  2. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/pyproject.toml +17 -1
  3. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/agents/agent.py +37 -102
  4. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/app.py +16 -27
  5. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/cli/commands/bootstrap.py +22 -52
  6. fast_agent_mcp-0.1.13/src/mcp_agent/cli/commands/config.py +11 -0
  7. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/cli/commands/setup.py +11 -26
  8. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/cli/main.py +6 -9
  9. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/cli/terminal.py +2 -2
  10. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/config.py +1 -5
  11. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/context.py +13 -26
  12. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/context_dependent.py +3 -7
  13. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/agent_app.py +46 -122
  14. fast_agent_mcp-0.1.13/src/mcp_agent/core/agent_types.py +43 -0
  15. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/agent_utils.py +3 -5
  16. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/decorators.py +6 -14
  17. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/enhanced_prompt.py +25 -52
  18. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/error_handling.py +1 -1
  19. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/exceptions.py +8 -8
  20. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/factory.py +30 -72
  21. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/fastagent.py +48 -88
  22. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/mcp_content.py +10 -19
  23. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/prompt.py +8 -15
  24. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/proxies.py +34 -25
  25. fast_agent_mcp-0.1.13/src/mcp_agent/core/request_params.py +46 -0
  26. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/types.py +6 -6
  27. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/validation.py +16 -16
  28. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/executor/decorator_registry.py +11 -23
  29. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/executor/executor.py +8 -17
  30. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/executor/task_registry.py +2 -4
  31. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/executor/temporal.py +28 -74
  32. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/executor/workflow.py +3 -5
  33. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/executor/workflow_signal.py +17 -29
  34. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/human_input/handler.py +4 -9
  35. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/human_input/types.py +2 -3
  36. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/logging/events.py +1 -5
  37. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/logging/json_serializer.py +7 -6
  38. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/logging/listeners.py +20 -23
  39. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/logging/logger.py +15 -17
  40. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/logging/rich_progress.py +10 -8
  41. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/logging/tracing.py +4 -6
  42. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/logging/transport.py +24 -24
  43. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/gen_client.py +4 -12
  44. fast_agent_mcp-0.1.13/src/mcp_agent/mcp/interfaces.py +171 -0
  45. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/mcp_agent_client_session.py +11 -19
  46. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/mcp_agent_server.py +8 -10
  47. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/mcp_aggregator.py +49 -122
  48. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/mcp_connection_manager.py +16 -37
  49. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/prompt_message_multipart.py +12 -18
  50. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/prompt_serialization.py +13 -38
  51. fast_agent_mcp-0.1.13/src/mcp_agent/mcp/prompts/prompt_load.py +99 -0
  52. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/prompts/prompt_server.py +21 -128
  53. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/prompts/prompt_template.py +20 -42
  54. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/resource_utils.py +8 -17
  55. fast_agent_mcp-0.1.13/src/mcp_agent/mcp/sampling.py +131 -0
  56. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/stdio.py +11 -8
  57. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp_server/__init__.py +1 -1
  58. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp_server/agent_server.py +10 -17
  59. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp_server_registry.py +13 -35
  60. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/data-analysis/analysis-campaign.py +1 -1
  61. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/data-analysis/analysis.py +1 -1
  62. fast_agent_mcp-0.1.13/src/mcp_agent/resources/examples/data-analysis/slides.py +110 -0
  63. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/internal/agent.py +2 -1
  64. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/internal/job.py +2 -1
  65. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/internal/prompt_category.py +1 -1
  66. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/internal/prompt_sizing.py +3 -5
  67. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/internal/sizer.py +2 -1
  68. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/internal/social.py +2 -1
  69. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/mcp_researcher/researcher-eval.py +1 -1
  70. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/prompting/__init__.py +1 -1
  71. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/prompting/agent.py +2 -1
  72. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/prompting/image_server.py +5 -11
  73. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/researcher/researcher-eval.py +1 -1
  74. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/researcher/researcher-imp.py +3 -4
  75. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/researcher/researcher.py +2 -1
  76. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/workflows/agent_build.py +2 -1
  77. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/workflows/chaining.py +2 -1
  78. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/workflows/evaluator.py +2 -1
  79. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/workflows/human_input.py +2 -1
  80. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/workflows/orchestrator.py +2 -1
  81. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/workflows/parallel.py +2 -1
  82. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/workflows/router.py +2 -1
  83. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/workflows/sse.py +1 -1
  84. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/telemetry/usage_tracking.py +2 -1
  85. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/ui/console_display.py +17 -41
  86. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/embedding/embedding_base.py +1 -4
  87. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/embedding/embedding_cohere.py +2 -2
  88. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/embedding/embedding_openai.py +4 -13
  89. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/evaluator_optimizer/evaluator_optimizer.py +23 -57
  90. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/intent_classifier/intent_classifier_base.py +5 -8
  91. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/intent_classifier/intent_classifier_embedding.py +7 -11
  92. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/intent_classifier/intent_classifier_embedding_cohere.py +4 -8
  93. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/intent_classifier/intent_classifier_embedding_openai.py +4 -8
  94. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/intent_classifier/intent_classifier_llm.py +11 -22
  95. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/intent_classifier/intent_classifier_llm_anthropic.py +3 -3
  96. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/intent_classifier/intent_classifier_llm_openai.py +4 -6
  97. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/anthropic_utils.py +8 -29
  98. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/augmented_llm.py +94 -332
  99. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/augmented_llm_anthropic.py +43 -76
  100. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/augmented_llm_openai.py +46 -100
  101. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/augmented_llm_passthrough.py +42 -20
  102. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/augmented_llm_playback.py +8 -6
  103. fast_agent_mcp-0.1.13/src/mcp_agent/workflows/llm/memory.py +103 -0
  104. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/model_factory.py +9 -21
  105. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/openai_utils.py +1 -1
  106. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/prompt_utils.py +39 -27
  107. fast_agent_mcp-0.1.13/src/mcp_agent/workflows/llm/providers/multipart_converter_anthropic.py +410 -0
  108. fast_agent_mcp-0.1.13/src/mcp_agent/workflows/llm/providers/multipart_converter_openai.py +436 -0
  109. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/providers/openai_multipart.py +19 -61
  110. fast_agent_mcp-0.1.13/src/mcp_agent/workflows/llm/providers/sampling_converter_anthropic.py +57 -0
  111. fast_agent_mcp-0.1.13/src/mcp_agent/workflows/llm/providers/sampling_converter_openai.py +27 -0
  112. fast_agent_mcp-0.1.13/src/mcp_agent/workflows/llm/sampling_converter.py +117 -0
  113. fast_agent_mcp-0.1.13/src/mcp_agent/workflows/llm/sampling_format_converter.py +22 -0
  114. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/orchestrator/orchestrator.py +24 -67
  115. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/orchestrator/orchestrator_models.py +14 -40
  116. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/parallel/fan_in.py +17 -47
  117. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/parallel/fan_out.py +6 -12
  118. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/parallel/parallel_llm.py +9 -26
  119. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/router/router_base.py +29 -59
  120. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/router/router_embedding.py +11 -25
  121. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/router/router_embedding_cohere.py +2 -2
  122. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/router/router_embedding_openai.py +2 -2
  123. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/router/router_llm.py +12 -28
  124. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/swarm/swarm.py +20 -48
  125. fast_agent_mcp-0.1.11/src/mcp_agent/cli/commands/config.py +0 -11
  126. fast_agent_mcp-0.1.11/src/mcp_agent/core/agent_types.py +0 -16
  127. fast_agent_mcp-0.1.11/src/mcp_agent/mcp/interfaces.py +0 -152
  128. fast_agent_mcp-0.1.11/src/mcp_agent/mcp/sampling.py +0 -133
  129. fast_agent_mcp-0.1.11/src/mcp_agent/workflows/llm/llm_selector.py +0 -345
  130. fast_agent_mcp-0.1.11/src/mcp_agent/workflows/llm/providers/multipart_converter_anthropic.py +0 -348
  131. fast_agent_mcp-0.1.11/src/mcp_agent/workflows/llm/providers/multipart_converter_openai.py +0 -426
  132. fast_agent_mcp-0.1.11/src/mcp_agent/workflows/llm/providers/sampling_converter_anthropic.py +0 -258
  133. fast_agent_mcp-0.1.11/src/mcp_agent/workflows/llm/providers/sampling_converter_openai.py +0 -229
  134. fast_agent_mcp-0.1.11/src/mcp_agent/workflows/llm/sampling_format_converter.py +0 -39
  135. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/.gitignore +0 -0
  136. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/LICENSE +0 -0
  137. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/README.md +0 -0
  138. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/__init__.py +0 -0
  139. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/agents/__init__.py +0 -0
  140. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/cli/__init__.py +0 -0
  141. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/cli/__main__.py +0 -0
  142. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/console.py +0 -0
  143. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/__init__.py +0 -0
  144. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/eval/__init__.py +0 -0
  145. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/event_progress.py +0 -0
  146. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/executor/__init__.py +0 -0
  147. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/human_input/__init__.py +0 -0
  148. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/logging/__init__.py +0 -0
  149. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/__init__.py +0 -0
  150. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/mcp_activity.py +0 -0
  151. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/mime_utils.py +0 -0
  152. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/prompts/__init__.py +0 -0
  153. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/prompts/__main__.py +0 -0
  154. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/progress_display.py +0 -0
  155. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/data-analysis/fastagent.config.yaml +0 -0
  156. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
  157. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/internal/fastagent.config.yaml +0 -0
  158. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/prompting/fastagent.config.yaml +0 -0
  159. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/researcher/fastagent.config.yaml +0 -0
  160. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/workflows/fastagent.config.yaml +0 -0
  161. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/telemetry/__init__.py +0 -0
  162. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/__init__.py +0 -0
  163. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/embedding/__init__.py +0 -0
  164. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/evaluator_optimizer/__init__.py +0 -0
  165. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/intent_classifier/__init__.py +0 -0
  166. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/__init__.py +0 -0
  167. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/providers/__init__.py +0 -0
  168. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/orchestrator/__init__.py +0 -0
  169. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/orchestrator/orchestrator_prompts.py +0 -0
  170. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/parallel/__init__.py +0 -0
  171. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/router/__init__.py +0 -0
  172. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/swarm/__init__.py +0 -0
  173. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/swarm/swarm_anthropic.py +2 -2
  174. {fast_agent_mcp-0.1.11 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/swarm/swarm_openai.py +2 -2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fast-agent-mcp
3
- Version: 0.1.11
3
+ Version: 0.1.13
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fast-agent-mcp"
3
- version = "0.1.11"
3
+ version = "0.1.13"
4
4
  description = "Define, Prompt and Test MCP enabled Agents and Workflows"
5
5
  readme = "README.md"
6
6
  license = { file = "LICENSE" }
@@ -112,3 +112,19 @@ mcp_agent = [
112
112
  "resources/examples/**/mount-point/*.csv"
113
113
  ]
114
114
 
115
+ [tool.ruff]
116
+ line-length = 160
117
+ target-version = "py310"
118
+
119
+ [tool.ruff.lint]
120
+ select = [
121
+ "E", # pycodestyle errors
122
+ "F", # pyflakes
123
+ "I", # isort
124
+ "TCH" # type checking
125
+ ]
126
+ ignore=["E501"]
127
+
128
+ # More lenient settings for existing code
129
+ [tool.ruff.lint.per-file-ignores]
130
+ "tests/*" = ["ANN"] # Don't require type annotations in tests
@@ -1,30 +1,30 @@
1
1
  import asyncio
2
2
  import uuid
3
- from dataclasses import dataclass
4
- from typing import Callable, Dict, List, Optional, TypeVar, Union, TYPE_CHECKING
3
+ from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, TypeVar, Union
5
4
 
6
5
  from mcp.server.fastmcp.tools import Tool as FastTool
7
6
  from mcp.types import (
8
7
  CallToolResult,
8
+ EmbeddedResource,
9
9
  ListToolsResult,
10
+ ReadResourceResult,
10
11
  TextContent,
11
12
  Tool,
12
- EmbeddedResource,
13
- ReadResourceResult,
14
13
  )
15
- from mcp_agent.mcp.prompt_message_multipart import PromptMessageMultipart
16
14
 
15
+ from mcp_agent.core.agent_types import AgentConfig
17
16
  from mcp_agent.core.exceptions import PromptExitError
18
- from mcp_agent.mcp.mcp_aggregator import MCPAggregator
19
- from mcp_agent.workflows.llm.augmented_llm import RequestParams
17
+ from mcp_agent.core.request_params import RequestParams
20
18
  from mcp_agent.human_input.types import (
19
+ HUMAN_INPUT_SIGNAL_NAME,
21
20
  HumanInputCallback,
22
21
  HumanInputRequest,
23
22
  HumanInputResponse,
24
- HUMAN_INPUT_SIGNAL_NAME,
25
23
  )
26
- from mcp_agent.workflows.llm.augmented_llm import AugmentedLLM
27
24
  from mcp_agent.logging.logger import get_logger
25
+ from mcp_agent.mcp.mcp_aggregator import MCPAggregator
26
+ from mcp_agent.mcp.prompt_message_multipart import PromptMessageMultipart
27
+ from mcp_agent.workflows.llm.augmented_llm import AugmentedLLMProtocol
28
28
 
29
29
  if TYPE_CHECKING:
30
30
  from mcp_agent.context import Context
@@ -33,33 +33,11 @@ import traceback
33
33
  logger = get_logger(__name__)
34
34
 
35
35
  # Define a TypeVar for AugmentedLLM and its subclasses
36
- LLM = TypeVar("LLM", bound=AugmentedLLM)
36
+ LLM = TypeVar("LLM", bound=AugmentedLLMProtocol)
37
37
 
38
38
  HUMAN_INPUT_TOOL_NAME = "__human_input__"
39
39
 
40
40
 
41
- @dataclass
42
- class AgentConfig:
43
- """Configuration for an Agent instance"""
44
-
45
- name: str
46
- instruction: Union[str, Callable[[Dict], str]]
47
- servers: List[str]
48
- model: Optional[str] = None
49
- use_history: bool = True
50
- default_request_params: Optional[RequestParams] = None
51
- human_input: bool = False
52
-
53
- def __post_init__(self):
54
- """Ensure default_request_params exists with proper history setting"""
55
-
56
- if self.default_request_params is None:
57
- self.default_request_params = RequestParams(use_history=self.use_history)
58
- else:
59
- # Override the request params history setting if explicitly configured
60
- self.default_request_params.use_history = self.use_history
61
-
62
-
63
41
  class Agent(MCPAggregator):
64
42
  """
65
43
  An Agent is an entity that has access to a set of MCP servers and can interact with them.
@@ -68,17 +46,15 @@ class Agent(MCPAggregator):
68
46
 
69
47
  def __init__(
70
48
  self,
71
- config: Union[
72
- AgentConfig, str
73
- ], # Can be AgentConfig or backward compatible str name
49
+ config: Union[AgentConfig, str], # Can be AgentConfig or backward compatible str name
74
50
  instruction: Optional[Union[str, Callable[[Dict], str]]] = None,
75
51
  server_names: Optional[List[str]] = None,
76
52
  functions: Optional[List[Callable]] = None,
77
53
  connection_persistence: bool = True,
78
54
  human_input_callback: Optional[HumanInputCallback] = None,
79
55
  context: Optional["Context"] = None,
80
- **kwargs,
81
- ):
56
+ **kwargs: dict[str, Any],
57
+ ) -> None:
82
58
  # Handle backward compatibility where first arg was name
83
59
  if isinstance(config, str):
84
60
  self.config = AgentConfig(
@@ -117,14 +93,12 @@ class Agent(MCPAggregator):
117
93
  if self.context.human_input_handler:
118
94
  self.human_input_callback = self.context.human_input_handler
119
95
 
120
- async def initialize(self):
96
+ async def initialize(self) -> None:
121
97
  """
122
98
  Initialize the agent and connect to the MCP servers.
123
99
  NOTE: This method is called automatically when the agent is used as an async context manager.
124
100
  """
125
- await (
126
- self.__aenter__()
127
- ) # This initializes the connection manager and loads the servers
101
+ await self.__aenter__() # This initializes the connection manager and loads the servers
128
102
 
129
103
  for function in self.functions:
130
104
  tool: FastTool = FastTool.from_function(function)
@@ -142,11 +116,9 @@ class Agent(MCPAggregator):
142
116
  Returns:
143
117
  An instance of AugmentedLLM or one of its subclasses.
144
118
  """
145
- return llm_factory(
146
- agent=self, default_request_params=self._default_request_params
147
- )
119
+ return llm_factory(agent=self, default_request_params=self._default_request_params)
148
120
 
149
- async def shutdown(self):
121
+ async def shutdown(self) -> None:
150
122
  """
151
123
  Shutdown the agent and close all MCP server connections.
152
124
  NOTE: This method is called automatically when the agent is used as an async context manager.
@@ -176,8 +148,9 @@ class Agent(MCPAggregator):
176
148
  request.metadata = {"agent_name": self.name}
177
149
  self.logger.debug("Requesting human input:", data=request)
178
150
 
179
- async def call_callback_and_signal():
151
+ async def call_callback_and_signal() -> None:
180
152
  try:
153
+ assert self.human_input_callback is not None
181
154
  user_input = await self.human_input_callback(request)
182
155
 
183
156
  self.logger.debug("Received human input:", data=user_input)
@@ -190,9 +163,7 @@ class Agent(MCPAggregator):
190
163
  payload={"exit_requested": True, "error": str(e)},
191
164
  )
192
165
  except Exception as e:
193
- await self.executor.signal(
194
- request_id, payload=f"Error getting human input: {str(e)}"
195
- )
166
+ await self.executor.signal(request_id, payload=f"Error getting human input: {str(e)}")
196
167
 
197
168
  asyncio.create_task(call_callback_and_signal())
198
169
 
@@ -209,9 +180,7 @@ class Agent(MCPAggregator):
209
180
  )
210
181
 
211
182
  if isinstance(result, dict) and result.get("exit_requested", False):
212
- raise PromptExitError(
213
- result.get("error", "User requested to exit FastAgent session")
214
- )
183
+ raise PromptExitError(result.get("error", "User requested to exit FastAgent session"))
215
184
  self.logger.debug("Received human input signal", data=result)
216
185
  return result
217
186
 
@@ -249,9 +218,7 @@ class Agent(MCPAggregator):
249
218
  return result
250
219
 
251
220
  # todo would prefer to use tool_name to disambiguate agent name
252
- async def call_tool(
253
- self, name: str, arguments: dict | None = None
254
- ) -> CallToolResult:
221
+ async def call_tool(self, name: str, arguments: dict | None = None) -> CallToolResult:
255
222
  if name == HUMAN_INPUT_TOOL_NAME:
256
223
  # Call the human input tool
257
224
  return await self._call_human_input_tool(arguments)
@@ -263,9 +230,7 @@ class Agent(MCPAggregator):
263
230
  else:
264
231
  return await super().call_tool(name, arguments)
265
232
 
266
- async def _call_human_input_tool(
267
- self, arguments: dict | None = None
268
- ) -> CallToolResult:
233
+ async def _call_human_input_tool(self, arguments: dict | None = None) -> CallToolResult:
269
234
  # Handle human input request
270
235
  try:
271
236
  # Make sure arguments is not None
@@ -287,17 +252,9 @@ class Agent(MCPAggregator):
287
252
  result = await self.request_human_input(request=request)
288
253
 
289
254
  # Use response attribute if available, otherwise use the result directly
290
- response_text = (
291
- result.response
292
- if isinstance(result, HumanInputResponse)
293
- else str(result)
294
- )
255
+ response_text = result.response if isinstance(result, HumanInputResponse) else str(result)
295
256
 
296
- return CallToolResult(
297
- content=[
298
- TextContent(type="text", text=f"Human response: {response_text}")
299
- ]
300
- )
257
+ return CallToolResult(content=[TextContent(type="text", text=f"Human response: {response_text}")])
301
258
 
302
259
  except PromptExitError:
303
260
  raise
@@ -316,21 +273,10 @@ class Agent(MCPAggregator):
316
273
 
317
274
  return CallToolResult(
318
275
  isError=True,
319
- content=[
320
- TextContent(
321
- type="text", text=f"Error requesting human input: {str(e)}"
322
- )
323
- ],
276
+ content=[TextContent(type="text", text=f"Error requesting human input: {str(e)}")],
324
277
  )
325
278
 
326
- async def read_resource(
327
- self, server_name: str, resource_name: str
328
- ) -> ReadResourceResult:
329
- return None
330
-
331
- async def apply_prompt(
332
- self, prompt_name: str, arguments: dict[str, str] = None
333
- ) -> str:
279
+ async def apply_prompt(self, prompt_name: str, arguments: dict[str, str] | None) -> str:
334
280
  """
335
281
  Apply an MCP Server Prompt by name and return the assistant's response.
336
282
  Will search all available servers for the prompt if not namespaced.
@@ -354,9 +300,7 @@ class Agent(MCPAggregator):
354
300
  prompt_result = await self.get_prompt(prompt_name, arguments)
355
301
 
356
302
  if not prompt_result or not prompt_result.messages:
357
- error_msg = (
358
- f"Prompt '{prompt_name}' could not be found or contains no messages"
359
- )
303
+ error_msg = f"Prompt '{prompt_name}' could not be found or contains no messages"
360
304
  self.logger.warning(error_msg)
361
305
  return error_msg
362
306
 
@@ -395,16 +339,10 @@ class Agent(MCPAggregator):
395
339
  resource_result = await server.get_resource(resource_name)
396
340
  return resource_result
397
341
  except Exception as e:
398
- self.logger.error(
399
- f"Error retrieving resource '{resource_name}' from server '{server_name}': {str(e)}"
400
- )
401
- raise ValueError(
402
- f"Failed to retrieve resource '{resource_name}' from server '{server_name}': {str(e)}"
403
- )
342
+ self.logger.error(f"Error retrieving resource '{resource_name}' from server '{server_name}': {str(e)}")
343
+ raise ValueError(f"Failed to retrieve resource '{resource_name}' from server '{server_name}': {str(e)}")
404
344
 
405
- async def get_embedded_resources(
406
- self, server_name: str, resource_name: str
407
- ) -> List[EmbeddedResource]:
345
+ async def get_embedded_resources(self, server_name: str, resource_name: str) -> List[EmbeddedResource]:
408
346
  """
409
347
  Get a resource from an MCP server and return it as a list of embedded resources ready for use in prompts.
410
348
 
@@ -419,20 +357,19 @@ class Agent(MCPAggregator):
419
357
  ValueError: If the server doesn't exist or the resource couldn't be found
420
358
  """
421
359
  # Get the raw resource result
422
- result: ReadResourceResult = await super().get_resource(
423
- server_name, resource_name
424
- )
360
+ result: ReadResourceResult = await super().get_resource(server_name, resource_name)
425
361
 
426
362
  # Convert each resource content to an EmbeddedResource
427
363
  embedded_resources: List[EmbeddedResource] = []
428
364
  for resource_content in result.contents:
429
- embedded_resource = EmbeddedResource(
430
- type="resource", resource=resource_content, annotations=None
431
- )
365
+ embedded_resource = EmbeddedResource(type="resource", resource=resource_content, annotations=None)
432
366
  embedded_resources.append(embedded_resource)
433
367
 
434
368
  return embedded_resources
435
369
 
370
+ async def apply_prompt_messages(self, prompts: List[PromptMessageMultipart], request_params: RequestParams | None) -> str:
371
+ return self._llm.apply_prompt_messages(prompts, request_params)
372
+
436
373
  async def with_resource(
437
374
  self,
438
375
  prompt_content: Union[str, PromptMessageMultipart],
@@ -451,9 +388,7 @@ class Agent(MCPAggregator):
451
388
  The agent's response as a string
452
389
  """
453
390
  # Get the embedded resources
454
- embedded_resources: List[EmbeddedResource] = await self.get_embedded_resources(
455
- server_name, resource_name
456
- )
391
+ embedded_resources: List[EmbeddedResource] = await self.get_embedded_resources(server_name, resource_name)
457
392
 
458
393
  # Create or update the prompt message
459
394
  prompt: PromptMessageMultipart
@@ -1,17 +1,18 @@
1
- from typing import Any, Dict, Optional, Type, TypeVar, Callable
2
- from datetime import timedelta
3
1
  import asyncio
4
2
  from contextlib import asynccontextmanager
3
+ from datetime import timedelta
4
+ from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Type, TypeVar
5
5
 
6
- from mcp import ServerSession
7
- from mcp_agent.context import Context, initialize_context, cleanup_context
8
6
  from mcp_agent.config import Settings
7
+ from mcp_agent.context import Context, cleanup_context, initialize_context
9
8
  from mcp_agent.event_progress import ProgressAction
10
- from mcp_agent.logging.logger import get_logger
11
9
  from mcp_agent.executor.workflow_signal import SignalWaitCallback
12
- from mcp_agent.human_input.types import HumanInputCallback
13
10
  from mcp_agent.human_input.handler import console_input_callback
14
- from mcp_agent.workflows.llm.llm_selector import ModelSelector
11
+ from mcp_agent.human_input.types import HumanInputCallback
12
+ from mcp_agent.logging.logger import get_logger
13
+
14
+ if TYPE_CHECKING:
15
+ from mcp import ServerSession
15
16
 
16
17
  R = TypeVar("R")
17
18
 
@@ -44,8 +45,7 @@ class MCPApp:
44
45
  human_input_callback: Optional[HumanInputCallback] = console_input_callback,
45
46
  signal_notification: Optional[SignalWaitCallback] = None,
46
47
  upstream_session: Optional["ServerSession"] = None,
47
- model_selector: ModelSelector = None,
48
- ):
48
+ ) -> None:
49
49
  """
50
50
  Initialize the application with a name and optional settings.
51
51
  Args:
@@ -55,7 +55,6 @@ class MCPApp:
55
55
  human_input_callback: Callback for handling human input
56
56
  signal_notification: Callback for getting notified on workflow signals/events.
57
57
  upstream_session: Optional upstream session if the MCPApp is running as a server to an MCP client.
58
- initialize_model_selector: Initializes the built-in ModelSelector to help with model selection. Defaults to False.
59
58
  """
60
59
  self.name = name
61
60
 
@@ -64,7 +63,6 @@ class MCPApp:
64
63
  self._human_input_callback = human_input_callback
65
64
  self._signal_notification = signal_notification
66
65
  self._upstream_session = upstream_session
67
- self._model_selector = model_selector
68
66
 
69
67
  self._workflows: Dict[str, Type] = {} # id to workflow class
70
68
  self._logger = None
@@ -74,9 +72,7 @@ class MCPApp:
74
72
  @property
75
73
  def context(self) -> Context:
76
74
  if self._context is None:
77
- raise RuntimeError(
78
- "MCPApp not initialized, please call initialize() first, or use async with app.run()."
79
- )
75
+ raise RuntimeError("MCPApp not initialized, please call initialize() first, or use async with app.run().")
80
76
  return self._context
81
77
 
82
78
  @property
@@ -100,7 +96,7 @@ class MCPApp:
100
96
  return self._context.upstream_session
101
97
 
102
98
  @upstream_session.setter
103
- def upstream_session(self, value):
99
+ def upstream_session(self, value) -> None:
104
100
  self._context.upstream_session = value
105
101
 
106
102
  @property
@@ -117,7 +113,7 @@ class MCPApp:
117
113
  self._logger = get_logger(f"mcp_agent.{self.name}")
118
114
  return self._logger
119
115
 
120
- async def initialize(self):
116
+ async def initialize(self) -> None:
121
117
  """Initialize the application."""
122
118
  if self._initialized:
123
119
  return
@@ -128,7 +124,6 @@ class MCPApp:
128
124
  self._context.human_input_handler = self._human_input_callback
129
125
  self._context.signal_notification = self._signal_notification
130
126
  self._context.upstream_session = self._upstream_session
131
- self._context.model_selector = self._model_selector
132
127
 
133
128
  self._initialized = True
134
129
  self.logger.info(
@@ -140,7 +135,7 @@ class MCPApp:
140
135
  },
141
136
  )
142
137
 
143
- async def cleanup(self):
138
+ async def cleanup(self) -> None:
144
139
  """Cleanup application resources."""
145
140
  if not self._initialized:
146
141
  return
@@ -178,9 +173,7 @@ class MCPApp:
178
173
  finally:
179
174
  await self.cleanup()
180
175
 
181
- def workflow(
182
- self, cls: Type, *args, workflow_id: str | None = None, **kwargs
183
- ) -> Type:
176
+ def workflow(self, cls: Type, *args, workflow_id: str | None = None, **kwargs) -> Type:
184
177
  """
185
178
  Decorator for a workflow class. By default it's a no-op,
186
179
  but different executors can use this to customize behavior
@@ -192,9 +185,7 @@ class MCPApp:
192
185
  """
193
186
  decorator_registry = self.context.decorator_registry
194
187
  execution_engine = self.engine
195
- workflow_defn_decorator = decorator_registry.get_workflow_defn_decorator(
196
- execution_engine
197
- )
188
+ workflow_defn_decorator = decorator_registry.get_workflow_defn_decorator(execution_engine)
198
189
 
199
190
  if workflow_defn_decorator:
200
191
  return workflow_defn_decorator(cls, *args, **kwargs)
@@ -216,9 +207,7 @@ class MCPApp:
216
207
 
217
208
  decorator_registry = self.context.decorator_registry
218
209
  execution_engine = self.engine
219
- workflow_run_decorator = decorator_registry.get_workflow_run_decorator(
220
- execution_engine
221
- )
210
+ workflow_run_decorator = decorator_registry.get_workflow_run_decorator(execution_engine)
222
211
 
223
212
  if workflow_run_decorator:
224
213
  return workflow_run_decorator(fn)
@@ -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
 
@@ -72,12 +71,7 @@ def copy_example_files(
72
71
  console.print(f"Created mount-point directory: {mount_point_dir}")
73
72
 
74
73
  # Use the resources directory from the package
75
- source_dir = (
76
- Path(__file__).parent.parent.parent
77
- / "resources"
78
- / "examples"
79
- / ("workflows" if example_type == "workflow" else f"{example_type}")
80
- )
74
+ source_dir = Path(__file__).parent.parent.parent / "resources" / "examples" / ("workflows" if example_type == "workflow" else f"{example_type}")
81
75
 
82
76
  if not source_dir.exists():
83
77
  console.print(f"[red]Error: Source directory not found: {source_dir}[/red]")
@@ -116,9 +110,7 @@ def copy_example_files(
116
110
  continue
117
111
 
118
112
  if target.exists() and not force:
119
- console.print(
120
- f"[yellow]Skipping[/yellow] mount-point/{filename} (already exists)"
121
- )
113
+ console.print(f"[yellow]Skipping[/yellow] mount-point/{filename} (already exists)")
122
114
  continue
123
115
 
124
116
  shutil.copy2(source, target)
@@ -126,22 +118,18 @@ def copy_example_files(
126
118
  console.print(f"[green]Created[/green] mount-point/{filename}")
127
119
 
128
120
  except Exception as e:
129
- console.print(
130
- f"[red]Error copying mount-point/{filename}: {str(e)}[/red]"
131
- )
121
+ console.print(f"[red]Error copying mount-point/{filename}: {str(e)}[/red]")
132
122
 
133
123
  return created
134
124
 
135
125
 
136
- def show_overview():
126
+ def show_overview() -> None:
137
127
  """Display an overview of available examples in a nicely formatted table."""
138
128
  console.print("\n[bold cyan]fast-agent Example Applications[/bold cyan]")
139
129
  console.print("Build agents and compose workflows through practical examples\n")
140
130
 
141
131
  # Create a table for better organization
142
- table = Table(
143
- show_header=True, header_style="bold magenta", box=None, padding=(0, 2)
144
- )
132
+ table = Table(show_header=True, header_style="bold magenta", box=None, padding=(0, 2))
145
133
  table.add_column("Example")
146
134
  table.add_column("Description")
147
135
  table.add_column("Files")
@@ -149,9 +137,7 @@ def show_overview():
149
137
  for name, info in EXAMPLE_TYPES.items():
150
138
  files_list = "\n".join(f"• {f}" for f in info["files"])
151
139
  if "mount_point_files" in info:
152
- files_list += "\n[blue]mount-point:[/blue]\n" + "\n".join(
153
- f"• {f}" for f in info["mount_point_files"]
154
- )
140
+ files_list += "\n[blue]mount-point:[/blue]\n" + "\n".join(f"• {f}" for f in info["mount_point_files"])
155
141
  table.add_row(f"[green]{name}[/green]", info["description"], files_list)
156
142
 
157
143
  console.print(table)
@@ -178,10 +164,8 @@ def workflow(
178
164
  Path("."),
179
165
  help="Directory where workflow examples will be created",
180
166
  ),
181
- force: bool = typer.Option(
182
- False, "--force", "-f", help="Force overwrite existing files"
183
- ),
184
- ):
167
+ force: bool = typer.Option(False, "--force", "-f", help="Force overwrite existing files"),
168
+ ) -> None:
185
169
  """Create workflow pattern examples."""
186
170
  target_dir = directory.resolve()
187
171
  if not target_dir.exists():
@@ -198,10 +182,8 @@ def researcher(
198
182
  Path("."),
199
183
  help="Directory where researcher examples will be created (in 'researcher' subdirectory)",
200
184
  ),
201
- force: bool = typer.Option(
202
- False, "--force", "-f", help="Force overwrite existing files"
203
- ),
204
- ):
185
+ force: bool = typer.Option(False, "--force", "-f", help="Force overwrite existing files"),
186
+ ) -> None:
205
187
  """Create researcher pattern examples."""
206
188
  target_dir = directory.resolve()
207
189
  if not target_dir.exists():
@@ -218,10 +200,8 @@ def data_analysis(
218
200
  Path("."),
219
201
  help="Directory where data analysis examples will be created (creates 'data-analysis' subdirectory with mount-point)",
220
202
  ),
221
- force: bool = typer.Option(
222
- False, "--force", "-f", help="Force overwrite existing files"
223
- ),
224
- ):
203
+ force: bool = typer.Option(False, "--force", "-f", help="Force overwrite existing files"),
204
+ ) -> None:
225
205
  """Create data analysis examples with sample dataset."""
226
206
  target_dir = directory.resolve()
227
207
  if not target_dir.exists():
@@ -232,7 +212,7 @@ def data_analysis(
232
212
  _show_completion_message("data-analysis", created)
233
213
 
234
214
 
235
- def _show_completion_message(example_type: str, created: list[str]):
215
+ def _show_completion_message(example_type: str, created: list[str]) -> None:
236
216
  """Show completion message and next steps."""
237
217
  if created:
238
218
  console.print("\n[green]Setup completed successfully![/green]")
@@ -249,33 +229,23 @@ def _show_completion_message(example_type: str, created: list[str]):
249
229
  console.print(" - evaluator.py: Add evaluation capabilities")
250
230
  console.print(" - human_input.py: Incorporate human feedback")
251
231
  console.print("3. Run an example with: uv run <example>.py")
252
- console.print(
253
- "4. Try a different model with --model=<model>, or update the agent config"
254
- )
232
+ console.print("4. Try a different model with --model=<model>, or update the agent config")
255
233
 
256
234
  elif example_type == "researcher":
257
- console.print(
258
- "1. Set up the Brave MCP Server (get an API key from https://brave.com/search/api/)"
259
- )
235
+ console.print("1. Set up the Brave MCP Server (get an API key from https://brave.com/search/api/)")
260
236
  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
- )
237
+ console.print("3. Try `uv run researcher-eval.py` for the eval/optimize version")
264
238
  elif example_type == "data-analysis":
265
- console.print(
266
- "1. Run uv `analysis.py` to perform data analysis and visualization"
267
- )
239
+ console.print("1. Run uv `analysis.py` to perform data analysis and visualization")
268
240
  console.print("2. The dataset is available in the mount-point directory:")
269
241
  console.print(" - mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv")
270
- console.print(
271
- "On Windows platforms, please edit the fastagent.config.yaml and adjust the volume mount point."
272
- )
242
+ console.print("On Windows platforms, please edit the fastagent.config.yaml and adjust the volume mount point.")
273
243
  else:
274
244
  console.print("\n[yellow]No files were created.[/yellow]")
275
245
 
276
246
 
277
247
  @app.callback(invoke_without_command=True)
278
- def main(ctx: typer.Context):
248
+ def main(ctx: typer.Context) -> None:
279
249
  """Create example applications and learn FastAgent patterns."""
280
250
  if ctx.invoked_subcommand is None:
281
251
  show_overview()
@@ -0,0 +1,11 @@
1
+ from typing import NoReturn
2
+
3
+ import typer
4
+
5
+ app = typer.Typer()
6
+
7
+
8
+ @app.command()
9
+ def show() -> NoReturn:
10
+ """Show the configuration."""
11
+ raise NotImplementedError("The show configuration command has not been implemented yet")