fastworkflow 2.17.8__tar.gz → 2.17.9__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 (184) hide show
  1. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/PKG-INFO +1 -1
  2. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/_workflows/command_metadata_extraction/parameter_extraction.py +81 -5
  3. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/chat_session.py +14 -3
  4. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/command_metadata_api.py +50 -0
  5. fastworkflow-2.17.9/fastworkflow/intent_clarification_agent.py +132 -0
  6. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/train/__main__.py +1 -1
  7. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/utils/react.py +13 -1
  8. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/utils/signatures.py +49 -31
  9. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/workflow_agent.py +78 -4
  10. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/pyproject.toml +1 -1
  11. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/LICENSE +0 -0
  12. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/README.md +0 -0
  13. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/.DS_Store +0 -0
  14. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/__init__.py +0 -0
  15. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/_commands/.gitkeep +0 -0
  16. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/_workflows/__init__.py +0 -0
  17. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/_workflows/command_metadata_extraction/__init__.py +0 -0
  18. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/_workflows/command_metadata_extraction/_commands/ErrorCorrection/abort.py +0 -0
  19. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/_workflows/command_metadata_extraction/_commands/ErrorCorrection/you_misunderstood.py +0 -0
  20. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/go_up.py +0 -0
  21. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/reset_context.py +0 -0
  22. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/what_can_i_do.py +0 -0
  23. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/what_is_current_context.py +0 -0
  24. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/_workflows/command_metadata_extraction/_commands/__init__.py +0 -0
  25. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/_workflows/command_metadata_extraction/_commands/wildcard.py +0 -0
  26. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/_workflows/command_metadata_extraction/command_context_model.json +0 -0
  27. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/_workflows/command_metadata_extraction/intent_detection.py +0 -0
  28. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/__main__.py +0 -0
  29. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/ast_class_extractor.py +0 -0
  30. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/class_analysis_structures.py +0 -0
  31. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/cli_specification.md +0 -0
  32. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/command_dependency_resolver.py +0 -0
  33. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/command_file_generator.py +0 -0
  34. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/command_file_template.py +0 -0
  35. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/command_import_utils.py +0 -0
  36. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/command_stub_generator.py +0 -0
  37. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/context_folder_generator.py +0 -0
  38. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/context_model_generator.py +0 -0
  39. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/dependency_manager.py +0 -0
  40. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/dir_scanner.py +0 -0
  41. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/documentation_generator.py +0 -0
  42. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/genai_postprocessor.py +0 -0
  43. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/inheritance_block_regenerator.py +0 -0
  44. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/libcst_transformers.py +0 -0
  45. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/navigator_stub_generator.py +0 -0
  46. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/pydantic_model_generator.py +0 -0
  47. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/build/utterance_generator.py +0 -0
  48. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/cache_matching.py +0 -0
  49. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/cli.py +0 -0
  50. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/command_context_model.py +0 -0
  51. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/command_directory.py +0 -0
  52. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/command_executor.py +0 -0
  53. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/command_interfaces.py +0 -0
  54. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/command_routing.py +0 -0
  55. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/docs/context_modules_prd.txt +0 -0
  56. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/extended_workflow_example/README.md +0 -0
  57. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/extended_workflow_example/_commands/WorkItem/get_status.py +0 -0
  58. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/extended_workflow_example/_commands/generate_report.py +0 -0
  59. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/extended_workflow_example/_commands/startup.py +0 -0
  60. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/extended_workflow_example/simple_workflow_template.json +0 -0
  61. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/extended_workflow_example/workflow_inheritance_model.json +0 -0
  62. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/fastworkflow.env +0 -0
  63. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/fastworkflow.passwords.env +0 -0
  64. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/hello_world/_commands/README.md +0 -0
  65. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/hello_world/_commands/add_two_numbers.py +0 -0
  66. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/hello_world/_commands/context_inheritance_model.json +0 -0
  67. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/hello_world/application/add_two_numbers.py +0 -0
  68. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_1/_commands/context_inheritance_model.json +0 -0
  69. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_1/_commands/send_message.py +0 -0
  70. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_1/application/send_message.py +0 -0
  71. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_2/_commands/User/send_message.py +0 -0
  72. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_2/_commands/context_inheritance_model.json +0 -0
  73. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_2/_commands/startup.py +0 -0
  74. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_2/application/user.py +0 -0
  75. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_3/_commands/PremiumUser/send_priority_message.py +0 -0
  76. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_3/_commands/User/send_message.py +0 -0
  77. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_3/_commands/context_inheritance_model.json +0 -0
  78. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_3/_commands/initialize_user.py +0 -0
  79. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_3/application/user.py +0 -0
  80. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/_ChatRoom.py +0 -0
  81. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/add_user.py +0 -0
  82. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/broadcast_message.py +0 -0
  83. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/get_current_user.py +0 -0
  84. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/list_users.py +0 -0
  85. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/set_current_user.py +0 -0
  86. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_4/_commands/PremiumUser/_PremiumUser.py +0 -0
  87. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_4/_commands/PremiumUser/send_priority_message.py +0 -0
  88. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_4/_commands/User/_User.py +0 -0
  89. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_4/_commands/User/send_message.py +0 -0
  90. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_4/_commands/context_inheritance_model.json +0 -0
  91. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_4/_commands/set_root_context.py +0 -0
  92. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_4/application/chatroom.py +0 -0
  93. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_4/application/user.py +0 -0
  94. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_4/context_hierarchy_model.json +0 -0
  95. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/messaging_app_4/startup_action.json +0 -0
  96. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/_commands/calculate.py +0 -0
  97. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/_commands/cancel_pending_order.py +0 -0
  98. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/_commands/exchange_delivered_order_items.py +0 -0
  99. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/_commands/find_user_id_by_email.py +0 -0
  100. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/_commands/find_user_id_by_name_zip.py +0 -0
  101. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/_commands/get_order_details.py +0 -0
  102. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/_commands/get_product_details.py +0 -0
  103. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/_commands/get_user_details.py +0 -0
  104. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/_commands/list_all_product_types.py +0 -0
  105. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/_commands/modify_pending_order_address.py +0 -0
  106. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/_commands/modify_pending_order_items.py +0 -0
  107. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/_commands/modify_pending_order_payment.py +0 -0
  108. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/_commands/modify_user_address.py +0 -0
  109. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/_commands/return_delivered_order_items.py +0 -0
  110. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/_commands/transfer_to_human_agents.py +0 -0
  111. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/context_inheritance_model.json +0 -0
  112. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/retail_data/__init__.py +0 -0
  113. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/retail_data/orders.json +0 -0
  114. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/retail_data/products.json +0 -0
  115. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/retail_data/users.json +0 -0
  116. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/tools/calculate.py +0 -0
  117. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/tools/cancel_pending_order.py +0 -0
  118. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/tools/exchange_delivered_order_items.py +0 -0
  119. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/tools/find_user_id_by_email.py +0 -0
  120. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/tools/find_user_id_by_name_zip.py +0 -0
  121. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/tools/get_order_details.py +0 -0
  122. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/tools/get_product_details.py +0 -0
  123. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/tools/get_user_details.py +0 -0
  124. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/tools/list_all_product_types.py +0 -0
  125. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/tools/modify_pending_order_address.py +0 -0
  126. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/tools/modify_pending_order_items.py +0 -0
  127. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/tools/modify_pending_order_payment.py +0 -0
  128. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/tools/modify_user_address.py +0 -0
  129. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/tools/return_delivered_order_items.py +0 -0
  130. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/tools/think.py +0 -0
  131. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/tools/tool.py +0 -0
  132. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/tools/transfer_to_human_agents.py +0 -0
  133. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/retail_workflow/workflow_description.txt +0 -0
  134. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/simple_workflow_template/__init__.py +0 -0
  135. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/_WorkItem.py +0 -0
  136. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/add_child_workitem.py +0 -0
  137. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/get_status.py +0 -0
  138. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/go_to_workitem.py +0 -0
  139. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/mark_as_complete.py +0 -0
  140. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/move_to_first_child_workitem.py +0 -0
  141. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/move_to_last_child_workitem.py +0 -0
  142. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/move_to_next_workitem.py +0 -0
  143. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/move_to_previous_workitem.py +0 -0
  144. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/remove_all_child_workitems.py +0 -0
  145. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/remove_child_workitem.py +0 -0
  146. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/show_schema.py +0 -0
  147. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/simple_workflow_template/_commands/startup.py +0 -0
  148. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/simple_workflow_template/application/__init__.py +0 -0
  149. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/simple_workflow_template/application/workitem.py +0 -0
  150. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/simple_workflow_template/simple_workflow_template.json +0 -0
  151. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/examples/simple_workflow_template/startup_action.json +0 -0
  152. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/mcp_server.py +0 -0
  153. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/model_pipeline_training.py +0 -0
  154. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/refine/__main__.py +0 -0
  155. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/run/__init__.py +0 -0
  156. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/run/__main__.py +0 -0
  157. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/run_fastapi_mcp/README.md +0 -0
  158. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/run_fastapi_mcp/__init__.py +0 -0
  159. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/run_fastapi_mcp/__main__.py +0 -0
  160. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/run_fastapi_mcp/conversation_store.py +0 -0
  161. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/run_fastapi_mcp/jwt_manager.py +0 -0
  162. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/run_fastapi_mcp/mcp_specific.py +0 -0
  163. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/run_fastapi_mcp/redoc_2_standalone_html.py +0 -0
  164. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/run_fastapi_mcp/utils.py +0 -0
  165. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/train/__init__.py +0 -0
  166. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/train/generate_synthetic.py +0 -0
  167. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/user_message_queues.py +0 -0
  168. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/utils/__init__.py +0 -0
  169. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/utils/chat_adapter.py +0 -0
  170. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/utils/command_dependency_graph.py +0 -0
  171. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/utils/context_utils.py +0 -0
  172. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/utils/dspy_cache_utils.py +0 -0
  173. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/utils/dspy_logger.py +0 -0
  174. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/utils/dspy_utils.py +0 -0
  175. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/utils/env.py +0 -0
  176. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/utils/fuzzy_match.py +0 -0
  177. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/utils/generate_param_examples.py +0 -0
  178. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/utils/logging.py +0 -0
  179. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/utils/parameterize_func_decorator.py +0 -0
  180. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/utils/pydantic_model_2_dspy_signature_class.py +0 -0
  181. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/utils/python_utils.py +0 -0
  182. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/utils/startup_progress.py +0 -0
  183. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/workflow.py +0 -0
  184. {fastworkflow-2.17.8 → fastworkflow-2.17.9}/fastworkflow/workflow_inheritance_model.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fastworkflow
3
- Version: 2.17.8
3
+ Version: 2.17.9
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
@@ -1,8 +1,10 @@
1
1
  import contextlib
2
2
  import sys
3
+ import re
3
4
  from typing import Dict, List, Optional
4
5
 
5
6
  from pydantic import BaseModel
7
+ from pydantic_core import PydanticUndefined
6
8
 
7
9
  import fastworkflow
8
10
  from fastworkflow.utils.logging import logger
@@ -59,11 +61,29 @@ class ParameterExtraction:
59
61
  if stored_params:
60
62
  new_params = self._extract_and_merge_missing_parameters(stored_params, self.command)
61
63
  else:
62
- # Otherwise use the LLM-based extraction
63
- new_params = input_for_param_extraction.extract_parameters(
64
- command_parameters_class,
65
- self.command_name,
66
- app_workflow_folderpath)
64
+ # Check if we're in agentic mode (not assistant mode command)
65
+ is_agentic_mode = (
66
+ "is_assistant_mode_command" not in self.cme_workflow.context
67
+ and "run_as_agent" in self.app_workflow.context
68
+ and self.app_workflow.context["run_as_agent"]
69
+ )
70
+
71
+ if is_agentic_mode:
72
+ # Try regex-based extraction first in agentic mode
73
+ new_params = self._extract_parameters_from_xml(self.command, command_parameters_class)
74
+
75
+ # If regex extraction fails, fall back to LLM-based extraction
76
+ if new_params is None:
77
+ new_params = input_for_param_extraction.extract_parameters(
78
+ command_parameters_class,
79
+ self.command_name,
80
+ app_workflow_folderpath)
81
+ else:
82
+ # Use LLM-based extraction for assistant mode
83
+ new_params = input_for_param_extraction.extract_parameters(
84
+ command_parameters_class,
85
+ self.command_name,
86
+ app_workflow_folderpath)
67
87
 
