fast-agent-mcp 0.1.12__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 (166) hide show
  1. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/PKG-INFO +1 -1
  2. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/pyproject.toml +17 -1
  3. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/agents/agent.py +37 -79
  4. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/app.py +16 -22
  5. {fast_agent_mcp-0.1.12 → 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.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/cli/commands/setup.py +11 -26
  8. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/cli/main.py +6 -9
  9. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/cli/terminal.py +2 -2
  10. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/config.py +1 -5
  11. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/context.py +13 -24
  12. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/context_dependent.py +3 -7
  13. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/agent_app.py +45 -121
  14. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/agent_utils.py +3 -5
  15. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/decorators.py +5 -12
  16. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/enhanced_prompt.py +25 -52
  17. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/exceptions.py +8 -8
  18. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/factory.py +29 -70
  19. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/fastagent.py +48 -88
  20. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/mcp_content.py +8 -16
  21. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/prompt.py +8 -15
  22. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/proxies.py +34 -25
  23. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/request_params.py +6 -3
  24. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/types.py +4 -6
  25. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/validation.py +4 -3
  26. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/executor/decorator_registry.py +11 -23
  27. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/executor/executor.py +8 -17
  28. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/executor/task_registry.py +2 -4
  29. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/executor/temporal.py +28 -74
  30. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/executor/workflow.py +3 -5
  31. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/executor/workflow_signal.py +17 -29
  32. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/human_input/handler.py +4 -9
  33. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/human_input/types.py +2 -3
  34. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/logging/events.py +1 -5
  35. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/logging/json_serializer.py +7 -6
  36. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/logging/listeners.py +20 -23
  37. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/logging/logger.py +15 -17
  38. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/logging/rich_progress.py +10 -8
  39. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/logging/tracing.py +4 -6
  40. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/logging/transport.py +22 -22
  41. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/gen_client.py +4 -12
  42. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/interfaces.py +71 -86
  43. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/mcp_agent_client_session.py +11 -19
  44. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/mcp_agent_server.py +8 -10
  45. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/mcp_aggregator.py +45 -117
  46. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/mcp_connection_manager.py +16 -37
  47. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/prompt_message_multipart.py +12 -18
  48. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/prompt_serialization.py +13 -38
  49. fast_agent_mcp-0.1.13/src/mcp_agent/mcp/prompts/prompt_load.py +99 -0
  50. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/prompts/prompt_server.py +21 -128
  51. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/prompts/prompt_template.py +20 -42
  52. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/resource_utils.py +8 -17
  53. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/sampling.py +5 -14
  54. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/stdio.py +11 -8
  55. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp_server/agent_server.py +10 -17
  56. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp_server_registry.py +13 -35
  57. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/data-analysis/analysis-campaign.py +1 -1
  58. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/data-analysis/analysis.py +1 -1
  59. fast_agent_mcp-0.1.13/src/mcp_agent/resources/examples/data-analysis/slides.py +110 -0
  60. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/internal/agent.py +2 -1
  61. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/internal/job.py +2 -1
  62. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/internal/prompt_category.py +1 -1
  63. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/internal/prompt_sizing.py +3 -5
  64. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/internal/sizer.py +2 -1
  65. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/internal/social.py +2 -1
  66. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/mcp_researcher/researcher-eval.py +1 -1
  67. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/prompting/agent.py +2 -1
  68. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/prompting/image_server.py +5 -11
  69. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/researcher/researcher-eval.py +1 -1
  70. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/researcher/researcher-imp.py +3 -4
  71. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/researcher/researcher.py +2 -1
  72. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/workflows/agent_build.py +2 -1
  73. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/workflows/chaining.py +2 -1
  74. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/workflows/evaluator.py +2 -1
  75. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/workflows/human_input.py +2 -1
  76. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/workflows/orchestrator.py +2 -1
  77. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/workflows/parallel.py +2 -1
  78. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/workflows/router.py +2 -1
  79. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/workflows/sse.py +1 -1
  80. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/telemetry/usage_tracking.py +2 -1
  81. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/ui/console_display.py +15 -39
  82. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/embedding/embedding_base.py +1 -4
  83. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/embedding/embedding_cohere.py +2 -2
  84. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/embedding/embedding_openai.py +4 -13
  85. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/evaluator_optimizer/evaluator_optimizer.py +23 -57
  86. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/intent_classifier/intent_classifier_base.py +5 -8
  87. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/intent_classifier/intent_classifier_embedding.py +7 -11
  88. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/intent_classifier/intent_classifier_embedding_cohere.py +4 -8
  89. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/intent_classifier/intent_classifier_embedding_openai.py +4 -8
  90. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/intent_classifier/intent_classifier_llm.py +11 -22
  91. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/intent_classifier/intent_classifier_llm_anthropic.py +3 -3
  92. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/intent_classifier/intent_classifier_llm_openai.py +4 -6
  93. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/anthropic_utils.py +8 -29
  94. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/augmented_llm.py +69 -247
  95. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/augmented_llm_anthropic.py +39 -73
  96. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/augmented_llm_openai.py +42 -97
  97. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/augmented_llm_passthrough.py +13 -20
  98. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/augmented_llm_playback.py +8 -6
  99. fast_agent_mcp-0.1.13/src/mcp_agent/workflows/llm/memory.py +103 -0
  100. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/model_factory.py +8 -20
  101. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/openai_utils.py +1 -1
  102. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/prompt_utils.py +1 -3
  103. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/providers/multipart_converter_anthropic.py +47 -89
  104. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/providers/multipart_converter_openai.py +20 -55
  105. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/providers/openai_multipart.py +19 -61
  106. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/providers/sampling_converter_anthropic.py +10 -12
  107. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/providers/sampling_converter_openai.py +7 -11
  108. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/sampling_converter.py +4 -11
  109. fast_agent_mcp-0.1.13/src/mcp_agent/workflows/llm/sampling_format_converter.py +22 -0
  110. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/orchestrator/orchestrator.py +24 -67
  111. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/orchestrator/orchestrator_models.py +14 -40
  112. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/parallel/fan_in.py +17 -47
  113. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/parallel/fan_out.py +6 -12
  114. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/parallel/parallel_llm.py +9 -26
  115. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/router/router_base.py +19 -49
  116. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/router/router_embedding.py +11 -25
  117. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/router/router_embedding_cohere.py +2 -2
  118. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/router/router_embedding_openai.py +2 -2
  119. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/router/router_llm.py +12 -28
  120. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/swarm/swarm.py +20 -48
  121. fast_agent_mcp-0.1.12/src/mcp_agent/cli/commands/config.py +0 -11
  122. fast_agent_mcp-0.1.12/src/mcp_agent/workflows/llm/sampling_format_converter.py +0 -22
  123. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/.gitignore +0 -0
  124. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/LICENSE +0 -0
  125. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/README.md +0 -0
  126. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/__init__.py +0 -0
  127. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/agents/__init__.py +0 -0
  128. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/cli/__init__.py +0 -0
  129. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/cli/__main__.py +0 -0
  130. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/console.py +0 -0
  131. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/__init__.py +0 -0
  132. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/agent_types.py +0 -0
  133. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/core/error_handling.py +0 -0
  134. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/eval/__init__.py +0 -0
  135. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/event_progress.py +0 -0
  136. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/executor/__init__.py +0 -0
  137. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/human_input/__init__.py +0 -0
  138. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/logging/__init__.py +0 -0
  139. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/__init__.py +0 -0
  140. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/mcp_activity.py +0 -0
  141. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/mime_utils.py +0 -0
  142. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/prompts/__init__.py +0 -0
  143. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp/prompts/__main__.py +0 -0
  144. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/mcp_server/__init__.py +0 -0
  145. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/progress_display.py +0 -0
  146. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/data-analysis/fastagent.config.yaml +0 -0
  147. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
  148. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/internal/fastagent.config.yaml +0 -0
  149. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/prompting/__init__.py +0 -0
  150. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/prompting/fastagent.config.yaml +0 -0
  151. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/researcher/fastagent.config.yaml +0 -0
  152. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/resources/examples/workflows/fastagent.config.yaml +0 -0
  153. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/telemetry/__init__.py +0 -0
  154. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/__init__.py +0 -0
  155. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/embedding/__init__.py +0 -0
  156. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/evaluator_optimizer/__init__.py +0 -0
  157. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/intent_classifier/__init__.py +0 -0
  158. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/__init__.py +0 -0
  159. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/llm/providers/__init__.py +0 -0
  160. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/orchestrator/__init__.py +0 -0
  161. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/orchestrator/orchestrator_prompts.py +0 -0
  162. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/parallel/__init__.py +0 -0
  163. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/router/__init__.py +0 -0
  164. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/swarm/__init__.py +0 -0
  165. {fast_agent_mcp-0.1.12 → fast_agent_mcp-0.1.13}/src/mcp_agent/workflows/swarm/swarm_anthropic.py +2 -2
  166. {fast_agent_mcp-0.1.12 → 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.12
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.12"
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,29 +1,30 @@
1
1
  import asyncio
2
2
  import uuid
3
- from typing import Callable, Dict, List, Optional, TypeVar, Union, TYPE_CHECKING
3
+ from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, TypeVar, Union
4
4
 
5
5
  from mcp.server.fastmcp.tools import Tool as FastTool
6
6
  from mcp.types import (
7
7
  CallToolResult,
8
+ EmbeddedResource,
8
9
  ListToolsResult,
10
+ ReadResourceResult,
9
11
  TextContent,
10
12
  Tool,
11
- EmbeddedResource,
12
- ReadResourceResult,
13
13
  )
14
- from mcp_agent.mcp.prompt_message_multipart import PromptMessageMultipart
15
14
 
16
- from mcp_agent.core.exceptions import PromptExitError
17
- from mcp_agent.mcp.mcp_aggregator import MCPAggregator
18
15
  from mcp_agent.core.agent_types import AgentConfig
16
+ from mcp_agent.core.exceptions import PromptExitError
17
+ from mcp_agent.core.request_params import RequestParams
19
18
  from mcp_agent.human_input.types import (
19
+ HUMAN_INPUT_SIGNAL_NAME,
20
20
  HumanInputCallback,
21
21
  HumanInputRequest,
22
22
  HumanInputResponse,
23
- HUMAN_INPUT_SIGNAL_NAME,
24
23
  )
25
- from mcp_agent.workflows.llm.augmented_llm import AugmentedLLM
26
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
27
28
 
28
29
  if TYPE_CHECKING:
29
30
  from mcp_agent.context import Context
@@ -32,7 +33,7 @@ import traceback
32
33
  logger = get_logger(__name__)
33
34
 
34
35
  # Define a TypeVar for AugmentedLLM and its subclasses
35
- LLM = TypeVar("LLM", bound=AugmentedLLM)
36
+ LLM = TypeVar("LLM", bound=AugmentedLLMProtocol)
36
37
 
37
38
  HUMAN_INPUT_TOOL_NAME = "__human_input__"
38
39
 
@@ -45,17 +46,15 @@ class Agent(MCPAggregator):
45
46
 
46
47
  def __init__(
47
48
  self,
48
- config: Union[
49
- AgentConfig, str
50
- ], # Can be AgentConfig or backward compatible str name
49
+ config: Union[AgentConfig, str], # Can be AgentConfig or backward compatible str name
51
50
  instruction: Optional[Union[str, Callable[[Dict], str]]] = None,
52
51
  server_names: Optional[List[str]] = None,
53
52
  functions: Optional[List[Callable]] = None,
54
53
  connection_persistence: bool = True,
55
54
  human_input_callback: Optional[HumanInputCallback] = None,
56
55
  context: Optional["Context"] = None,
57
- **kwargs,
58
- ):
56
+ **kwargs: dict[str, Any],
57
+ ) -> None:
59
58
  # Handle backward compatibility where first arg was name
60
59
  if isinstance(config, str):
61
60
  self.config = AgentConfig(
@@ -94,14 +93,12 @@ class Agent(MCPAggregator):
94
93
  if self.context.human_input_handler:
95
94
  self.human_input_callback = self.context.human_input_handler
96
95
 
97
- async def initialize(self):
96
+ async def initialize(self) -> None:
98
97
  """
99
98
  Initialize the agent and connect to the MCP servers.
100
99
  NOTE: This method is called automatically when the agent is used as an async context manager.
101
100
  """
102
- await (
103
- self.__aenter__()
104
- ) # This initializes the connection manager and loads the servers
101
+ await self.__aenter__() # This initializes the connection manager and loads the servers
105
102
 
106
103
  for function in self.functions:
107
104
  tool: FastTool = FastTool.from_function(function)
@@ -119,11 +116,9 @@ class Agent(MCPAggregator):
119
116
  Returns:
120
117
  An instance of AugmentedLLM or one of its subclasses.
121
118
  """
122
- return llm_factory(
123
- agent=self, default_request_params=self._default_request_params
124
- )
119
+ return llm_factory(agent=self, default_request_params=self._default_request_params)
125
120
 
126
- async def shutdown(self):
121
+ async def shutdown(self) -> None:
127
122
  """
128
123
  Shutdown the agent and close all MCP server connections.
129
124
  NOTE: This method is called automatically when the agent is used as an async context manager.
@@ -153,8 +148,9 @@ class Agent(MCPAggregator):
153
148
  request.metadata = {"agent_name": self.name}
154
149
  self.logger.debug("Requesting human input:", data=request)
155
150
 
156
- async def call_callback_and_signal():
151
+ async def call_callback_and_signal() -> None:
157
152
  try:
153
+ assert self.human_input_callback is not None
158
154
  user_input = await self.human_input_callback(request)
159
155
 
160
156
  self.logger.debug("Received human input:", data=user_input)
@@ -167,9 +163,7 @@ class Agent(MCPAggregator):
167
163
  payload={"exit_requested": True, "error": str(e)},
168
164
  )
169
165
  except Exception as e:
170
- await self.executor.signal(
171
- request_id, payload=f"Error getting human input: {str(e)}"
172
- )
166
+ await self.executor.signal(request_id, payload=f"Error getting human input: {str(e)}")
173
167
 
174
168
  asyncio.create_task(call_callback_and_signal())
175
169
 
@@ -186,9 +180,7 @@ class Agent(MCPAggregator):
186
180
  )
