fast-agent-mcp 0.2.5__tar.gz → 0.2.7__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 (159) hide show
  1. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/.gitignore +1 -0
  2. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/PKG-INFO +3 -4
  3. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/README.md +2 -3
  4. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/pyproject.toml +1 -1
  5. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/agents/agent.py +1 -1
  6. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/agents/base_agent.py +13 -1
  7. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/agents/workflow/chain_agent.py +9 -11
  8. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/agents/workflow/evaluator_optimizer.py +6 -0
  9. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/agents/workflow/orchestrator_agent.py +6 -1
  10. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/agents/workflow/parallel_agent.py +7 -1
  11. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/agents/workflow/router_agent.py +27 -5
  12. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/cli/commands/setup.py +2 -2
  13. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/config.py +3 -3
  14. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/core/agent_app.py +8 -19
  15. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/core/agent_types.py +1 -0
  16. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/core/direct_decorators.py +2 -1
  17. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/core/direct_factory.py +1 -1
  18. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/core/fastagent.py +2 -0
  19. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/core/interactive_prompt.py +1 -1
  20. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/augmented_llm.py +5 -1
  21. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/providers/augmented_llm_anthropic.py +15 -49
  22. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/providers/augmented_llm_openai.py +19 -40
  23. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/interfaces.py +5 -0
  24. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/mcp_connection_manager.py +5 -3
  25. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp_server/agent_server.py +8 -8
  26. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp_server_registry.py +2 -1
  27. fast_agent_mcp-0.2.5/src/mcp_agent/mcp/mcp_activity.py +0 -18
  28. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/LICENSE +0 -0
  29. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/examples/data-analysis/analysis-campaign.py +0 -0
  30. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/examples/data-analysis/analysis.py +0 -0
  31. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/examples/data-analysis/fastagent.config.yaml +0 -0
  32. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
  33. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/examples/researcher/fastagent.config.yaml +0 -0
  34. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/examples/researcher/researcher-eval.py +0 -0
  35. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/examples/researcher/researcher-imp.py +0 -0
  36. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/examples/researcher/researcher.py +0 -0
  37. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/examples/workflows/chaining.py +0 -0
  38. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/examples/workflows/evaluator.py +0 -0
  39. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/examples/workflows/fastagent.config.yaml +0 -0
  40. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/examples/workflows/graded_report.md +0 -0
  41. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/examples/workflows/human_input.py +0 -0
  42. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/examples/workflows/orchestrator.py +0 -0
  43. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/examples/workflows/parallel.py +0 -0
  44. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/examples/workflows/router.py +0 -0
  45. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/examples/workflows/short_story.md +0 -0
  46. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/examples/workflows/short_story.txt +0 -0
  47. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/__init__.py +0 -0
  48. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/agents/__init__.py +0 -0
  49. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/agents/workflow/__init__.py +0 -0
  50. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/agents/workflow/orchestrator_models.py +0 -0
  51. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/agents/workflow/orchestrator_prompts.py +0 -0
  52. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/app.py +0 -0
  53. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/cli/__init__.py +0 -0
  54. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/cli/__main__.py +0 -0
  55. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/cli/commands/bootstrap.py +0 -0
  56. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/cli/commands/config.py +0 -0
  57. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/cli/main.py +0 -0
  58. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/cli/terminal.py +0 -0
  59. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/console.py +0 -0
  60. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/context.py +0 -0
  61. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/context_dependent.py +0 -0
  62. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/core/__init__.py +0 -0
  63. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/core/enhanced_prompt.py +0 -0
  64. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/core/error_handling.py +0 -0
  65. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/core/exceptions.py +0 -0
  66. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/core/mcp_content.py +0 -0
  67. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/core/prompt.py +0 -0
  68. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/core/request_params.py +0 -0
  69. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/core/validation.py +0 -0
  70. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/event_progress.py +0 -0
  71. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/executor/__init__.py +0 -0
  72. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/executor/decorator_registry.py +0 -0
  73. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/executor/executor.py +0 -0
  74. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/executor/task_registry.py +0 -0
  75. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/executor/temporal.py +0 -0
  76. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/executor/workflow.py +0 -0
  77. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/executor/workflow_signal.py +0 -0
  78. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/human_input/__init__.py +0 -0
  79. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/human_input/handler.py +0 -0
  80. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/human_input/types.py +0 -0
  81. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/__init__.py +0 -0
  82. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/augmented_llm_passthrough.py +0 -0
  83. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/augmented_llm_playback.py +0 -0
  84. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/memory.py +0 -0
  85. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/model_factory.py +0 -0
  86. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/prompt_utils.py +0 -0
  87. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/providers/__init__.py +0 -0
  88. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/providers/anthropic_utils.py +0 -0
  89. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/providers/augmented_llm_deepseek.py +0 -0
  90. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/providers/augmented_llm_generic.py +0 -0
  91. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/providers/multipart_converter_anthropic.py +0 -0
  92. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/providers/multipart_converter_openai.py +0 -0
  93. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/providers/openai_multipart.py +0 -0
  94. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/providers/openai_utils.py +0 -0
  95. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/providers/sampling_converter_anthropic.py +0 -0
  96. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/providers/sampling_converter_openai.py +0 -0
  97. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/sampling_converter.py +0 -0
  98. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/llm/sampling_format_converter.py +0 -0
  99. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/logging/__init__.py +0 -0
  100. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/logging/events.py +0 -0
  101. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/logging/json_serializer.py +0 -0
  102. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/logging/listeners.py +0 -0
  103. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/logging/logger.py +0 -0
  104. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/logging/rich_progress.py +0 -0
  105. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/logging/tracing.py +0 -0
  106. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/logging/transport.py +0 -0
  107. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/__init__.py +0 -0
  108. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/gen_client.py +0 -0
  109. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/helpers/__init__.py +0 -0
  110. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/helpers/content_helpers.py +0 -0
  111. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/logger_textio.py +0 -0
  112. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/mcp_agent_client_session.py +0 -0
  113. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/mcp_aggregator.py +0 -0
  114. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/mime_utils.py +0 -0
  115. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/prompt_message_multipart.py +0 -0
  116. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/prompt_render.py +0 -0
  117. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/prompt_serialization.py +0 -0
  118. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/prompts/__init__.py +0 -0
  119. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/prompts/__main__.py +0 -0
  120. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/prompts/prompt_constants.py +0 -0
  121. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/prompts/prompt_helpers.py +0 -0
  122. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/prompts/prompt_load.py +0 -0
  123. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/prompts/prompt_server.py +0 -0
  124. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/prompts/prompt_template.py +0 -0
  125. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/resource_utils.py +0 -0
  126. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp/sampling.py +0 -0
  127. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/mcp_server/__init__.py +0 -0
  128. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/progress_display.py +0 -0
  129. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/data-analysis/analysis-campaign.py +0 -0
  130. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/data-analysis/analysis.py +0 -0
  131. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/data-analysis/fastagent.config.yaml +0 -0
  132. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
  133. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/in_dev/agent_build.py +0 -0
  134. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/in_dev/slides.py +0 -0
  135. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/internal/agent.py +0 -0
  136. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/internal/fastagent.config.yaml +0 -0
  137. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/internal/history_transfer.py +0 -0
  138. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/internal/job.py +0 -0
  139. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/internal/prompt_category.py +0 -0
  140. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/internal/prompt_sizing.py +0 -0
  141. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/internal/sizer.py +0 -0
  142. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/internal/social.py +0 -0
  143. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/prompting/__init__.py +0 -0
  144. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/prompting/agent.py +0 -0
  145. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/prompting/fastagent.config.yaml +0 -0
  146. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/prompting/image_server.py +0 -0
  147. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/prompting/work_with_image.py +0 -0
  148. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/researcher/fastagent.config.yaml +0 -0
  149. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/researcher/researcher-eval.py +0 -0
  150. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/researcher/researcher-imp.py +0 -0
  151. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/researcher/researcher.py +0 -0
  152. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/workflows/chaining.py +0 -0
  153. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/workflows/evaluator.py +0 -0
  154. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/workflows/fastagent.config.yaml +0 -0
  155. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/workflows/human_input.py +0 -0
  156. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/workflows/orchestrator.py +0 -0
  157. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/workflows/parallel.py +0 -0
  158. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/resources/examples/workflows/router.py +0 -0
  159. {fast_agent_mcp-0.2.5 → fast_agent_mcp-0.2.7}/src/mcp_agent/ui/console_display.py +0 -0
