fastworkflow 2.13.5__tar.gz → 2.14.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.
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/PKG-INFO +1 -1
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/_workflows/command_metadata_extraction/_commands/ErrorCorrection/you_misunderstood.py +1 -1
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/go_up.py +1 -1
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/reset_context.py +1 -1
- fastworkflow-2.14.0/fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/what_can_i_do.py +158 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/_workflows/command_metadata_extraction/_commands/wildcard.py +7 -3
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/genai_postprocessor.py +143 -149
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/chat_session.py +42 -11
- fastworkflow-2.14.0/fastworkflow/command_metadata_api.py +788 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/command_routing.py +4 -1
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/hello_world/_commands/add_two_numbers.py +1 -0
- fastworkflow-2.14.0/fastworkflow/examples/retail_workflow/_commands/calculate.py +67 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/_commands/cancel_pending_order.py +4 -1
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/_commands/exchange_delivered_order_items.py +13 -1
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/_commands/find_user_id_by_email.py +6 -1
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/_commands/find_user_id_by_name_zip.py +6 -1
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/_commands/get_order_details.py +22 -10
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/_commands/get_product_details.py +12 -4
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/_commands/get_user_details.py +21 -5
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/_commands/list_all_product_types.py +4 -1
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/_commands/modify_pending_order_address.py +3 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/_commands/modify_pending_order_items.py +12 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/_commands/modify_pending_order_payment.py +7 -1
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/_commands/modify_user_address.py +3 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/_commands/return_delivered_order_items.py +10 -1
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/_commands/transfer_to_human_agents.py +1 -1
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/tools/calculate.py +1 -1
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/mcp_server.py +52 -44
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/run/__main__.py +9 -5
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/run_agent/__main__.py +8 -8
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/run_agent/agent_module.py +6 -16
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/utils/command_dependency_graph.py +130 -143
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/utils/dspy_utils.py +11 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/utils/signatures.py +7 -0
- fastworkflow-2.14.0/fastworkflow/workflow_agent.py +186 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/pyproject.toml +1 -1
- fastworkflow-2.13.5/fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/what_can_i_do.py +0 -226
- fastworkflow-2.13.5/fastworkflow/agent_integration.py +0 -239
- fastworkflow-2.13.5/fastworkflow/examples/retail_workflow/_commands/parameter_dependency_graph.json +0 -36
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/LICENSE +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/README.md +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/.DS_Store +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/__init__.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/_workflows/__init__.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/_workflows/command_metadata_extraction/__init__.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/_workflows/command_metadata_extraction/_commands/ErrorCorrection/abort.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/what_is_current_context.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/_workflows/command_metadata_extraction/_commands/__init__.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/_workflows/command_metadata_extraction/command_context_model.json +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/__main__.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/ast_class_extractor.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/class_analysis_structures.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/cli_specification.md +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/command_dependency_resolver.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/command_file_generator.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/command_file_template.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/command_import_utils.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/command_stub_generator.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/context_folder_generator.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/context_model_generator.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/dependency_manager.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/dir_scanner.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/documentation_generator.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/inheritance_block_regenerator.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/libcst_transformers.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/navigator_stub_generator.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/pydantic_model_generator.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/build/utterance_generator.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/cache_matching.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/cli.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/command_context_model.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/command_directory.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/command_executor.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/command_interfaces.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/docs/context_modules_prd.txt +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/extended_workflow_example/README.md +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/extended_workflow_example/_commands/WorkItem/get_status.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/extended_workflow_example/_commands/generate_report.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/extended_workflow_example/_commands/startup.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/extended_workflow_example/simple_workflow_template.json +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/extended_workflow_example/workflow_inheritance_model.json +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/fastworkflow.env +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/fastworkflow.passwords.env +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/hello_world/_commands/README.md +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/hello_world/_commands/context_inheritance_model.json +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/hello_world/application/add_two_numbers.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_1/_commands/context_inheritance_model.json +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_1/_commands/send_message.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_1/application/send_message.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_2/_commands/User/send_message.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_2/_commands/context_inheritance_model.json +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_2/_commands/startup.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_2/application/user.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_3/_commands/PremiumUser/send_priority_message.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_3/_commands/User/send_message.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_3/_commands/context_inheritance_model.json +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_3/_commands/initialize_user.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_3/application/user.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/_ChatRoom.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/add_user.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/broadcast_message.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/get_current_user.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/list_users.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_4/_commands/ChatRoom/set_current_user.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_4/_commands/PremiumUser/_PremiumUser.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_4/_commands/PremiumUser/send_priority_message.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_4/_commands/User/_User.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_4/_commands/User/send_message.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_4/_commands/context_inheritance_model.json +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_4/_commands/set_root_context.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_4/application/chatroom.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_4/application/user.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_4/context_hierarchy_model.json +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/messaging_app_4/startup_action.json +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/command_dependency_graph.json +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/context_inheritance_model.json +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/retail_data/__init__.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/retail_data/orders.json +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/retail_data/products.json +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/retail_data/users.json +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/tools/cancel_pending_order.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/tools/exchange_delivered_order_items.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/tools/find_user_id_by_email.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/tools/find_user_id_by_name_zip.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/tools/get_order_details.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/tools/get_product_details.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/tools/get_user_details.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/tools/list_all_product_types.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/tools/modify_pending_order_address.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/tools/modify_pending_order_items.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/tools/modify_pending_order_payment.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/tools/modify_user_address.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/tools/return_delivered_order_items.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/tools/think.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/tools/tool.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/tools/transfer_to_human_agents.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/retail_workflow/workflow_description.txt +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/simple_workflow_template/__init__.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/_WorkItem.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/add_child_workitem.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/get_status.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/go_to_workitem.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/mark_as_complete.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/move_to_first_child_workitem.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/move_to_last_child_workitem.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/move_to_next_workitem.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/move_to_previous_workitem.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/remove_all_child_workitems.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/remove_child_workitem.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/simple_workflow_template/_commands/WorkItem/show_schema.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/simple_workflow_template/_commands/startup.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/simple_workflow_template/application/__init__.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/simple_workflow_template/application/workitem.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/simple_workflow_template/simple_workflow_template.json +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/examples/simple_workflow_template/startup_action.json +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/model_pipeline_training.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/refine/__main__.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/run/__init__.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/run_agent/__init__.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/train/__init__.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/train/__main__.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/train/generate_synthetic.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/user_message_queues.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/utils/__init__.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/utils/context_utils.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/utils/dspy_cache_utils.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/utils/dspy_logger.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/utils/env.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/utils/fuzzy_match.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/utils/generate_param_examples.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/utils/logging.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/utils/parameterize_func_decorator.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/utils/pydantic_model_2_dspy_signature_class.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/utils/python_utils.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/utils/startup_progress.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.0}/fastworkflow/workflow.py +0 -0
- {fastworkflow-2.13.5 → fastworkflow-2.14.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.
|
|
3
|
+
Version: 2.14.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
|
|
@@ -41,7 +41,7 @@ class ResponseGenerator:
|
|
|
41
41
|
fully_qualified_command_names = (
|
|
42
42
|
set(cme_command_names) |
|
|
43
43
|
set(subject_crd.get_command_names(app_workflow.current_command_context_name))
|
|
44
|
-
)
|
|
44
|
+
)
|
|
45
45
|
|
|
46
46
|
valid_command_names = [
|
|
47
47
|
fully_qualified_command_name.split('/')[-1]
|
|
@@ -6,7 +6,7 @@ from fastworkflow.train.generate_synthetic import generate_diverse_utterances
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class Signature: # noqa: D101
|
|
9
|
-
"""Change context to the parent of the current context."""
|
|
9
|
+
"""Change context to the parent of the current context. This could change the commands that are available."""
|
|
10
10
|
|
|
11
11
|
plain_utterances = [
|
|
12
12
|
"go up",
|
|
@@ -5,7 +5,7 @@ from fastworkflow.train.generate_synthetic import generate_diverse_utterances
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class Signature: # noqa: D101
|
|
8
|
-
"""Reset the current context to the global context (*)."""
|
|
8
|
+
"""Reset the current context to the global context (*). This could change the commands that are available."""
|
|
9
9
|
plain_utterances = [
|
|
10
10
|
"reset context",
|
|
11
11
|
"clear context",
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import contextlib
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Dict, Any
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
import json
|
|
8
|
+
|
|
9
|
+
import fastworkflow
|
|
10
|
+
from fastworkflow.train.generate_synthetic import generate_diverse_utterances
|
|
11
|
+
from fastworkflow.command_metadata_api import CommandMetadataAPI
|
|
12
|
+
|
|
13
|
+
class Signature:
|
|
14
|
+
"""List all the commands available in the current context along with their metadata"""
|
|
15
|
+
class Output(BaseModel):
|
|
16
|
+
valid_command_names: list[str]
|
|
17
|
+
|
|
18
|
+
# Constants from plain_utterances.json
|
|
19
|
+
plain_utterances = [
|
|
20
|
+
"show me all the utterances",
|
|
21
|
+
"what can you do?",
|
|
22
|
+
"what are my options?",
|
|
23
|
+
"what are my choices?",
|
|
24
|
+
"what are my capabilities?",
|
|
25
|
+
"what can i do?",
|
|
26
|
+
"what can i do here?",
|
|
27
|
+
"what can i use?",
|
|
28
|
+
"what are my tools?",
|
|
29
|
+
"now what?",
|
|
30
|
+
"list commands",
|
|
31
|
+
"list utterances"
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def generate_utterances(workflow: fastworkflow.Workflow, command_name: str) -> list[str]:
|
|
36
|
+
return [
|
|
37
|
+
command_name.split('/')[-1].lower().replace('_', ' ')
|
|
38
|
+
] + generate_diverse_utterances(Signature.plain_utterances, command_name)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ResponseGenerator:
|
|
42
|
+
# def _get_enhanced_command_info(self, workflow: fastworkflow.Workflow) -> Dict[str, Any]:
|
|
43
|
+
# """
|
|
44
|
+
# Get enhanced command information for agent mode.
|
|
45
|
+
# Returns structured JSON with context info, command details, etc.
|
|
46
|
+
# """
|
|
47
|
+
# app_workflow = workflow.context["app_workflow"]
|
|
48
|
+
|
|
49
|
+
# # Get the current context information
|
|
50
|
+
# context_info = {
|
|
51
|
+
# "name": app_workflow.current_command_context_name,
|
|
52
|
+
# "display_name": app_workflow.current_command_context_displayname,
|
|
53
|
+
# "description": "",
|
|
54
|
+
# "inheritance": [],
|
|
55
|
+
# "containment": []
|
|
56
|
+
# }
|
|
57
|
+
|
|
58
|
+
# # Try to load context hierarchy information if available
|
|
59
|
+
# with contextlib.suppress(Exception):
|
|
60
|
+
# inheritance_path = Path(app_workflow.folderpath) / "context_inheritance_model.json"
|
|
61
|
+
# if inheritance_path.exists():
|
|
62
|
+
# with open(inheritance_path) as f:
|
|
63
|
+
# inheritance_data = json.load(f)
|
|
64
|
+
# context_info["inheritance"] = inheritance_data.get(context_info["name"], [])
|
|
65
|
+
|
|
66
|
+
# containment_path = Path(app_workflow.folderpath) / "context_containment_model.json"
|
|
67
|
+
# if containment_path.exists():
|
|
68
|
+
# with open(containment_path) as f:
|
|
69
|
+
# containment_data = json.load(f)
|
|
70
|
+
# context_info["containment"] = containment_data.get(context_info["name"], [])
|
|
71
|
+
|
|
72
|
+
# from fastworkflow.command_metadata_api import CommandMetadataAPI
|
|
73
|
+
|
|
74
|
+
# meta = CommandMetadataAPI.get_enhanced_command_info(
|
|
75
|
+
# subject_workflow_path=app_workflow.folderpath,
|
|
76
|
+
# cme_workflow_path=workflow.folderpath,
|
|
77
|
+
# active_context_name=app_workflow.current_command_context_name,
|
|
78
|
+
# )
|
|
79
|
+
|
|
80
|
+
# return {
|
|
81
|
+
# "context": context_info,
|
|
82
|
+
# "commands": meta.get("commands", [])
|
|
83
|
+
# }
|
|
84
|
+
|
|
85
|
+
# def _process_command(
|
|
86
|
+
# self, workflow: fastworkflow.Workflow
|
|
87
|
+
# ) -> Signature.Output:
|
|
88
|
+
# """
|
|
89
|
+
# Provides helpful information about this type of work-item.
|
|
90
|
+
# If the workitem_path is not provided, it provides information about the current work-item.
|
|
91
|
+
|
|
92
|
+
# :param input: The input parameters for the function.
|
|
93
|
+
# """
|
|
94
|
+
# app_workflow = workflow.context["app_workflow"]
|
|
95
|
+
# subject_crd = fastworkflow.RoutingRegistry.get_definition(
|
|
96
|
+
# app_workflow.folderpath)
|
|
97
|
+
|
|
98
|
+
# crd = fastworkflow.RoutingRegistry.get_definition(
|
|
99
|
+
# workflow.folderpath)
|
|
100
|
+
# cme_command_names = crd.get_command_names('IntentDetection')
|
|
101
|
+
|
|
102
|
+
# # ------------------------------------------------------------------
|
|
103
|
+
# # Build the union of command names that *should* be visible, then
|
|
104
|
+
# # filter out any command that (a) is the special wildcard helper or
|
|
105
|
+
# # (b) has no user-facing utterances in *any* command directory.
|
|
106
|
+
# # ------------------------------------------------------------------
|
|
107
|
+
|
|
108
|
+
# candidate_commands: set[str] = (
|
|
109
|
+
# set(cme_command_names)
|
|
110
|
+
# | set(subject_crd.get_command_names(app_workflow.current_command_context_name))
|
|
111
|
+
# )
|
|
112
|
+
|
|
113
|
+
# def _has_utterances(fq_cmd: str) -> bool:
|
|
114
|
+
# """Return True if *fq_cmd* has at least one utterance definition in
|
|
115
|
+
# either the subject workflow or the CME workflow."""
|
|
116
|
+
# return (
|
|
117
|
+
# subject_crd.command_directory.get_utterance_metadata(fq_cmd) is not None
|
|
118
|
+
# or crd.command_directory.get_utterance_metadata(fq_cmd) is not None
|
|
119
|
+
# )
|
|
120
|
+
|
|
121
|
+
# visible_commands = [
|
|
122
|
+
# fq_cmd for fq_cmd in candidate_commands
|
|
123
|
+
# if fq_cmd != "wildcard" and _has_utterances(fq_cmd)
|
|
124
|
+
# ]
|
|
125
|
+
|
|
126
|
+
# valid_command_names = [
|
|
127
|
+
# cmd.split("/")[-1] for cmd in sorted(visible_commands)
|
|
128
|
+
# ]
|
|
129
|
+
|
|
130
|
+
# return Signature.Output(valid_command_names=valid_command_names)
|
|
131
|
+
|
|
132
|
+
def __call__(
|
|
133
|
+
self,
|
|
134
|
+
workflow: fastworkflow.Workflow,
|
|
135
|
+
command: str,
|
|
136
|
+
) -> fastworkflow.CommandOutput:
|
|
137
|
+
# Check if we're in agent mode by looking for chat session run_as_agent flag
|
|
138
|
+
is_agent_mode = False
|
|
139
|
+
with contextlib.suppress(Exception):
|
|
140
|
+
if fastworkflow.chat_session:
|
|
141
|
+
is_agent_mode = fastworkflow.chat_session.run_as_agent
|
|
142
|
+
|
|
143
|
+
app_workflow = workflow.context["app_workflow"]
|
|
144
|
+
response = CommandMetadataAPI.get_command_display_text(
|
|
145
|
+
subject_workflow_path=app_workflow.folderpath,
|
|
146
|
+
cme_workflow_path=workflow.folderpath,
|
|
147
|
+
active_context_name=app_workflow.current_command_context_name,
|
|
148
|
+
for_agents=is_agent_mode,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
return fastworkflow.CommandOutput(
|
|
152
|
+
workflow_id=workflow.id,
|
|
153
|
+
command_responses=[
|
|
154
|
+
fastworkflow.CommandResponse(
|
|
155
|
+
response=response,
|
|
156
|
+
)
|
|
157
|
+
]
|
|
158
|
+
)
|
|
@@ -80,7 +80,7 @@ class CommandNamePrediction:
|
|
|
80
80
|
valid_command_names = (
|
|
81
81
|
set(cme_command_names) |
|
|
82
82
|
set(app_crd.get_command_names(command_context_name))
|
|
83
|
-
)
|
|
83
|
+
)
|
|
84
84
|
|
|
85
85
|
command_name_dict = {
|
|
86
86
|
fully_qualified_command_name.split('/')[-1]: fully_qualified_command_name
|
|
@@ -338,7 +338,11 @@ class ParameterExtraction:
|
|
|
338
338
|
|
|
339
339
|
stored_params = self._get_stored_parameters(self.cme_workflow)
|
|
340
340
|
|
|
341
|
-
|
|
341
|
+
self.command = self.command.replace(self.command_name, "").strip()
|
|
342
|
+
|
|
343
|
+
input_for_param_extraction = InputForParamExtraction.create(
|
|
344
|
+
self.app_workflow, self.command_name,
|
|
345
|
+
self.command)
|
|
342
346
|
|
|
343
347
|
if stored_params:
|
|
344
348
|
_, _, _, stored_missing_fields = self._extract_missing_fields(input_for_param_extraction, self.app_workflow, self.command_name, stored_params)
|
|
@@ -372,7 +376,7 @@ class ParameterExtraction:
|
|
|
372
376
|
if params_str := self._format_parameters_for_display(merged_params):
|
|
373
377
|
error_msg = f"Extracted parameters so far:\n{params_str}\n\n{error_msg}"
|
|
374
378
|
|
|
375
|
-
error_msg += "\nEnter 'abort'
|
|
379
|
+
error_msg += "\nEnter 'abort' to get out of this error state and/or execute a different command."
|
|
376
380
|
error_msg += "\nEnter 'you misunderstood' if the wrong command was executed."
|
|
377
381
|
return self.Output(
|
|
378
382
|
parameters_are_valid=False,
|
|
@@ -18,8 +18,9 @@ import traceback
|
|
|
18
18
|
import libcst as cst
|
|
19
19
|
import dspy
|
|
20
20
|
from pydantic import BaseModel, Field
|
|
21
|
-
import fastworkflow
|
|
22
21
|
|
|
22
|
+
import fastworkflow
|
|
23
|
+
from fastworkflow.utils import dspy_utils
|
|
23
24
|
from fastworkflow.build.class_analysis_structures import ClassInfo, MethodInfo, FunctionInfo
|
|
24
25
|
from fastworkflow.build.libcst_transformers import (
|
|
25
26
|
SignatureDocstringUpdater,
|
|
@@ -235,11 +236,7 @@ class GenAIPostProcessor:
|
|
|
235
236
|
def __init__(self):
|
|
236
237
|
"""Initialize the post-processor with DSPy configuration."""
|
|
237
238
|
# Get model and API key from FastWorkflow environment
|
|
238
|
-
self.
|
|
239
|
-
self.api_key = fastworkflow.get_env_var("LITELLM_API_KEY_COMMANDMETADATA_GEN", default=None)
|
|
240
|
-
|
|
241
|
-
# Initialize DSPy with the configured model
|
|
242
|
-
self._initialize_dspy()
|
|
239
|
+
self.lm = dspy_utils.get_lm("LLM_COMMAND_METADATA_GEN", "LITELLM_API_KEY_COMMANDMETADATA_GEN", max_tokens=2000)
|
|
243
240
|
|
|
244
241
|
# Initialize DSPy modules (reuse from original)
|
|
245
242
|
self.field_generator = FieldMetadataGenerator()
|
|
@@ -256,16 +253,6 @@ class GenAIPostProcessor:
|
|
|
256
253
|
'utterances_added': 0
|
|
257
254
|
}
|
|
258
255
|
|
|
259
|
-
def _initialize_dspy(self):
|
|
260
|
-
"""Initialize DSPy with the configured model using LiteLLM."""
|
|
261
|
-
try:
|
|
262
|
-
lm = dspy.LM(model=self.model, api_key=self.api_key, max_tokens=2000)
|
|
263
|
-
dspy.settings.configure(lm=lm)
|
|
264
|
-
logger.info(f"DSPy initialized with model: {self.model}")
|
|
265
|
-
except Exception as e:
|
|
266
|
-
logger.error(f"Failed to initialize DSPy: {e}")
|
|
267
|
-
raise
|
|
268
|
-
|
|
269
256
|
def process_workflow(self, workflow_path: str, classes: Dict[str, ClassInfo],
|
|
270
257
|
functions: Optional[Dict[str, FunctionInfo]] = None) -> bool:
|
|
271
258
|
"""Process all command files in the workflow with targeted updates.
|
|
@@ -280,17 +267,17 @@ class GenAIPostProcessor:
|
|
|
280
267
|
"""
|
|
281
268
|
try:
|
|
282
269
|
logger.info("Starting targeted GenAI post-processing with LibCST...")
|
|
283
|
-
|
|
270
|
+
|
|
284
271
|
# Process command files
|
|
285
272
|
commands_dir = os.path.join(workflow_path, "_commands")
|
|
286
273
|
if not os.path.exists(commands_dir):
|
|
287
274
|
logger.error(f"Commands directory not found: {commands_dir}")
|
|
288
275
|
return False
|
|
289
|
-
|
|
276
|
+
|
|
290
277
|
# Track all contexts and commands for workflow description
|
|
291
278
|
all_contexts = {}
|
|
292
279
|
global_commands = []
|
|
293
|
-
|
|
280
|
+
|
|
294
281
|
# Process context-specific commands
|
|
295
282
|
for context_dir in os.listdir(commands_dir):
|
|
296
283
|
context_path = os.path.join(commands_dir, context_dir)
|
|
@@ -304,10 +291,10 @@ class GenAIPostProcessor:
|
|
|
304
291
|
'commands': context_commands,
|
|
305
292
|
'docstring': ""
|
|
306
293
|
}
|
|
307
|
-
|
|
294
|
+
|
|
308
295
|
# Generate context handler docstring (still uses original method)
|
|
309
296
|
self._generate_context_handler_docstring(context_path, context_dir, context_commands)
|
|
310
|
-
|
|
297
|
+
|
|
311
298
|
# Process global commands
|
|
312
299
|
for file_name in os.listdir(commands_dir):
|
|
313
300
|
file_path = os.path.join(commands_dir, file_name)
|
|
@@ -319,20 +306,20 @@ class GenAIPostProcessor:
|
|
|
319
306
|
'name': command_name,
|
|
320
307
|
'docstring': func_info.docstring if func_info else ""
|
|
321
308
|
})
|
|
322
|
-
|
|
309
|
+
|
|
323
310
|
# Generate workflow description (reuse original method)
|
|
324
311
|
self._generate_workflow_description(workflow_path, all_contexts, global_commands)
|
|
325
|
-
|
|
312
|
+
|
|
326
313
|
# Log statistics
|
|
327
|
-
logger.info(
|
|
314
|
+
logger.info("Targeted post-processing completed:")
|
|
328
315
|
logger.info(f" Files processed: {self.stats['files_processed']}")
|
|
329
316
|
logger.info(f" Files updated: {self.stats['files_updated']}")
|
|
330
317
|
logger.info(f" Docstrings added: {self.stats['docstrings_added']}")
|
|
331
318
|
logger.info(f" Fields updated: {self.stats['fields_updated']}")
|
|
332
319
|
logger.info(f" Utterances added: {self.stats['utterances_added']}")
|
|
333
|
-
|
|
320
|
+
|
|
334
321
|
return True
|
|
335
|
-
|
|
322
|
+
|
|
336
323
|
except Exception as e:
|
|
337
324
|
logger.error(f"Error during targeted GenAI post-processing: {e}")
|
|
338
325
|
logger.error(traceback.format_exc())
|
|
@@ -465,112 +452,116 @@ class GenAIPostProcessor:
|
|
|
465
452
|
"""Generate enhanced content using DSPy modules, only for missing elements."""
|
|
466
453
|
|
|
467
454
|
enhanced_data = {}
|
|
468
|
-
|
|
455
|
+
|
|
469
456
|
# Only generate docstring if missing or empty
|
|
470
457
|
if not current_state.get('has_signature_docstring'):
|
|
471
458
|
try:
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
459
|
+
with dspy.context(lm=self.lm):
|
|
460
|
+
signature_docstring = self.docstring_generator.generate_signature_docstring(
|
|
461
|
+
command_name=command_name,
|
|
462
|
+
input_fields=[{
|
|
463
|
+
'name': f['name'],
|
|
464
|
+
'type': f['type'],
|
|
465
|
+
'description': '' # Will be generated if needed
|
|
466
|
+
} for f in current_state['input_fields']],
|
|
467
|
+
output_fields=[{
|
|
468
|
+
'name': f['name'],
|
|
469
|
+
'type': f['type'],
|
|
470
|
+
'description': ''
|
|
471
|
+
} for f in current_state['output_fields']],
|
|
472
|
+
context_name=context_name or "global"
|
|
473
|
+
)
|
|
474
|
+
enhanced_data['signature_docstring'] = signature_docstring
|
|
475
|
+
logger.debug(f"Generated new docstring for {command_name}")
|
|
488
476
|
except Exception as e:
|
|
489
477
|
logger.warning(f"Failed to generate docstring for {command_name}: {e}")
|
|
490
|
-
|
|
478
|
+
|
|
491
479
|
# Generate field metadata only for fields missing descriptions/examples
|
|
492
480
|
field_metadata = {}
|
|
493
|
-
|
|
481
|
+
|
|
494
482
|
# Process input fields
|
|
495
483
|
for field_info in current_state['input_fields']:
|
|
496
484
|
if not field_info.get('has_description') or not field_info.get('has_examples'):
|
|
497
485
|
try:
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
486
|
+
with dspy.context(lm=self.lm):
|
|
487
|
+
metadata = self.field_generator(
|
|
488
|
+
field_name=field_info['name'],
|
|
489
|
+
field_type=field_info['type'],
|
|
490
|
+
method_docstring=method_or_func_info.docstring if method_or_func_info else "",
|
|
491
|
+
method_name=command_name,
|
|
492
|
+
context_name=context_name or "global",
|
|
493
|
+
is_input=True
|
|
494
|
+
)
|
|
495
|
+
|
|
496
|
+
field_key = f"Input.{field_info['name']}"
|
|
497
|
+
field_metadata[field_key] = {}
|
|
498
|
+
|
|
499
|
+
if not field_info.get('has_description'):
|
|
500
|
+
field_metadata[field_key]['description'] = metadata.description
|
|
501
|
+
|
|
502
|
+
if not field_info.get('has_examples'):
|
|
503
|
+
field_metadata[field_key]['examples'] = metadata.examples
|
|
504
|
+
|
|
505
|
+
if metadata.pattern and metadata.pattern.strip():
|
|
506
|
+
field_metadata[field_key]['pattern'] = metadata.pattern
|
|
507
|
+
|
|
508
|
+
logger.debug(f"Generated metadata for {field_key}")
|
|
520
509
|
except Exception as e:
|
|
521
510
|
logger.warning(f"Failed to generate metadata for Input.{field_info['name']}: {e}")
|
|
522
|
-
|
|
511
|
+
|
|
523
512
|
# Process output fields
|
|
524
513
|
for field_info in current_state['output_fields']:
|
|
525
514
|
if not field_info.get('has_description') or not field_info.get('has_examples'):
|
|
526
515
|
try:
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
516
|
+
with dspy.context(lm=self.lm):
|
|
517
|
+
metadata = self.field_generator(
|
|
518
|
+
field_name=field_info['name'],
|
|
519
|
+
field_type=field_info['type'],
|
|
520
|
+
method_docstring=method_or_func_info.docstring if method_or_func_info else "",
|
|
521
|
+
method_name=command_name,
|
|
522
|
+
context_name=context_name or "global",
|
|
523
|
+
is_input=False
|
|
524
|
+
)
|
|
525
|
+
|
|
526
|
+
field_key = f"Output.{field_info['name']}"
|
|
527
|
+
field_metadata[field_key] = {}
|
|
528
|
+
|
|
529
|
+
if not field_info.get('has_description'):
|
|
530
|
+
field_metadata[field_key]['description'] = metadata.description
|
|
531
|
+
|
|
532
|
+
if not field_info.get('has_examples'):
|
|
533
|
+
field_metadata[field_key]['examples'] = metadata.examples
|
|
534
|
+
|
|
535
|
+
logger.debug(f"Generated metadata for {field_key}")
|
|
546
536
|
except Exception as e:
|
|
547
537
|
logger.warning(f"Failed to generate metadata for Output.{field_info['name']}: {e}")
|
|
548
|
-
|
|
538
|
+
|
|
549
539
|
if field_metadata:
|
|
550
540
|
enhanced_data['field_metadata'] = field_metadata
|
|
551
|
-
|
|
541
|
+
|
|
552
542
|
# Generate new utterances to append
|
|
553
543
|
try:
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
544
|
+
with dspy.context(lm=self.lm):
|
|
545
|
+
new_utterances = self.utterance_generator(
|
|
546
|
+
command_name=command_name,
|
|
547
|
+
command_docstring=method_or_func_info.docstring if method_or_func_info else "",
|
|
548
|
+
input_fields=[{
|
|
549
|
+
'name': f['name'],
|
|
550
|
+
'type': f['type'],
|
|
551
|
+
'description': ''
|
|
552
|
+
} for f in current_state['input_fields']]
|
|
553
|
+
)
|
|
554
|
+
|
|
555
|
+
# Filter out existing utterances
|
|
556
|
+
existing_utterances = set(current_state.get('plain_utterances', []))
|
|
557
|
+
if truly_new_utterances := [
|
|
558
|
+
u for u in new_utterances if u not in existing_utterances
|
|
559
|
+
]:
|
|
560
|
+
enhanced_data['new_utterances'] = truly_new_utterances
|
|
561
|
+
logger.debug(f"Generated {len(truly_new_utterances)} new utterances for {command_name}")
|
|
571
562
|
except Exception as e:
|
|
572
563
|
logger.warning(f"Failed to generate utterances for {command_name}: {e}")
|
|
573
|
-
|
|
564
|
+
|
|
574
565
|
return enhanced_data
|
|
575
566
|
|
|
576
567
|
def _generate_context_handler_docstring(self, context_path: str, context_name: str,
|
|
@@ -581,66 +572,67 @@ class GenAIPostProcessor:
|
|
|
581
572
|
if not os.path.exists(handler_file):
|
|
582
573
|
logger.debug(f"Context handler file not found: {handler_file}")
|
|
583
574
|
return
|
|
584
|
-
|
|
575
|
+
|
|
585
576
|
# Read the file
|
|
586
577
|
with open(handler_file, 'r') as f:
|
|
587
578
|
content = f.read()
|
|
588
|
-
|
|
579
|
+
|
|
589
580
|
# Parse with LibCST
|
|
590
581
|
module = cst.parse_module(content)
|
|
591
|
-
|
|
582
|
+
|
|
592
583
|
# Generate context docstring
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
584
|
+
with dspy.context(lm=self.lm):
|
|
585
|
+
context_docstring = self.docstring_generator.generate_context_docstring(
|
|
586
|
+
context_name=context_name,
|
|
587
|
+
commands=commands
|
|
588
|
+
)
|
|
589
|
+
|
|
599
590
|
class UpdateContextDocstring(cst.CSTTransformer):
|
|
600
591
|
def __init__(self, docstring: str):
|
|
601
592
|
self.docstring = docstring
|
|
602
593
|
self.updated = False
|
|
603
|
-
|
|
594
|
+
|
|
604
595
|
def leave_ClassDef(self, original_node: cst.ClassDef, updated_node: cst.ClassDef) -> cst.ClassDef:
|
|
605
596
|
# Update the first class that matches the context name pattern
|
|
606
|
-
if
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
597
|
+
if (
|
|
598
|
+
self.updated
|
|
599
|
+
or updated_node.name.value != context_name
|
|
600
|
+
and not updated_node.name.value.endswith("Handler")
|
|
601
|
+
):
|
|
602
|
+
return updated_node
|
|
603
|
+
|
|
604
|
+
self.updated = True
|
|
605
|
+
# Add or update docstring
|
|
606
|
+
if updated_node.body and updated_node.body.body:
|
|
607
|
+
first_stmt = updated_node.body.body[0]
|
|
608
|
+
if isinstance(first_stmt, cst.SimpleStatementLine) and (first_stmt.body and isinstance(first_stmt.body[0], cst.Expr)) and isinstance(first_stmt.body[0].value, (cst.SimpleString, cst.ConcatenatedString)):
|
|
609
|
+
new_docstring = cst.SimpleStatementLine(
|
|
610
|
+
body=[cst.Expr(cst.SimpleString(f'"""{self.docstring}"""'))]
|
|
611
|
+
)
|
|
612
|
+
new_body = [new_docstring] + list(updated_node.body.body[1:])
|
|
613
|
+
return updated_node.with_changes(
|
|
614
|
+
body=updated_node.body.with_changes(body=new_body)
|
|
615
|
+
)
|
|
616
|
+
|
|
617
|
+
# Add new docstring
|
|
618
|
+
docstring_node = cst.SimpleStatementLine(
|
|
619
|
+
body=[cst.Expr(cst.SimpleString(f'"""{self.docstring}"""'))]
|
|
620
|
+
)
|
|
621
|
+
new_body = [docstring_node] + list(updated_node.body.body)
|
|
622
|
+
return updated_node.with_changes(
|
|
623
|
+
body=updated_node.body.with_changes(body=new_body)
|
|
624
|
+
)
|
|
625
|
+
|
|
626
|
+
|
|
635
627
|
transformer = UpdateContextDocstring(context_docstring)
|
|
636
628
|
module = module.visit(transformer)
|
|
637
|
-
|
|
629
|
+
|
|
638
630
|
if transformer.updated:
|
|
639
631
|
# Write back
|
|
640
632
|
with open(handler_file, 'w') as f:
|
|
641
633
|
f.write(module.code)
|
|
642
634
|
logger.debug(f"Updated context handler docstring for {context_name}")
|
|
643
|
-
|
|
635
|
+
|
|
644
636
|
except Exception as e:
|
|
645
637
|
logger.error(f"Error generating context handler docstring: {e}")
|
|
646
638
|
logger.error(traceback.format_exc())
|
|
@@ -649,8 +641,10 @@ class GenAIPostProcessor:
|
|
|
649
641
|
all_contexts: Dict[str, Dict],
|
|
650
642
|
global_commands: List[Dict[str, str]]):
|
|
651
643
|
"""Generate workflow_description.txt file."""
|
|
644
|
+
|
|
652
645
|
try:
|
|
653
|
-
|
|
646
|
+
with dspy.context(lm=self.lm):
|
|
647
|
+
description = self.workflow_generator(all_contexts, global_commands)
|
|
654
648
|
|
|
655
649
|
desc_file = os.path.join(workflow_path, "workflow_description.txt")
|
|
656
650
|
with open(desc_file, 'w') as f:
|