fastworkflow 2.14.2__tar.gz → 2.15.0__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 (175) hide show
  1. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/PKG-INFO +1 -1
  2. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/_workflows/command_metadata_extraction/_commands/ErrorCorrection/abort.py +1 -1
  3. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/_workflows/command_metadata_extraction/_commands/wildcard.py +12 -19
  4. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/chat_session.py +50 -27
  5. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/cli.py +16 -0
  6. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/command_executor.py +21 -2
  7. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/_commands/cancel_pending_order.py +15 -6
  8. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/_commands/exchange_delivered_order_items.py +14 -4
  9. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/_commands/find_user_id_by_email.py +1 -1
  10. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/_commands/get_order_details.py +11 -2
  11. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/_commands/modify_pending_order_address.py +11 -2
  12. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/_commands/modify_pending_order_items.py +13 -4
  13. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/_commands/modify_pending_order_payment.py +13 -4
  14. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/_commands/return_delivered_order_items.py +14 -5
  15. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/_commands/transfer_to_human_agents.py +1 -1
  16. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/utils/signatures.py +8 -2
  17. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/workflow.py +18 -0
  18. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/workflow_agent.py +46 -5
  19. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/pyproject.toml +1 -1
  20. fastworkflow-2.14.2/fastworkflow/examples/retail_workflow/command_dependency_graph.json +0 -80
  21. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/LICENSE +0 -0
  22. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/README.md +0 -0
  23. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/.DS_Store +0 -0
  24. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/__init__.py +0 -0
  25. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/_commands/.gitkeep +0 -0
  26. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/_workflows/__init__.py +0 -0
  27. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/_workflows/command_metadata_extraction/__init__.py +0 -0
  28. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/_workflows/command_metadata_extraction/_commands/ErrorCorrection/you_misunderstood.py +0 -0
  29. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/go_up.py +0 -0
  30. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/reset_context.py +0 -0
  31. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/what_can_i_do.py +0 -0
  32. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/what_is_current_context.py +0 -0
  33. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/_workflows/command_metadata_extraction/_commands/__init__.py +0 -0
  34. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/_workflows/command_metadata_extraction/command_context_model.json +0 -0
  35. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/__main__.py +0 -0
  36. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/ast_class_extractor.py +0 -0
  37. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/class_analysis_structures.py +0 -0
  38. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/cli_specification.md +0 -0
  39. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/command_dependency_resolver.py +0 -0
  40. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/command_file_generator.py +0 -0
  41. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/command_file_template.py +0 -0
  42. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/command_import_utils.py +0 -0
  43. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/command_stub_generator.py +0 -0
  44. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/context_folder_generator.py +0 -0
  45. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/context_model_generator.py +0 -0
  46. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/dependency_manager.py +0 -0
  47. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/dir_scanner.py +0 -0
  48. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/documentation_generator.py +0 -0
  49. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/genai_postprocessor.py +0 -0
  50. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/inheritance_block_regenerator.py +0 -0
  51. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/libcst_transformers.py +0 -0
  52. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/navigator_stub_generator.py +0 -0
  53. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/pydantic_model_generator.py +0 -0
  54. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/build/utterance_generator.py +0 -0
  55. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/cache_matching.py +0 -0
  56. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/command_context_model.py +0 -0
  57. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/command_directory.py +0 -0
  58. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/command_interfaces.py +0 -0
  59. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/command_metadata_api.py +0 -0
  60. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/command_routing.py +0 -0
  61. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/docs/context_modules_prd.txt +0 -0
  62. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/extended_workflow_example/README.md +0 -0
  63. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/extended_workflow_example/_commands/WorkItem/get_status.py +0 -0
  64. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/extended_workflow_example/_commands/generate_report.py +0 -0
  65. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/extended_workflow_example/_commands/startup.py +0 -0
  66. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/extended_workflow_example/simple_workflow_template.json +0 -0
  67. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/extended_workflow_example/workflow_inheritance_model.json +0 -0
  68. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/fastworkflow.env +0 -0
  69. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/fastworkflow.passwords.env +0 -0
  70. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/hello_world/_commands/README.md +0 -0
  71. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/hello_world/_commands/add_two_numbers.py +0 -0
  72. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/hello_world/_commands/context_inheritance_model.json +0 -0
  73. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/hello_world/application/add_two_numbers.py +0 -0
  74. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_1/_commands/context_inheritance_model.json +0 -0
  75. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_1/_commands/send_message.py +0 -0
  76. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_1/application/send_message.py +0 -0
  77. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_2/_commands/User/send_message.py +0 -0
  78. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_2/_commands/context_inheritance_model.json +0 -0
  79. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_2/_commands/startup.py +0 -0
  80. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_2/application/user.py +0 -0
  81. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_3/_commands/PremiumUser/send_priority_message.py +0 -0
  82. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_3/_commands/User/send_message.py +0 -0
  83. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_3/_commands/context_inheritance_model.json +0 -0
  84. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_3/_commands/initialize_user.py +0 -0
  85. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_3/application/user.py +0 -0
  86. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/_ChatRoom.py +0 -0
  87. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/add_user.py +0 -0
  88. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/broadcast_message.py +0 -0
  89. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/get_current_user.py +0 -0
  90. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/list_users.py +0 -0
  91. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/set_current_user.py +0 -0
  92. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_4/_commands/PremiumUser/_PremiumUser.py +0 -0
  93. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_4/_commands/PremiumUser/send_priority_message.py +0 -0
  94. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_4/_commands/User/_User.py +0 -0
  95. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_4/_commands/User/send_message.py +0 -0
  96. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_4/_commands/context_inheritance_model.json +0 -0
  97. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_4/_commands/set_root_context.py +0 -0
  98. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_4/application/chatroom.py +0 -0
  99. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_4/application/user.py +0 -0
  100. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_4/context_hierarchy_model.json +0 -0
  101. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/messaging_app_4/startup_action.json +0 -0
  102. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/_commands/calculate.py +0 -0
  103. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/_commands/find_user_id_by_name_zip.py +0 -0
  104. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/_commands/get_product_details.py +0 -0
  105. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/_commands/get_user_details.py +0 -0
  106. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/_commands/list_all_product_types.py +0 -0
  107. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/_commands/modify_user_address.py +0 -0
  108. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/context_inheritance_model.json +0 -0
  109. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/retail_data/__init__.py +0 -0
  110. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/retail_data/orders.json +0 -0
  111. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/retail_data/products.json +0 -0
  112. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/retail_data/users.json +0 -0
  113. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/tools/calculate.py +0 -0
  114. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/tools/cancel_pending_order.py +0 -0
  115. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/tools/exchange_delivered_order_items.py +0 -0
  116. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/tools/find_user_id_by_email.py +0 -0
  117. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/tools/find_user_id_by_name_zip.py +0 -0
  118. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/tools/get_order_details.py +0 -0
  119. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/tools/get_product_details.py +0 -0
  120. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/tools/get_user_details.py +0 -0
  121. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/tools/list_all_product_types.py +0 -0
  122. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/tools/modify_pending_order_address.py +0 -0
  123. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/tools/modify_pending_order_items.py +0 -0
  124. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/tools/modify_pending_order_payment.py +0 -0
  125. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/tools/modify_user_address.py +0 -0
  126. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/tools/return_delivered_order_items.py +0 -0
  127. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/tools/think.py +0 -0
  128. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/tools/tool.py +0 -0
  129. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/tools/transfer_to_human_agents.py +0 -0
  130. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/retail_workflow/workflow_description.txt +0 -0
  131. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/simple_workflow_template/__init__.py +0 -0
  132. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/_WorkItem.py +0 -0
  133. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/add_child_workitem.py +0 -0
  134. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/get_status.py +0 -0
  135. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/go_to_workitem.py +0 -0
  136. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/mark_as_complete.py +0 -0
  137. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/move_to_first_child_workitem.py +0 -0
  138. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/move_to_last_child_workitem.py +0 -0
  139. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/move_to_next_workitem.py +0 -0
  140. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/move_to_previous_workitem.py +0 -0
  141. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/remove_all_child_workitems.py +0 -0
  142. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/remove_child_workitem.py +0 -0
  143. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/show_schema.py +0 -0
  144. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/simple_workflow_template/_commands/startup.py +0 -0
  145. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/simple_workflow_template/application/__init__.py +0 -0
  146. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/simple_workflow_template/application/workitem.py +0 -0
  147. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/simple_workflow_template/simple_workflow_template.json +0 -0
  148. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/examples/simple_workflow_template/startup_action.json +0 -0
  149. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/mcp_server.py +0 -0
  150. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/model_pipeline_training.py +0 -0
  151. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/refine/__main__.py +0 -0
  152. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/run/__init__.py +0 -0
  153. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/run/__main__.py +0 -0
  154. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/run_agent/__init__.py +0 -0
  155. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/run_agent/__main__.py +0 -0
  156. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/run_agent/agent_module.py +0 -0
  157. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/train/__init__.py +0 -0
  158. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/train/__main__.py +0 -0
  159. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/train/generate_synthetic.py +0 -0
  160. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/user_message_queues.py +0 -0
  161. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/utils/__init__.py +0 -0
  162. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/utils/command_dependency_graph.py +0 -0
  163. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/utils/context_utils.py +0 -0
  164. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/utils/dspy_cache_utils.py +0 -0
  165. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/utils/dspy_logger.py +0 -0
  166. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/utils/dspy_utils.py +0 -0
  167. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/utils/env.py +0 -0
  168. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/utils/fuzzy_match.py +0 -0
  169. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/utils/generate_param_examples.py +0 -0
  170. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/utils/logging.py +0 -0
  171. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/utils/parameterize_func_decorator.py +0 -0
  172. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/utils/pydantic_model_2_dspy_signature_class.py +0 -0
  173. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/utils/python_utils.py +0 -0
  174. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/utils/startup_progress.py +0 -0
  175. {fastworkflow-2.14.2 → fastworkflow-2.15.0}/fastworkflow/workflow_inheritance_model.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fastworkflow
