fast-agent-mcp 0.2.6__tar.gz → 0.2.8__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 (160) hide show
  1. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/PKG-INFO +3 -4
  2. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/README.md +2 -3
  3. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/pyproject.toml +1 -1
  4. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/agents/base_agent.py +5 -5
  5. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/agents/workflow/chain_agent.py +3 -11
  6. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/agents/workflow/router_agent.py +22 -5
  7. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/config.py +17 -3
  8. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/core/enhanced_prompt.py +28 -9
  9. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/core/fastagent.py +2 -0
  10. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/core/interactive_prompt.py +130 -26
  11. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/augmented_llm.py +5 -1
  12. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/model_factory.py +5 -0
  13. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/providers/augmented_llm_anthropic.py +15 -49
  14. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/providers/augmented_llm_openai.py +19 -40
  15. fast_agent_mcp-0.2.8/src/mcp_agent/llm/providers/augmented_llm_openrouter.py +78 -0
  16. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/logger_textio.py +15 -4
  17. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/mcp_connection_manager.py +5 -3
  18. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp_server_registry.py +2 -1
  19. fast_agent_mcp-0.2.6/src/mcp_agent/mcp/mcp_activity.py +0 -18
  20. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/.gitignore +0 -0
  21. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/LICENSE +0 -0
  22. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/examples/data-analysis/analysis-campaign.py +0 -0
  23. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/examples/data-analysis/analysis.py +0 -0
  24. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/examples/data-analysis/fastagent.config.yaml +0 -0
  25. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
  26. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/examples/researcher/fastagent.config.yaml +0 -0
  27. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/examples/researcher/researcher-eval.py +0 -0
  28. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/examples/researcher/researcher-imp.py +0 -0
  29. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/examples/researcher/researcher.py +0 -0
  30. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/examples/workflows/chaining.py +0 -0
  31. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/examples/workflows/evaluator.py +0 -0
  32. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/examples/workflows/fastagent.config.yaml +0 -0
  33. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/examples/workflows/graded_report.md +0 -0
  34. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/examples/workflows/human_input.py +0 -0
  35. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/examples/workflows/orchestrator.py +0 -0
  36. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/examples/workflows/parallel.py +0 -0
  37. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/examples/workflows/router.py +0 -0
  38. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/examples/workflows/short_story.md +0 -0
  39. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/examples/workflows/short_story.txt +0 -0
  40. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/__init__.py +0 -0
  41. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/agents/__init__.py +0 -0
  42. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/agents/agent.py +0 -0
  43. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/agents/workflow/__init__.py +0 -0
  44. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/agents/workflow/evaluator_optimizer.py +0 -0
  45. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/agents/workflow/orchestrator_agent.py +0 -0
  46. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/agents/workflow/orchestrator_models.py +0 -0
  47. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/agents/workflow/orchestrator_prompts.py +0 -0
  48. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/agents/workflow/parallel_agent.py +0 -0
  49. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/app.py +0 -0
  50. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/cli/__init__.py +0 -0
  51. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/cli/__main__.py +0 -0
  52. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/cli/commands/bootstrap.py +0 -0
  53. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/cli/commands/config.py +0 -0
  54. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/cli/commands/setup.py +0 -0
  55. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/cli/main.py +0 -0
  56. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/cli/terminal.py +0 -0
  57. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/console.py +0 -0
  58. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/context.py +0 -0
  59. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/context_dependent.py +0 -0
  60. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/core/__init__.py +0 -0
  61. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/core/agent_app.py +0 -0
  62. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/core/agent_types.py +0 -0
  63. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/core/direct_decorators.py +0 -0
  64. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/core/direct_factory.py +0 -0
  65. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/core/error_handling.py +0 -0
  66. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/core/exceptions.py +0 -0
  67. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/core/mcp_content.py +0 -0
  68. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/core/prompt.py +0 -0
  69. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/core/request_params.py +0 -0
  70. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/core/validation.py +0 -0
  71. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/event_progress.py +0 -0
  72. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/executor/__init__.py +0 -0
  73. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/executor/decorator_registry.py +0 -0
  74. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/executor/executor.py +0 -0
  75. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/executor/task_registry.py +0 -0
  76. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/executor/temporal.py +0 -0
  77. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/executor/workflow.py +0 -0
  78. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/executor/workflow_signal.py +0 -0
  79. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/human_input/__init__.py +0 -0
  80. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/human_input/handler.py +0 -0
  81. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/human_input/types.py +0 -0
  82. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/__init__.py +0 -0
  83. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/augmented_llm_passthrough.py +0 -0
  84. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/augmented_llm_playback.py +0 -0
  85. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/memory.py +0 -0
  86. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/prompt_utils.py +0 -0
  87. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/providers/__init__.py +0 -0
  88. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/providers/anthropic_utils.py +0 -0
  89. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/providers/augmented_llm_deepseek.py +0 -0
  90. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/providers/augmented_llm_generic.py +0 -0
  91. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/providers/multipart_converter_anthropic.py +0 -0
  92. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/providers/multipart_converter_openai.py +0 -0
  93. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/providers/openai_multipart.py +0 -0
  94. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/providers/openai_utils.py +0 -0
  95. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/providers/sampling_converter_anthropic.py +0 -0
  96. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/providers/sampling_converter_openai.py +0 -0
  97. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/sampling_converter.py +0 -0
  98. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/llm/sampling_format_converter.py +0 -0
  99. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/logging/__init__.py +0 -0
  100. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/logging/events.py +0 -0
  101. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/logging/json_serializer.py +0 -0
  102. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/logging/listeners.py +0 -0
  103. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/logging/logger.py +0 -0
  104. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/logging/rich_progress.py +0 -0
  105. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/logging/tracing.py +0 -0
  106. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/logging/transport.py +0 -0
  107. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/__init__.py +0 -0
  108. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/gen_client.py +0 -0
  109. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/helpers/__init__.py +0 -0
  110. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/helpers/content_helpers.py +0 -0
  111. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/interfaces.py +0 -0
  112. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/mcp_agent_client_session.py +0 -0
  113. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/mcp_aggregator.py +0 -0
  114. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/mime_utils.py +0 -0
  115. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/prompt_message_multipart.py +0 -0
  116. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/prompt_render.py +0 -0
  117. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/prompt_serialization.py +0 -0
  118. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/prompts/__init__.py +0 -0
  119. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/prompts/__main__.py +0 -0
  120. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/prompts/prompt_constants.py +0 -0
  121. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/prompts/prompt_helpers.py +0 -0
  122. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/prompts/prompt_load.py +0 -0
  123. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/prompts/prompt_server.py +0 -0
  124. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/prompts/prompt_template.py +0 -0
  125. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/resource_utils.py +0 -0
  126. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp/sampling.py +0 -0
  127. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp_server/__init__.py +0 -0
  128. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/mcp_server/agent_server.py +0 -0
  129. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/progress_display.py +0 -0
  130. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/data-analysis/analysis-campaign.py +0 -0
  131. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/data-analysis/analysis.py +0 -0
  132. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/data-analysis/fastagent.config.yaml +0 -0
  133. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
  134. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/in_dev/agent_build.py +0 -0
  135. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/in_dev/slides.py +0 -0
  136. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/internal/agent.py +0 -0
  137. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/internal/fastagent.config.yaml +0 -0
  138. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/internal/history_transfer.py +0 -0
  139. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/internal/job.py +0 -0
  140. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/internal/prompt_category.py +0 -0
  141. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/internal/prompt_sizing.py +0 -0
  142. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/internal/sizer.py +0 -0
  143. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/internal/social.py +0 -0
  144. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/prompting/__init__.py +0 -0
  145. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/prompting/agent.py +0 -0
  146. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/prompting/fastagent.config.yaml +0 -0
  147. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/prompting/image_server.py +0 -0
  148. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/prompting/work_with_image.py +0 -0
  149. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/researcher/fastagent.config.yaml +0 -0
  150. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/researcher/researcher-eval.py +0 -0
  151. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/researcher/researcher-imp.py +0 -0
  152. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/researcher/researcher.py +0 -0
  153. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/workflows/chaining.py +0 -0
  154. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/workflows/evaluator.py +0 -0
  155. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/workflows/fastagent.config.yaml +0 -0
  156. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/workflows/human_input.py +0 -0
  157. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/workflows/orchestrator.py +0 -0
  158. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/workflows/parallel.py +0 -0
  159. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/resources/examples/workflows/router.py +0 -0
  160. {fast_agent_mcp-0.2.6 → fast_agent_mcp-0.2.8}/src/mcp_agent/ui/console_display.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fast-agent-mcp