187
181
 
188
182
  if isinstance(result, dict) and result.get("exit_requested", False):
189
- raise PromptExitError(
190
- result.get("error", "User requested to exit FastAgent session")
191
- )
183
+ raise PromptExitError(result.get("error", "User requested to exit FastAgent session"))
192
184
  self.logger.debug("Received human input signal", data=result)
193
185
  return result
194
186
 
@@ -226,9 +218,7 @@ class Agent(MCPAggregator):
226
218
  return result
227
219
 
228
220
  # todo would prefer to use tool_name to disambiguate agent name
229
- async def call_tool(
230
- self, name: str, arguments: dict | None = None
231
- ) -> CallToolResult:
221
+ async def call_tool(self, name: str, arguments: dict | None = None) -> CallToolResult:
232
222
  if name == HUMAN_INPUT_TOOL_NAME:
233
223
  # Call the human input tool
234
224
  return await self._call_human_input_tool(arguments)
@@ -240,9 +230,7 @@ class Agent(MCPAggregator):
240
230
  else:
241
231
  return await super().call_tool(name, arguments)
242
232
 
243
- async def _call_human_input_tool(
244
- self, arguments: dict | None = None
245
- ) -> CallToolResult:
233
+ async def _call_human_input_tool(self, arguments: dict | None = None) -> CallToolResult:
246
234
  # Handle human input request