3
- Version: 2.14.2
3
+ Version: 2.15.0
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
@@ -29,7 +29,7 @@ class Signature:
29
29
 
30
30
  class ResponseGenerator:
31
31
  def _process_command(self, workflow: Workflow, command: str) -> Signature.Output:
32
- workflow.is_complete = True
32
+ workflow.end_command_processing()
33
33
  return Signature.Output(command=command, command_name="abort")
34
34
 
35
35
  def __call__(self, workflow: Workflow, command: str) -> CommandOutput:
@@ -560,7 +560,8 @@ class ParameterExtraction:
560
560
  return params
561
561
 
562
562
  except Exception as exc:
563
- logger.warning(PARAMETER_EXTRACTION_ERROR_MSG.format(error=exc))
563
+ # logger.warning(PARAMETER_EXTRACTION_ERROR_MSG.format(error=exc))
564
+ pass
564
565
 
565
566
  return params
566
567
 
@@ -589,8 +590,6 @@ class ResponseGenerator:
589
590
  workflow: fastworkflow.Workflow,
590
591
  command: str,
591
592
  ) -> CommandOutput: # sourcery skip: hoist-if-from-if
592
- workflow.is_complete = False
593
-
594
593
  app_workflow = workflow.context["app_workflow"] # type: fastworkflow.Workflow