3
- Version: 0.2.6
3
+ Version: 0.2.8
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
@@ -260,8 +260,7 @@ The simple declarative syntax lets you concentrate on composing your Prompts and
260
260
 
261
261
  `fast-agent` is multi-modal, supporting Images and PDFs for both Anthropic and OpenAI endpoints via Prompts, Resources and MCP Tool Call results. The inclusion of passthrough and playback LLMs enable rapid development and test of Python glue-code for your applications.
262
262
 
263
- > [!TIP]
264
- > `fast-agent` is now MCP Native! Coming Soon - Full Documentation Site and Further MCP Examples.
263
+ > [!TIP] > `fast-agent` is now MCP Native! Coming Soon - Full Documentation Site and Further MCP Examples.
265
264
 
266
265
  ### Agent Application Development
267
266
 
@@ -525,7 +524,7 @@ agent["greeter"].send("Good Evening!") # Dictionary access is supported
525
524
  servers=["filesystem"], # list of MCP Servers for the agent
526
525
  model="o3-mini.high", # specify a model for the agent
527
526
  use_history=True, # agent maintains chat history
528
- request_params={"temperature": 0.7}, # additional parameters for the LLM (or RequestParams())
527
+ request_params=RequestParams(temperature= 0.7)), # additional parameters for the LLM (or RequestParams())
529
528
  human_input=True, # agent can request human input