@@ -190,3 +190,4 @@ tests/integration/workflow/orchestrator/fastagent.jsonl
190
190
  fastagent.jsonl
191
191
  tests/integration/resources/fastagent.jsonl
192
192
  fastagent.jsonl
193
+ tests/e2e/workflow/weather_location.txt
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fast-agent-mcp
3
- Version: 0.2.5
3
+ Version: 0.2.7
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.5"
3
+ version = "0.2.7"
4
4
  description = "Define, Prompt and Test MCP enabled Agents and Workflows"
5
5
  readme = "README.md"
6
6
  license = { file = "LICENSE" }
@@ -66,7 +66,7 @@ class Agent(BaseAgent):
66
66
  agent_name_str = str(self.name)
67
67
 
68
68
  # Create agent_types dictionary with just this agent
69
- agent_types = {agent_name_str: getattr(self.config, "agent_type", "Agent")}
69
+ agent_types = {agent_name_str: self.agent_type}
70
70
 
71
71
  # Create the interactive prompt
72
72
  prompt = InteractivePrompt(agent_types=agent_types)
@@ -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]
@@ -622,6 +622,18 @@ class BaseAgent(MCPAggregator, AgentProtocol):
622
622
  response = await self.generate(prompts, request_params)
623
623
  return response.first_text()