247
235
  try:
248
236
  # Make sure arguments is not None
@@ -264,17 +252,9 @@ class Agent(MCPAggregator):
264
252
  result = await self.request_human_input(request=request)
265
253
 
266
254
  # Use response attribute if available, otherwise use the result directly
267
- response_text = (
268
- result.response
269
- if isinstance(result, HumanInputResponse)
270
- else str(result)
271
- )
255
+ response_text = result.response if isinstance(result, HumanInputResponse) else str(result)
272
256
 
273
- return CallToolResult(
274
- content=[
275
- TextContent(type="text", text=f"Human response: {response_text}")
276
- ]
277
- )
257
+ return CallToolResult(content=[TextContent(type="text", text=f"Human response: {response_text}")])
278
258
 
279
259
  except PromptExitError:
280
260
  raise
@@ -293,21 +273,10 @@ class Agent(MCPAggregator):
293
273
 
294
274
  return CallToolResult(
295
275
  isError=True,
296
- content=[
297
- TextContent(
298
- type="text", text=f"Error requesting human input: {str(e)}"
299
- )
300
- ],
276
+ content=[TextContent(type="text", text=f"Error requesting human input: {str(e)}")],
301
277
  )
302
278
 
303
- async def read_resource(
304
- self, server_name: str, resource_name: str
305
- ) -> ReadResourceResult:
306
- return None
307
-
308
- async def apply_prompt(
309
- self, prompt_name: str, arguments: dict[str, str] = None
310
- ) -> str:
279
+ async def apply_prompt(self, prompt_name: str, arguments: dict[str, str] | None) -> str:
311
280
  """
312
281
  Apply an MCP Server Prompt by name and return the assistant's response.
313
282
  Will search all available servers for the prompt if not namespaced.
@@ -331,9 +300,7 @@ class Agent(MCPAggregator):
331
300
  prompt_result = await self.get_prompt(prompt_name, arguments)
332
301
 
333
302
  if not prompt_result or not prompt_result.messages:
334
- error_msg = (
335
- f"Prompt '{prompt_name}' could not be found or contains no messages"
336
- )
303
+ error_msg = f"Prompt '{prompt_name}' could not be found or contains no messages"
337
304
  self.logger.warning(error_msg)
338
305
  return error_msg
339
306
 
@@ -372,16 +339,10 @@ class Agent(MCPAggregator):
372
339
  resource_result = await server.get_resource(resource_name)
373
340
  return resource_result
374
341
  except Exception as e:
375
- self.logger.error(
376
- f"Error retrieving resource '{resource_name}' from server '{server_name}': {str(e)}"
377
- )
378
- raise ValueError(
379
- f"Failed to retrieve resource '{resource_name}' from server '{server_name}': {str(e)}"
380
- )
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)}")
381
344
 
382
- async def get_embedded_resources(
383
- self, server_name: str, resource_name: str
384
- ) -> List[EmbeddedResource]:
345
+ async def get_embedded_resources(self, server_name: str, resource_name: str) -> List[EmbeddedResource]:
385
346
  """