530
529
  )
531
530
  ```
@@ -18,8 +18,7 @@ The simple declarative syntax lets you concentrate on composing your Prompts and
18
18
 
19
19
  `fast-agent` is multi-modal, supporting Images and PDFs for both Anthropic and OpenAI endpoints via Prompts, Resources and MCP Tool Call results. The inclusion of passthrough and playback LLMs enable rapid development and test of Python glue-code for your applications.
20
20
 
21
- > [!TIP]
22
- > `fast-agent` is now MCP Native! Coming Soon - Full Documentation Site and Further MCP Examples.
21
+ > [!TIP] > `fast-agent` is now MCP Native! Coming Soon - Full Documentation Site and Further MCP Examples.
23
22
 
24
23
  ### Agent Application Development
25
24
 
@@ -283,7 +282,7 @@ agent["greeter"].send("Good Evening!") # Dictionary access is supported
283
282
  servers=["filesystem"], # list of MCP Servers for the agent
284
283
  model="o3-mini.high", # specify a model for the agent
285
284
  use_history=True, # agent maintains chat history
286
- request_params={"temperature": 0.7}, # additional parameters for the LLM (or RequestParams())
285
+ request_params=RequestParams(temperature= 0.7)), # additional parameters for the LLM (or RequestParams())
287
286
  human_input=True, # agent can request human input
288
287
  )
289
288
  ```
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fast-agent-mcp"
3
- version = "0.2.6"
3
+ version = "0.2.8"
4
4
  description = "Define, Prompt and Test MCP enabled Agents and Workflows"
5
5
  readme = "README.md"
6
6
  license = { file = "LICENSE" }
@@ -215,7 +215,7 @@ class BaseAgent(MCPAggregator, AgentProtocol):
215
215
 
216
216
  # Use the LLM to generate a response
217
217
  response = await self.generate([prompt], None)
218
- return response.first_text()
218
+ return response.all_text()
219
219
 
