rasa-pro 3.14.0.dev3__py3-none-any.whl → 3.14.0.dev5__py3-none-any.whl
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 rasa-pro might be problematic. Click here for more details.
- rasa/api.py +0 -5
- rasa/builder/README.md +120 -0
- rasa/builder/auth.py +176 -0
- rasa/builder/config.py +115 -0
- rasa/builder/copilot/constants.py +25 -0
- rasa/builder/copilot/copilot.py +372 -0
- rasa/builder/copilot/copilot_response_handler.py +487 -0
- rasa/builder/copilot/copilot_templated_message_provider.py +58 -0
- rasa/builder/copilot/exceptions.py +20 -0
- rasa/builder/copilot/models.py +431 -0
- rasa/builder/copilot/prompts/copilot_system_prompt.jinja2 +726 -0
- rasa/builder/copilot/telemetry.py +195 -0
- rasa/builder/copilot/templated_messages/copilot_internal_messages_templates.yml +16 -0
- rasa/builder/copilot/templated_messages/copilot_templated_responses.yml +26 -0
- rasa/builder/document_retrieval/constants.py +15 -0
- rasa/builder/document_retrieval/inkeep-rag-response-schema.json +64 -0
- rasa/builder/document_retrieval/inkeep_document_retrieval.py +238 -0
- rasa/builder/document_retrieval/models.py +62 -0
- rasa/builder/download.py +140 -0
- rasa/builder/exceptions.py +55 -0
- rasa/builder/guardrails/__init__.py +1 -0
- rasa/builder/guardrails/constants.py +3 -0
- rasa/builder/guardrails/exceptions.py +4 -0
- rasa/builder/guardrails/lakera.py +206 -0
- rasa/builder/guardrails/models.py +199 -0
- rasa/builder/guardrails/utils.py +305 -0
- rasa/builder/job_manager.py +87 -0
- rasa/builder/jobs.py +234 -0
- rasa/builder/llm_service.py +246 -0
- rasa/builder/logging_utils.py +209 -0
- rasa/builder/main.py +174 -0
- rasa/builder/models.py +197 -0
- rasa/builder/project_generator.py +450 -0
- rasa/builder/project_info.py +72 -0
- rasa/builder/scrape_rasa_docs.py +97 -0
- rasa/builder/service.py +1142 -0
- rasa/builder/shared/tracker_context.py +212 -0
- rasa/builder/skill_to_bot_prompt.jinja2 +164 -0
- rasa/builder/training_service.py +132 -0
- rasa/builder/validation_service.py +93 -0
- rasa/cli/arguments/default_arguments.py +0 -12
- rasa/cli/arguments/run.py +0 -2
- rasa/cli/dialogue_understanding_test.py +0 -4
- rasa/cli/e2e_test.py +0 -4
- rasa/cli/inspect.py +0 -3
- rasa/cli/llm_fine_tuning.py +0 -5
- rasa/cli/project_templates/basic/actions/action_api.py +15 -0
- rasa/cli/project_templates/basic/actions/action_human_handoff.py +44 -0
- rasa/cli/project_templates/basic/config.yml +23 -0
- rasa/cli/project_templates/basic/credentials.yml +34 -0
- rasa/cli/project_templates/basic/data/general/feedback.yml +20 -0
- rasa/cli/project_templates/basic/data/general/goodbye.yml +6 -0
- rasa/cli/project_templates/basic/data/general/hello.yml +7 -0
- rasa/cli/project_templates/basic/data/general/help.yml +6 -0
- rasa/cli/project_templates/basic/data/general/human_handoff.yml +16 -0
- rasa/cli/project_templates/basic/data/general/welcome.yml +9 -0
- rasa/cli/project_templates/basic/data/system/pattern_completed.yml +7 -0
- rasa/cli/project_templates/basic/data/system/pattern_correction.yml +7 -0
- rasa/cli/project_templates/basic/data/system/pattern_search.yml +8 -0
- rasa/cli/project_templates/basic/data/system/pattern_session_start.yml +8 -0
- rasa/cli/project_templates/basic/docs/rasa_assistant_qa.txt +65 -0
- rasa/cli/project_templates/basic/docs/template.txt +7 -0
- rasa/cli/project_templates/basic/domain/general/assistant_details.yml +12 -0
- rasa/cli/project_templates/basic/domain/general/bot_identity.yml +5 -0
- rasa/cli/project_templates/basic/domain/general/cannot_handle.yml +5 -0
- rasa/cli/project_templates/basic/domain/general/feedback.yml +28 -0
- rasa/cli/project_templates/basic/domain/general/goodbye.yml +7 -0
- rasa/cli/project_templates/basic/domain/general/help.yml +5 -0
- rasa/cli/project_templates/basic/domain/general/human_handoff_domain.yml +35 -0
- rasa/cli/project_templates/basic/domain/general/utils.yml +13 -0
- rasa/cli/project_templates/basic/domain/general/welcome.yml +7 -0
- rasa/cli/project_templates/basic/endpoints.yml +73 -0
- rasa/cli/project_templates/basic/prompts/rephraser_demo_personality_prompt.jinja2 +19 -0
- rasa/cli/project_templates/finance/actions/__init__.py +46 -0
- rasa/cli/project_templates/finance/actions/accounts/action_ask_account.py +47 -0
- rasa/cli/project_templates/finance/actions/accounts/action_check_balance.py +40 -0
- rasa/cli/project_templates/finance/actions/action_session_start.py +74 -0
- rasa/cli/project_templates/finance/actions/cards/action_ask_card.py +48 -0
- rasa/cli/project_templates/finance/actions/cards/action_check_card_existence.py +36 -0
- rasa/cli/project_templates/finance/actions/cards/action_update_card_status.py +54 -0
- rasa/cli/project_templates/finance/actions/database.py +277 -0
- rasa/cli/project_templates/finance/actions/transfers/__init__.py +0 -0
- rasa/cli/project_templates/finance/actions/transfers/action_add_payee.py +52 -0
- rasa/cli/project_templates/finance/actions/transfers/action_ask_account_from.py +51 -0
- rasa/cli/project_templates/finance/actions/transfers/action_check_payee_existence.py +40 -0
- rasa/cli/project_templates/finance/actions/transfers/action_check_sufficient_funds.py +40 -0
- rasa/cli/project_templates/finance/actions/transfers/action_list_payees.py +46 -0
- rasa/cli/project_templates/finance/actions/transfers/action_process_immediate_payment.py +18 -0
- rasa/cli/project_templates/finance/actions/transfers/action_remove_payee.py +49 -0
- rasa/cli/project_templates/finance/actions/transfers/action_schedule_payment.py +19 -0
- rasa/cli/project_templates/finance/actions/transfers/action_validate_payment_date.py +36 -0
- rasa/cli/project_templates/finance/config.yml +21 -0
- rasa/cli/project_templates/finance/credentials.yml +32 -0
- rasa/cli/project_templates/finance/csvs/accounts.csv +8 -0
- rasa/cli/project_templates/finance/csvs/advisors.csv +7 -0
- rasa/cli/project_templates/finance/csvs/appointments.csv +211 -0
- rasa/cli/project_templates/finance/csvs/branches.csv +10 -0
- rasa/cli/project_templates/finance/csvs/cards.csv +11 -0
- rasa/cli/project_templates/finance/csvs/payees.csv +11 -0
- rasa/cli/project_templates/finance/csvs/transactions.csv +71 -0
- rasa/cli/project_templates/finance/csvs/users.csv +4 -0
- rasa/cli/project_templates/finance/data/accounts/check_balance.yml +10 -0
- rasa/cli/project_templates/finance/data/cards/block_card.yml +66 -0
- rasa/cli/project_templates/finance/data/cards/select_card.yml +12 -0
- rasa/cli/project_templates/finance/data/general/bot_identity.yml +6 -0
- rasa/cli/project_templates/finance/data/general/feedback.yml +20 -0
- rasa/cli/project_templates/finance/data/general/goodbye.yml +6 -0
- rasa/cli/project_templates/finance/data/general/hello.yml +7 -0
- rasa/cli/project_templates/finance/data/general/help.yml +9 -0
- rasa/cli/project_templates/finance/data/general/human_handoff.yml +16 -0
- rasa/cli/project_templates/finance/data/general/welcome.yml +9 -0
- rasa/cli/project_templates/finance/data/system/patterns/pattern_chitchat.yml +5 -0
- rasa/cli/project_templates/finance/data/system/patterns/pattern_completed.yml +7 -0
- rasa/cli/project_templates/finance/data/system/patterns/pattern_correction.yml +7 -0
- rasa/cli/project_templates/finance/data/system/patterns/pattern_search.yml +8 -0
- rasa/cli/project_templates/finance/data/system/patterns/pattern_session_start.yml +8 -0
- rasa/cli/project_templates/finance/data/system/source/accounts.json +51 -0
- rasa/cli/project_templates/finance/data/system/source/advisors.json +44 -0
- rasa/cli/project_templates/finance/data/system/source/appointments.json +1474 -0
- rasa/cli/project_templates/finance/data/system/source/branches.json +47 -0
- rasa/cli/project_templates/finance/data/system/source/cards.json +72 -0
- rasa/cli/project_templates/finance/data/system/source/payees.json +74 -0
- rasa/cli/project_templates/finance/data/system/source/transactions.json +492 -0
- rasa/cli/project_templates/finance/data/system/source/users.json +29 -0
- rasa/cli/project_templates/finance/data/transfers/add_payee.yml +29 -0
- rasa/cli/project_templates/finance/data/transfers/list_payees.yml +5 -0
- rasa/cli/project_templates/finance/data/transfers/remove_payee.yml +21 -0
- rasa/cli/project_templates/finance/data/transfers/transfer_money.yml +67 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/consequences_of_blocking_card.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/reasons_to_block_card.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/recovering_from_card_fraud.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/tips_for_card_security.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/what_to_do_if_card_is_lost.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/account_balance_security.txt +7 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/common_balance_inquiries.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/methods_to_check_balance.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/understanding_balance_updates.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/what_to_do_if_balance_is_incorrect.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/benefits_of_authorised_payees.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/common_issues_with_payees.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/general_payee_information.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/payee_management_tips.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/understanding_payee_types.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/common_transfer_errors.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/fees_for_transfers.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/general_transfer_information.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/security_tips_for_transfers.txt +8 -0
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/transfer_processing_times.txt +8 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part1.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part10.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part11.txt +48 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part12.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part13.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part14.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part15.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part16.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part17.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part18.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part19.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part2.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part20.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part21.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part22.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part23.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part24.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part25.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part26.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part27.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part28.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part29.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part3.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part30.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part31.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part32.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part33.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part34.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part35.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part36.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part37.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part38.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part39.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part4.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part40.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part41.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part42.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part43.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part44.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part45.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part46.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part47.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part48.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part49.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part5.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part50.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part51.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part52.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part53.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part54.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part55.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part56.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part57.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part58.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part59.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part6.txt +47 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part60.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part61.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part7.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part8.txt +50 -0
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part9.txt +47 -0
- rasa/cli/project_templates/finance/domain/accounts/check_balance.yml +11 -0
- rasa/cli/project_templates/finance/domain/cards/block_card.yml +101 -0
- rasa/cli/project_templates/finance/domain/cards/select_card.yml +12 -0
- rasa/cli/project_templates/finance/domain/general/assistant_details.yml +12 -0
- rasa/cli/project_templates/finance/domain/general/bot_identity.yml +5 -0
- rasa/cli/project_templates/finance/domain/general/cannot_handle.yml +5 -0
- rasa/cli/project_templates/finance/domain/general/defaults.yml +24 -0
- rasa/cli/project_templates/finance/domain/general/feedback.yml +28 -0
- rasa/cli/project_templates/finance/domain/general/goodbye.yml +7 -0
- rasa/cli/project_templates/finance/domain/general/help.yml +5 -0
- rasa/cli/project_templates/finance/domain/general/human_handoff.yml +30 -0
- rasa/cli/project_templates/finance/domain/general/utils.yml +13 -0
- rasa/cli/project_templates/finance/domain/general/welcome.yml +8 -0
- rasa/cli/project_templates/finance/domain/transfers/add_payee.yml +47 -0
- rasa/cli/project_templates/finance/domain/transfers/list_payees.yml +4 -0
- rasa/cli/project_templates/finance/domain/transfers/remove_payee.yml +16 -0
- rasa/cli/project_templates/finance/domain/transfers/transfer_money.yml +79 -0
- rasa/cli/project_templates/finance/endpoints.yml +63 -0
- rasa/cli/project_templates/finance/prompts/rephraser_demo_personality_prompt.jinja2 +19 -0
- rasa/cli/project_templates/telco/actions/__init__.py +0 -0
- rasa/cli/project_templates/telco/actions/actions_billing.py +204 -0
- rasa/cli/project_templates/telco/actions/actions_get_data_from_db.py +48 -0
- rasa/cli/project_templates/telco/actions/actions_run_diagnostics.py +28 -0
- rasa/cli/project_templates/telco/actions/actions_session_start.py +18 -0
- rasa/cli/project_templates/telco/config.yml +25 -0
- rasa/cli/project_templates/telco/credentials.yml +33 -0
- rasa/cli/project_templates/telco/csvs/billing.csv +10 -0
- rasa/cli/project_templates/telco/csvs/customers.csv +5 -0
- rasa/cli/project_templates/telco/data/flows/flow_global.yml +5 -0
- rasa/cli/project_templates/telco/data/flows/flow_reboot_router.yml +8 -0
- rasa/cli/project_templates/telco/data/flows/flow_reset_router.yml +7 -0
- rasa/cli/project_templates/telco/data/flows/flow_solve_internet_issue.yml +73 -0
- rasa/cli/project_templates/telco/data/flows/flow_undertand_bill.yml +45 -0
- rasa/cli/project_templates/telco/data/patterns/pattern_completed.yml +7 -0
- rasa/cli/project_templates/telco/data/patterns/pattern_human_handoff.yml +6 -0
- rasa/cli/project_templates/telco/data/patterns/pattern_search.yml +7 -0
- rasa/cli/project_templates/telco/data/patterns/pattern_session_start.yml +9 -0
- rasa/cli/project_templates/telco/docs/reset_vs_rboot_router.txt +1 -0
- rasa/cli/project_templates/telco/docs/restart_router.txt +6 -0
- rasa/cli/project_templates/telco/docs/run_speed_test.txt +6 -0
- rasa/cli/project_templates/telco/domain/domain_global.yml +29 -0
- rasa/cli/project_templates/telco/domain/domain_patterns.yml +17 -0
- rasa/cli/project_templates/telco/domain/domain_reboot_router.yml +20 -0
- rasa/cli/project_templates/telco/domain/domain_reset_router.yml +11 -0
- rasa/cli/project_templates/telco/domain/domain_run_speed_test.yml +24 -0
- rasa/cli/project_templates/telco/domain/domain_solve_internet_issue.yml +74 -0
- rasa/cli/project_templates/telco/domain/domain_undertand_bill.yml +102 -0
- rasa/cli/project_templates/telco/endpoints.yml +60 -0
- rasa/{dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 → cli/project_templates/telco/prompts/command-generator.jinja2} +3 -7
- rasa/cli/project_templates/telco/tests/e2e_results_failed.yml +62 -0
- rasa/cli/project_templates/telco/tests/e2e_results_passed.yml +130 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/billing_test_cases.yml +68 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/global_test_cases.yml +13 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/internet_slow_test_case.yml +47 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/out_of_scope_test_case.yml +21 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/patterns_test_cases.yml +15 -0
- rasa/cli/project_templates/tutorial/config.yml +2 -1
- rasa/cli/run.py +0 -4
- rasa/cli/scaffold.py +46 -2
- rasa/cli/shell.py +0 -3
- rasa/constants.py +0 -6
- rasa/core/actions/action.py +2 -43
- rasa/core/agent.py +0 -16
- rasa/core/available_endpoints.py +0 -30
- rasa/core/channels/channel.py +4 -3
- rasa/core/channels/constants.py +3 -0
- rasa/core/channels/development_inspector.py +1 -1
- rasa/core/channels/inspector/dist/assets/{arc-2e78c586.js → arc-18042c22.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-806b712e.js → blockDiagram-38ab4fdb-fdd6bcfa.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-0745efa9.js → c4Diagram-3d4e48cf-f5ae6786.js} +1 -1
- rasa/core/channels/inspector/dist/assets/channel-b9b536fc.js +1 -0
- rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-7bd1082b.js → classDiagram-70f12bd4-81efba3e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-d937ba49.js → classDiagram-v2-f2320105-3b6b6a92.js} +1 -1
- rasa/core/channels/inspector/dist/assets/clone-78d2ddcf.js +1 -0
- rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-a2a564ca.js → createText-2e5e7dd3-31422447.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-b5256940.js → edges-e0da2a9e-518a90db.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-e6883ad2.js → erDiagram-9861fffd-a6d3c25a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-e576fc02.js → flowDb-956e92f1-e048c2be.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-2e298d01.js → flowDiagram-66a62f08-c7474c91.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-8b09c060.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-dd7b150a.js → flowchart-elk-definition-4a651766-cb4d8723.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-5b79575c.js → ganttDiagram-c361ad54-346636a2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-3016f40a.js → gitGraphDiagram-72cf32ee-7c508874.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{graph-3e19170f.js → graph-14702d8a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-3862675e-eb9c86de.js → index-3862675e-f18b534b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/index-4d4bdf3a.js +1335 -0
- rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-b4280e4d.js → infoDiagram-f8f76790-64154b83.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-556091f8.js → journeyDiagram-49397b02-833a5f95.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-08436411.js → layout-5a3b2123.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-683c4f3b.js → line-2272a8c7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-cee6d791.js → linear-35bcf273.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-a0bf0b1a.js → mindmap-definition-fc14e90a-92dcb0e9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-3730d5c4.js → pieDiagram-8a3498a8-94dbc900.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-12a20fed.js → quadrantDiagram-120e2f19-8b7a9c33.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-b9732102.js → requirementDiagram-deff3bca-6f7eab81.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-a2e72776.js → sankeyDiagram-04a897e0-f43e581d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-8b7a76bb.js → sequenceDiagram-704730f1-0bcbefc3.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-e65853ac.js → stateDiagram-587899a1-b8a74083.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-6f58a44b.js → stateDiagram-v2-d93cdb3a-2070218f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-df25b934.js → styles-6aaf32cf-f1d54e34.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9a916d00-88357141.js → styles-9a916d00-980de489.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-c10674c1-d600174d.js → styles-c10674c1-3c03abde.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-4adc3e0b.js → svgDrawCommon-08f97a94-46ba068f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-42816fa1.js → timeline-definition-85554ec2-901f5e3d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-621eb66a.js → xychartDiagram-e933f94c-acbc628a.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +2 -2
- rasa/core/channels/inspector/index.html +1 -1
- rasa/core/channels/inspector/src/App.tsx +10 -11
- rasa/core/channels/inspector/src/components/DialogueInformation.tsx +12 -3
- rasa/core/channels/inspector/src/components/DialogueStack.tsx +5 -7
- rasa/core/channels/inspector/src/helpers/formatters.ts +3 -24
- rasa/core/channels/inspector/src/theme/base/styles.ts +1 -19
- rasa/core/channels/inspector/src/types.ts +0 -4
- rasa/core/channels/socketio.py +212 -51
- rasa/core/channels/studio_chat.py +43 -23
- rasa/core/channels/voice_stream/voice_channel.py +5 -3
- rasa/core/constants.py +0 -4
- rasa/core/policies/enterprise_search_policy.py +6 -11
- rasa/core/policies/flow_policy.py +4 -4
- rasa/core/policies/flows/flow_executor.py +45 -415
- rasa/core/processor.py +1 -6
- rasa/core/run.py +14 -11
- rasa/core/utils.py +1 -21
- rasa/dialogue_understanding/commands/__init__.py +0 -8
- rasa/dialogue_understanding/commands/cancel_flow_command.py +4 -97
- rasa/dialogue_understanding/commands/chit_chat_answer_command.py +0 -11
- rasa/dialogue_understanding/commands/clarify_command.py +0 -10
- rasa/dialogue_understanding/commands/knowledge_answer_command.py +0 -11
- rasa/dialogue_understanding/commands/start_flow_command.py +8 -164
- rasa/dialogue_understanding/commands/utils.py +2 -6
- rasa/dialogue_understanding/generator/command_parser.py +0 -4
- rasa/dialogue_understanding/generator/flow_retrieval.py +10 -9
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +12 -50
- rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +6 -7
- rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +6 -7
- rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +2 -41
- rasa/dialogue_understanding/patterns/continue_interrupted.py +1 -163
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +8 -52
- rasa/dialogue_understanding/processor/command_processor.py +15 -31
- rasa/dialogue_understanding/stack/dialogue_stack.py +2 -123
- rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +0 -57
- rasa/dialogue_understanding/stack/utils.py +2 -17
- rasa/dialogue_understanding_test/du_test_runner.py +2 -7
- rasa/e2e_test/e2e_test_runner.py +0 -5
- rasa/engine/storage/local_model_storage.py +45 -2
- rasa/model_manager/model_api.py +4 -5
- rasa/model_manager/runner_service.py +1 -1
- rasa/model_manager/socket_bridge.py +20 -14
- rasa/model_manager/trainer_service.py +12 -9
- rasa/model_manager/utils.py +1 -29
- rasa/server.py +0 -10
- rasa/shared/constants.py +0 -5
- rasa/shared/core/constants.py +1 -12
- rasa/shared/core/domain.py +58 -11
- rasa/shared/core/events.py +0 -319
- rasa/shared/core/flows/flow_step.py +7 -1
- rasa/shared/core/flows/flows_list.py +2 -2
- rasa/shared/core/flows/flows_yaml_schema.json +186 -112
- rasa/shared/core/flows/steps/call.py +5 -53
- rasa/shared/core/flows/validation.py +7 -46
- rasa/shared/core/flows/yaml_flows_io.py +16 -8
- rasa/shared/core/slots.py +4 -0
- rasa/shared/importers/importer.py +6 -0
- rasa/shared/importers/utils.py +77 -1
- rasa/shared/providers/_utils.py +60 -44
- rasa/shared/providers/embedding/default_litellm_embedding_client.py +2 -0
- rasa/shared/providers/llm/_base_litellm_client.py +7 -39
- rasa/shared/providers/llm/default_litellm_llm_client.py +2 -0
- rasa/shared/providers/llm/litellm_router_llm_client.py +4 -8
- rasa/shared/providers/llm/llm_client.py +3 -7
- rasa/shared/providers/llm/llm_response.py +0 -49
- rasa/shared/providers/llm/self_hosted_llm_client.py +4 -8
- rasa/shared/utils/llm.py +5 -28
- rasa/shared/utils/schemas/events.py +0 -42
- rasa/studio/upload.py +16 -47
- rasa/telemetry.py +97 -23
- rasa/tracing/instrumentation/instrumentation.py +2 -4
- rasa/utils/common.py +0 -79
- rasa/utils/io.py +27 -9
- rasa/utils/json_utils.py +6 -1
- rasa/utils/log_utils.py +5 -1
- rasa/utils/openapi.py +144 -0
- rasa/validator.py +7 -3
- rasa/version.py +1 -1
- {rasa_pro-3.14.0.dev3.dist-info → rasa_pro-3.14.0.dev5.dist-info}/METADATA +3 -3
- {rasa_pro-3.14.0.dev3.dist-info → rasa_pro-3.14.0.dev5.dist-info}/RECORD +405 -174
- rasa/agents/agent_factory.py +0 -122
- rasa/agents/agent_manager.py +0 -162
- rasa/agents/constants.py +0 -32
- rasa/agents/core/agent_protocol.py +0 -108
- rasa/agents/core/types.py +0 -70
- rasa/agents/exceptions.py +0 -8
- rasa/agents/protocol/__init__.py +0 -5
- rasa/agents/protocol/a2a/a2a_agent.py +0 -51
- rasa/agents/protocol/mcp/mcp_base_agent.py +0 -674
- rasa/agents/protocol/mcp/mcp_open_agent.py +0 -276
- rasa/agents/protocol/mcp/mcp_task_agent.py +0 -469
- rasa/agents/schemas/__init__.py +0 -12
- rasa/agents/schemas/agent_input.py +0 -38
- rasa/agents/schemas/agent_output.py +0 -26
- rasa/agents/schemas/agent_tool_result.py +0 -51
- rasa/agents/schemas/agent_tool_schema.py +0 -134
- rasa/agents/templates/mcp_open_agent_prompt_template.jinja2 +0 -15
- rasa/agents/templates/mcp_task_agent_prompt_template.jinja2 +0 -17
- rasa/agents/utils.py +0 -72
- rasa/core/available_agents.py +0 -196
- rasa/core/channels/inspector/dist/assets/channel-c436ca7c.js +0 -1
- rasa/core/channels/inspector/dist/assets/clone-50dd656b.js +0 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-2b2aeaf8.js +0 -1
- rasa/core/channels/inspector/dist/assets/index-1bd9135e.js +0 -1353
- rasa/core/policies/flows/mcp_tool_executor.py +0 -277
- rasa/dialogue_understanding/commands/continue_agent_command.py +0 -91
- rasa/dialogue_understanding/commands/restart_agent_command.py +0 -162
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +0 -61
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2 +0 -81
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +0 -81
- rasa/shared/agents/utils.py +0 -35
- rasa/shared/utils/mcp/server_connection.py +0 -157
- /rasa/{agents → builder}/__init__.py +0 -0
- /rasa/{agents/core → builder/copilot}/__init__.py +0 -0
- /rasa/{agents/protocol/a2a → builder/copilot/prompts}/__init__.py +0 -0
- /rasa/{agents/protocol/mcp → builder/copilot/templated_messages}/__init__.py +0 -0
- /rasa/{agents/templates → builder/document_retrieval}/__init__.py +0 -0
- /rasa/{shared/agents → cli/project_templates/finance/actions/accounts}/__init__.py +0 -0
- /rasa/{shared/utils/mcp → cli/project_templates/finance/actions/cards}/__init__.py +0 -0
- {rasa_pro-3.14.0.dev3.dist-info → rasa_pro-3.14.0.dev5.dist-info}/NOTICE +0 -0
- {rasa_pro-3.14.0.dev3.dist-info → rasa_pro-3.14.0.dev5.dist-info}/WHEEL +0 -0
- {rasa_pro-3.14.0.dev3.dist-info → rasa_pro-3.14.0.dev5.dist-info}/entry_points.txt +0 -0
|
@@ -8,13 +8,6 @@ from typing import Any, Callable, Dict, List, Optional
|
|
|
8
8
|
import jsonpatch
|
|
9
9
|
import structlog
|
|
10
10
|
|
|
11
|
-
from rasa.dialogue_understanding.stack.frames.flow_stack_frame import (
|
|
12
|
-
AgentStackFrame,
|
|
13
|
-
AgentState,
|
|
14
|
-
FlowStackFrameType,
|
|
15
|
-
UserFlowStackFrame,
|
|
16
|
-
)
|
|
17
|
-
|
|
18
11
|
if typing.TYPE_CHECKING:
|
|
19
12
|
from rasa.dialogue_understanding.stack.frames import DialogueStackFrame
|
|
20
13
|
|
|
@@ -98,42 +91,6 @@ class DialogueStack:
|
|
|
98
91
|
"""
|
|
99
92
|
return self.frames.pop()
|
|
100
93
|
|
|
101
|
-
def move_frames_to_top(self, frames_to_move: List["DialogueStackFrame"]) -> None:
|
|
102
|
-
"""Moves specified frames to top of stack while preserving their relative order.
|
|
103
|
-
|
|
104
|
-
Args:
|
|
105
|
-
frames_to_move: The frames to move to the top of the stack.
|
|
106
|
-
"""
|
|
107
|
-
# Get frames that are not being moved
|
|
108
|
-
frames_to_keep = [frame for frame in self.frames if frame not in frames_to_move]
|
|
109
|
-
|
|
110
|
-
# Reorder: keep frames first, then moved frames
|
|
111
|
-
self.frames = frames_to_keep + frames_to_move
|
|
112
|
-
|
|
113
|
-
# set all frames to interrupt except for LINK and CALL
|
|
114
|
-
for frame in self.frames:
|
|
115
|
-
if (
|
|
116
|
-
isinstance(frame, UserFlowStackFrame)
|
|
117
|
-
and frame.frame_type == FlowStackFrameType.LINK
|
|
118
|
-
):
|
|
119
|
-
continue
|
|
120
|
-
if (
|
|
121
|
-
isinstance(frame, UserFlowStackFrame)
|
|
122
|
-
and frame.frame_type == FlowStackFrameType.CALL
|
|
123
|
-
):
|
|
124
|
-
continue
|
|
125
|
-
if (
|
|
126
|
-
isinstance(frame, UserFlowStackFrame)
|
|
127
|
-
and frame.frame_type == FlowStackFrameType.REGULAR
|
|
128
|
-
):
|
|
129
|
-
frame.frame_type = FlowStackFrameType.INTERRUPT
|
|
130
|
-
|
|
131
|
-
# set the first frame to regular
|
|
132
|
-
for frame in self.frames:
|
|
133
|
-
if isinstance(frame, UserFlowStackFrame):
|
|
134
|
-
frame.frame_type = FlowStackFrameType.REGULAR
|
|
135
|
-
return
|
|
136
|
-
|
|
137
94
|
def current_context(self) -> Dict[str, Any]:
|
|
138
95
|
"""Returns the context of the topmost frame.
|
|
139
96
|
|
|
@@ -152,7 +109,7 @@ class DialogueStack:
|
|
|
152
109
|
"""Returns the topmost frame from the stack.
|
|
153
110
|
|
|
154
111
|
Args:
|
|
155
|
-
|
|
112
|
+
ignore_frame: The ID of the flow to ignore. Picks the top most
|
|
156
113
|
frame that has a different flow ID.
|
|
157
114
|
|
|
158
115
|
Returns:
|
|
@@ -179,8 +136,7 @@ class DialogueStack:
|
|
|
179
136
|
patch_dump: The patch to apply to the stack.
|
|
180
137
|
|
|
181
138
|
Returns:
|
|
182
|
-
|
|
183
|
-
"""
|
|
139
|
+
The updated stack."""
|
|
184
140
|
patch = jsonpatch.JsonPatch.from_string(patch_dump)
|
|
185
141
|
dialogue_stack_dump = patch.apply(self.as_dict())
|
|
186
142
|
return DialogueStack.from_dict(dialogue_stack_dump)
|
|
@@ -221,80 +177,3 @@ class DialogueStack:
|
|
|
221
177
|
if patch:
|
|
222
178
|
return patch.to_string()
|
|
223
179
|
return None
|
|
224
|
-
|
|
225
|
-
def _find_agent_frame_by_predicate(
|
|
226
|
-
self, predicate: Callable[[AgentStackFrame], bool]
|
|
227
|
-
) -> List[AgentStackFrame]:
|
|
228
|
-
stack_frames: List[AgentStackFrame] = []
|
|
229
|
-
for stack_frame in reversed(self.frames):
|
|
230
|
-
if isinstance(stack_frame, AgentStackFrame) and predicate(stack_frame):
|
|
231
|
-
stack_frames.append(stack_frame)
|
|
232
|
-
return stack_frames
|
|
233
|
-
|
|
234
|
-
def find_active_agent_frame(self) -> Optional[AgentStackFrame]:
|
|
235
|
-
stack_frames = self._find_agent_frame_by_predicate(
|
|
236
|
-
lambda frame: frame.state == AgentState.WAITING_FOR_INPUT
|
|
237
|
-
)
|
|
238
|
-
if stack_frames:
|
|
239
|
-
return stack_frames[0]
|
|
240
|
-
return None
|
|
241
|
-
|
|
242
|
-
def find_agent_stack_frame_by_agent(
|
|
243
|
-
self, agent_id: str
|
|
244
|
-
) -> Optional[AgentStackFrame]:
|
|
245
|
-
"""Get the agent stack frame for a specific agent ID.
|
|
246
|
-
|
|
247
|
-
May also include the agent stack frame in the INTERRUPTED state.
|
|
248
|
-
"""
|
|
249
|
-
stack_frames = self._find_agent_frame_by_predicate(
|
|
250
|
-
lambda frame: frame.agent_id == agent_id
|
|
251
|
-
)
|
|
252
|
-
if stack_frames:
|
|
253
|
-
return stack_frames[0]
|
|
254
|
-
return None
|
|
255
|
-
|
|
256
|
-
def find_active_agent_stack_frame_for_flow(
|
|
257
|
-
self, flow_id: str
|
|
258
|
-
) -> Optional[AgentStackFrame]:
|
|
259
|
-
"""Get the agent stack frame of a specific flow."""
|
|
260
|
-
stack_frames = self._find_agent_frame_by_predicate(
|
|
261
|
-
lambda frame: frame.flow_id == flow_id
|
|
262
|
-
)
|
|
263
|
-
for stack_frame in stack_frames:
|
|
264
|
-
if stack_frame.state == AgentState.WAITING_FOR_INPUT:
|
|
265
|
-
return stack_frame
|
|
266
|
-
return None
|
|
267
|
-
|
|
268
|
-
def get_active_agent_id(self) -> Optional[typing.Text]:
|
|
269
|
-
agent_frame = self.find_active_agent_frame()
|
|
270
|
-
if agent_frame:
|
|
271
|
-
return agent_frame.agent_id
|
|
272
|
-
return None
|
|
273
|
-
|
|
274
|
-
def agent_is_active(self) -> bool:
|
|
275
|
-
return self.find_active_agent_frame() is not None
|
|
276
|
-
|
|
277
|
-
def get_all_user_flow_frames(
|
|
278
|
-
self, ignore_call_and_link_frames: bool = True
|
|
279
|
-
) -> List[UserFlowStackFrame]:
|
|
280
|
-
"""Get all user flow frames from the dialogue stack.
|
|
281
|
-
|
|
282
|
-
Args:
|
|
283
|
-
ignore_call_and_link_frames: Whether to ignore user frames of type `call`
|
|
284
|
-
and `link`. By default, these frames are ignored.
|
|
285
|
-
|
|
286
|
-
Returns:
|
|
287
|
-
A list of all user flow frames in the dialogue stack.
|
|
288
|
-
"""
|
|
289
|
-
return [
|
|
290
|
-
frame
|
|
291
|
-
for frame in self.frames
|
|
292
|
-
if isinstance(frame, UserFlowStackFrame)
|
|
293
|
-
and (
|
|
294
|
-
not ignore_call_and_link_frames
|
|
295
|
-
or (
|
|
296
|
-
frame.frame_type != FlowStackFrameType.CALL
|
|
297
|
-
and frame.frame_type != FlowStackFrameType.LINK
|
|
298
|
-
)
|
|
299
|
-
)
|
|
300
|
-
]
|
|
@@ -94,18 +94,6 @@ class InvalidFlowStepIdException(Exception):
|
|
|
94
94
|
super().__init__(f"Invalid flow step ID '{step_id}' for flow '{flow_id}'.")
|
|
95
95
|
|
|
96
96
|
|
|
97
|
-
class InvalidAgentState(RasaException):
|
|
98
|
-
"""Raised if the agent state is invalid."""
|
|
99
|
-
|
|
100
|
-
def __init__(self, invalid_state: str) -> None:
|
|
101
|
-
"""Creates a `InvalidAgentState`.
|
|
102
|
-
|
|
103
|
-
Args:
|
|
104
|
-
invalid_state: The invalid agent state.
|
|
105
|
-
"""
|
|
106
|
-
super().__init__(f"Invalid agent state '{invalid_state}'.")
|
|
107
|
-
|
|
108
|
-
|
|
109
97
|
@dataclass
|
|
110
98
|
class BaseFlowStackFrame(DialogueStackFrame):
|
|
111
99
|
flow_id: str = "" # needed to avoid "default arg before non-default" error
|
|
@@ -183,48 +171,3 @@ class UserFlowStackFrame(BaseFlowStackFrame):
|
|
|
183
171
|
step_id=data["step_id"],
|
|
184
172
|
frame_type=FlowStackFrameType.from_str(data.get("frame_type")),
|
|
185
173
|
)
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
class AgentState(str, Enum):
|
|
189
|
-
INTERRUPTED = "interrupted"
|
|
190
|
-
WAITING_FOR_INPUT = "waiting_for_input"
|
|
191
|
-
|
|
192
|
-
@staticmethod
|
|
193
|
-
def from_str(state: Optional[str]) -> AgentState:
|
|
194
|
-
if state == AgentState.WAITING_FOR_INPUT.value:
|
|
195
|
-
return AgentState.WAITING_FOR_INPUT
|
|
196
|
-
elif state == AgentState.INTERRUPTED.value:
|
|
197
|
-
return AgentState.INTERRUPTED
|
|
198
|
-
else:
|
|
199
|
-
raise InvalidAgentState(state)
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
@dataclass
|
|
203
|
-
class AgentStackFrame(BaseFlowStackFrame):
|
|
204
|
-
agent_id: str = ""
|
|
205
|
-
state: AgentState = AgentState.WAITING_FOR_INPUT
|
|
206
|
-
metadata: Optional[Dict[str, Any]] = None
|
|
207
|
-
|
|
208
|
-
@classmethod
|
|
209
|
-
def type(cls) -> str:
|
|
210
|
-
"""Returns the type of the frame."""
|
|
211
|
-
return "agent"
|
|
212
|
-
|
|
213
|
-
@staticmethod
|
|
214
|
-
def from_dict(data: Dict[str, Any]) -> AgentStackFrame:
|
|
215
|
-
"""Creates a `AgentStackFrame` from a dictionary.
|
|
216
|
-
|
|
217
|
-
Args:
|
|
218
|
-
data: The dictionary to create the `AgentStackFrame` from.
|
|
219
|
-
|
|
220
|
-
Returns:
|
|
221
|
-
The created `AgentStackFrame`.
|
|
222
|
-
"""
|
|
223
|
-
return AgentStackFrame(
|
|
224
|
-
frame_id=data["frame_id"],
|
|
225
|
-
flow_id=data["flow_id"],
|
|
226
|
-
step_id=data["step_id"],
|
|
227
|
-
agent_id=data["agent_id"],
|
|
228
|
-
state=AgentState.from_str(data["state"]),
|
|
229
|
-
metadata=data.get("metadata"),
|
|
230
|
-
)
|
|
@@ -198,9 +198,8 @@ def end_top_user_flow(stack: DialogueStack) -> DialogueStack:
|
|
|
198
198
|
def get_collect_steps_excluding_ask_before_filling_for_active_flow(
|
|
199
199
|
dialogue_stack: DialogueStack, all_flows: FlowsList
|
|
200
200
|
) -> Set[str]:
|
|
201
|
-
"""Get all collect steps that are part of the current flow
|
|
202
|
-
|
|
203
|
-
Collect steps that have to be asked before filling are not considered.
|
|
201
|
+
"""Get all collect steps that are part of the current flow, without
|
|
202
|
+
considering the collect steps that has to be asked before filling.
|
|
204
203
|
|
|
205
204
|
Args:
|
|
206
205
|
dialogue_stack: The dialogue stack.
|
|
@@ -231,17 +230,3 @@ def get_collect_steps_excluding_ask_before_filling_for_active_flow(
|
|
|
231
230
|
for step in active_flow.get_collect_steps()
|
|
232
231
|
if not step.ask_before_filling
|
|
233
232
|
)
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
def is_continue_interrupted_flow_active(stack: DialogueStack) -> bool:
|
|
237
|
-
"""Check if the continue interrupted flow is active."""
|
|
238
|
-
from rasa.dialogue_understanding.patterns.continue_interrupted import (
|
|
239
|
-
ContinueInterruptedPatternFlowStackFrame,
|
|
240
|
-
)
|
|
241
|
-
|
|
242
|
-
for frame in reversed(stack.frames):
|
|
243
|
-
if isinstance(frame, ContinueInterruptedPatternFlowStackFrame):
|
|
244
|
-
return True
|
|
245
|
-
if isinstance(frame, UserFlowStackFrame):
|
|
246
|
-
return False
|
|
247
|
-
return False
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import time
|
|
3
|
-
from
|
|
4
|
-
from typing import Any, Dict, List, Optional, Union
|
|
3
|
+
from typing import Any, Dict, List, Optional, Text
|
|
5
4
|
|
|
6
5
|
import structlog
|
|
7
6
|
from tqdm import tqdm
|
|
8
7
|
|
|
9
|
-
from rasa.core.available_agents import AvailableAgents
|
|
10
8
|
from rasa.core.available_endpoints import AvailableEndpoints
|
|
11
9
|
from rasa.core.channels import CollectingOutputChannel, UserMessage
|
|
12
10
|
from rasa.core.exceptions import AgentNotReady
|
|
@@ -54,11 +52,10 @@ class DialogueUnderstandingTestRunner:
|
|
|
54
52
|
|
|
55
53
|
def __init__(
|
|
56
54
|
self,
|
|
57
|
-
model_path: Optional[
|
|
55
|
+
model_path: Optional[Text] = None,
|
|
58
56
|
model_server: Optional[EndpointConfig] = None,
|
|
59
57
|
remote_storage: Optional[StorageType] = None,
|
|
60
58
|
endpoints: Optional[AvailableEndpoints] = None,
|
|
61
|
-
sub_agents_path: Optional[Union[Path, str]] = None,
|
|
62
59
|
) -> None:
|
|
63
60
|
"""Initializes the Dialogue Understanding test suite runner.
|
|
64
61
|
|
|
@@ -71,7 +68,6 @@ class DialogueUnderstandingTestRunner:
|
|
|
71
68
|
import rasa.core.agent
|
|
72
69
|
|
|
73
70
|
self._check_action_server(endpoints)
|
|
74
|
-
sub_agents = AvailableAgents.get_instance(sub_agents_path)
|
|
75
71
|
|
|
76
72
|
self.agent = asyncio.run(
|
|
77
73
|
rasa.core.agent.load_agent(
|
|
@@ -79,7 +75,6 @@ class DialogueUnderstandingTestRunner:
|
|
|
79
75
|
model_server=model_server,
|
|
80
76
|
remote_storage=remote_storage,
|
|
81
77
|
endpoints=endpoints,
|
|
82
|
-
sub_agents=sub_agents,
|
|
83
78
|
)
|
|
84
79
|
)
|
|
85
80
|
if not self.agent.is_ready():
|
rasa/e2e_test/e2e_test_runner.py
CHANGED
|
@@ -13,7 +13,6 @@ import structlog
|
|
|
13
13
|
from tqdm import tqdm
|
|
14
14
|
|
|
15
15
|
import rasa.shared.utils.io
|
|
16
|
-
from rasa.core.available_agents import AvailableAgents
|
|
17
16
|
from rasa.core.available_endpoints import AvailableEndpoints
|
|
18
17
|
from rasa.core.channels import CollectingOutputChannel, UserMessage
|
|
19
18
|
from rasa.core.constants import ACTIVE_FLOW_METADATA_KEY, STEP_ID_METADATA_KEY
|
|
@@ -66,7 +65,6 @@ class E2ETestRunner:
|
|
|
66
65
|
model_server: Optional[EndpointConfig] = None,
|
|
67
66
|
remote_storage: Optional[StorageType] = None,
|
|
68
67
|
endpoints: Optional[AvailableEndpoints] = None,
|
|
69
|
-
sub_agents_path: Optional[Text] = None,
|
|
70
68
|
**kwargs: Any,
|
|
71
69
|
) -> None:
|
|
72
70
|
"""Initializes the E2E test suite runner.
|
|
@@ -96,15 +94,12 @@ class E2ETestRunner:
|
|
|
96
94
|
if endpoints and not are_custom_actions_stubbed:
|
|
97
95
|
self._action_server_is_reachable(endpoints)
|
|
98
96
|
|
|
99
|
-
sub_agents = AvailableAgents.get_instance(sub_agents_path)
|
|
100
|
-
|
|
101
97
|
self.agent = asyncio.run(
|
|
102
98
|
rasa.core.agent.load_agent(
|
|
103
99
|
model_path=model_path,
|
|
104
100
|
model_server=model_server,
|
|
105
101
|
remote_storage=remote_storage,
|
|
106
102
|
endpoints=endpoints,
|
|
107
|
-
sub_agents=sub_agents,
|
|
108
103
|
)
|
|
109
104
|
)
|
|
110
105
|
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
+
import os
|
|
4
5
|
import shutil
|
|
5
6
|
import sys
|
|
7
|
+
import tarfile
|
|
6
8
|
import tempfile
|
|
7
9
|
import uuid
|
|
8
10
|
from contextlib import contextmanager
|
|
9
11
|
from datetime import datetime
|
|
10
12
|
from pathlib import Path
|
|
11
|
-
from typing import Generator, Optional, Text, Tuple, Union
|
|
13
|
+
from typing import Callable, Generator, Optional, Text, Tuple, Union
|
|
12
14
|
|
|
13
15
|
from tarsafe import TarSafe
|
|
14
16
|
|
|
@@ -57,6 +59,35 @@ def windows_safe_temporary_directory(
|
|
|
57
59
|
yield temporary_directory
|
|
58
60
|
|
|
59
61
|
|
|
62
|
+
def filter_normpath(member: tarfile.TarInfo, dest_path: str) -> tarfile.TarInfo:
|
|
63
|
+
"""Normalize tar member paths for safe extraction"""
|
|
64
|
+
if member.name:
|
|
65
|
+
member.name = os.path.normpath(member.name)
|
|
66
|
+
return member
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
FilterFunction = Callable[[tarfile.TarInfo, str], Optional[tarfile.TarInfo]]
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def create_combined_filter(existing_filter: Optional[FilterFunction]) -> FilterFunction:
|
|
73
|
+
"""Create a filter that combines existing filter with path normalization"""
|
|
74
|
+
|
|
75
|
+
def combined_filter(
|
|
76
|
+
member: tarfile.TarInfo, dest_path: str
|
|
77
|
+
) -> Optional[tarfile.TarInfo]:
|
|
78
|
+
"""Apply existing filter first, then path normalization"""
|
|
79
|
+
if existing_filter is not None:
|
|
80
|
+
filtered_member = existing_filter(member, dest_path)
|
|
81
|
+
if filtered_member is None:
|
|
82
|
+
return None # Rejected by existing filter
|
|
83
|
+
member = filtered_member # Use the filtered result
|
|
84
|
+
|
|
85
|
+
# Apply our path normalization
|
|
86
|
+
return filter_normpath(member, dest_path)
|
|
87
|
+
|
|
88
|
+
return combined_filter
|
|
89
|
+
|
|
90
|
+
|
|
60
91
|
class LocalModelStorage(ModelStorage):
|
|
61
92
|
"""Stores and provides output of `GraphComponents` on local disk."""
|
|
62
93
|
|
|
@@ -122,7 +153,19 @@ class LocalModelStorage(ModelStorage):
|
|
|
122
153
|
# this restriction in environments where it's not possible
|
|
123
154
|
# to override this behavior, mostly for internal policy reasons
|
|
124
155
|
# reference: https://stackoverflow.com/a/49102229
|
|
125
|
-
|
|
156
|
+
try:
|
|
157
|
+
# Use extraction filter to normalize paths for compatibility
|
|
158
|
+
# before trying the \\?\ prefix approach first
|
|
159
|
+
prev_filter = getattr(tar, "extraction_filter", None)
|
|
160
|
+
tar.extraction_filter = create_combined_filter(prev_filter)
|
|
161
|
+
tar.extractall(f"\\\\?\\{temporary_directory}")
|
|
162
|
+
except Exception:
|
|
163
|
+
# Fallback for Python versions with tarfile security fix
|
|
164
|
+
logger.warning(
|
|
165
|
+
"Failed to extract model archive with long path support. "
|
|
166
|
+
"Falling back to regular extraction."
|
|
167
|
+
)
|
|
168
|
+
tar.extractall(temporary_directory)
|
|
126
169
|
else:
|
|
127
170
|
tar.extractall(temporary_directory)
|
|
128
171
|
LocalModelStorage._assert_not_rasa2_archive(temporary_directory)
|
rasa/model_manager/model_api.py
CHANGED
|
@@ -39,11 +39,9 @@ from rasa.model_manager.trainer_service import (
|
|
|
39
39
|
update_training_status,
|
|
40
40
|
)
|
|
41
41
|
from rasa.model_manager.utils import (
|
|
42
|
-
InvalidPathException,
|
|
43
42
|
get_logs_content,
|
|
44
43
|
logs_base_path,
|
|
45
44
|
models_base_path,
|
|
46
|
-
subpath,
|
|
47
45
|
)
|
|
48
46
|
from rasa.model_manager.warm_rasa_process import (
|
|
49
47
|
initialize_warm_rasa_process,
|
|
@@ -53,6 +51,7 @@ from rasa.server import ErrorResponse
|
|
|
53
51
|
from rasa.shared.exceptions import InvalidConfigException
|
|
54
52
|
from rasa.shared.utils.yaml import dump_obj_as_yaml_to_string
|
|
55
53
|
from rasa.studio.upload import build_calm_import_parts
|
|
54
|
+
from rasa.utils.io import InvalidPathException, subpath
|
|
56
55
|
|
|
57
56
|
dotenv.load_dotenv()
|
|
58
57
|
|
|
@@ -571,10 +570,10 @@ def external_blueprint() -> Blueprint:
|
|
|
571
570
|
"""Create a blueprint for the model manager API."""
|
|
572
571
|
from rasa.core.channels.socketio import SocketBlueprint
|
|
573
572
|
|
|
574
|
-
|
|
575
|
-
bp = SocketBlueprint(
|
|
573
|
+
sio_server = AsyncServer(async_mode="sanic", cors_allowed_origins="*")
|
|
574
|
+
bp = SocketBlueprint(sio_server, "", "model_api_external")
|
|
576
575
|
|
|
577
|
-
create_bridge_server(
|
|
576
|
+
create_bridge_server(sio_server, running_bots)
|
|
578
577
|
|
|
579
578
|
@bp.get("/health")
|
|
580
579
|
async def health(request: Request) -> response.HTTPResponse:
|
|
@@ -15,11 +15,11 @@ from rasa.model_manager import config
|
|
|
15
15
|
from rasa.model_manager.utils import (
|
|
16
16
|
logs_path,
|
|
17
17
|
models_base_path,
|
|
18
|
-
subpath,
|
|
19
18
|
write_encoded_data_to_file,
|
|
20
19
|
)
|
|
21
20
|
from rasa.model_manager.warm_rasa_process import start_rasa_process
|
|
22
21
|
from rasa.studio.prompts import handle_prompts
|
|
22
|
+
from rasa.utils.io import subpath
|
|
23
23
|
|
|
24
24
|
structlogger = structlog.get_logger()
|
|
25
25
|
|
|
@@ -19,7 +19,7 @@ socket_proxy_clients = {}
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
async def socketio_websocket_traffic_wrapper(
|
|
22
|
-
|
|
22
|
+
sio_server: AsyncServer,
|
|
23
23
|
running_bots: Dict[str, BotSession],
|
|
24
24
|
sid: str,
|
|
25
25
|
auth: Optional[Dict],
|
|
@@ -55,7 +55,9 @@ async def socketio_websocket_traffic_wrapper(
|
|
|
55
55
|
structlogger.error("model_runner.bot_not_alive", deployment_id=deployment_id)
|
|
56
56
|
raise ConnectionRefusedError("model_runner.bot_not_alive")
|
|
57
57
|
|
|
58
|
-
client = await create_bridge_client(
|
|
58
|
+
client = await create_bridge_client(
|
|
59
|
+
sio_server, bot.internal_url, sid, deployment_id
|
|
60
|
+
)
|
|
59
61
|
|
|
60
62
|
if client.sid is not None:
|
|
61
63
|
structlogger.debug(
|
|
@@ -70,20 +72,24 @@ async def socketio_websocket_traffic_wrapper(
|
|
|
70
72
|
raise ConnectionRefusedError("model_runner.bot_connection_failed")
|
|
71
73
|
|
|
72
74
|
|
|
73
|
-
def create_bridge_server(
|
|
75
|
+
def create_bridge_server(
|
|
76
|
+
sio_server: AsyncServer, running_bots: Dict[str, BotSession]
|
|
77
|
+
) -> None:
|
|
74
78
|
"""Create handlers for the socket server side.
|
|
75
79
|
|
|
76
80
|
Forwards messages coming from the user to the bot.
|
|
77
81
|
"""
|
|
78
82
|
|
|
79
|
-
@
|
|
83
|
+
@sio_server.on("connect")
|
|
80
84
|
async def socketio_websocket_traffic(
|
|
81
85
|
sid: str, environ: Dict, auth: Optional[Dict]
|
|
82
86
|
) -> bool:
|
|
83
87
|
"""Bridge websockets between user chat socket and bot server."""
|
|
84
|
-
return await socketio_websocket_traffic_wrapper(
|
|
88
|
+
return await socketio_websocket_traffic_wrapper(
|
|
89
|
+
sio_server, running_bots, sid, auth
|
|
90
|
+
)
|
|
85
91
|
|
|
86
|
-
@
|
|
92
|
+
@sio_server.on("disconnect")
|
|
87
93
|
async def disconnect(sid: str) -> None:
|
|
88
94
|
"""Disconnect the bot connection."""
|
|
89
95
|
structlogger.debug("model_runner.bot_disconnect", sid=sid)
|
|
@@ -91,7 +97,7 @@ def create_bridge_server(sio: AsyncServer, running_bots: Dict[str, BotSession])
|
|
|
91
97
|
await socket_proxy_clients[sid].disconnect()
|
|
92
98
|
del socket_proxy_clients[sid]
|
|
93
99
|
|
|
94
|
-
@
|
|
100
|
+
@sio_server.on("*")
|
|
95
101
|
async def handle_message(event: str, sid: str, data: Dict[str, Any]) -> None:
|
|
96
102
|
"""Bridge messages between user and bot.
|
|
97
103
|
|
|
@@ -108,7 +114,7 @@ def create_bridge_server(sio: AsyncServer, running_bots: Dict[str, BotSession])
|
|
|
108
114
|
|
|
109
115
|
|
|
110
116
|
async def create_bridge_client(
|
|
111
|
-
|
|
117
|
+
sio_server: AsyncServer, url: str, sid: str, deployment_id: str
|
|
112
118
|
) -> AsyncClient:
|
|
113
119
|
"""Create a new socket bridge client.
|
|
114
120
|
|
|
@@ -123,36 +129,36 @@ async def create_bridge_client(
|
|
|
123
129
|
structlogger.debug(
|
|
124
130
|
"model_runner.bot_session_confirmed", deployment_id=deployment_id
|
|
125
131
|
)
|
|
126
|
-
await
|
|
132
|
+
await sio_server.emit("session_confirm", room=sid)
|
|
127
133
|
|
|
128
134
|
@client.event # type: ignore[misc]
|
|
129
135
|
async def bot_message(data: Dict[str, Any]) -> None:
|
|
130
136
|
structlogger.debug("model_runner.bot_message", deployment_id=deployment_id)
|
|
131
|
-
await
|
|
137
|
+
await sio_server.emit("bot_message", data, room=sid)
|
|
132
138
|
|
|
133
139
|
@client.event # type: ignore[misc]
|
|
134
140
|
async def error(data: Dict[str, Any]) -> None:
|
|
135
141
|
structlogger.debug(
|
|
136
142
|
"model_runner.bot_error", deployment_id=deployment_id, data=data
|
|
137
143
|
)
|
|
138
|
-
await
|
|
144
|
+
await sio_server.emit("error", data, room=sid)
|
|
139
145
|
|
|
140
146
|
@client.event # type: ignore[misc]
|
|
141
147
|
async def tracker(data: Dict[str, Any]) -> None:
|
|
142
|
-
await
|
|
148
|
+
await sio_server.emit("tracker", json.loads(data), room=sid)
|
|
143
149
|
|
|
144
150
|
@client.event # type: ignore[misc]
|
|
145
151
|
async def disconnect() -> None:
|
|
146
152
|
structlogger.debug(
|
|
147
153
|
"model_runner.bot_connection_closed", deployment_id=deployment_id
|
|
148
154
|
)
|
|
149
|
-
await
|
|
155
|
+
await sio_server.emit("disconnect", room=sid)
|
|
150
156
|
|
|
151
157
|
@client.event # type: ignore[misc]
|
|
152
158
|
async def connect_error() -> None:
|
|
153
159
|
structlogger.error(
|
|
154
160
|
"model_runner.bot_connection_error", deployment_id=deployment_id
|
|
155
161
|
)
|
|
156
|
-
await
|
|
162
|
+
await sio_server.emit("disconnect", room=sid)
|
|
157
163
|
|
|
158
164
|
return client
|
|
@@ -14,7 +14,6 @@ from rasa.model_manager.utils import (
|
|
|
14
14
|
ensure_base_directory_exists,
|
|
15
15
|
logs_path,
|
|
16
16
|
models_base_path,
|
|
17
|
-
subpath,
|
|
18
17
|
write_encoded_data_to_file,
|
|
19
18
|
)
|
|
20
19
|
from rasa.model_manager.warm_rasa_process import (
|
|
@@ -22,6 +21,7 @@ from rasa.model_manager.warm_rasa_process import (
|
|
|
22
21
|
)
|
|
23
22
|
from rasa.model_training import generate_random_model_name
|
|
24
23
|
from rasa.studio.prompts import handle_prompts
|
|
24
|
+
from rasa.utils.io import subpath
|
|
25
25
|
|
|
26
26
|
structlogger = structlog.get_logger()
|
|
27
27
|
|
|
@@ -53,6 +53,15 @@ class TrainingSession(BaseModel):
|
|
|
53
53
|
"""Check if the training is running."""
|
|
54
54
|
return self.status == TrainingSessionStatus.RUNNING
|
|
55
55
|
|
|
56
|
+
def has_just_finished(self) -> bool:
|
|
57
|
+
if not self.is_status_indicating_alive():
|
|
58
|
+
# skip if the training is not running
|
|
59
|
+
return False
|
|
60
|
+
if self.process.poll() is None:
|
|
61
|
+
# process is still running
|
|
62
|
+
return False
|
|
63
|
+
return True
|
|
64
|
+
|
|
56
65
|
def model_path(self) -> str:
|
|
57
66
|
"""Return the path to the model."""
|
|
58
67
|
return subpath(models_base_path(), f"{self.model_name}.tar.gz")
|
|
@@ -89,14 +98,8 @@ def terminate_training(training: TrainingSession) -> None:
|
|
|
89
98
|
|
|
90
99
|
|
|
91
100
|
def update_training_status(training: TrainingSession) -> None:
|
|
92
|
-
if
|
|
93
|
-
|
|
94
|
-
return
|
|
95
|
-
if training.process.poll() is None:
|
|
96
|
-
# process is still running
|
|
97
|
-
return
|
|
98
|
-
|
|
99
|
-
complete_training(training)
|
|
101
|
+
if training.has_just_finished():
|
|
102
|
+
complete_training(training)
|
|
100
103
|
|
|
101
104
|
|
|
102
105
|
def complete_training(training: TrainingSession) -> None:
|
rasa/model_manager/utils.py
CHANGED
|
@@ -5,15 +5,11 @@ from typing import Optional
|
|
|
5
5
|
import structlog
|
|
6
6
|
|
|
7
7
|
from rasa.model_manager import config
|
|
8
|
-
from rasa.
|
|
8
|
+
from rasa.utils.io import subpath
|
|
9
9
|
|
|
10
10
|
structlogger = structlog.get_logger()
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
class InvalidPathException(RasaException):
|
|
14
|
-
"""Raised if a path is invalid - e.g. path traversal is detected."""
|
|
15
|
-
|
|
16
|
-
|
|
17
13
|
def write_encoded_data_to_file(encoded_data: bytes, file: str) -> None:
|
|
18
14
|
"""Write base64 encoded data to a file."""
|
|
19
15
|
# create the directory if it does not exist of the parent directory
|
|
@@ -53,30 +49,6 @@ def logs_path(action_id: str) -> str:
|
|
|
53
49
|
return subpath(logs_base_path(), f"{action_id}.txt")
|
|
54
50
|
|
|
55
51
|
|
|
56
|
-
def subpath(parent: str, child: str) -> str:
|
|
57
|
-
"""Return the path to the child directory of the parent directory.
|
|
58
|
-
|
|
59
|
-
Ensures, that child doesn't navigate to parent directories. Prevents
|
|
60
|
-
path traversal. Raises an InvalidPathException if the path is invalid.
|
|
61
|
-
|
|
62
|
-
Based on Snyk's directory traversal mitigation:
|
|
63
|
-
https://learn.snyk.io/lesson/directory-traversal/
|
|
64
|
-
"""
|
|
65
|
-
safe_path = os.path.abspath(os.path.join(parent, child))
|
|
66
|
-
parent = os.path.abspath(parent)
|
|
67
|
-
|
|
68
|
-
common_base = os.path.commonpath([parent, safe_path])
|
|
69
|
-
if common_base != parent:
|
|
70
|
-
raise InvalidPathException(f"Invalid path: {safe_path}")
|
|
71
|
-
|
|
72
|
-
if os.path.basename(safe_path) != child:
|
|
73
|
-
raise InvalidPathException(
|
|
74
|
-
f"Invalid path - path traversal detected: {safe_path}"
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
return safe_path
|
|
78
|
-
|
|
79
|
-
|
|
80
52
|
def get_logs_content(action_id: str) -> Optional[str]:
|
|
81
53
|
"""Return the content of the log file for a given action id."""
|
|
82
54
|
try:
|