386
347
  Get a resource from an MCP server and return it as a list of embedded resources ready for use in prompts.
387
348
 
@@ -396,20 +357,19 @@ class Agent(MCPAggregator):
396
357
  ValueError: If the server doesn't exist or the resource couldn't be found
397
358
  """
398
359
  # Get the raw resource result
399
- result: ReadResourceResult = await super().get_resource(
400
- server_name, resource_name
401
- )
360
+ result: ReadResourceResult = await super().get_resource(server_name, resource_name)
402
361
 
403
362
  # Convert each resource content to an EmbeddedResource
404
363
  embedded_resources: List[EmbeddedResource] = []
405
364
  for resource_content in result.contents:
406
- embedded_resource = EmbeddedResource(
407
- type="resource", resource=resource_content, annotations=None
408
- )
365
+ embedded_resource = EmbeddedResource(type="resource", resource=resource_content, annotations=None)
409
366
  embedded_resources.append(embedded_resource)
410
367
 
411
368
  return embedded_resources
412
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
+
413
373
  async def with_resource(
414
374
  self,
415
375
  prompt_content: Union[str, PromptMessageMultipart],
@@ -428,9 +388,7 @@ class Agent(MCPAggregator):
428
388
  The agent's response as a string
429
389
  """
430
390
  # Get the embedded resources