624
624
 
625
+ @property
626
+ def agent_type(self) -> str:
627
+ """
628
+ Return the type of this agent.
629
+
630
+ This is used for display purposes in the interactive prompt and other UI elements.
631
+
632
+ Returns:
633
+ String representing the agent type
634
+ """
635
+ return self.config.agent_type
636
+
625
637
  @property
626
638
  def message_history(self) -> List[PromptMessageMultipart]:
627
639
  """
@@ -9,8 +9,9 @@ from typing import Any, List, Optional, Tuple, Type
9
9
 
10
10
  from mcp.types import TextContent
11
11
 
12
- from mcp_agent.agents.agent import Agent, AgentConfig
12
+ from mcp_agent.agents.agent import Agent
13
13
  from mcp_agent.agents.base_agent import BaseAgent
14
+ from mcp_agent.core.agent_types import AgentConfig, AgentType
14
15
  from mcp_agent.core.prompt import Prompt
15
16
  from mcp_agent.core.request_params import RequestParams
16
17
  from mcp_agent.mcp.interfaces import ModelT
@@ -23,6 +24,12 @@ class ChainAgent(BaseAgent):
23
24
  Passes the output of each agent to the next agent in the chain.
24
25
  """
25
26
 
27
+ # TODO -- consider adding "repeat" mode
28
+ @property
29
+ def agent_type(self) -> str:
30
+ """Return the type of this agent."""
31
+ return AgentType.CHAIN.value
32
+
26
33
  def __init__(
27
34
  self,
28
35
  config: AgentConfig,
@@ -64,20 +71,11 @@ class ChainAgent(BaseAgent):
64
71
  # # Get the original user message (last message in the list)
65
72
  user_message = multipart_messages[-1] if multipart_messages else None
66
73
 
67
- # # If no user message, return an error
68
- # if not user_message:
69
- # return PromptMessageMultipart(
70
- # role="assistant",
71
- # content=[TextContent(type="text", text="No input message provided.")],
72
- # )
73
-
74
- # Initialize messages with the input
75
-
76
74
  if not self.cumulative:
77
75
  response: PromptMessageMultipart = await self.agents[0].generate(multipart_messages)
78
76
  # Process the rest of the agents in the chain
79
77
  for agent in self.agents[1:]:
80
- next_message = Prompt.user(response.content[0].text)
78
+ next_message = Prompt.user(*response.content)
81
79
  response = await agent.generate([next_message])
82
80
 
83
81
  return response
@@ -14,6 +14,7 @@ from pydantic import BaseModel, Field
14
14
 
15
15
  from mcp_agent.agents.agent import Agent
16
16
  from mcp_agent.agents.base_agent import BaseAgent
17
+ from mcp_agent.core.agent_types import AgentType
17
18
  from mcp_agent.core.exceptions import AgentConfigError
18
19
  from mcp_agent.core.prompt import Prompt
19
20
  from mcp_agent.core.request_params import RequestParams
@@ -63,6 +64,11 @@ class EvaluatorOptimizerAgent(BaseAgent):
63
64
  for refinement, continuing until a quality threshold is reached or a maximum
64
65
  number of refinement cycles is completed.
65
66
  """
67
+
68
+ @property
69
+ def agent_type(self) -> str:
70
+ """Return the type of this agent."""
71
+ return AgentType.EVALUATOR_OPTIMIZER.value
66
72
 
67
73
  def __init__(
68
74
  self,
@@ -27,7 +27,7 @@ from mcp_agent.agents.workflow.orchestrator_prompts import (
27
27
  SYNTHESIZE_PLAN_PROMPT_TEMPLATE,
28
28
  TASK_PROMPT_TEMPLATE,
29
29
  )
30
- from mcp_agent.core.agent_types import AgentConfig
30
+ from mcp_agent.core.agent_types import AgentConfig, AgentType
31
31
  from mcp_agent.core.exceptions import AgentConfigError
32
32
  from mcp_agent.core.prompt import Prompt
33
33
  from mcp_agent.core.request_params import RequestParams
@@ -46,6 +46,11 @@ class OrchestratorAgent(BaseAgent):
46
46
  to specialized worker agents, synthesizing their results into a cohesive output.
47
47
  Supports both full planning and iterative planning modes.
48
48
  """
49
+
50
+ @property
51
+ def agent_type(self) -> str:
52
+ """Return the type of this agent."""
53
+ return AgentType.ORCHESTRATOR.value
49
54
 
50
55
  def __init__(
51
56
  self,
@@ -3,8 +3,9 @@ from typing import Any, List, Optional, Tuple
3
3
 
4
4
  from mcp.types import TextContent
5
5
 
6
- from mcp_agent.agents.agent import Agent, AgentConfig
6
+ from mcp_agent.agents.agent import Agent
7
7
  from mcp_agent.agents.base_agent import BaseAgent
8
+ from mcp_agent.core.agent_types import AgentConfig, AgentType
8
9
  from mcp_agent.core.request_params import RequestParams
9
10
  from mcp_agent.mcp.interfaces import ModelT
10
11
  from mcp_agent.mcp.prompt_message_multipart import PromptMessageMultipart
@@ -17,6 +18,11 @@ class ParallelAgent(BaseAgent):
17
18
  This workflow performs both the fan-out and fan-in operations using LLMs.
18
19
  From the user's perspective, an input is specified and the output is returned.
19
20
  """
21
+
22
+ @property
23
+ def agent_type(self) -> str:
24
+ """Return the type of this agent."""
25
+ return AgentType.PARALLEL.value
20
26
 
21
27
  def __init__(
22
28
  self,
@@ -12,7 +12,7 @@ from pydantic import BaseModel
12
12
 
13
13
  from mcp_agent.agents.agent import Agent
14
14
  from mcp_agent.agents.base_agent import BaseAgent
15
- from mcp_agent.core.agent_types import AgentConfig
15
+ from mcp_agent.core.agent_types import AgentConfig, AgentType
16
16
  from mcp_agent.core.exceptions import AgentConfigError
17
17
  from mcp_agent.core.prompt import Prompt
18
18
  from mcp_agent.core.request_params import RequestParams
@@ -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. 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
 
@@ -88,6 +105,11 @@ class RouterAgent(BaseAgent):
88
105
  then dispatches the request to that agent and returns the response.
89
106
  """
90
107
 
108
+ @property
109
+ def agent_type(self) -> str:
110
+ """Return the type of this agent."""
111
+ return AgentType.ROUTER.value
112
+
91
113
  def __init__(
92
114
  self,
93
115
  config: AgentConfig,
@@ -73,7 +73,7 @@ mcp:
73
73
 
74
74
  GITIGNORE_TEMPLATE = """
75
75
  # FastAgent secrets file
76
- fastagent-secrets.yaml
76
+ fastagent.secrets.yaml
77
77
 
78
78
  # Python
79
79
  __pycache__/
@@ -215,7 +215,7 @@ def init(
215
215
  if "fastagent.secrets.yaml" in created:
216
216
  console.print("\n[yellow]Important:[/yellow] Remember to:")
217
217
  console.print(
218
- "1. Add your API keys to fastagent-secrets.yaml or set OPENAI_API_KEY and ANTHROPIC_API_KEY environment variables"
218
+ "1. Add your API keys to fastagent.secrets.yaml or set OPENAI_API_KEY and ANTHROPIC_API_KEY environment variables"
219
219
  )
220
220
  console.print(
221
221
  "2. Keep fastagent.secrets.yaml secure and never commit it to version control"
@@ -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
 
@@ -69,7 +69,7 @@ class AgentApp:
69
69
  if message:
70
70
  return await self._agent(agent_name).send(message)
71
71
 
72
- return await self.interactive(agent_name=agent_name, default_prompt=default_prompt)
72
+ return await self.interactive(agent=agent_name, default_prompt=default_prompt)
73
73
 
74
74
  async def send(
75
75
  self,
@@ -220,9 +220,9 @@ class AgentApp:
220
220
  """
221
221
  Deprecated - use interactive() instead.
222
222
  """
223
- return await self.interactive(agent_name=agent_name, default_prompt=default_prompt)
223
+ return await self.interactive(agent=agent_name, default_prompt=default_prompt)
224
224
 
225
- async def interactive(self, agent_name: str | None = None, default_prompt: str = "") -> str:
225
+ async def interactive(self, agent: str | None = None, default_prompt: str = "") -> str:
226
226
  """
227
227
  Interactive prompt for sending messages with advanced features.
228
228
 
@@ -235,11 +235,11 @@ class AgentApp:
235
235
  """
236
236
 
237
237
  # Get the default agent name if none specified
238
- if agent_name:
238
+ if agent:
239
239
  # Validate that this agent exists
240
- if agent_name not in self._agents:
241
- raise ValueError(f"Agent '{agent_name}' not found")
242
- target_name = agent_name
240
+ if agent not in self._agents:
241
+ raise ValueError(f"Agent '{agent}' not found")
242
+ target_name = agent
243
243
  else:
244
244
  # Use the first agent's name as default
245
245
  target_name = next(iter(self._agents.keys()))
@@ -248,18 +248,7 @@ class AgentApp:
248
248
  # The agent's prompt method doesn't fully support switching between agents
249
249
 
250
250
  # Create agent_types dictionary mapping agent names to their types
251
- agent_types = {}
252
- for name, agent in self._agents.items():
253
- # Determine agent type if possible
254
- agent_type = "Agent" # Default type
255
-
256
- # Try to get the type from the agent directly
257
- if hasattr(agent, "agent_type"):
258
- agent_type = agent.agent_type
259
- elif hasattr(agent, "config") and hasattr(agent.config, "agent_type"):
260
- agent_type = agent.config.agent_type
261
-
262
- agent_types[name] = agent_type
251
+ agent_types = {name: agent.agent_type for name, agent in self._agents.items()}
263
252
 
264
253
  # Create the interactive prompt
265
254
  prompt = InteractivePrompt(agent_types=agent_types)
@@ -33,6 +33,7 @@ class AgentConfig:
33
33
  use_history: bool = True
34
34
  default_request_params: RequestParams | None = None
35
35
  human_input: bool = False
36
+ agent_type: str = AgentType.BASIC.value
36
37
 
37
38
  def __post_init__(self) -> None:
38
39
  """Ensure default_request_params exists with proper history setting"""
@@ -269,6 +269,7 @@ def router(
269
269
  *,
270
270
  agents: List[str],
271
271
  instruction: Optional[str] = None,
272
+ servers: List[str] = [],
272
273
  model: Optional[str] = None,
273
274
  use_history: bool = False,
274
275
  request_params: RequestParams | None = None,
@@ -301,7 +302,7 @@ def router(
301
302
  AgentType.ROUTER,
302
303
  name=name,
303
304
  instruction=instruction or default_instruction,
304
- servers=[], # Routers don't connect to servers directly
305
+ servers=servers,
305
306
  model=model,
306
307
  use_history=use_history,
307
308
  request_params=request_params,
@@ -236,7 +236,7 @@ async def create_agents_by_type(
236
236
  config=config,
237
237
  context=app_instance.context,
238
238
  agents=router_agents,
239
- routing_instruction=agent_data.get("routing_instruction"),
239
+ routing_instruction=agent_data.get("instruction"),
240
240
  )
241
241
  await router.initialize()
242
242
 
@@ -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
 
@@ -77,7 +77,7 @@ class InteractivePrompt:
77
77
  if agent not in available_agents:
78
78
  raise ValueError(f"No agent named '{agent}'")
79
79
 
80
- # Create agent_types dictionary if not provided
80
+ # Ensure we track available agents in a set for fast lookup
81
81
  available_agents_set = set(available_agents)
82
82
 
83
83
  result = ""
@@ -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(), 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__)
@@ -1,5 +1,7 @@
1
1
  import os
2
- from typing import TYPE_CHECKING, List, Type
2
+ from typing import TYPE_CHECKING, List
3
+
4
+ from mcp.types import EmbeddedResource, ImageContent, TextContent
3
5
 
4
6
  from mcp_agent.core.prompt import Prompt
5
7
  from mcp_agent.llm.providers.multipart_converter_anthropic import (
@@ -28,13 +30,11 @@ from mcp.types import (
28
30
  CallToolRequest,
29
31
  CallToolRequestParams,
30
32
  )
31
- from pydantic_core import from_json
32
33
  from rich.text import Text
33
34
 
34
35
  from mcp_agent.core.exceptions import ProviderKeyError
35
36
  from mcp_agent.llm.augmented_llm import (
36
37
  AugmentedLLM,
37
- ModelT,
38
38
  RequestParams,
39
39
  )
40
40
  from mcp_agent.logging.logger import get_logger
@@ -69,14 +69,15 @@ class AnthropicAugmentedLLM(AugmentedLLM[MessageParam, Message]):
69
69
  use_history=True,
70
70
  )
71
71
 
72
- def _base_url(self) -> str:
72
+ def _base_url(self) -> str | None:
73
+ assert self.context.config
73
74
  return self.context.config.anthropic.base_url if self.context.config.anthropic else None
74
75
 
75
76
  async def generate_internal(
76
77
  self,
77
78
  message_param,
78
79
  request_params: RequestParams | None = None,
79
- ):
80
+ ) -> list[TextContent | ImageContent | EmbeddedResource]:
80
81
  """
81
82
  Process a query using an LLM and available tools.
82
83
  Override this method to use a different LLM.
@@ -113,7 +114,7 @@ class AnthropicAugmentedLLM(AugmentedLLM[MessageParam, Message]):
113
114
  for tool in tool_list.tools
114
115
  ]
115
116
 
116
- responses: List[Message] = []
117
+ responses: List[TextContent | ImageContent | EmbeddedResource] = []
117
118
 
118
119
  model = self.default_request_params.model
119
120
 
@@ -175,7 +176,8 @@ class AnthropicAugmentedLLM(AugmentedLLM[MessageParam, Message]):
175
176
 
176
177
  response_as_message = self.convert_message_to_message_param(response)
177
178
  messages.append(response_as_message)
178
- responses.append(response)
179
+ if response.content[0].type == "text":
180
+ responses.append(TextContent(type="text", text=response.content[0].text))
179
181
 
180
182
  if response.stop_reason == "end_turn":
181
183
  message_text = ""
@@ -255,6 +257,7 @@ class AnthropicAugmentedLLM(AugmentedLLM[MessageParam, Message]):
255
257
 
256
258
  # Add each result to our collection
257
259
  tool_results.append((tool_use_id, result))
260
+ responses.extend(result.content)
258
261
 
259
262
  messages.append(AnthropicConverter.create_tool_results_message(tool_results))
260
263
 
@@ -295,41 +298,22 @@ class AnthropicAugmentedLLM(AugmentedLLM[MessageParam, Message]):
295
298
 
296
299
  return api_key
297
300
 
298
- async def generate_str(
301
+ async def generate_messages(
299
302
  self,
300
303
  message_param,
301
304
  request_params: RequestParams | None = None,
302
- ) -> str:
305
+ ) -> PromptMessageMultipart:
303
306
  """
304
307
  Process a query using an LLM and available tools.
305
308
  The default implementation uses Claude as the LLM.
306
309
  Override this method to use a different LLM.
307
310
 
308
311
  """
309
-
310
- responses: List[Message] = await self.generate_internal(
312
+ res = await self.generate_internal(
311
313
  message_param=message_param,
312
314
  request_params=request_params,
313
315
  )
314
-
315
- final_text: List[str] = []
316
-
317
- # Process all responses and collect all text content
318
- for response in responses:
319
- # Extract text content from each message
320
- message_text = ""
321
- for content in response.content:
322
- if content.type == "text":
323
- # Extract text from text blocks
324
- message_text += content.text
325
-
326
- # Only append non-empty text
327
- if message_text:
328
- final_text.append(message_text)
329
-
330
- # TODO -- make tool detail inclusion behaviour configurable
331
- # Join all collected text
332
- return "\n".join(final_text)
316
+ return Prompt.assistant(*res)
333
317
 
334
318
  async def _apply_prompt_provider_specific(
335
319
  self,
@@ -352,30 +336,12 @@ class AnthropicAugmentedLLM(AugmentedLLM[MessageParam, Message]):
352
336
  if last_message.role == "user":
353
337
  self.logger.debug("Last message in prompt is from user, generating assistant response")
354
338
  message_param = AnthropicConverter.convert_to_anthropic(last_message)
355
- return Prompt.assistant(await self.generate_str(message_param, request_params))
339
+ return await self.generate_messages(message_param, request_params)
356
340
  else:
357
341
  # For assistant messages: Return the last message content as text
358
342
  self.logger.debug("Last message in prompt is from assistant, returning it directly")
359
343
  return last_message
360
344
 
361
- async def generate_structured(
362
- self,
363
- message: str,
364
- response_model: Type[ModelT],
365
- request_params: RequestParams | None = None,
366
- ) -> ModelT:
367
- # TODO -- simiar to the OAI version, we should create a tool call for the expected schema
368
- response = await self.generate_str(
369
- message=message,
370
- request_params=request_params,
371
- )
372
- # Don't try to parse if we got no response
373
- if not response:
374
- self.logger.error("No response from generate_str")
375
- return None
376
-
377
- return response_model.model_validate(from_json(response, allow_partial=True))
378
-
379
345
  @classmethod
380
346
  def convert_message_to_message_param(cls, message: Message, **kwargs) -> MessageParam:
381
347
  """Convert a response object to an input parameter object to allow LLM calls to be chained."""