595
594
  cmd_ctxt_obj_name = app_workflow.current_command_context_name
596
595
  nlu_pipeline_stage = workflow.context.get(
@@ -603,8 +602,6 @@ class ResponseGenerator:
603
602
  if cnp_output.error_msg:
604
603
  workflow_context = workflow.context
605
604
  workflow_context["NLU_Pipeline_Stage"] = NLUPipelineStage.INTENT_AMBIGUITY_CLARIFICATION
606
- if "command" not in workflow_context:
607
- workflow_context["command"] = command
608
605
  workflow.context = workflow_context
609
606
  return CommandOutput(
610
607
  command_responses=[
@@ -617,17 +614,19 @@ class ResponseGenerator:
617
614
  )
618
615
  ]
619
616
  )
617
+ else:
618
+ if nlu_pipeline_stage == NLUPipelineStage.INTENT_DETECTION and \
619
+ cnp_output.command_name != 'ErrorCorrection/you_misunderstood':
620
+ workflow_context = workflow.context
621
+ workflow_context["command"] = command
622
+ workflow.context = workflow_context
620
623
 
621
624
  if cnp_output.is_cme_command:
622
625
  workflow_context = workflow.context
623
626
  if cnp_output.command_name == 'ErrorCorrection/you_misunderstood':
624
627
  workflow_context["NLU_Pipeline_Stage"] = NLUPipelineStage.INTENT_MISUNDERSTANDING_CLARIFICATION
625
- if "command" not in workflow_context:
626
- workflow_context["command"] = command
627
628
  else:
628
- workflow.is_complete = True
629
- workflow_context["NLU_Pipeline_Stage"] = NLUPipelineStage.INTENT_DETECTION
630
- workflow_context.pop("command", None)
629
+ workflow.end_command_processing()
631
630
  workflow.context = workflow_context
632
631
 