431
- embedded_resources: List[EmbeddedResource] = await self.get_embedded_resources(
432
- server_name, resource_name
433
- )
391
+ embedded_resources: List[EmbeddedResource] = await self.get_embedded_resources(server_name, resource_name)
434
392
 
435
393
  # Create or update the prompt message
436
394
  prompt: PromptMessageMultipart
@@ -1,16 +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
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
14
16
 
15
17
  R = TypeVar("R")
16
18
 
@@ -43,7 +45,7 @@ class MCPApp:
43
45
  human_input_callback: Optional[HumanInputCallback] = console_input_callback,
44
46
  signal_notification: Optional[SignalWaitCallback] = None,
45
47
  upstream_session: Optional["ServerSession"] = None,
46
- ):
48
+ ) -> None:
47
49
  """
48
50
  Initialize the application with a name and optional settings.
49
51
  Args:
@@ -70,9 +72,7 @@ class MCPApp:
70
72
  @property
71
73
  def context(self) -> Context:
72
74
  if self._context is None:
73
- raise RuntimeError(
74
- "MCPApp not initialized, please call initialize() first, or use async with app.run()."
75
- )
75
+ raise RuntimeError("MCPApp not initialized, please call initialize() first, or use async with app.run().")
76
76
  return self._context
77
77
 
78
78
  @property
@@ -96,7 +96,7 @@ class MCPApp:
96
96
  return self._context.upstream_session
97
97
 
98
98
  @upstream_session.setter
99
- def upstream_session(self, value):
99
+ def upstream_session(self, value) -> None:
100
100
  self._context.upstream_session = value
101
101
 
102
102
  @property
@@ -113,7 +113,7 @@ class MCPApp:
113
113
  self._logger = get_logger(f"mcp_agent.{self.name}")
114
114
  return self._logger
115
115
 
116
- async def initialize(self):
116
+ async def initialize(self) -> None:
117
117
  """Initialize the application."""
118
118
  if self._initialized:
119
119
  return
@@ -135,7 +135,7 @@ class MCPApp:
135
135
  },
136
136
  )
137
137
 
138
- async def cleanup(self):
138
+ async def cleanup(self) -> None:
139
139
  """Cleanup application resources."""
140
140
  if not self._initialized:
141
141
  return
@@ -173,9 +173,7 @@ class MCPApp:
173
173
  finally:
174
174
  await self.cleanup()
175
175
 
176
- def workflow(
177
- self, cls: Type, *args, workflow_id: str | None = None, **kwargs
178
- ) -> Type:
176
+ def workflow(self, cls: Type, *args, workflow_id: str | None = None, **kwargs) -> Type:
179
177
  """
