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