68
88
  is_valid, error_msg, suggestions, missing_invalid_fields = \
69
89
  input_for_param_extraction.validate_parameters(
@@ -272,6 +292,62 @@ class ParameterExtraction:
272
292
  # Construct model without validation
273
293
  return default_params.__class__.model_construct(**params_data)
274
294
 
295
+ @staticmethod
296
+ def _extract_parameters_from_xml(command: str, command_parameters_class: type[BaseModel]) -> Optional[BaseModel]:
297
+ """
298
+ Extract parameters from XML-formatted command using regex.
299
+
300
+ Returns:
301
+ BaseModel instance with extracted parameters, or None if parsing fails
302
+ """
303
+ field_names = list(command_parameters_class.model_fields.keys())
304
+
305
+ # If no parameters are defined, return empty model immediately
306
+ if not field_names:
307
+ return command_parameters_class.model_construct()
308
+
309
+ extracted_data = {}
310
+
311
+ # Try to extract each parameter using XML tags
312
+ for field_name in field_names:
313
+ # Look for <field_name>value</field_name> pattern
314
+ pattern = rf'<{re.escape(field_name)}>(.+?)</{re.escape(field_name)}>'
315
+ if match := re.search(pattern, command, re.DOTALL):
316
+ parameter_value = match[1].strip()
317
+ extracted_data[field_name] = parameter_value
318
+
319
+ # Check if we extracted values for ALL fields (safest criteria for LLM fallback)
320
+ all_fields_extracted = len(extracted_data) == len(field_names)
321
+
322
+ # Check if agent used example values
323
+ if all_fields_extracted:
324
+ for field_name, extracted_value in extracted_data.items():
325
+ field_info = command_parameters_class.model_fields[field_name]
326
+ examples = getattr(field_info, "examples", None)
327
+ if examples and extracted_value in examples:
328
+ all_fields_extracted = False
329
+ break
330
+
331
+ if all_fields_extracted:
332
+ # Initialize all fields with their default values (if they exist) or None
333
+ params_data = {}
334
+ for field_name in field_names:
335
+ field_info = command_parameters_class.model_fields[field_name]
336
+ if field_info.default is not PydanticUndefined:
337
+ params_data[field_name] = field_info.default
338
+ elif field_info.default_factory is not None:
339
+ params_data[field_name] = field_info.default_factory()
340
+ else:
341
+ params_data[field_name] = None
342
+
343
+ # Update with extracted values
344
+ params_data |= extracted_data
345
+
346
+ # Construct model without validation
347
+ return command_parameters_class.model_construct(**params_data)
348
+
349
+ return None
350
+
275
351
  @staticmethod
276
352
  def _extract_and_merge_missing_parameters(stored_params: BaseModel, command: str):
277
353
  """
@@ -133,7 +133,8 @@ class ChatSession:
133
133
 
134
134
  # Initialize agent-related attributes
135
135
  self._run_as_agent = run_as_agent
136
- self._workflow_tool_agent = None
136
+ self._workflow_tool_agent = None
137
+ self._intent_clarification_agent = None
137
138
 
138
139
  # Create the command metadata extraction workflow with a unique ID
139
140
  self._cme_workflow = fastworkflow.Workflow.create(
@@ -272,13 +273,23 @@ class ChatSession:
272
273
  self._current_workflow.context["run_as_agent"] = True
273
274
 
274
275
  # Initialize the workflow tool agent
275
- from fastworkflow.workflow_agent import initialize_workflow_tool_agent
276
+ from fastworkflow.workflow_agent import initialize_workflow_tool_agent
276
277
  self._workflow_tool_agent = initialize_workflow_tool_agent(self)
277
278
 
279
+ # Initialize the intent clarification agent
280
+ from fastworkflow.intent_clarification_agent import initialize_intent_clarification_agent
281
+ self._intent_clarification_agent = initialize_intent_clarification_agent(self)
282
+
278
283
  @property
279
284
  def workflow_tool_agent(self):
280
285
  """Get the workflow tool agent for agent mode."""
281
286
  return self._workflow_tool_agent
287
+
288
+ @property
289
+ def intent_clarification_agent(self):
290
+ """Get the intent clarification agent for agent mode."""
291
+ return self._intent_clarification_agent
292
+
282
293
  @property
283
294
  def cme_workflow(self) -> fastworkflow.Workflow:
284
295
  """Get the command metadata extraction workflow."""
@@ -647,7 +658,7 @@ class ChatSession:
647
658
  def _extract_conversation_summary(self,
648
659
  user_query: str, workflow_actions: list[dict[str, str]], final_agent_response: str) -> str:
649
660
  """
650
- Summarizes conversation based on original user query, workflow actions and agentt response.
661
+ Summarizes conversation based on original user query, workflow actions and agent response.
651
662
  Returns the conversation summary and the log entry
652
663
  """
653
664
  # Lets log everything to a file called action_log.jsonl, if it exists
@@ -613,6 +613,56 @@ class CommandMetadataAPI:
613
613
 
614
614
  return "\n".join(combined_lines)
615
615
 
616
+ @staticmethod
617
+ def get_suggested_commands_metadata(
618
+ subject_workflow_path: str,
619
+ cme_workflow_path: str,
620
+ active_context_name: str,
621
+ suggested_command_names: list[str],
622
+ for_agents: bool = False,
623
+ ) -> str:
624
+ """
625
+ Get metadata display text for ONLY the suggested commands.
626
+
627
+ Args:
628
+ subject_workflow_path: Path to the subject workflow
629
+ cme_workflow_path: Path to the CME workflow
630
+ active_context_name: Active context name
631
+ suggested_command_names: List of suggested command names (can be short names or qualified)
632
+ for_agents: Include agent-specific fields
633
+
634
+ Returns:
635
+ YAML-like formatted string with metadata for suggested commands only
636
+ """
637
+ if not suggested_command_names:
638
+ return "No suggested commands provided."
639
+
640
+ parts: list[str] = []
641
+ for suggested_cmd in suggested_command_names:
642
+ # Try to get metadata for this command
643
+ # The command name could be qualified (Context/command) or short (command)
644
+ if part := CommandMetadataAPI.get_command_display_text_for_command(
645
+ subject_workflow_path=subject_workflow_path,
646
+ cme_workflow_path=cme_workflow_path,
647
+ active_context_name=active_context_name,
648
+ qualified_command_name=suggested_cmd,
649
+ for_agents=for_agents,
650
+ ):
651
+ parts.append(part)
652
+
653
+ if not parts:
654
+ return "No metadata available for suggested commands."
655
+
656
+ # Combine all parts with header
657
+ combined_lines: list[str] = ["Suggested commands with metadata:"]
658
+ for idx, text in enumerate(parts):
659
+ lines = text.splitlines()
660
+ if idx > 0:
661
+ combined_lines.append("") # Blank line separator
662
+ combined_lines.extend(lines)
663
+
664
+ return "\n".join(combined_lines)
665
+
616
666
  @staticmethod
617
667
  def get_command_display_text_for_command(
618
668
  subject_workflow_path: str,
@@ -0,0 +1,132 @@
1
+ """
2
+ Intent detection error state agent module for fastWorkflow.
3
+ Specialized agent for handling intent detection errors.
4
+ """
5
+
6
+ import json
7
+ import dspy
8
+
9
+ import fastworkflow
10
+ from fastworkflow.utils.react import fastWorkflowReAct
11
+ from fastworkflow.command_metadata_api import CommandMetadataAPI
12
+
13
+
14
+ class IntentClarificationAgentSignature(dspy.Signature):
15
+ """
16
+ Handle intent detection errors by clarifying user intent.
17
+ You are provided with:
18
+ 1. The workflow agent's inputs and trajectory - showing what the agent has been trying to do
19
+ 2. Suggested commands metadata (for intent ambiguity) or empty (for intent misunderstanding - use show_available_commands tool)
20
+
21
+ Review the agent trajectory to understand the context and what led to this error.
22
+ If suggested_commands_metadata is provided, review it carefully to understand each command's purpose, parameters, and usage.
23
+ If suggested_commands_metadata is empty, use the show_available_commands tool to get the full list of available commands.
24
+ IMPORTANT: When clarifying intent, preserve ALL parameters from the original command.
25
+ Use available tools to resolve ambiguous or misunderstood commands. Use the ask_user tool ONLY as a last resort. Return the complete clarified command with the correct name and all original parameters.
26
+ """
27
+ original_command = dspy.InputField(desc="The original command with all parameters that caused the error.")
28
+ error_message = dspy.InputField(desc="The intent detection error message from the workflow.")
29
+ agent_inputs = dspy.InputField(desc="The original inputs to the workflow agent.")
30
+ agent_trajectory = dspy.InputField(desc="The workflow agent's trajectory showing all actions taken so far leading to this error.")
31
+ suggested_commands_metadata = dspy.InputField(desc="Metadata for suggested commands (for ambiguity clarification), or empty string (for misunderstanding - use show_available_commands tool instead).")
32
+ clarified_command = dspy.OutputField(desc="The complete command with correct command name AND all original parameters preserved.")
33
+
34
+
35
+ def _show_available_commands(chat_session: fastworkflow.ChatSession) -> str:
36
+ """
37
+ Show available commands to help resolve intent detection errors.
38
+
39
+ Args:
40
+ chat_session: The chat session instance
41
+
42
+ Returns:
43
+ List of available commands
44
+ """
45
+
46
+ current_workflow = chat_session.get_active_workflow()
47
+ return CommandMetadataAPI.get_command_display_text(
48
+ subject_workflow_path=current_workflow.folderpath,
49
+ cme_workflow_path=fastworkflow.get_internal_workflow_path("command_metadata_extraction"),
50
+ active_context_name=current_workflow.current_command_context_name,
51
+ )
52
+
53
+
54
+ def _ask_user_for_clarification(
55
+ clarification_request: str,
56
+ chat_session: fastworkflow.ChatSession
57
+ ) -> str:
58
+ """
59
+ Ask user for clarification when intent is unclear.
60
+
61
+ Args:
62
+ clarification_request: The question to ask the user
63
+ chat_session: The chat session instance
64
+
65
+ Returns:
66
+ User's response
67
+ """
68
+ command_output = fastworkflow.CommandOutput(
69
+ command_responses=[fastworkflow.CommandResponse(response=clarification_request)],
70
+ workflow_name=chat_session.get_active_workflow().folderpath.split('/')[-1]
71
+ )
72
+ chat_session.command_output_queue.put(command_output)
73
+
74
+ user_response = chat_session.user_message_queue.get()
75
+
76
+ # Log to action.jsonl (shared with main agent)
77
+ with open("action.jsonl", "a", encoding="utf-8") as f:
78
+ agent_user_dialog = {
79
+ "intent_clarification_agent": True,
80
+ "agent_query": clarification_request,
81
+ "user_response": user_response
82
+ }
83
+ f.write(json.dumps(agent_user_dialog, ensure_ascii=False) + "\n")
84
+
85
+ return user_response
86
+
87
+
88
+ def initialize_intent_clarification_agent(
89
+ chat_session: fastworkflow.ChatSession,
90
+ max_iters: int = 20
91
+ ):
92
+ """
93
+ Initialize a specialized agent for handling intent detection errors.
94
+ This agent has a limited tool set and shares traces with the main execution agent.
95
+
96
+ Args:
97
+ chat_session: The chat session instance
98
+ max_iters: Maximum iterations for the agent (default: 10)
99
+
100
+ Returns:
101
+ DSPy ReAct agent configured for intent detection error handling
102
+ """
103
+ if not chat_session:
104
+ raise ValueError("chat_session cannot be null")
105
+
106
+ def show_available_commands() -> str:
107
+ """
108
+ Show all available commands to help resolve intent ambiguity.
109
+ """
110
+ return _show_available_commands(chat_session)
111
+
112
+ def ask_user(clarification_request: str) -> str:
113
+ """
114
+ Ask the user for clarification when the intent is unclear.
115
+ Use this as a last resort when you cannot determine the correct command.
116
+
117
+ Args:
118
+ clarification_request: Clear question to ask the user
119
+ """
120
+ return _ask_user_for_clarification(clarification_request, chat_session)
121
+
122
+ # Limited tool set for intent detection errors
123
+ tools = [
124
+ show_available_commands,
125
+ ask_user,
126
+ ]
127
+
128
+ return fastWorkflowReAct(
129
+ IntentClarificationAgentSignature,
130
+ tools=tools,
131
+ max_iters=max_iters,
132
+ )
@@ -114,7 +114,7 @@ def _get_commands_with_parameters(json_path):
114
114
  command_directory = json.load(f)
115
115
 
116
116
  # Extract the command metadata
117
- commands_metadata = command_directory.get("map_commandkey_2_metadata", {})
117
+ commands_metadata = command_directory.get("map_command_2_metadata", {})
118
118
 
119
119
  # Initialize result dictionary
120
120
  commands_with_parameters = {}
@@ -2,6 +2,7 @@ import logging
2
2
  from typing import TYPE_CHECKING, Any, Callable, Literal
3
3
 
4
4
  from litellm import ContextWindowExceededError
5
+ from litellm import exceptions as litellm_exceptions
5
6
 
6
7
  import dspy
7
8
  from dspy.adapters.types.tool import Tool
@@ -41,6 +42,7 @@ class fastWorkflowReAct(Module):
41
42
  super().__init__()
42
43
  self.signature = signature = ensure_signature(signature)
43
44
  self.max_iters = max_iters
45
+ self.iteration_counter = 0
44
46
 
45
47
  tools = [t if isinstance(t, Tool) else Tool(t) for t in tools]
46
48
  tools = {tool.name: tool for tool in tools}
@@ -105,7 +107,8 @@ class fastWorkflowReAct(Module):
105
107
 
106
108
  trajectory = {}
107
109
  max_iters = input_args.pop("max_iters", self.max_iters)
108
- for idx in range(max_iters):
110
+ idx = 0
111
+ while True:
109
112
  try:
110
113
  pred = self._call_with_potential_trajectory_truncation(self.react, trajectory, **input_args)
111
114
  except ValueError as err:
@@ -126,6 +129,12 @@ class fastWorkflowReAct(Module):
126
129
  if pred.next_tool_name == "finish":
127
130
  break
128
131
 
132
+ idx += 1 # this is the counter for the index of the entire trajectory
133
+ self.iteration_counter += 1 # this counter just determines the number of times we run the react agent and it's reset everytime we call the user for clarification
134
+ if self.iteration_counter >= max_iters:
135
+ logger.warning("Max iterations reached")
136
+ break
137
+
129
138
  extract = self._call_with_potential_trajectory_truncation(self.extract, trajectory, **input_args)
130
139
  return dspy.Prediction(trajectory=trajectory, **extract)
131
140
 
@@ -161,6 +170,9 @@ class fastWorkflowReAct(Module):
161
170
  **input_args,
162
171
  trajectory=self._format_trajectory(trajectory),
163
172
  )
173
+ except litellm_exceptions.BadRequestError:
174
+ logger.warning("Trajectory exceeded the context window, truncating the oldest tool call information.")
175
+ trajectory = self.truncate_trajectory(trajectory)
164
176
  except ContextWindowExceededError:
165
177
  logger.warning("Trajectory exceeded the context window, truncating the oldest tool call information.")
166
178
  trajectory = self.truncate_trajectory(trajectory)
@@ -407,7 +407,7 @@ Today's date is {today}.
407
407
  parsed = ast.literal_eval(text)
408
408
  if isinstance(parsed, list):
409
409
  return parsed
410
- # Fallback: comma-separated
410
+ # Comma-separated values
411
411
  if "," in text:
412
412
  parts = [p.strip() for p in text.split(",")]
413
413
  cleaned = [
@@ -415,6 +415,12 @@ Today's date is {today}.
415
415
  for p in parts
416
416
  ]
417
417
  return cleaned
418
+ # Single value - treat as a list with one element
419
+ if text:
420
+ # Remove quotes if present
421
+ if len(text) >= 2 and ((text[0] == text[-1] == '"') or (text[0] == text[-1] == "'")):
422
+ return [text[1:-1]]
423
+ return [text]
418
424
  return None
419
425
 
420
426
  def _coerce_scalar(expected_type: Type[Any], val: Any) -> Tuple[bool, Optional[Any]]:
@@ -511,7 +517,48 @@ Today's date is {today}.
511
517
 
512
518
  if valid_by_type:
513
519
  if corrected_value is not None:
514
- setattr(cmd_parameters, field_name, corrected_value)
520
+ pattern = next(
521
+ (meta.pattern
522
+ for meta in getattr(field_info, "metadata", [])
523
+ if hasattr(meta, "pattern")),
524
+ None,
525
+ )
526
+ if pattern and field_value is not None and field_value != NOT_FOUND:
527
+ invalid_value = None
528
+ if hasattr(field_info, "json_schema_extra") and field_info.json_schema_extra:
529
+ invalid_value = field_info.json_schema_extra.get("invalid_value")
530
+
531
+ # if invalid_value and field_value == invalid_value:
532
+ # invalid_fields.append(f"{field_name} '{field_value}'")
533
+ # pattern_str = str(pattern)
534
+ # examples = getattr(field_info, "examples", [])
535
+ # example = examples[0] if examples else ""
536
+ # all_suggestions[field_name] = [f"Please use the format matching pattern {pattern_str} (e.g., {example})"]
537
+ # is_valid = False
538
+
539
+ # else:
540
+ pattern_regex = re.compile(pattern)
541
+ if not pattern_regex.fullmatch(str(field_value)):
542
+ invalid_fields.append(f"{field_name} '{field_value}'")
543
+ pattern_str = str(pattern)
544
+ examples = getattr(field_info, "examples", [])
545
+ example = examples[0] if examples else ""
546
+
547
+ invalid_fields.append(f"{field_name} '{field_value}'")
548
+ all_suggestions[field_name] = [f"Please use the format matching pattern {pattern_str} (e.g., {example})"]
549
+ is_valid = False
550
+ else:
551
+ try:
552
+ setattr(cmd_parameters, field_name, corrected_value)
553
+ except Exception as e:
554
+ logger.critical(f"Failed to set attribute {field_name} with value {corrected_value}")
555
+ raise e
556
+ else:
557
+ try:
558
+ setattr(cmd_parameters, field_name, corrected_value)
559
+ except Exception as e:
560
+ logger.critical(f"Failed to set attribute {field_name} with value {corrected_value}")
561
+ raise e
515
562
  else:
516
563
  invalid_fields.append(f"{field_name} '{field_value}'")
517
564
  all_suggestions[field_name] = build_type_suggestion()
@@ -539,35 +586,6 @@ Today's date is {today}.
539
586
  missing_fields.append(field_name)
540
587
  is_valid = False
541
588
 
542
- pattern = next(
543
- (meta.pattern
544
- for meta in getattr(field_info, "metadata", [])
545
- if hasattr(meta, "pattern")),
546
- None,
547
- )
548
- if pattern and field_value is not None and field_value != NOT_FOUND:
549
- invalid_value = None
550
- if hasattr(field_info, "json_schema_extra") and field_info.json_schema_extra:
551
- invalid_value = field_info.json_schema_extra.get("invalid_value")
552
-
553
- if invalid_value and field_value == invalid_value:
554
- invalid_fields.append(f"{field_name} '{field_value}'")
555
- pattern_str = str(pattern)
556
- examples = getattr(field_info, "examples", [])
557
- example = examples[0] if examples else ""
558
- all_suggestions[field_name] = [f"Please use the format matching pattern {pattern_str} (e.g., {example})"]
559
- is_valid = False
560
-
561
- else:
562
- pattern_regex = re.compile(pattern)
563
- if not pattern_regex.fullmatch(str(field_value)):
564
- invalid_fields.append(f"{field_name} '{field_value}'")
565
- pattern_str = str(pattern)
566
- examples = getattr(field_info, "examples", [])
567
- example = examples[0] if examples else ""
568
- all_suggestions[field_name] = [f"Please use the format matching pattern {pattern_str} (e.g., {example})"]
569
- is_valid = False
570
-
571
589
  for field_name, field_info in type(cmd_parameters).model_fields.items():
572
590
  field_value = getattr(cmd_parameters, field_name, None)
573
591
 
@@ -99,10 +99,10 @@ def _execute_workflow_query(command: str, chat_session_obj: fastworkflow.ChatSes
99
99
  # Extract command name and parameters from command_output
100
100
  name = command_output.command_name
101
101
  params = command_output.command_parameters
102
-
102
+
103
103
  # Handle parameter serialization
104
104
  params_dict = params.model_dump() if params else None
105
-
105
+
106
106
  # Extract response text
107
107
  response_text = ""
108
108
  if command_output.command_responses:
@@ -135,8 +135,81 @@ def _execute_workflow_query(command: str, chat_session_obj: fastworkflow.ChatSes
135
135
  with open("action.jsonl", "a", encoding="utf-8") as f:
136
136
  f.write(json.dumps(record, ensure_ascii=False) + "\n")
137
137
 
138
- if 'PARAMETER EXTRACTION ERROR' in response_text or 'The command is ambiguous' in response_text:
139
- abort_confirmation = _execute_workflow_query('abort', chat_session_obj = chat_session_obj)
138
+ # Check workflow context to determine if we're in an error state that needs specialized handling
139
+ cme_workflow = chat_session_obj.cme_workflow
140
+ nlu_stage = cme_workflow.context.get("NLU_Pipeline_Stage")
141
+
142
+ # Handle intent ambiguity clarification state with specialized agent
143
+ if nlu_stage == fastworkflow.NLUPipelineStage.INTENT_AMBIGUITY_CLARIFICATION:
144
+ if intent_agent := chat_session_obj.intent_clarification_agent:
145
+ # Get suggested commands from intent detection system
146
+ from fastworkflow._workflows.command_metadata_extraction.intent_detection import CommandNamePrediction
147
+ predictor = CommandNamePrediction(cme_workflow)
148
+ suggested_commands = predictor._get_suggested_commands(predictor.path)
149
+
150
+ suggested_commands = list(suggested_commands) if suggested_commands is not None else []
151
+
152
+ # Get metadata for only the suggested commands
153
+ current_workflow = chat_session_obj.get_active_workflow()
154
+ suggested_commands_metadata = CommandMetadataAPI.get_suggested_commands_metadata(
155
+ subject_workflow_path=current_workflow.folderpath,
156
+ cme_workflow_path=fastworkflow.get_internal_workflow_path("command_metadata_extraction"),
157
+ active_context_name=current_workflow.current_command_context_name,
158
+ suggested_command_names=suggested_commands
159
+ )
160
+
161
+ # Get the workflow agent's trajectory and inputs for context
162
+ workflow_tool_agent = chat_session_obj.workflow_tool_agent
163
+ agent_inputs = workflow_tool_agent.inputs if workflow_tool_agent else {}
164
+ agent_trajectory = workflow_tool_agent.current_trajectory if workflow_tool_agent else {}
165
+
166
+ lm = dspy_utils.get_lm("LLM_AGENT", "LITELLM_API_KEY_AGENT")
167
+ with dspy.context(lm=lm):
168
+ result = intent_agent(
169
+ original_command=command,
170
+ error_message=response_text,
171
+ agent_inputs=agent_inputs,
172
+ agent_trajectory=agent_trajectory,
173
+ suggested_commands_metadata=suggested_commands_metadata
174
+ )
175
+ # The clarified command should have the correct name with all original parameters
176
+ clarified_cmd = result.clarified_command if hasattr(result, 'clarified_command') else str(result)
177
+ # Execute the clarified command
178
+ return _execute_workflow_query(clarified_cmd, chat_session_obj=chat_session_obj)
179
+ else:
180
+ # No intent clarification agent available, fall back to abort
181
+ abort_confirmation = _execute_workflow_query('abort', chat_session_obj=chat_session_obj)
182
+ return f'{response_text}\n{abort_confirmation}'
183
+
184
+ # Handle intent misunderstanding clarification state with specialized agent
185
+ if nlu_stage == fastworkflow.NLUPipelineStage.INTENT_MISUNDERSTANDING_CLARIFICATION:
186
+ if intent_agent := chat_session_obj.intent_clarification_agent:
187
+ # Get the workflow agent's trajectory and inputs for context
188
+ workflow_tool_agent = chat_session_obj.workflow_tool_agent
189
+ agent_inputs = workflow_tool_agent.inputs if workflow_tool_agent else {}
190
+ agent_trajectory = workflow_tool_agent.current_trajectory if workflow_tool_agent else {}
191
+
192
+ lm = dspy_utils.get_lm("LLM_AGENT", "LITELLM_API_KEY_AGENT")
193
+ with dspy.context(lm=lm):
194
+ result = intent_agent(
195
+ original_command=command,
196
+ error_message=response_text,
197
+ agent_inputs=agent_inputs,
198
+ agent_trajectory=agent_trajectory,
199
+ suggested_commands_metadata=""
200
+ )
201
+
202
+ clarified_cmd = result.clarified_command if hasattr(result, 'clarified_command') else str(result)
203
+
204
+ return _execute_workflow_query(clarified_cmd, chat_session_obj=chat_session_obj)
205
+ else:
206
+ # No intent clarification agent available, fall back to abort
207
+ abort_confirmation = _execute_workflow_query('abort', chat_session_obj=chat_session_obj)
208
+ return f'{response_text}\n{abort_confirmation}'
209
+
210
+ # Handle parameter extraction errors with abort
211
+ if nlu_stage == fastworkflow.NLUPipelineStage.PARAMETER_EXTRACTION:
212
+ abort_confirmation = _execute_workflow_query('abort', chat_session_obj=chat_session_obj)
140
213
  return f'{response_text}\n{abort_confirmation}'
141
214
 
142
215
  return response_text
@@ -253,6 +326,7 @@ def initialize_workflow_tool_agent(chat_session: fastworkflow.ChatSession, max_i
253
326
  The clarification_request must be plain text without any formatting.
254
327
  Note that using the wrong command name can produce missing information errors. Double-check with the what_can_i_do tool to verify that the correct command name is being used
255
328
  """
329
+ chat_session_obj.workflow_tool_agent.iteration_counter = 0 # reset iteration counter, everytime we ask the user
256
330
  return _ask_user_tool(clarification_request, chat_session_obj=chat_session_obj)
257
331
 
258
332
  tools = [
@@ -9,7 +9,7 @@ repository = "https://github.com/radiantlogicinc/fastworkflow"
9
9
 
10
10
  [tool.poetry]
11
11
  name = "fastworkflow"
12
- version = "2.17.8"
12
+ version = "2.17.9"
13
13
  description = "A framework for rapidly building large-scale, deterministic, interactive workflows with a fault-tolerant, conversational UX"
14
14
  authors = ["Dhar Rawal <drawal@radiantlogic.com>"]
15
15
  license = "Apache-2.0"
File without changes
File without changes