180
178
  Decorator for a workflow class. By default it's a no-op,
181
179
  but different executors can use this to customize behavior
@@ -187,9 +185,7 @@ class MCPApp:
187
185
  """
188
186
  decorator_registry = self.context.decorator_registry
189
187
  execution_engine = self.engine
190
- workflow_defn_decorator = decorator_registry.get_workflow_defn_decorator(
191
- execution_engine
192
- )
188
+ workflow_defn_decorator = decorator_registry.get_workflow_defn_decorator(execution_engine)
193
189
 
194
190
  if workflow_defn_decorator:
195
191
  return workflow_defn_decorator(cls, *args, **kwargs)
@@ -211,9 +207,7 @@ class MCPApp:
211
207
 
212
208
  decorator_registry = self.context.decorator_registry
213
209
  execution_engine = self.engine
214
- workflow_run_decorator = decorator_registry.get_workflow_run_decorator(
215
- execution_engine
216
- )
210
+ workflow_run_decorator = decorator_registry.get_workflow_run_decorator(execution_engine)
217
211
 
218
212
  if workflow_run_decorator:
219
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")
@@ -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,17 +167,13 @@ def init(
166
167
  "-c",
167
168
  help="Directory where configuration files will be created",
168
169
  ),
169
- force: bool = typer.Option(
170
- False, "--force", "-f", help="Force overwrite existing files"
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()
176
175
  if not config_path.exists():
177
- should_create = Confirm.ask(
178
- f"Directory {config_path} does not exist. Create it?", default=True
179
- )
176
+ should_create = Confirm.ask(f"Directory {config_path} does not exist. Create it?", default=True)
180
177
  if should_create:
181
178
  config_path.mkdir(parents=True)
182
179
  else:
@@ -198,38 +195,26 @@ def init(
198
195
 
199
196
  # Create configuration files
200
197
  created = []
201
- if create_file(
202
- config_path / "fastagent.config.yaml", FASTAGENT_CONFIG_TEMPLATE, force
203
- ):
198
+ if create_file(config_path / "fastagent.config.yaml", FASTAGENT_CONFIG_TEMPLATE, force):
204
199
  created.append("fastagent.yaml")
205
200
 
206
- if create_file(
207
- config_path / "fastagent.secrets.yaml", FASTAGENT_SECRETS_TEMPLATE, force
208
- ):
201
+ if create_file(config_path / "fastagent.secrets.yaml", FASTAGENT_SECRETS_TEMPLATE, force):
209
202
  created.append("fastagent.secrets.yaml")
210
203
 
211
204
  if create_file(config_path / "agent.py", AGENT_EXAMPLE_TEMPLATE, force):
212
205
  created.append("agent.py")
213
206
 
214
207
  # Only create .gitignore if none exists in parent directories
215
- if needs_gitignore and create_file(
216
- config_path / ".gitignore", GITIGNORE_TEMPLATE, force
217
- ):
208
+ if needs_gitignore and create_file(config_path / ".gitignore", GITIGNORE_TEMPLATE, force):
218
209
  created.append(".gitignore")
219
210
 
220
211
  if created:
221
212
  console.print("\n[green]Setup completed successfully![/green]")
222
213
  if "fastagent.secrets.yaml" in created:
223
214
  console.print("\n[yellow]Important:[/yellow] Remember to:")
224
- console.print(
225
- "1. Add your API keys to fastagent-secrets.yaml or set OPENAI_API_KEY and ANTHROPIC_API_KEY environment variables"
226
- )
227
- console.print(
228
- "2. Keep fastagent.secrets.yaml secure and never commit it to version control"
229
- )
230
- console.print(
231
- "3. Update fastagent.config.yaml to set a default model (currently system default is 'haiku')"
232
- )
215
+ console.print("1. Add your API keys to fastagent-secrets.yaml or set OPENAI_API_KEY and ANTHROPIC_API_KEY environment variables")
216
+ console.print("2. Keep fastagent.secrets.yaml secure and never commit it to version control")
217
+ console.print("3. Update fastagent.config.yaml to set a default model (currently system default is 'haiku')")
233
218
  console.print("\nTo get started, run:")
234
219
  console.print(" uv run agent.py")
235
220
  else: