fastworkflow 2.16.0__tar.gz → 2.17.1__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.

Potentially problematic release.


This version of fastworkflow might be problematic. Click here for more details.

Files changed (182) hide show
  1. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/PKG-INFO +1 -1
  2. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/what_can_i_do.py +12 -7
  3. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/chat_session.py +1 -0
  4. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/command_context_model.py +73 -7
  5. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/command_metadata_api.py +56 -6
  6. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/run/__main__.py +0 -6
  7. fastworkflow-2.17.1/fastworkflow/run_fastapi_mcp/README.md +300 -0
  8. fastworkflow-2.17.1/fastworkflow/run_fastapi_mcp/conversation_store.py +391 -0
  9. fastworkflow-2.17.1/fastworkflow/run_fastapi_mcp/jwt_manager.py +256 -0
  10. fastworkflow-2.17.1/fastworkflow/run_fastapi_mcp/main.py +1206 -0
  11. fastworkflow-2.17.1/fastworkflow/run_fastapi_mcp/mcp_specific.py +103 -0
  12. fastworkflow-2.17.1/fastworkflow/run_fastapi_mcp/redoc_2_standalone_html.py +40 -0
  13. fastworkflow-2.17.1/fastworkflow/run_fastapi_mcp/utils.py +427 -0
  14. fastworkflow-2.17.1/fastworkflow/utils/__init__.py +0 -0
  15. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/pyproject.toml +3 -1
  16. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/LICENSE +0 -0
  17. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/README.md +0 -0
  18. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/.DS_Store +0 -0
  19. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/__init__.py +0 -0
  20. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/_commands/.gitkeep +0 -0
  21. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/_workflows/__init__.py +0 -0
  22. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/_workflows/command_metadata_extraction/__init__.py +0 -0
  23. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/_workflows/command_metadata_extraction/_commands/ErrorCorrection/abort.py +0 -0
  24. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/_workflows/command_metadata_extraction/_commands/ErrorCorrection/you_misunderstood.py +0 -0
  25. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/go_up.py +0 -0
  26. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/reset_context.py +0 -0
  27. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/what_is_current_context.py +0 -0
  28. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/_workflows/command_metadata_extraction/_commands/__init__.py +0 -0
  29. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/_workflows/command_metadata_extraction/_commands/wildcard.py +0 -0
  30. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/_workflows/command_metadata_extraction/command_context_model.json +0 -0
  31. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/_workflows/command_metadata_extraction/intent_detection.py +0 -0
  32. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/_workflows/command_metadata_extraction/parameter_extraction.py +0 -0
  33. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/__main__.py +0 -0
  34. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/ast_class_extractor.py +0 -0
  35. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/class_analysis_structures.py +0 -0
  36. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/cli_specification.md +0 -0
  37. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/command_dependency_resolver.py +0 -0
  38. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/command_file_generator.py +0 -0
  39. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/command_file_template.py +0 -0
  40. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/command_import_utils.py +0 -0
  41. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/command_stub_generator.py +0 -0
  42. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/context_folder_generator.py +0 -0
  43. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/context_model_generator.py +0 -0
  44. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/dependency_manager.py +0 -0
  45. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/dir_scanner.py +0 -0
  46. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/documentation_generator.py +0 -0
  47. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/genai_postprocessor.py +0 -0
  48. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/inheritance_block_regenerator.py +0 -0
  49. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/libcst_transformers.py +0 -0
  50. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/navigator_stub_generator.py +0 -0
  51. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/pydantic_model_generator.py +0 -0
  52. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/build/utterance_generator.py +0 -0
  53. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/cache_matching.py +0 -0
  54. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/cli.py +0 -0
  55. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/command_directory.py +0 -0
  56. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/command_executor.py +0 -0
  57. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/command_interfaces.py +0 -0
  58. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/command_routing.py +0 -0
  59. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/docs/context_modules_prd.txt +0 -0
  60. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/extended_workflow_example/README.md +0 -0
  61. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/extended_workflow_example/_commands/WorkItem/get_status.py +0 -0
  62. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/extended_workflow_example/_commands/generate_report.py +0 -0
  63. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/extended_workflow_example/_commands/startup.py +0 -0
  64. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/extended_workflow_example/simple_workflow_template.json +0 -0
  65. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/extended_workflow_example/workflow_inheritance_model.json +0 -0
  66. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/fastworkflow.env +0 -0
  67. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/fastworkflow.passwords.env +0 -0
  68. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/hello_world/_commands/README.md +0 -0
  69. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/hello_world/_commands/add_two_numbers.py +0 -0
  70. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/hello_world/_commands/context_inheritance_model.json +0 -0
  71. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/hello_world/application/add_two_numbers.py +0 -0
  72. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_1/_commands/context_inheritance_model.json +0 -0
  73. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_1/_commands/send_message.py +0 -0
  74. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_1/application/send_message.py +0 -0
  75. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_2/_commands/User/send_message.py +0 -0
  76. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_2/_commands/context_inheritance_model.json +0 -0
  77. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_2/_commands/startup.py +0 -0
  78. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_2/application/user.py +0 -0
  79. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_3/_commands/PremiumUser/send_priority_message.py +0 -0
  80. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_3/_commands/User/send_message.py +0 -0
  81. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_3/_commands/context_inheritance_model.json +0 -0
  82. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_3/_commands/initialize_user.py +0 -0
  83. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_3/application/user.py +0 -0
  84. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/_ChatRoom.py +0 -0
  85. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/add_user.py +0 -0
  86. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/broadcast_message.py +0 -0
  87. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/get_current_user.py +0 -0
  88. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/list_users.py +0 -0
  89. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/set_current_user.py +0 -0
  90. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_4/_commands/PremiumUser/_PremiumUser.py +0 -0
  91. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_4/_commands/PremiumUser/send_priority_message.py +0 -0
  92. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_4/_commands/User/_User.py +0 -0
  93. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_4/_commands/User/send_message.py +0 -0
  94. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_4/_commands/context_inheritance_model.json +0 -0
  95. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_4/_commands/set_root_context.py +0 -0
  96. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_4/application/chatroom.py +0 -0
  97. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_4/application/user.py +0 -0
  98. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_4/context_hierarchy_model.json +0 -0
  99. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/messaging_app_4/startup_action.json +0 -0
  100. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/_commands/calculate.py +0 -0
  101. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/_commands/cancel_pending_order.py +0 -0
  102. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/_commands/exchange_delivered_order_items.py +0 -0
  103. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/_commands/find_user_id_by_email.py +0 -0
  104. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/_commands/find_user_id_by_name_zip.py +0 -0
  105. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/_commands/get_order_details.py +0 -0
  106. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/_commands/get_product_details.py +0 -0
  107. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/_commands/get_user_details.py +0 -0
  108. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/_commands/list_all_product_types.py +0 -0
  109. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/_commands/modify_pending_order_address.py +0 -0
  110. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/_commands/modify_pending_order_items.py +0 -0
  111. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/_commands/modify_pending_order_payment.py +0 -0
  112. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/_commands/modify_user_address.py +0 -0
  113. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/_commands/return_delivered_order_items.py +0 -0
  114. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/_commands/transfer_to_human_agents.py +0 -0
  115. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/context_inheritance_model.json +0 -0
  116. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/retail_data/__init__.py +0 -0
  117. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/retail_data/orders.json +0 -0
  118. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/retail_data/products.json +0 -0
  119. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/retail_data/users.json +0 -0
  120. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/tools/calculate.py +0 -0
  121. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/tools/cancel_pending_order.py +0 -0
  122. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/tools/exchange_delivered_order_items.py +0 -0
  123. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/tools/find_user_id_by_email.py +0 -0
  124. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/tools/find_user_id_by_name_zip.py +0 -0
  125. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/tools/get_order_details.py +0 -0
  126. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/tools/get_product_details.py +0 -0
  127. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/tools/get_user_details.py +0 -0
  128. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/tools/list_all_product_types.py +0 -0
  129. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/tools/modify_pending_order_address.py +0 -0
  130. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/tools/modify_pending_order_items.py +0 -0
  131. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/tools/modify_pending_order_payment.py +0 -0
  132. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/tools/modify_user_address.py +0 -0
  133. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/tools/return_delivered_order_items.py +0 -0
  134. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/tools/think.py +0 -0
  135. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/tools/tool.py +0 -0
  136. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/tools/transfer_to_human_agents.py +0 -0
  137. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/retail_workflow/workflow_description.txt +0 -0
  138. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/simple_workflow_template/__init__.py +0 -0
  139. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/_WorkItem.py +0 -0
  140. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/add_child_workitem.py +0 -0
  141. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/get_status.py +0 -0
  142. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/go_to_workitem.py +0 -0
  143. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/mark_as_complete.py +0 -0
  144. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/move_to_first_child_workitem.py +0 -0
  145. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/move_to_last_child_workitem.py +0 -0
  146. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/move_to_next_workitem.py +0 -0
  147. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/move_to_previous_workitem.py +0 -0
  148. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/remove_all_child_workitems.py +0 -0
  149. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/remove_child_workitem.py +0 -0
  150. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/show_schema.py +0 -0
  151. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/simple_workflow_template/_commands/startup.py +0 -0
  152. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/simple_workflow_template/application/__init__.py +0 -0
  153. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/simple_workflow_template/application/workitem.py +0 -0
  154. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/simple_workflow_template/simple_workflow_template.json +0 -0
  155. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/examples/simple_workflow_template/startup_action.json +0 -0
  156. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/mcp_server.py +0 -0
  157. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/model_pipeline_training.py +0 -0
  158. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/refine/__main__.py +0 -0
  159. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/run/__init__.py +0 -0
  160. {fastworkflow-2.16.0/fastworkflow/train → fastworkflow-2.17.1/fastworkflow/run_fastapi_mcp}/__init__.py +0 -0
  161. {fastworkflow-2.16.0/fastworkflow/utils → fastworkflow-2.17.1/fastworkflow/train}/__init__.py +0 -0
  162. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/train/__main__.py +0 -0
  163. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/train/generate_synthetic.py +0 -0
  164. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/user_message_queues.py +0 -0
  165. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/utils/command_dependency_graph.py +0 -0
  166. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/utils/context_utils.py +0 -0
  167. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/utils/dspy_cache_utils.py +0 -0
  168. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/utils/dspy_logger.py +0 -0
  169. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/utils/dspy_utils.py +0 -0
  170. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/utils/env.py +0 -0
  171. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/utils/fuzzy_match.py +0 -0
  172. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/utils/generate_param_examples.py +0 -0
  173. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/utils/logging.py +0 -0
  174. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/utils/parameterize_func_decorator.py +0 -0
  175. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/utils/pydantic_model_2_dspy_signature_class.py +0 -0
  176. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/utils/python_utils.py +0 -0
  177. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/utils/react.py +0 -0
  178. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/utils/signatures.py +0 -0
  179. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/utils/startup_progress.py +0 -0
  180. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/workflow.py +0 -0
  181. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/workflow_agent.py +0 -0
  182. {fastworkflow-2.16.0 → fastworkflow-2.17.1}/fastworkflow/workflow_inheritance_model.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fastworkflow
3
- Version: 2.16.0
3
+ Version: 2.17.1
4
4
  Summary: A framework for rapidly building large-scale, deterministic, interactive workflows with a fault-tolerant, conversational UX
5
5
  License: Apache-2.0
6
6
  Keywords: fastworkflow,ai,workflow,llm,openai
@@ -8,6 +8,7 @@ import json
8
8
 
9
9
  import fastworkflow
10
10
  from fastworkflow.train.generate_synthetic import generate_diverse_utterances
11
+ from fastworkflow.command_context_model import get_workflow_info
11
12
  from fastworkflow.command_metadata_api import CommandMetadataAPI
12
13
 
13
14
  class Signature:
@@ -139,23 +140,27 @@ class ResponseGenerator:
139
140
  with contextlib.suppress(Exception):
140
141
  if fastworkflow.chat_session:
141
142
  is_agent_mode = fastworkflow.chat_session.run_as_agent
142
-
143
+
143
144
  app_workflow = workflow.context["app_workflow"]
144
- response = CommandMetadataAPI.get_command_display_text(
145
+
146
+ # Get workflow definition
147
+ workflow_info = get_workflow_info(app_workflow.folderpath)
148
+ workflow_def_text = CommandMetadataAPI.get_workflow_definition_display_text(workflow_info)
149
+
150
+ # Get available commands in current context
151
+ commands_text = CommandMetadataAPI.get_command_display_text(
145
152
  subject_workflow_path=app_workflow.folderpath,
146
153
  cme_workflow_path=workflow.folderpath,
147
154
  active_context_name=app_workflow.current_command_context_name,
148
155
  for_agents=is_agent_mode,
149
156
  )
157
+
158
+ response = f"{workflow_def_text}\n\n{commands_text}"
150
159
 
151
- # Check if the NLU pipeline stage is intent detection
152
- success = False
153
160
  nlu_pipeline_stage = workflow.context.get(
154
161
  "NLU_Pipeline_Stage",
155
162
  fastworkflow.NLUPipelineStage.INTENT_DETECTION)
156
- if nlu_pipeline_stage == fastworkflow.NLUPipelineStage.INTENT_DETECTION:
157
- success = True
158
-
163
+ success = nlu_pipeline_stage == fastworkflow.NLUPipelineStage.INTENT_DETECTION
159
164
  return fastworkflow.CommandOutput(
160
165
  workflow_id=workflow.id,
161
166
  command_responses=[
@@ -495,6 +495,7 @@ class ChatSession:
495
495
  # Create CommandOutput with the agent's response
496
496
  command_response = fastworkflow.CommandResponse(response=result_text)
497
497
 
498
+ conversation_traces = None
498
499
  conversation_summary = message
499
500
  # Attach actions captured during agent execution as artifacts if available
500
501
  if os.path.exists("action.jsonl"):
@@ -2,11 +2,12 @@ from __future__ import annotations
2
2
 
3
3
  import json
4
4
  from dataclasses import dataclass, field
5
+ from typing import Any
6
+ import os
5
7
  from pathlib import Path
6
- from typing import Any, Optional, Type
7
8
 
8
9
  import fastworkflow
9
- from fastworkflow.command_directory import CommandDirectory, get_cached_command_directory
10
+ from fastworkflow.command_directory import get_cached_command_directory
10
11
  from fastworkflow.utils import python_utils
11
12
 
12
13
  """Utility for loading and traversing the single-file workflow command context model.
@@ -152,10 +153,10 @@ class CommandContextModel:
152
153
  hierarchy_model_path = Path(self._workflow_path) / "context_hierarchy_model.json"
153
154
  if not hierarchy_model_path.is_file():
154
155
  return {}
155
-
156
+
156
157
  with hierarchy_model_path.open("r") as f:
157
158
  hierarchy_data = json.load(f)
158
-
159
+
159
160
  return hierarchy_data
160
161
 
161
162
  def _resolve_ancestry(self, hierarchy: dict[str, dict[str, list[str]]]) -> None:
@@ -205,10 +206,10 @@ class CommandContextModel:
205
206
  all_ancestors.add(parent)
206
207
  grandparents = self.get_ancestor_contexts(parent, visiting.copy(), _hierarchy)
207
208
  all_ancestors.update(grandparents)
208
-
209
+
209
210
  final_ancestors = sorted(list(all_ancestors))
210
211
  self._resolved_ancestors[context_name] = final_ancestors
211
-
212
+
212
213
  visiting.remove(context_name)
213
214
 
214
215
  return final_ancestors
@@ -228,7 +229,7 @@ class CommandContextModel:
228
229
  # or by being part of a command inheritance structure. If it's not
229
230
  # in _command_contexts, it's an unknown/invalid context.
230
231
  raise CommandContextModelValidationError(f"Context '{context_name}' not found in model.")
231
-
232
+
232
233
  if visiting is None:
233
234
  visiting = set()
234
235
 
@@ -294,3 +295,68 @@ class CommandContextModel:
294
295
  return getattr(module, context_metadata.context_class, None)
295
296
  else:
296
297
  return None
298
+
299
+
300
+ # ---------------------------------------------------------------------
301
+ # Workflow info helper (module-level)
302
+ # ---------------------------------------------------------------------
303
+
304
+ def get_workflow_info(chat_session_or_path: fastworkflow.ChatSession | str) -> dict[str, Any]:
305
+ """
306
+ Return workflow-level metadata for the active workflow in the given chat session or workflow path.
307
+
308
+ Shape:
309
+ {
310
+ "workflow_name": str,
311
+ "available_contexts": list[str],
312
+ "context_inheritance_model": dict,
313
+ "context_hierarchy_model": dict
314
+ }
315
+
316
+ Notes:
317
+ - available_contexts are derived from CommandContextModel.load(workflow_path)
318
+ so they reflect filesystem + inheritance.
319
+ - current context and purpose/description are intentionally omitted.
320
+ - Raw JSON for inheritance (from _commands/context_inheritance_model.json)
321
+ and hierarchy (from context_hierarchy_model.json) is returned verbatim when present.
322
+ """
323
+ if isinstance(chat_session_or_path, str):
324
+ workflow_path_str = chat_session_or_path
325
+ else:
326
+ workflow_path_str = chat_session_or_path.get_active_workflow().folderpath
327
+ workflow_name = os.path.basename(os.path.abspath(workflow_path_str))
328
+
329
+ available_contexts: list[str]
330
+ inheritance_json: dict[str, Any] = {}
331
+ hierarchy_json: dict[str, Any] = {}
332
+
333
+ try:
334
+ # Derive contexts via consolidated model
335
+ context_model = CommandContextModel.load(workflow_path_str)
336
+ # Do not normalize names beyond keeping what the model exposes
337
+ available_contexts = sorted([key for key in context_model._command_contexts.keys() if key != 'IntentDetection'])
338
+ except Exception:
339
+ available_contexts = ["/"]
340
+
341
+ # Load raw context inheritance model (if present)
342
+ try:
343
+ inheritance_path = Path(workflow_path_str) / "_commands" / "context_inheritance_model.json"
344
+ if inheritance_path.is_file():
345
+ inheritance_json = json.loads(inheritance_path.read_text())
346
+ except Exception:
347
+ inheritance_json = {}
348
+
349
+ # Load raw context hierarchy model (if present)
350
+ try:
351
+ hierarchy_path = Path(workflow_path_str) / "context_hierarchy_model.json"
352
+ if hierarchy_path.is_file():
353
+ hierarchy_json = json.loads(hierarchy_path.read_text())
354
+ except Exception:
355
+ hierarchy_json = {}
356
+
357
+ return {
358
+ "workflow_name": workflow_name,
359
+ "available_contexts": available_contexts,
360
+ "context_inheritance_model": inheritance_json,
361
+ "context_hierarchy_model": hierarchy_json,
362
+ }
@@ -480,6 +480,58 @@ class CommandMetadataAPI:
480
480
 
481
481
  return f"{indent_str}{value}"
482
482
 
483
+ @staticmethod
484
+ def get_workflow_definition_display_text(workflow_info: Dict[str, Any]) -> str:
485
+ """
486
+ Convert workflow definition dict to human-readable text display.
487
+
488
+ Args:
489
+ workflow_info: Workflow info dict from get_workflow_info()
490
+ {
491
+ "workflow_name": str,
492
+ "available_contexts": list[str],
493
+ "context_inheritance_model": dict,
494
+ "context_hierarchy_model": dict
495
+ }
496
+
497
+ Returns:
498
+ Human-readable text representation of workflow definition
499
+ """
500
+ lines: List[str] = ["Workflow Definition:"]
501
+
502
+ # Workflow name
503
+ if workflow_name := workflow_info.get("workflow_name"):
504
+ lines.append(f" name: {workflow_name}")
505
+
506
+ # Available contexts
507
+ if contexts := workflow_info.get("available_contexts"):
508
+ lines.append(" available_contexts:")
509
+ for ctx in contexts:
510
+ display_name = "global" if ctx == "*" else ctx
511
+ lines.append(f" - {display_name}")
512
+
513
+ # Context inheritance (if present and non-empty)
514
+ if inheritance := workflow_info.get("context_inheritance_model"):
515
+ if inheritance: # Only show if not empty dict
516
+ lines.append(" context_inheritance:")
517
+ for ctx, parents in sorted(inheritance.items()):
518
+ if parents: # Only show if has parents
519
+ display_ctx = "global" if ctx == "*" else ctx
520
+ parent_list = ", ".join(["global" if p == "*" else p for p in parents])
521
+ lines.append(f" {display_ctx}: [{parent_list}]")
522
+
523
+ # Context hierarchy (if present and non-empty)
524
+ if hierarchy := workflow_info.get("context_hierarchy_model"):
525
+ if hierarchy: # Only show if not empty dict
526
+ lines.append(" context_hierarchy:")
527
+ for parent, children in sorted(hierarchy.items()):
528
+ if children: # Only show if has children
529
+ display_parent = "global" if parent == "*" else parent
530
+ children_list = ", ".join(["global" if c == "*" else c for c in children])
531
+ lines.append(f" {display_parent}: [{children_list}]")
532
+
533
+ return "\n".join(lines)
534
+
483
535
  @staticmethod
484
536
  def get_command_display_text(
485
537
  subject_workflow_path: str,
@@ -499,7 +551,7 @@ class CommandMetadataAPI:
499
551
  cme_workflow_path=cme_workflow_path,
500
552
  active_context_name=active_context_name,
501
553
  )
502
-
554
+
503
555
  # Build minimal context info (inheritance/containment if available)
504
556
  context_info: Dict[str, Any] = {
505
557
  "name": active_context_name,
@@ -529,10 +581,8 @@ class CommandMetadataAPI:
529
581
  empty_display = CommandMetadataAPI._prune_empty(empty_display, remove_keys={"default"})
530
582
  rendered = CommandMetadataAPI._to_yaml_like(empty_display, omit_command_name=False)
531
583
  # Ensure a visible header is present
532
- header = "Commands available:"
533
- if not rendered.strip():
534
- return header
535
- return f"{header}\n{rendered}"
584
+ header = "Commands available in the current context:"
585
+ return f"{header}\n{rendered}" if rendered.strip() else header
536
586
 
537
587
  # Build the combined display by stitching per-command strings while keeping
538
588
  # a single "Commands available:" header and blank lines between commands
@@ -553,7 +603,7 @@ class CommandMetadataAPI:
553
603
  empty_display = CommandMetadataAPI._prune_empty(empty_display, remove_keys={"default"})
554
604
  return CommandMetadataAPI._to_yaml_like(empty_display, omit_command_name=False)
555
605
 
556
- combined_lines: List[str] = ["Commands available:"]
606
+ combined_lines: List[str] = [f"Commands available in the current context ({context_info['display_name']}):"]
557
607
  for idx, text in enumerate(parts):
558
608
  lines = text.splitlines()
559
609
  if idx > 0:
@@ -19,7 +19,6 @@ def run_main(args):
19
19
  from rich.table import Table
20
20
  from rich.text import Text
21
21
  from rich.console import Group
22
- from rich.live import Live
23
22
  from rich.spinner import Spinner
24
23
  from prompt_toolkit import PromptSession
25
24
  from prompt_toolkit.patch_stdout import patch_stdout
@@ -27,7 +26,6 @@ def run_main(args):
27
26
 
28
27
  import fastworkflow
29
28
  from fastworkflow.utils.logging import logger
30
- from fastworkflow.command_executor import CommandExecutor
31
29
 
32
30
  # Progress bar helper
33
31
  from fastworkflow.utils.startup_progress import StartupProgress
@@ -146,10 +144,6 @@ def run_main(args):
146
144
  # ------------------------------------------------------------------
147
145
  # Startup progress bar ------------------------------------------------
148
146
  # ------------------------------------------------------------------
149
- command_info_root = os.path.join(args.workflow_path, "___command_info")
150
- subdir_count = 0
151
- if os.path.isdir(command_info_root):
152
- subdir_count = len([d for d in os.listdir(command_info_root) if os.path.isdir(os.path.join(command_info_root, d))])
153
147
 
154
148
  # 3 coarse CLI steps + per-directory warm-up (handled inside ChatSession) + 1 global warm-up
155
149
  StartupProgress.begin(total=3)
@@ -0,0 +1,300 @@
1
+ # FastWorkflow FastAPI + MCP Service
2
+
3
+ HTTP + MCP interface for FastWorkflow workflows with synchronous and streaming execution.
4
+
5
+ ## Overview
6
+
7
+ This service exposes FastWorkflow workflows as REST endpoints and as MCP tools, enabling clients to:
8
+ - Initialize workflow sessions per user
9
+ - Submit natural language queries (agent mode)
10
+ - Execute deterministic commands (assistant mode)
11
+ - Perform explicit actions
12
+ - Manage conversations with persistent history
13
+ - Collect feedback on interactions
14
+
15
+ ## Architecture
16
+
17
+ - **Session Management**: In-memory `UserSessionManager` with per-user `ChatSession` instances
18
+ - **Persistence**: Rdict-backed conversation storage (one DB file per user)
19
+ - **Execution**: Synchronous turn-based processing with queue-based communication
20
+ - **Tracing**: Traces are collected by default and included in synchronous responses or emitted incrementally during streaming
21
+ - **Streaming (REST)**: `/invoke_agent_stream` supports Streamable HTTP via NDJSON by default and SSE when requested in REST initialize
22
+ - **Streaming (MCP)**: MCP transport mounted at `/mcp`; tools stream partials via MCP transport by default or SSE when requested in MCP initialize
23
+
24
+ See [`docs/fastworkflow_fastapi_spec.md`](../../docs/fastworkflow_fastapi_spec.md) and [`docs/fastworkflow_fastapi_architecture.md`](../../docs/fastworkflow_fastapi_architecture.md) for complete specification and design.
25
+
26
+ ## Running the Service
27
+
28
+ ### Start Server (REST + MCP)
29
+
30
+ ```bash
31
+ uvicorn services.run_fastapi.main:app --host 0.0.0.0 --port 8000
32
+
33
+ # MCP (auto-mounted via fastapi_mcp) will be available at `/mcp`.
34
+ ```
35
+
36
+ ### Access Documentation
37
+
38
+ Once running, visit:
39
+ - **Swagger UI**: http://localhost:8000/docs
40
+ - **ReDoc**: http://localhost:8000/redoc
41
+ - **Health Check**: http://localhost:8000/
42
+
43
+ ## Environment Variables
44
+
45
+ Configure in your environment (loaded at process startup via CLI args or env load):
46
+
47
+ | Variable | Description | Required | Default |
48
+ |----------|-------------|----------|---------|
49
+ | `SPEEDDICT_FOLDERNAME` | Base folder for workflow contexts and conversation storage | Yes | - |
50
+
51
+ Notes:
52
+ - Conversation DBs are stored under `SPEEDDICT_FOLDERNAME/user_conversations` (directory is auto-created).
53
+ - `/conversations` now accepts a `limit` query parameter (default `20`).
54
+ - Shutdown waits up to 30 seconds for active turns (hard-coded).
55
+
56
+ ## API Endpoints (REST)
57
+
58
+ ### `POST /initialize`
59
+ Initialize a session for a user. Workflow configuration is loaded at server startup from CLI args/env.
60
+
61
+ **Request:**
62
+ ```json
63
+ {
64
+ "user_id": "user-123",
65
+ "stream_format": "ndjson" // optional: "ndjson" | "sse" (default "ndjson")
66
+ }
67
+ ```
68
+
69
+ **Important Notes:**
70
+ - `stream_format` controls REST streaming format for `/invoke_agent_stream` (NDJSON default, SSE optional).
71
+ - Workflow configuration is loaded at server startup from CLI args/env, not from the request.
72
+
73
+ **Response:**
74
+ ```json
75
+ {
76
+ "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
77
+ "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
78
+ "token_type": "bearer",
79
+ "expires_in": 3600
80
+ }
81
+
82
+ ```
83
+
84
+ ### `POST /invoke_agent`
85
+ Submit a natural language query for agentic processing.
86
+
87
+ **Request:**
88
+ ```json
89
+ {
90
+ "user_id": "user-123",
91
+ "user_query": "find orders for user 42",
92
+ "timeout_seconds": 60
93
+ }
94
+ ```
95
+
96
+ **Response:**
97
+ ```json
98
+ {
99
+ "command_responses": [
100
+ {
101
+ "response": "Found 3 orders for user 42",
102
+ "success": true,
103
+ "artifacts": {},
104
+ "next_actions": [],
105
+ "recommendations": []
106
+ }
107
+ ],
108
+ "workflow_name": "default_workflow",
109
+ "context": "Order management context",
110
+ "command_name": "find_orders",
111
+ "command_parameters": "user_id=42",
112
+ "traces": [...]
113
+ }
114
+ ```
115
+
116
+ ### `POST /invoke_assistant`
117
+ Submit a query for deterministic/assistant execution (no planning).
118
+
119
+ Same request/response format as `/invoke_agent`.
120
+
121
+ ### `POST /perform_action`
122
+ Execute a specific workflow action directly (bypasses parameter extraction).
123
+
124
+ **Request:**
125
+ ```json
126
+ {
127
+ "action": {
128
+ "command_name": "find_orders",
129
+ "parameters": {"user_id": 42}
130
+ },
131
+ "timeout_seconds": 60
132
+ }
133
+ ```
134
+
135
+ **Response:**
136
+ Same format as `/invoke_agent` (CommandOutput with traces).
137
+
138
+ ### `POST /invoke_agent_stream`
139
+ Stream trace events and final `CommandOutput` via Streamable HTTP:
140
+ - NDJSON (default; `Content-Type: application/x-ndjson`)
141
+ - SSE (when REST `stream_format` is set to `sse`; `Content-Type: text/event-stream`)
142
+
143
+ ## Conversation Management (REST)
144
+
145
+ ### `POST /new_conversation`
146
+ Persist current conversation and start a new one.
147
+
148
+ **Request:**
149
+ ```json
150
+ {}
151
+ ```
152
+
153
+ **Response:**
154
+ ```json
155
+ {
156
+ "status": "ok"
157
+ }
158
+ ```
159
+
160
+ ### `GET /conversations?user_id={user_id}&limit=20`
161
+ List conversations for a user (most recent first). `limit` is optional; defaults to `20`.
162
+
163
+ **Response:**
164
+ ```json
165
+ [
166
+ {
167
+ "conversation_id": 1,
168
+ "topic": "Order Management",
169
+ "summary": "...",
170
+ "created_at": 1234567890000,
171
+ "updated_at": 1234567890000
172
+ }
173
+ ]
174
+ ```
175
+
176
+ ### `POST /activate_conversation`
177
+ Switch to a different conversation by ID.
178
+
179
+ **Request:**
180
+ ```json
181
+ {
182
+ "conversation_id": 1
183
+ }
184
+ ```
185
+
186
+ ### `POST /post_feedback`
187
+ Attach feedback to the latest turn.
188
+
189
+ **Request:**
190
+ ```json
191
+ {
192
+ "binary_or_numeric_score": true,
193
+ "nl_feedback": "Helpful response"
194
+ }
195
+ ```
196
+
197
+ At least one of `binary_or_numeric_score` or `nl_feedback` must be provided.
198
+
199
+ ## Admin Endpoints (REST-only; not exposed via MCP)
200
+
201
+ ### `POST /admin/dump_all_conversations`
202
+ Export all conversations to JSONL.
203
+
204
+ **Request:**
205
+ ```json
206
+ {
207
+ "output_folder": "/path/to/export"
208
+ }
209
+ ```
210
+
211
+ **Response:**
212
+ ```json
213
+ {
214
+ "file_path": "/path/to/export/all_conversations_1234567890.jsonl"
215
+ }
216
+ ```
217
+
218
+ ## Usage Examples
219
+
220
+ ### REST initialize
221
+ ```python
222
+ import requests
223
+
224
+ resp = requests.post("http://localhost:8000/initialize", json={
225
+ "user_id": "alice",
226
+ "stream_format": "ndjson"
227
+ })
228
+ print(resp.json()) # {"access_token": "...", "refresh_token": "...", "token_type": "bearer", "expires_in": 3600}
229
+ ```
230
+
231
+ ### REST sync invoke
232
+ ```python
233
+ # First get a token from /initialize
234
+ init_resp = requests.post("http://localhost:8000/initialize", json={
235
+ "user_id": "alice",
236
+ "stream_format": "ndjson"
237
+ })
238
+ token_data = init_resp.json()
239
+ access_token = token_data["access_token"]
240
+
241
+ # Then use the token for authenticated requests
242
+ resp = requests.post("http://localhost:8000/invoke_agent",
243
+ headers={"Authorization": f"Bearer {access_token}"},
244
+ json={
245
+ "user_query": "list all users",
246
+ "timeout_seconds": 30
247
+ }
248
+ )
249
+ result = resp.json()
250
+ print(result["command_responses"])
251
+ print(result.get("traces"))
252
+ ```
253
+
254
+ ### MCP Quickstart
255
+ - Mount is available at `/mcp` (auto-exposed by fastapi_mcp).
256
+ - MCP clients use pre-configured long-lived access tokens (generated via `/admin/generate_mcp_token`).
257
+ - No need for initialize or refresh_token tools in MCP context.
258
+
259
+ MCP invoke agent (streaming):
260
+
261
+ ```bash
262
+ # NDJSON (default for MCP)
263
+ curl -N -X POST http://localhost:8000/mcp/invoke_agent \
264
+ -H 'Content-Type: application/json' \
265
+ -H 'Accept: application/x-ndjson' \
266
+ -H 'Authorization: Bearer <your-mcp-token>' \
267
+ -d '{"user_query":"find orders for user 42","timeout_seconds":60}'
268
+
269
+ # SSE (if stream_format was set to "sse" during MCP setup)
270
+ curl -N -X POST http://localhost:8000/mcp/invoke_agent \
271
+ -H 'Content-Type: application/json' \
272
+ -H 'Accept: text/event-stream' \
273
+ -H 'Authorization: Bearer <your-mcp-token>' \
274
+ -d '{"user_query":"find orders for user 42","timeout_seconds":60}'
275
+ ```
276
+
277
+ ### MCP Prompts
278
+ The MCP mount registers two prompts for client discovery:
279
+ - `format-command(intent, metadata)`
280
+ - `clarify-params(error_message, metadata)`
281
+
282
+ ## Testing
283
+
284
+ See [`tests/`](../../tests/) for unit and integration tests.
285
+
286
+ **Key test scenarios:**
287
+ - SessionManager concurrency and lifecycle
288
+ - Env loading from files only
289
+ - CLI argument validation (startup_command vs startup_action)
290
+ - Timeout behavior (504 on no output)
291
+ - Conversation persistence and listing
292
+ - Feedback attachment
293
+
294
+ ## Future Enhancements
295
+
296
+ - Session TTL and eviction policy
297
+ - Richer observability and structured logging
298
+ - Security: workflow path allow-list, authn/z
299
+ - Conversation history restoration on session resume
300
+