633
632
  startup_action = Action(
@@ -664,8 +663,6 @@ class ResponseGenerator:
664
663
  workflow_context = workflow.context
665
664
  workflow_context["NLU_Pipeline_Stage"] = \
666
665
  NLUPipelineStage.INTENT_MISUNDERSTANDING_CLARIFICATION
667
- if "command" not in workflow_context:
668
- workflow_context["command"] = command
669
666
  workflow.context = workflow_context
670
667
 
671
668
  startup_action = Action(
@@ -689,9 +686,6 @@ class ResponseGenerator:
689
686
  workflow_context = workflow.context
690
687
  workflow_context["NLU_Pipeline_Stage"] = NLUPipelineStage.PARAMETER_EXTRACTION
691
688
  workflow_context["command_name"] = cnp_output.command_name
692
- # Only update command if it's not already set (preserve original command with parameters)
693
- if "command" not in workflow_context:
694
- workflow_context["command"] = command
695
689
  workflow.context = workflow_context
696
690
 
697
691
  command_name = workflow.context["command_name"]
@@ -699,6 +693,7 @@ class ResponseGenerator:
699
693
  pe_output = extractor.extract()
700
694
  if not pe_output.parameters_are_valid:
701
695
  return CommandOutput(
696
+ command_name = command_name,
702
697
  command_responses=[
703
698
  CommandResponse(
704
699
  response=(
@@ -710,16 +705,14 @@ class ResponseGenerator:
710
705
  ]
711
706
  )
712
707
 
713
- workflow.is_complete = True
714
- workflow.context["NLU_Pipeline_Stage"] = \
715
- NLUPipelineStage.INTENT_DETECTION
708
+ workflow.end_command_processing()
716
709
 
717
710
  return CommandOutput(
718
711
  command_responses=[
719
712
  CommandResponse(
720
713
  response="",
721
714
  artifacts={
722
- "command": workflow.context["command"],
715
+ "command": command,
723
716
  "command_name": command_name,
724
717
  "cmd_parameters": pe_output.cmd_parameters,
725
718
  },
@@ -7,6 +7,7 @@ import json
7
7
  import contextlib
8
8
  import uuid
9
9
  from pathlib import Path
10
+ import os
10
11
 
11
12
  import dspy
12
13
 
@@ -15,6 +16,7 @@ from fastworkflow.utils.logging import logger
15
16
  from fastworkflow.utils import dspy_utils
16
17
  from fastworkflow.model_pipeline_training import CommandRouter
17
18
  from fastworkflow.utils.startup_progress import StartupProgress
19
+ from fastworkflow.command_metadata_api import CommandMetadataAPI
18
20
 
19
21
 
20
22
  class SessionStatus(Enum):
@@ -310,7 +312,11 @@ class ChatSession:
310
312
  try:
311
313
  # Handle startup command/action
312
314
  if self._startup_command:
313
- last_output = self._process_message(self._startup_command)
315
+ if self._run_as_agent:
316
+ # In agent mode, use workflow tool agent for processing
317
+ last_output = self._process_agent_message(self._startup_command)
318
+ else:
319
+ last_output = self._process_message(self._startup_command)
314
320
  elif self._startup_action:
315
321
  last_output = self._process_action(self._startup_action)
316
322
 
@@ -407,31 +413,13 @@ class ChatSession:
407
413
  # The agent processes the user's message and may make multiple tool calls
408
414
  # to the workflow internally (directly via CommandExecutor)
409
415
 
410
- planner_lm = dspy_utils.get_lm("LLM_PLANNER", "LITELLM_API_KEY_PLANNER")
411
- lm = dspy_utils.get_lm("LLM_AGENT", "LITELLM_API_KEY_AGENT")
412
-
413
- class TaskPlannerSignature(dspy.Signature):
414
- """
415
- Breakdown the user query into a todo list, based only on the user query and available_commands and nothing else.
416
- """
417
- user_query: str = dspy.InputField()
418
- available_commands: list[str] = dspy.InputField()
419
- todo_list: list[str] = dspy.OutputField(desc="task descriptions as short sentences")
416
+ # Ensure any prior action log is removed before a fresh agent run
417
+ if os.path.exists("action.json"):
418
+ os.remove("action.json")
420
419
 
421
- app_workflow = self.get_active_workflow()
422
- crd = fastworkflow.RoutingRegistry.get_definition(app_workflow.folderpath)
423
- available_commands = crd.get_command_names('*')
424
-
425
- with dspy.context(lm=planner_lm):
426
- task_planner_func = dspy.ChainOfThought(TaskPlannerSignature)
427
- prediction = task_planner_func(user_query=message, available_commands=available_commands)
428
- prediction.todo_list.insert(0, "Use the 'what_can_i_do' tool to get details on available commands")
429
- refined_message = (
430
- f"{message}\n"
431
- "Todo list:\n"
432
- f"{'\n'.join([f'{i+1}. {task}' for i, task in enumerate(prediction.todo_list)])}"
433
- )
420
+ refined_message = f'messsage\n{self._think_and_plan(message)}'
434
421
 
422
+ lm = dspy_utils.get_lm("LLM_AGENT", "LITELLM_API_KEY_AGENT")
435
423
  with dspy.context(lm=lm):
436
424
  agent_result = self._workflow_tool_agent(user_query=refined_message)
437
425
  # dspy.inspect_history(n=1)
@@ -444,8 +432,15 @@ class ChatSession:
444
432
  )
445
433
 
446
434
  # Create CommandOutput with the agent's response
435
+ command_response = fastworkflow.CommandResponse(response=result_text)
436
+ # Attach actions captured during agent execution as artifacts if available
437
+ if os.path.exists("action.json"):
438
+ with open("action.json", "r", encoding="utf-8") as f:
439
+ actions = [json.loads(line) for line in f if line.strip()]
440
+ command_response.artifacts["extracted_actions"] = actions
441
+
447
442
  command_output = fastworkflow.CommandOutput(
448
- command_responses=[fastworkflow.CommandResponse(response=result_text)]
443
+ command_responses=[command_response]
449
444
  )
450
445
 
451
446
  # Put output in queue (following same pattern as _process_message)
@@ -470,7 +465,6 @@ class ChatSession:
470
465
  Returns:
471
466
  The result of the invoke_command call
472
467
  """
473
- import os
474
468
  from datetime import datetime
475
469
 
476
470
  # Generate a unique filename with timestamp
@@ -480,7 +474,6 @@ class ChatSession:
480
474
  import cProfile
481
475
  import pstats
482
476
  import io
483
- import os
484
477
  import time
485
478
 
486
479
  # Create a Profile object
@@ -579,3 +572,33 @@ class ChatSession:
579
572
  workflow.flush()
580
573
 
581
574
  return command_output
575
+
576
+ def _think_and_plan(self, user_query: str) -> str:
577
+ """
578
+ Returns a refined plan by breaking down a user_query into simpler tasks based only on available commands and returns a todo list.
579
+ """
580
+ class TaskPlannerSignature(dspy.Signature):
581
+ """
582
+ Break down a user_query into simpler tasks based only on available commands and return a todo list.
583
+ If user_query is simple, return a single todo that is the user_query as-is
584
+ """
585
+ user_query: str = dspy.InputField()
586
+ available_commands: list[str] = dspy.InputField()
587
+ todo_list: list[str] = dspy.OutputField(desc="task descriptions as short sentences")
588
+
589
+ current_workflow = ChatSession.get_active_workflow()
590
+ available_commands = CommandMetadataAPI.get_command_display_text(
591
+ subject_workflow_path=current_workflow.folderpath,
592
+ cme_workflow_path=fastworkflow.get_internal_workflow_path("command_metadata_extraction"),
593
+ active_context_name=current_workflow.current_command_context_name,
594
+ )
595
+
596
+ planner_lm = dspy_utils.get_lm("LLM_PLANNER", "LITELLM_API_KEY_PLANNER")
597
+ with dspy.context(lm=planner_lm):
598
+ task_planner_func = dspy.ChainOfThought(TaskPlannerSignature)
599
+ prediction = task_planner_func(user_query=user_query, available_commands=available_commands)
600
+
601
+ if not prediction.todo_list or (len(prediction.todo_list) == 1 and prediction.todo_list[0] == user_query):
602
+ return user_query
603
+
604
+ return f"{user_query}\nNext steps:\n{'\n'.join([f'{i + 1}. {task}' for i, task in enumerate(prediction.todo_list)])}"
@@ -338,6 +338,12 @@ def add_run_parser(subparsers):
338
338
  parser_run.add_argument("--startup_action", help="Optional startup action", default="")
339
339
  parser_run.add_argument("--keep_alive", help="Optional keep_alive", default=True)
340
340
  parser_run.add_argument("--project_folderpath", help="Optional path to project folder containing application code", default=None)
341
+ parser_run.add_argument(
342
+ "--run_as_agent",
343
+ help="Run in agent mode (uses DSPy for tool selection)",
344
+ action="store_true",
345
+ default=False,
346
+ )
341
347
  parser_run.set_defaults(func=lambda args: run_with_defaults(args))
342
348
 
343
349
  def train_with_defaults(args): # sourcery skip: extract-duplicate-method
@@ -485,6 +491,10 @@ def run_example(args):
485
491
  str(passwords_file)
486
492
  ]
487
493
 
494
+ # Forward agent mode flag if requested
495
+ if getattr(args, "run_as_agent", False):
496
+ cmd.append("--run_as_agent")
497
+
488
498
  try:
489
499
  rprint(f"[bold green]Starting interactive session...[/bold green]")
490
500
  # Replace the current process with the run command
@@ -526,6 +536,12 @@ def main():
526
536
  # 'examples run' command
527
537
  parser_run_example = examples_subparsers.add_parser("run", help="Run a specific example")
528
538
  parser_run_example.add_argument("name", help="The name of the example to run")
539
+ parser_run_example.add_argument(
540
+ "--run_as_agent",
541
+ help="Run the example in agent mode (uses DSPy for tool selection)",
542
+ action="store_true",
543
+ default=False,
544
+ )
529
545
  parser_run_example.set_defaults(func=run_example)
530
546
 
531
547
  # Add top-level commands
@@ -45,10 +45,20 @@ class CommandExecutor(CommandExecutorInterface):
45
45
  command = command)
46
46
  )
47
47
 
48
+ import json
49
+
48
50
  if command_output.command_handled or not command_output.success:
51
+ # Append executed action to action.json for external consumers
52
+ record = {
53
+ "command" if command_output.success else "failing command": command,
54
+ "command_name": command_output.command_name,
55
+ "parameters": command_output.command_parametersr.model_dump(),
56
+ "response": command_output.command_responses[0].response if command_output.success else ''}
57
+ with open("action.json", "a", encoding="utf-8") as f:
58
+ f.write(json.dumps(record, ensure_ascii=False) + "\n")
59
+
49
60
  return command_output
50
61
 
51
- command = command_output.command_responses[0].artifacts["command"]
52
62
  command_name = command_output.command_responses[0].artifacts["command_name"]
53
63
  input_obj = command_output.command_responses[0].artifacts["cmd_parameters"]
54
64
 
@@ -84,7 +94,16 @@ class CommandExecutor(CommandExecutorInterface):
84
94
  command_output.context = context
85
95
  command_output.command_name = command_name
86
96
  command_output.command_parameters = str(input_obj) if input_obj else ''
87
-
97
+
98
+ # Append executed action to action.json for external consumers
99
+ record = {
100
+ "command": command,
101
+ "command_name": command_name,
102
+ "parameters": input_obj.model_dump(),
103
+ "response": command_output.command_responses[0].response}
104
+ with open("action.json", "a", encoding="utf-8") as f:
105
+ f.write(json.dumps(record, ensure_ascii=False) + "\n")
106
+
88
107
  return command_output
89
108
 
90
109
  @classmethod
@@ -22,9 +22,9 @@ class Signature:
22
22
  str,
23
23
  Field(
24
24
  default="NOT_FOUND",
25
- description="The order ID to cancel (must start with #)",
26
- pattern=r"^(#[\w\d]+|NOT_FOUND)$",
27
- examples=["#123", "#abc123", "#order456"],
25
+ description="The order ID to cancel",
26
+ pattern=r"^(#?[\w\d]+|NOT_FOUND)$",
27
+ examples=["123", "#abc123", "order456"],
28
28
  json_schema_extra={
29
29
  "available_from": ["get_user_details"]
30
30
  }
@@ -34,10 +34,10 @@ class Signature:
34
34
  reason: Annotated[
35
35
  str,
36
36
  Field(
37
- default="NOT_FOUND",
38
- description="Reason for cancellation",
37
+ default="ordered by mistake",
38
+ description="Reason for cancellation. If reason is invalid, use the default reason value",
39
39
  json_schema_extra={
40
- "enum": ["no longer needed", "ordered by mistake", "NOT_FOUND"]
40
+ "enum": ["no longer needed", "ordered by mistake"]
41
41
  },
42
42
  examples=["no longer needed", "ordered by mistake"]
43
43
  )
@@ -78,6 +78,15 @@ class Signature:
78
78
  utterances_obj.plain_utterances, command_name
79
79
  )
80
80
 
81
+ @staticmethod
82
+ def validate_extracted_parameters(
83
+ workflow: fastworkflow.Workflow,
84
+ command: str, cmd_parameters: "Signature.Input"
85
+ ) -> tuple[bool, str]:
86
+ if not cmd_parameters.order_id.startswith('#'):
87
+ cmd_parameters.order_id = f'#{cmd_parameters.order_id}'
88
+ return (True, '')
89
+
81
90
 
82
91
  class ResponseGenerator:
83
92
  def __call__(
@@ -14,9 +14,9 @@ class Signature:
14
14
  class Input(BaseModel):
15
15
  order_id: str = Field(
16
16
  default="NOT_FOUND",
17
- description="The order ID to exchange (must start with #)",
18
- pattern=r"^(#[\w\d]+|NOT_FOUND)$",
19
- examples=["#W0000000"],
17
+ description="The order ID to exchange",
18
+ pattern=r"^(#?[\w\d]+|NOT_FOUND)$",
19
+ examples=["#W00000000"],
20
20
  json_schema_extra={
21
21
  "available_from": ["get_user_details"]
22
22
  }
@@ -40,7 +40,8 @@ class Signature:
40
40
  payment_method_id: str = Field(
41
41
  default="NOT_FOUND",
42
42
  description="Payment method ID for price difference.",
43
- examples=["gift_card_0000000", "credit_card_0000000"],
43
+ pattern=r"^((gift_card|credit_card|paypal)_\d+|NOT_FOUND)$",
44
+ examples=["gift_card_0000000", "credit_card_0000000", "paypal_0000000"],
44
45
  json_schema_extra={
45
46
  "available_from": ["get_order_details", "get_user_details"]
46
47
  }
@@ -67,6 +68,15 @@ class Signature:
67
68
  from fastworkflow.train.generate_synthetic import generate_diverse_utterances
68
69
  return generate_diverse_utterances(utterances_obj.plain_utterances, command_name)
69
70
 
71
+ @staticmethod
72
+ def validate_extracted_parameters(
73
+ workflow: fastworkflow.Workflow,
74
+ command: str, cmd_parameters: "Signature.Input"
75
+ ) -> tuple[bool, str]:
76
+ if not cmd_parameters.order_id.startswith('#'):
77
+ cmd_parameters.order_id = f'#{cmd_parameters.order_id}'
78
+ return (True, '')
79
+
70
80
 
71
81
  class ResponseGenerator:
72
82
  def __call__(self, workflow: Workflow, command: str, command_parameters: Signature.Input) -> CommandOutput:
@@ -19,7 +19,7 @@ class Signature:
19
19
  default="NOT_FOUND",
20
20
  description=(
21
21
  "The email address to search for. If email is not available, "
22
- "use `find_user_id_by_name_zip` instead."
22
+ "use `find_user_id_by_name_zip` instead. As a last resort transfer to a human agent"
23
23
  ),
24
24
  pattern=r"^(NOT_FOUND|[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$",
25
25
  examples=["user@example.com"],
@@ -16,9 +16,9 @@ class Signature:
16
16
  order_id: str = Field(
17
17
  default="NOT_FOUND",
18
18
  description=(
19
- "The order ID to get details for (must start with #)"
19
+ "The order ID to get details for"
20
20
  ),
21
- pattern=r"^(#[\w\d]+|NOT_FOUND)$",
21
+ pattern=r"^(#?[\w\d]+|NOT_FOUND)$",
22
22
  examples=["#W0000000"],
23
23
  json_schema_extra={
24
24
  "available_from": ["get_user_details"]
@@ -66,6 +66,15 @@ class Signature:
66
66
 
67
67
  return generate_diverse_utterances(utterances_obj.plain_utterances, command_name)
68
68
 
69
+ @staticmethod
70
+ def validate_extracted_parameters(
71
+ workflow: fastworkflow.Workflow,
72
+ command: str, cmd_parameters: "Signature.Input"
73
+ ) -> tuple[bool, str]:
74
+ if not cmd_parameters.order_id.startswith('#'):
75
+ cmd_parameters.order_id = f'#{cmd_parameters.order_id}'
76
+ return (True, '')
77
+
69
78
 
70
79
  class ResponseGenerator:
71
80
  def __call__(
@@ -14,8 +14,8 @@ class Signature:
14
14
  class Input(BaseModel):
15
15
  order_id: str = Field(
16
16
  default="NOT_FOUND",
17
- description="The order ID to modify (must start with #)",
18
- pattern=r"^(#W\d+|NOT_FOUND)$",
17
+ description="The order ID to modify",
18
+ pattern=r"^(#?[\w\d]+|NOT_FOUND)$",
19
19
  examples=["#W0000000"],
20
20
  json_schema_extra={
21
21
  "available_from": ["get_user_details"]
@@ -59,6 +59,15 @@ class Signature:
59
59
  from fastworkflow.train.generate_synthetic import generate_diverse_utterances
60
60
  return generate_diverse_utterances(utterances_obj.plain_utterances, command_name)
61
61
 
62
+ @staticmethod
63
+ def validate_extracted_parameters(
64
+ workflow: fastworkflow.Workflow,
65
+ command: str, cmd_parameters: "Signature.Input"
66
+ ) -> tuple[bool, str]:
67
+ if not cmd_parameters.order_id.startswith('#'):
68
+ cmd_parameters.order_id = f'#{cmd_parameters.order_id}'
69
+ return (True, '')
70
+
62
71
 
63
72
  class ResponseGenerator:
64
73
  def __call__(self, workflow: Workflow, command: str, command_parameters: Signature.Input) -> CommandOutput:
@@ -14,8 +14,8 @@ class Signature:
14
14
  class Input(BaseModel):
15
15
  order_id: str = Field(
16
16
  default="NOT_FOUND",
17
- description="The order ID to modify (must start with #)",
18
- pattern=r"^(#W\d+|NOT_FOUND)$",
17
+ description="The order ID to modify",
18
+ pattern=r"^(#?[\w\d]+|NOT_FOUND)$",
19
19
  examples=["#W0000000"],
20
20
  json_schema_extra={
21
21
  "available_from": ["get_user_details"]
@@ -40,8 +40,8 @@ class Signature:
40
40
  payment_method_id: str = Field(
41
41
  default="NOT_FOUND",
42
42
  description="Payment method ID for price differences",
43
- pattern=r"^((gift_card|credit_card)_\d+|NOT_FOUND)$",
44
- examples=["gift_card_0000000", "credit_card_0000000"],
43
+ pattern=r"^((gift_card|credit_card|paypal)_\d+|NOT_FOUND)$",
44
+ examples=["gift_card_0000000", "credit_card_0000000", "paypal_0000000"],
45
45
  json_schema_extra={
46
46
  "available_from": ["get_order_details", "get_user_details"]
47
47
  }
@@ -68,6 +68,15 @@ class Signature:
68
68
  from fastworkflow.train.generate_synthetic import generate_diverse_utterances
69
69
  return generate_diverse_utterances(utterances_obj.plain_utterances, command_name)
70
70
 
71
+ @staticmethod
72
+ def validate_extracted_parameters(
73
+ workflow: fastworkflow.Workflow,
74
+ command: str, cmd_parameters: "Signature.Input"
75
+ ) -> tuple[bool, str]:
76
+ if not cmd_parameters.order_id.startswith('#'):
77
+ cmd_parameters.order_id = f'#{cmd_parameters.order_id}'
78
+ return (True, '')
79
+
71
80
 
72
81
  class ResponseGenerator:
73
82
  def __call__(self, workflow: Workflow, command: str, command_parameters: Signature.Input) -> CommandOutput:
@@ -14,8 +14,8 @@ class Signature:
14
14
  class Input(BaseModel):
15
15
  order_id: str = Field(
16
16
  default="NOT_FOUND",
17
- description="The order ID to modify (must start with #)",
18
- pattern=r"^(#W\d+|NOT_FOUND)$",
17
+ description="The order ID to modify",
18
+ pattern=r"^(#?[\w\d]+|NOT_FOUND)$",
19
19
  examples=["#W0000000"],
20
20
  json_schema_extra={
21
21
  "available_from": ["get_user_details"]
@@ -24,8 +24,8 @@ class Signature:
24
24
  payment_method_id: str = Field(
25
25
  default="NOT_FOUND",
26
26
  description="Payment method ID to switch to",
27
- pattern=r"^((gift_card|credit_card)_\d+|NOT_FOUND)$",
28
- examples=["gift_card_0000000", "credit_card_0000000"],
27
+ pattern=r"^((gift_card|credit_card|paypal)_\d+|NOT_FOUND)$",
28
+ examples=["gift_card_0000000", "credit_card_0000000", "paypal_0000000"],
29
29
  json_schema_extra={
30
30
  "available_from": ["get_user_details"]
31
31
  }
@@ -52,6 +52,15 @@ class Signature:
52
52
  from fastworkflow.train.generate_synthetic import generate_diverse_utterances
53
53
  return generate_diverse_utterances(utterances_obj.plain_utterances, command_name)
54
54
 
55
+ @staticmethod
56
+ def validate_extracted_parameters(
57
+ workflow: fastworkflow.Workflow,
58
+ command: str, cmd_parameters: "Signature.Input"
59
+ ) -> tuple[bool, str]:
60
+ if not cmd_parameters.order_id.startswith('#'):
61
+ cmd_parameters.order_id = f'#{cmd_parameters.order_id}'
62
+ return (True, '')
63
+
55
64
 
56
65
  class ResponseGenerator:
57
66
  def __call__(self, workflow: Workflow, command: str, command_parameters: Signature.Input) -> CommandOutput:
@@ -14,9 +14,9 @@ class Signature:
14
14
  class Input(BaseModel):
15
15
  order_id: str = Field(
16
16
  default="NOT_FOUND",
17
- description="The order ID for return (must start with #)",
18
- pattern=r"^(#W\d+|NOT_FOUND)$",
19
- examples=["#W3456890"],
17
+ description="The order ID of return items",
18
+ pattern=r"^(#?[\w\d]+|NOT_FOUND)$",
19
+ examples=["#W00000000"],
20
20
  json_schema_extra={
21
21
  "available_from": ["get_user_details"]
22
22
  }
@@ -32,8 +32,8 @@ class Signature:
32
32
  payment_method_id: str = Field(
33
33
  default="NOT_FOUND",
34
34
  description="Payment method ID for refund",
35
- pattern=r"^((gift_card|credit_card)_\d+|NOT_FOUND)$",
36
- examples=["gift_card_0000000", "credit_card_0000000"],
35
+ pattern=r"^((gift_card|credit_card|paypal)_\d+|NOT_FOUND)$",
36
+ examples=["gift_card_0000000", "credit_card_0000000", "paypal_0000000"],
37
37
  json_schema_extra={
38
38
  "available_from": ["get_order_details"]
39
39
  }
@@ -62,6 +62,15 @@ class Signature:
62
62
  from fastworkflow.train.generate_synthetic import generate_diverse_utterances
63
63
  return generate_diverse_utterances(utterances_obj.plain_utterances, command_name)
64
64
 
65
+ @staticmethod
66
+ def validate_extracted_parameters(
67
+ workflow: fastworkflow.Workflow,
68
+ command: str, cmd_parameters: "Signature.Input"
69
+ ) -> tuple[bool, str]:
70
+ if not cmd_parameters.order_id.startswith('#'):
71
+ cmd_parameters.order_id = f'#{cmd_parameters.order_id}'
72
+ return (True, '')
73
+
65
74
 
66
75
  class ResponseGenerator:
67
76
  def __call__(self, workflow: Workflow, command: str, command_parameters: Signature.Input) -> CommandOutput:
@@ -10,7 +10,7 @@ from ..tools.transfer_to_human_agents import TransferToHumanAgents
10
10
 
11
11
 
12
12
  class Signature:
13
- """Transfer to a human agent as the last resort"""
13
+ """Transfer to a human agent ONLY AS THE LAST RESORT"""
14
14
  class Input(BaseModel):
15
15
  summary: str = Field(
16
16
  default="NOT_FOUND",
@@ -408,7 +408,13 @@ Today's date is {today}.
408
408
  ):
409
409
  return (True, "All required parameters are valid.", {})
410
410
 
411
- is_valid, message = self.input_for_param_extraction_class.validate_extracted_parameters(app_workflow, subject_command_name, cmd_parameters)
411
+ try:
412
+ is_valid, message = self.input_for_param_extraction_class.validate_extracted_parameters(app_workflow, subject_command_name, cmd_parameters)
413
+ except Exception as e:
414
+ message = f"Exception in {subject_command_name}'s validate_extracted_parameters function: {str(e)}"
415
+ logger.critical(message)
416
+ return (False, message, {})
417
+
412
418
  if is_valid:
413
419
  return (True, "All required parameters are valid.", {})
414
420
  return (False, message, {})
@@ -422,7 +428,7 @@ Today's date is {today}.
422
428
  if hasattr(type(cmd_parameters).model_fields.get(missing_field), "json_schema_extra") and type(cmd_parameters).model_fields.get(missing_field).json_schema_extra:
423
429
  is_available_from = type(cmd_parameters).model_fields.get(missing_field).json_schema_extra.get("available_from")
424
430
  if is_available_from:
425
- message += f"abort and use the {' or '.join(is_available_from)} command(s) to get {missing_field} information\n"
431
+ message += f"abort and use the {' or '.join(is_available_from)} command(s) to get {missing_field} information. OR...\n"
426
432
 
427
433
  if invalid_fields:
428
434
  message += f"{INVALID_INFORMATION_ERRMSG}" + ", ".join(invalid_fields) + "\n"
@@ -285,6 +285,24 @@ class Workflow:
285
285
  def is_complete(self, value: bool) -> None:
286
286
  self._is_complete = value
287
287
  self._mark_dirty()
288
+
289
+ def end_command_processing(self) -> None:
290
+ """Process the end of a command"""
291
+ mark_dirty = False
292
+ # important to clear the current command from the workflow context
293
+ if "command" in self._context:
294
+ del self._context["command"]
295
+ mark_dirty = True
296
+
297
+ # important to clear parameter extraction error state (if any)
298
+ if "stored_parameters" in self._context:
299
+ del self._context["stored_parameters"]
300
+ mark_dirty = True
301
+
302
+ self._context["NLU_Pipeline_Stage"] = fastworkflow.NLUPipelineStage.INTENT_DETECTION
303
+
304
+ if mark_dirty:
305
+ self._mark_dirty()
288
306
 
289
307
  def close(self) -> bool:
290
308
  """close the session"""