220
220
  def _normalize_message_input(
221
221
  self, message: Union[str, PromptMessage, PromptMessageMultipart]
@@ -625,15 +625,15 @@ class BaseAgent(MCPAggregator, AgentProtocol):
625
625
  @property
626
626
  def agent_type(self) -> str:
627
627
  """
628
- Return the type of this agent.
629
-
628
+ Return the type of this agent.
629
+
630
630
  This is used for display purposes in the interactive prompt and other UI elements.
631
-
631
+
632
632
  Returns:
633
633
  String representing the agent type
634
634
  """
635
635
  return self.config.agent_type
636
-
636
+
637
637
  @property
638
638
  def message_history(self) -> List[PromptMessageMultipart]:
639
639
  """
@@ -23,7 +23,8 @@ class ChainAgent(BaseAgent):
23
23
  A chain agent that processes requests through a series of specialized agents in sequence.
24
24
  Passes the output of each agent to the next agent in the chain.
25
25
  """
26
-
26
+
27
+ # TODO -- consider adding "repeat" mode
27
28
  @property
28
29
  def agent_type(self) -> str:
29
30
  """Return the type of this agent."""
@@ -70,20 +71,11 @@ class ChainAgent(BaseAgent):
70
71
  # # Get the original user message (last message in the list)
71
72
  user_message = multipart_messages[-1] if multipart_messages else None
72
73
 
73
- # # If no user message, return an error
74
- # if not user_message:
75
- # return PromptMessageMultipart(
76
- # role="assistant",
77
- # content=[TextContent(type="text", text="No input message provided.")],
78
- # )
79
-
80
- # Initialize messages with the input
81
-
82
74
  if not self.cumulative:
83
75
  response: PromptMessageMultipart = await self.agents[0].generate(multipart_messages)
84
76
  # Process the rest of the agents in the chain
85
77
  for agent in self.agents[1:]:
86
- next_message = Prompt.user(response.content[0].text)
78
+ next_message = Prompt.user(*response.content)
87
79
  response = await agent.generate([next_message])
88
80
 
89
81
  return response
@@ -53,12 +53,29 @@ You are a highly accurate request router that directs incoming requests to the m
53
53
  Your task is to analyze the request and determine the most appropriate agent from the options above.
54
54
 
55
55
  <fastagent:instruction>
56
- Respond in JSON format. ONLY include JSON (no explanation). NEVER include Code Fences:
56
+ Respond with JSON following the schema below:
57
57
  {{
58
- "agent": "<agent name>",
59
- "confidence": "<high, medium or low>",
60
- "reasoning": "<brief explanation>"
58
+ "type": "object",
59
+ "required": ["agent", "confidence", "reasoning"],
60
+ "properties": {{
61
+ "agent": {{
62
+ "type": "string",
63
+ "description": "The exact name of the selected agent"
64
+ }},
65
+ "confidence": {{
66
+ "type": "string",
67
+ "enum": ["high", "medium", "low"],
68
+ "description": "Your confidence level in this selection"
69
+ }},
70
+ "reasoning": {{
71
+ "type": "string",
72
+ "description": "Brief explanation for your selection"
73
+ }}
74
+ }}
61
75
  }}
76
+
77
+ Supply only the JSON with no preamble. Use "reasoning" field to describe actions. NEVER EMIT CODE FENCES.
78
+
62
79
  </fastagent:instruction>
63
80
  """
64
81
 
@@ -87,7 +104,7 @@ class RouterAgent(BaseAgent):
87
104
  A simplified router that uses an LLM to determine the best agent for a request,
88
105
  then dispatches the request to that agent and returns the response.
89
106
  """
90
-
107
+
91
108
  @property
92
109
  def agent_type(self) -> str:
93
110
  """Return the type of this agent."""
@@ -75,6 +75,9 @@ class MCPServerSettings(BaseModel):
75
75
  url: str | None = None
76
76
  """The URL for the server (e.g. for SSE transport)."""
77
77
 
78
+ headers: Dict[str, str] | None = None
79
+ """Headers dictionary for SSE connections"""
80
+
78
81
  auth: MCPServerAuthSettings | None = None
79
82
  """The authentication configuration for the server."""
80
83
 
@@ -84,9 +87,6 @@ class MCPServerSettings(BaseModel):
84
87
  env: Dict[str, str] | None = None
85
88
  """Environment variables to pass to the server process."""
86
89
 
87
- env: Dict[str, str] | None = None
88
- """Environment variables to pass to the server process."""
89
-
90
90
  sampling: MCPSamplingSettings | None = None
91
91
  """Sampling settings for this Client/Server pair"""
92
92
 
@@ -146,6 +146,17 @@ class GenericSettings(BaseModel):
146
146
  base_url: str | None = None
147
147
 
148
148
  model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True)
149
+
150
+
151
+ class OpenRouterSettings(BaseModel):
152
+ """
153
+ Settings for using OpenRouter models via its OpenAI-compatible API.
154
+ """
155
+ api_key: str | None = None
156
+
157
+ base_url: str | None = None # Optional override, defaults handled in provider
158
+
159
+ model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True)
149
160
 
150
161
 
151
162
  class TemporalSettings(BaseModel):
@@ -262,6 +273,9 @@ class Settings(BaseSettings):
262
273
  deepseek: DeepSeekSettings | None = None
263
274
  """Settings for using DeepSeek models in the fast-agent application"""
264
275
 
276
+ openrouter: OpenRouterSettings | None = None
277
+ """Settings for using OpenRouter models in the fast-agent application"""
278
+
265
279
  generic: GenericSettings | None = None
266
280
  """Settings for using Generic models in the fast-agent application"""
267
281
 
@@ -285,10 +285,17 @@ async def get_enhanced_input(
285
285
  elif cmd == "agents":
286
286
  return "LIST_AGENTS"
287
287
  elif cmd == "prompts":
288
- return "SELECT_PROMPT" # Directly launch prompt selection UI
288
+ # Return a dictionary with select_prompt action instead of a string
289
+ # This way it will match what the command handler expects
290
+ return {"select_prompt": True, "prompt_name": None}
289
291
  elif cmd == "prompt" and len(cmd_parts) > 1:
290
- # Direct prompt selection with name
291
- return f"SELECT_PROMPT:{cmd_parts[1].strip()}"
292
+ # Direct prompt selection with name or number
293
+ prompt_arg = cmd_parts[1].strip()
294
+ # Check if it's a number (use as index) or a name (use directly)
295
+ if prompt_arg.isdigit():
296
+ return {"select_prompt": True, "prompt_index": int(prompt_arg)}
297
+ else:
298
+ return f"SELECT_PROMPT:{prompt_arg}"
292
299
  elif cmd == "exit":
293
300
  return "EXIT"
294
301
  elif cmd.lower() == "stop":
@@ -420,13 +427,27 @@ async def get_argument_input(
420
427
  prompt_session.app.exit()
421
428
 
422
429
 
423
- async def handle_special_commands(command: str, agent_app=None):
424
- """Handle special input commands."""
430
+ async def handle_special_commands(command, agent_app=None):
431
+ """
432
+ Handle special input commands.
433
+
434
+ Args:
435
+ command: The command to handle, can be string or dictionary
436
+ agent_app: Optional agent app reference
437
+
438
+ Returns:
439
+ True if command was handled, False if not, or a dict with action info
440
+ """
425
441
  # Quick guard for empty or None commands
426
442
  if not command:
427
443
  return False
444
+
445
+ # If command is already a dictionary, it has been pre-processed
446
+ # Just return it directly (like when /prompts converts to select_prompt dict)
447
+ if isinstance(command, dict):
448
+ return command
428
449
 
429
- # Check for special commands
450
+ # Check for special string commands
430
451
  if command == "HELP":
431
452
  rich_print("\n[bold]Available Commands:[/bold]")
432
453
  rich_print(" /help - Show this help")
@@ -450,7 +471,7 @@ async def handle_special_commands(command: str, agent_app=None):
450
471
  print("\033c", end="")
451
472
  return True
452
473
 
453
- elif command.upper() == "EXIT":
474
+ elif isinstance(command, str) and command.upper() == "EXIT":
454
475
  raise PromptExitError("User requested to exit fast-agent session")
455
476
 
456
477
  elif command == "LIST_AGENTS":
@@ -462,8 +483,6 @@ async def handle_special_commands(command: str, agent_app=None):
462
483
  rich_print("[yellow]No agents available[/yellow]")
463
484
  return True
464
485
 
465
- # Removed LIST_PROMPTS handling as it's now covered by SELECT_PROMPT
466
-
467
486
  elif command == "SELECT_PROMPT" or (
468
487
  isinstance(command, str) and command.startswith("SELECT_PROMPT:")
469
488
  ):
@@ -235,6 +235,8 @@ class FastAgent:
235
235
  progress_display.stop()
236
236
 
237
237
  # Pre-flight validation
238
+ if 0 == len(self.agents):
239
+ raise AgentConfigError("No agents defined. Please define at least one agent.")
238
240
  validate_server_references(self.context, self.agents)
239
241
  validate_workflow_references(self.agents)
240
242
 
@@ -26,6 +26,7 @@ from mcp_agent.core.enhanced_prompt import (
26
26
  get_selection_input,
27
27
  handle_special_commands,
28
28
  )
29
+ from mcp_agent.mcp.mcp_aggregator import SEP # Import SEP once at the top
29
30
  from mcp_agent.progress_display import progress_display
30
31
 
31
32
 
@@ -96,7 +97,7 @@ class InteractivePrompt:
96
97
 
97
98
  # Handle special commands - pass "True" to enable agent switching
98
99
  command_result = await handle_special_commands(user_input, True)
99
-
100
+
100
101
  # Check if we should switch agents
101
102
  if isinstance(command_result, dict):
102
103
  if "switch_agent" in command_result:
@@ -107,6 +108,7 @@ class InteractivePrompt:
107
108
  else:
108
109
  rich_print(f"[red]Agent '{new_agent}' not found[/red]")
109
110
  continue
111
+ # Keep the existing list_prompts handler for backward compatibility
110
112
  elif "list_prompts" in command_result and list_prompts_func:
111
113
  # Use the list_prompts_func directly
112
114
  await self._list_prompts(list_prompts_func, agent)
@@ -114,7 +116,29 @@ class InteractivePrompt:
114
116
  elif "select_prompt" in command_result and (list_prompts_func and apply_prompt_func):
115
117
  # Handle prompt selection, using both list_prompts and apply_prompt
116
118
  prompt_name = command_result.get("prompt_name")
117
- await self._select_prompt(list_prompts_func, apply_prompt_func, agent, prompt_name)
119
+ prompt_index = command_result.get("prompt_index")
120
+
121
+ # If a specific index was provided (from /prompt <number>)
122
+ if prompt_index is not None:
123
+ # First get a list of all prompts to look up the index
124
+ all_prompts = await self._get_all_prompts(list_prompts_func, agent)
125
+ if not all_prompts:
126
+ rich_print("[yellow]No prompts available[/yellow]")
127
+ continue
128
+
129
+ # Check if the index is valid
130
+ if 1 <= prompt_index <= len(all_prompts):
131
+ # Get the prompt at the specified index (1-based to 0-based)
132
+ selected_prompt = all_prompts[prompt_index - 1]
133
+ # Use the already created namespaced_name to ensure consistency
134
+ await self._select_prompt(list_prompts_func, apply_prompt_func, agent, selected_prompt["namespaced_name"])
135
+ else:
136
+ rich_print(f"[red]Invalid prompt number: {prompt_index}. Valid range is 1-{len(all_prompts)}[/red]")
137
+ # Show the prompt list for convenience
138
+ await self._list_prompts(list_prompts_func, agent)
139
+ else:
140
+ # Use the name-based selection
141
+ await self._select_prompt(list_prompts_func, apply_prompt_func, agent, prompt_name)
118
142
  continue
119
143
 
120
144
  # Skip further processing if command was handled
@@ -131,42 +155,119 @@ class InteractivePrompt:
131
155
 
132
156
  return result
133
157
 
134
- async def _list_prompts(self, list_prompts_func, agent_name) -> None:
158
+ async def _get_all_prompts(self, list_prompts_func, agent_name):
135
159
  """
136
- List available prompts for an agent.
137
-
160
+ Get a list of all available prompts.
161
+
138
162
  Args:
139
163
  list_prompts_func: Function to get available prompts
140
164
  agent_name: Name of the agent
165
+
166
+ Returns:
167
+ List of prompt info dictionaries, sorted by server and name
141
168
  """
142
- from rich import print as rich_print
143
-
144
169
  try:
145
- # Directly call the list_prompts function for this agent
146
- rich_print(f"\n[bold]Fetching prompts for agent [cyan]{agent_name}[/cyan]...[/bold]")
147
-
148
- prompt_servers = await list_prompts_func(agent_name)
170
+ # Pass None instead of agent_name to get prompts from all servers
171
+ # the agent_name parameter should never be used as a server name
172
+ prompt_servers = await list_prompts_func(None)
173
+ all_prompts = []
149
174
 
150
175
  # Process the returned prompt servers
151
176
  if prompt_servers:
152
- found_prompts = False
177
+ # First collect all prompts
153
178
  for server_name, prompts_info in prompt_servers.items():
154
179
  if prompts_info and hasattr(prompts_info, "prompts") and prompts_info.prompts:
155
- rich_print(f"\n[bold cyan]{server_name}:[/bold cyan]")
156
180
  for prompt in prompts_info.prompts:
157
- rich_print(f" {prompt.name}")
158
- found_prompts = True
181
+ # Use the SEP constant for proper namespacing
182
+ all_prompts.append({
183
+ "server": server_name,
184
+ "name": prompt.name,
185
+ "namespaced_name": f"{server_name}{SEP}{prompt.name}",
186
+ "description": getattr(prompt, "description", "No description"),
187
+ "arg_count": len(getattr(prompt, "arguments", [])),
188
+ "arguments": getattr(prompt, "arguments", [])
189
+ })
159
190
  elif isinstance(prompts_info, list) and prompts_info:
160
- rich_print(f"\n[bold cyan]{server_name}:[/bold cyan]")
161
191
  for prompt in prompts_info:
162
192
  if isinstance(prompt, dict) and "name" in prompt:
163
- rich_print(f" {prompt['name']}")
193
+ all_prompts.append({
194
+ "server": server_name,
195
+ "name": prompt["name"],
196
+ "namespaced_name": f"{server_name}{SEP}{prompt['name']}",
197
+ "description": prompt.get("description", "No description"),
198
+ "arg_count": len(prompt.get("arguments", [])),
199
+ "arguments": prompt.get("arguments", [])
200
+ })
164
201
  else:
165
- rich_print(f" {prompt}")
166
- found_prompts = True
202
+ all_prompts.append({
203
+ "server": server_name,
204
+ "name": str(prompt),
205
+ "namespaced_name": f"{server_name}{SEP}{str(prompt)}",
206
+ "description": "No description",
207
+ "arg_count": 0,
208
+ "arguments": []
209
+ })
210
+
211
+ # Sort prompts by server and name for consistent ordering
212
+ all_prompts.sort(key=lambda p: (p["server"], p["name"]))
213
+
214
+ return all_prompts
215
+
216
+ except Exception as e:
217
+ import traceback
218
+
219
+ from rich import print as rich_print
220
+ rich_print(f"[red]Error getting prompts: {e}[/red]")
221
+ rich_print(f"[dim]{traceback.format_exc()}[/dim]")
222
+ return []
223
+
224
+ async def _list_prompts(self, list_prompts_func, agent_name) -> None:
225
+ """
226
+ List available prompts for an agent.
227
+
228
+ Args:
229
+ list_prompts_func: Function to get available prompts
230
+ agent_name: Name of the agent
231
+ """
232
+ from rich import print as rich_print
233
+ from rich.console import Console
234
+ from rich.table import Table
167
235
 
168
- if not found_prompts:
169
- rich_print("[yellow]No prompts available[/yellow]")
236
+ console = Console()
237
+
238
+ try:
239
+ # Directly call the list_prompts function for this agent
240
+ rich_print(f"\n[bold]Fetching prompts for agent [cyan]{agent_name}[/cyan]...[/bold]")
241
+
242
+ # Get all prompts using the helper function - pass None as server name
243
+ # to get prompts from all available servers
244
+ all_prompts = await self._get_all_prompts(list_prompts_func, None)
245
+
246
+ if all_prompts:
247
+ # Create a table for better display
248
+ table = Table(title="Available MCP Prompts")
249
+ table.add_column("#", justify="right", style="cyan")
250
+ table.add_column("Server", style="green")
251
+ table.add_column("Prompt Name", style="bright_blue")
252
+ table.add_column("Description")
253
+ table.add_column("Args", justify="center")
254
+
255
+ # Add prompts to table
256
+ for i, prompt in enumerate(all_prompts):
257
+ table.add_row(
258
+ str(i + 1),
259
+ prompt["server"],
260
+ prompt["name"],
261
+ prompt["description"],
262
+ str(prompt["arg_count"])
263
+ )
264
+
265
+ console.print(table)
266
+
267
+ # Add usage instructions
268
+ rich_print("\n[bold]Usage:[/bold]")
269
+ rich_print(" • Use [cyan]/prompt <number>[/cyan] to select a prompt by number")
270
+ rich_print(" • Or use [cyan]/prompts[/cyan] to open the prompt selection UI")
170
271
  else:
171
272
  rich_print("[yellow]No prompts available[/yellow]")
172
273
  except Exception as e:
@@ -192,7 +293,9 @@ class InteractivePrompt:
192
293
  try:
193
294
  # Get all available prompts directly from the list_prompts function
194
295
  rich_print(f"\n[bold]Fetching prompts for agent [cyan]{agent_name}[/cyan]...[/bold]")
195
- prompt_servers = await list_prompts_func(agent_name)
296
+ # IMPORTANT: list_prompts_func gets MCP server prompts, not agent prompts
297
+ # So we pass None to get prompts from all servers, not using agent_name as server name
298
+ prompt_servers = await list_prompts_func(None)
196
299
 
197
300
  if not prompt_servers:
198
301
  rich_print("[yellow]No prompts available for this agent[/yellow]")
@@ -242,8 +345,8 @@ class InteractivePrompt:
242
345
  else:
243
346
  optional_args.append(name)
244
347
 
245
- # Create namespaced version
246
- namespaced_name = f"{server_name}-{prompt_name}"
348
+ # Create namespaced version using the consistent separator
349
+ namespaced_name = f"{server_name}{SEP}{prompt_name}"
247
350
 
248
351
  # Add to collection
249
352
  all_prompts.append(
@@ -410,12 +513,13 @@ class InteractivePrompt:
410
513
  arg_values[arg_name] = arg_value
411
514
 
412
515
  # Apply the prompt
516
+ namespaced_name = selected_prompt["namespaced_name"]
413
517
  rich_print(
414
- f"\n[bold]Applying prompt [cyan]{selected_prompt['namespaced_name']}[/cyan]...[/bold]"
518
+ f"\n[bold]Applying prompt [cyan]{namespaced_name}[/cyan]...[/bold]"
415
519
  )
416
520
 
417
521
  # Call apply_prompt function with the prompt name and arguments
418
- await apply_prompt_func(selected_prompt["namespaced_name"], arg_values, agent_name)
522
+ await apply_prompt_func(namespaced_name, arg_values, agent_name)
419
523
 
420
524
  except Exception as e:
421
525
  import traceback
@@ -32,6 +32,7 @@ from mcp_agent.llm.sampling_format_converter import (
32
32
  ProviderFormatConverter,
33
33
  )
34
34
  from mcp_agent.logging.logger import get_logger
35
+ from mcp_agent.mcp.helpers.content_helpers import get_text
35
36
  from mcp_agent.mcp.interfaces import (
36
37
  AugmentedLLMProtocol,
37
38
  ModelT,
@@ -147,8 +148,11 @@ class AugmentedLLM(ContextDependent, AugmentedLLMProtocol, Generic[MessageParamT
147
148
  """Apply the prompt and return the result as a Pydantic model, or None if coercion fails"""
148
149
  try:
149
150
  result: PromptMessageMultipart = await self.generate(prompt, request_params)
150
- json_data = from_json(result.first_text().strip(), allow_partial=True)
151
+ final_generation = get_text(result.content[-1]) or ""
152
+ await self.show_assistant_message(final_generation)
153
+ json_data = from_json(final_generation, allow_partial=True)
151
154
  validated_model = model.model_validate(json_data)
155
+
152
156
  return cast("ModelT", validated_model), Prompt.assistant(json_data)
153
157
  except Exception as e:
154
158
  logger = get_logger(__name__)
@@ -11,6 +11,7 @@ from mcp_agent.llm.providers.augmented_llm_anthropic import AnthropicAugmentedLL
11
11
  from mcp_agent.llm.providers.augmented_llm_deepseek import DeepSeekAugmentedLLM
12
12
  from mcp_agent.llm.providers.augmented_llm_generic import GenericAugmentedLLM
13
13
  from mcp_agent.llm.providers.augmented_llm_openai import OpenAIAugmentedLLM
14
+ from mcp_agent.llm.providers.augmented_llm_openrouter import OpenRouterAugmentedLLM
14
15
  from mcp_agent.mcp.interfaces import AugmentedLLMProtocol
15
16
 
16
17
  # from mcp_agent.workflows.llm.augmented_llm_deepseek import DeekSeekAugmentedLLM
@@ -23,6 +24,7 @@ LLMClass = Union[
23
24
  Type[PassthroughLLM],
24
25
  Type[PlaybackLLM],
25
26
  Type[DeepSeekAugmentedLLM],
27
+ Type[OpenRouterAugmentedLLM],
26
28
  ]
27
29
 
28
30
 
@@ -34,6 +36,7 @@ class Provider(Enum):
34
36
  FAST_AGENT = auto()
35
37
  DEEPSEEK = auto()
36
38
  GENERIC = auto()
39
+ OPENROUTER = auto()
37
40
 
38
41
 
39
42
  class ReasoningEffort(Enum):
@@ -63,6 +66,7 @@ class ModelFactory:
63
66
  "fast-agent": Provider.FAST_AGENT,
64
67
  "deepseek": Provider.DEEPSEEK,
65
68
  "generic": Provider.GENERIC,
69
+ "openrouter": Provider.OPENROUTER,
66
70
  }
67
71
 
68
72
  # Mapping of effort strings to enum values
@@ -120,6 +124,7 @@ class ModelFactory:
120
124
  Provider.FAST_AGENT: PassthroughLLM,
121
125
  Provider.DEEPSEEK: DeepSeekAugmentedLLM,
122
126
  Provider.GENERIC: GenericAugmentedLLM,
127
+ Provider.OPENROUTER: OpenRouterAugmentedLLM,
123
128
  }
124
129
 
125
130
  # Mapping of special model names to their specific LLM classes