rasa-pro 3.14.0.dev20250901__py3-none-any.whl → 3.14.0.dev20250922__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/builder/config.py +1 -0
- rasa/builder/copilot/constants.py +3 -0
- rasa/builder/copilot/copilot.py +128 -54
- rasa/builder/copilot/models.py +39 -3
- rasa/builder/copilot/prompts/copilot_system_prompt.jinja2 +183 -188
- rasa/builder/copilot/prompts/latest_user_message_context_prompt.jinja2 +61 -0
- rasa/builder/copilot/telemetry.py +46 -20
- rasa/builder/document_retrieval/models.py +3 -3
- rasa/builder/download.py +1 -8
- rasa/builder/jobs.py +33 -21
- rasa/builder/main.py +38 -62
- rasa/builder/models.py +7 -7
- rasa/builder/project_generator.py +143 -147
- rasa/builder/service.py +42 -27
- rasa/builder/template_cache.py +69 -0
- rasa/builder/training_service.py +74 -4
- rasa/cli/project_templates/basic/README.md +23 -0
- rasa/cli/project_templates/basic/actions/actions.md +10 -0
- rasa/cli/project_templates/basic/config.yml +6 -4
- rasa/cli/project_templates/basic/data/data.md +5 -6
- rasa/cli/project_templates/basic/domain/domain.md +7 -5
- rasa/cli/project_templates/basic/domain/general/show_faqs.yml +1 -1
- rasa/cli/project_templates/basic/endpoints.yml +5 -1
- rasa/cli/project_templates/default/config.yml +4 -0
- rasa/cli/project_templates/default/endpoints.yml +4 -0
- rasa/cli/project_templates/finance/README.md +26 -0
- rasa/cli/project_templates/finance/actions/__init__.py +0 -46
- rasa/cli/project_templates/finance/actions/accounts/check_balance.py +18 -0
- rasa/cli/project_templates/finance/actions/actions.md +15 -0
- rasa/cli/project_templates/finance/actions/{transfers/action_process_immediate_payment.py → cards/check_that_card_exists.py} +6 -3
- rasa/cli/project_templates/finance/actions/cards/list_cards.py +22 -0
- rasa/cli/project_templates/finance/actions/contacts/__init__.py +0 -0
- rasa/cli/project_templates/finance/actions/contacts/add_contact.py +30 -0
- rasa/cli/project_templates/finance/actions/contacts/list_contacts.py +22 -0
- rasa/cli/project_templates/finance/actions/contacts/remove_contact.py +35 -0
- rasa/cli/project_templates/finance/actions/db.py +117 -0
- rasa/cli/project_templates/finance/actions/general/__init__.py +0 -0
- rasa/cli/project_templates/finance/actions/general/action_human_handoff.py +49 -0
- rasa/cli/project_templates/finance/actions/transfers/check_transfer_funds.py +27 -0
- rasa/cli/project_templates/finance/actions/transfers/check_transfer_limit.py +36 -0
- rasa/cli/project_templates/finance/actions/transfers/execute_recurrent_payment.py +20 -0
- rasa/cli/project_templates/finance/actions/transfers/execute_transfer.py +45 -0
- rasa/cli/project_templates/finance/actions/transfers/list_transactions.py +32 -0
- rasa/cli/project_templates/finance/config.yml +8 -0
- rasa/cli/project_templates/finance/credentials.yml +7 -6
- rasa/cli/project_templates/finance/data/accounts/check_balance.yml +3 -4
- rasa/cli/project_templates/finance/data/accounts/download_statements.yml +26 -0
- rasa/cli/project_templates/finance/data/bills/bill_pay_reminder.yml +25 -0
- rasa/cli/project_templates/finance/data/cards/activate_card.yml +35 -0
- rasa/cli/project_templates/finance/data/cards/block_card.yml +37 -58
- rasa/cli/project_templates/finance/data/cards/list_cards.yml +14 -0
- rasa/cli/project_templates/finance/data/cards/replace_card.yml +16 -0
- rasa/cli/project_templates/finance/data/cards/replace_eligible_card.yml +29 -0
- rasa/cli/project_templates/finance/data/contacts/add_contact.yml +33 -0
- rasa/cli/project_templates/finance/data/contacts/list_contacts.yml +14 -0
- rasa/cli/project_templates/finance/data/contacts/remove_contact.yml +31 -0
- rasa/cli/project_templates/finance/data/data.md +14 -0
- rasa/cli/project_templates/finance/data/general/bot_challenge.yml +6 -0
- rasa/cli/project_templates/finance/data/general/goodbye.yml +1 -1
- rasa/cli/project_templates/finance/data/general/hello.yml +1 -2
- rasa/cli/project_templates/finance/data/general/help.yml +2 -2
- rasa/cli/project_templates/finance/data/general/human_handoff.yml +2 -2
- rasa/cli/project_templates/finance/data/system/patterns/pattern_session_start.yml +1 -1
- rasa/cli/project_templates/finance/data/transfers/check_transfer_limit.yml +18 -0
- rasa/cli/project_templates/finance/data/transfers/list_transactions.yml +46 -0
- rasa/cli/project_templates/finance/data/transfers/move_money_between_accounts.yml +51 -0
- rasa/cli/project_templates/finance/data/transfers/transfer_money.yml +29 -62
- rasa/cli/project_templates/finance/data/transfers/transfer_money_to_a_third_party.yml +175 -0
- rasa/cli/project_templates/finance/db/cards.json +18 -0
- rasa/cli/project_templates/finance/db/contacts.json +10 -0
- rasa/cli/project_templates/finance/db/my_account.json +6 -0
- rasa/cli/project_templates/finance/db/transactions.json +22 -0
- rasa/cli/project_templates/finance/docs/docs.md +8 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/account_features/budgeting_analytics.txt +22 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/account_features/multi_currency_accounts.txt +19 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/account_features/premium_benefits.txt +19 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/card_management/contactless_limits.txt +16 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/card_management/freeze_unfreeze_card.txt +16 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/card_management/lost_stolen_card.txt +19 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/money_transfers/instant_payments.txt +19 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/money_transfers/international_transfers.txt +19 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/security_fraud/fraud_protection.txt +22 -0
- rasa/cli/project_templates/finance/docs/fenlo_banking_faq/security_fraud/secure_payments.txt +22 -0
- rasa/cli/project_templates/finance/domain/accounts/check_balance.yml +9 -5
- rasa/cli/project_templates/finance/domain/accounts/download_statements.yml +40 -0
- rasa/cli/project_templates/finance/domain/bills/bill_pay_reminder.yml +49 -0
- rasa/cli/project_templates/finance/domain/cards/activate_card.yml +24 -0
- rasa/cli/project_templates/finance/domain/cards/block_card.yml +33 -90
- rasa/cli/project_templates/finance/domain/cards/list_cards.yml +16 -0
- rasa/cli/project_templates/finance/domain/cards/replace_card.yml +43 -0
- rasa/cli/project_templates/finance/domain/cards/shared.yml +15 -0
- rasa/cli/project_templates/finance/domain/contacts/add_contact.yml +37 -0
- rasa/cli/project_templates/finance/domain/contacts/list_contacts.yml +16 -0
- rasa/cli/project_templates/finance/domain/contacts/remove_contact.yml +32 -0
- rasa/cli/project_templates/finance/domain/domain.md +18 -0
- rasa/cli/project_templates/finance/domain/general/_shared.yml +39 -0
- rasa/cli/project_templates/finance/domain/general/bot_challenge.yml +4 -0
- rasa/cli/project_templates/finance/domain/general/cannot_handle.yml +5 -2
- rasa/cli/project_templates/finance/domain/general/feedback.yml +0 -3
- rasa/cli/project_templates/finance/domain/general/goodbye.yml +6 -6
- rasa/cli/project_templates/finance/domain/general/human_handoff.yml +10 -9
- rasa/cli/project_templates/finance/domain/general/welcome.yml +33 -2
- rasa/cli/project_templates/finance/domain/transfers/check_transfer_limit.yml +32 -0
- rasa/cli/project_templates/finance/domain/transfers/list_transactions.yml +44 -0
- rasa/cli/project_templates/finance/domain/transfers/shared.yml +17 -0
- rasa/cli/project_templates/finance/domain/transfers/transfer_money.yml +203 -61
- rasa/cli/project_templates/finance/endpoints.yml +8 -4
- rasa/cli/project_templates/finance/prompts/rephraser_demo_personality_prompt.jinja2 +31 -12
- rasa/cli/project_templates/finance/tests/e2e_test_cases/accounts/check_balance.yml +9 -0
- rasa/cli/project_templates/finance/tests/e2e_test_cases/accounts/download_statements.yml +43 -0
- rasa/cli/project_templates/finance/tests/e2e_test_cases/cards/block_card.yml +55 -0
- rasa/cli/project_templates/finance/tests/e2e_test_cases/general/bot_challenge.yml +8 -0
- rasa/cli/project_templates/finance/tests/e2e_test_cases/general/feedback.yml +46 -0
- rasa/cli/project_templates/finance/tests/e2e_test_cases/general/goodbye.yml +9 -0
- rasa/cli/project_templates/finance/tests/e2e_test_cases/general/hello.yml +8 -0
- rasa/cli/project_templates/finance/tests/e2e_test_cases/general/human_handoff.yml +35 -0
- rasa/cli/project_templates/finance/tests/e2e_test_cases/general/patterns.yml +22 -0
- rasa/cli/project_templates/finance/tests/e2e_test_cases/transfers/transfer_money.yml +56 -0
- rasa/cli/project_templates/telco/README.md +25 -0
- rasa/cli/project_templates/telco/actions/actions.md +12 -0
- rasa/cli/project_templates/telco/config.yml +6 -4
- rasa/cli/project_templates/telco/data/data.md +11 -0
- rasa/cli/project_templates/telco/data/general/human_handoff.yml +1 -1
- rasa/cli/project_templates/telco/docs/docs.md +3 -0
- rasa/cli/project_templates/telco/domain/domain.md +13 -0
- rasa/cli/project_templates/telco/domain/general/human_handoff.yml +3 -6
- rasa/cli/project_templates/telco/endpoints.yml +5 -1
- rasa/cli/project_templates/telco/prompts/rephraser_demo_personality_prompt.jinja2 +1 -1
- rasa/cli/project_templates/telco/tests/e2e_test_cases/billing/understand_bill.yml +67 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/general/bot_challenge.yml +8 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/general/feedback.yml +46 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/general/goodbye.yml +9 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/general/hello.yml +8 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/general/human_handoff.yml +35 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/general/patterns.yml +23 -0
- rasa/cli/project_templates/telco/tests/e2e_test_cases/network/solve_internet_issue.yml +57 -0
- rasa/core/actions/action_run_slot_rejections.py +1 -1
- rasa/core/actions/direct_custom_actions_executor.py +9 -2
- rasa/core/brokers/broker.py +1 -1
- rasa/core/brokers/kafka.py +52 -8
- rasa/core/channels/development_inspector.py +1 -21
- rasa/core/channels/hangouts.py +2 -2
- rasa/core/channels/inspector/dist/assets/{arc-18042c22.js → arc-35222594.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-fdd6bcfa.js → blockDiagram-38ab4fdb-a0efbfd3.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-f5ae6786.js → c4Diagram-3d4e48cf-0584c0f2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/channel-8e08bed9.js +1 -0
- rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-81efba3e.js → classDiagram-70f12bd4-39f40dbe.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-3b6b6a92.js → classDiagram-v2-f2320105-1ad755f3.js} +1 -1
- rasa/core/channels/inspector/dist/assets/clone-78c82dea.js +1 -0
- rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-31422447.js → createText-2e5e7dd3-b0f4f0fe.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-518a90db.js → edges-e0da2a9e-9039bff9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-a6d3c25a.js → erDiagram-9861fffd-65c9b127.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-e048c2be.js → flowDb-956e92f1-4f08b38e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-c7474c91.js → flowDiagram-66a62f08-e95c362a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-2b08f601.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-cb4d8723.js → flowchart-elk-definition-4a651766-703c3015.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-346636a2.js → ganttDiagram-c361ad54-699328ea.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-7c508874.js → gitGraphDiagram-72cf32ee-04cf4b05.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{graph-14702d8a.js → graph-ee94449e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-3862675e-f18b534b.js → index-3862675e-940162b4.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-4d4bdf3a.js → index-c941dcb3.js} +132 -131
- rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-64154b83.js → infoDiagram-f8f76790-c79c2866.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-833a5f95.js → journeyDiagram-49397b02-84489d30.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-5a3b2123.js → layout-a9aa9858.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-2272a8c7.js → line-eb73cf26.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-35bcf273.js → linear-b3399f9a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-92dcb0e9.js → mindmap-definition-fc14e90a-b095bf1a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-94dbc900.js → pieDiagram-8a3498a8-07644b66.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-8b7a9c33.js → quadrantDiagram-120e2f19-573a3f9c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-6f7eab81.js → requirementDiagram-deff3bca-d457e1e1.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-f43e581d.js → sankeyDiagram-04a897e0-9d26e1a2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-0bcbefc3.js → sequenceDiagram-704730f1-3a9cde10.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-b8a74083.js → stateDiagram-587899a1-4f3e8cec.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-2070218f.js → stateDiagram-v2-d93cdb3a-e617e5bf.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-f1d54e34.js → styles-6aaf32cf-eab30d2f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9a916d00-980de489.js → styles-9a916d00-09994be2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-c10674c1-3c03abde.js → styles-c10674c1-b7110364.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-46ba068f.js → svgDrawCommon-08f97a94-3ebc92ad.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-901f5e3d.js → timeline-definition-85554ec2-7d13d2f2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-acbc628a.js → xychartDiagram-e933f94c-488385e1.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +1 -1
- rasa/core/channels/inspector/src/App.tsx +5 -31
- rasa/core/channels/inspector/src/components/Chat.tsx +2 -3
- rasa/core/channels/inspector/src/components/DialogueInformation.tsx +9 -1
- rasa/core/channels/inspector/src/components/LatencyDisplay.tsx +63 -35
- rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +14 -0
- rasa/core/channels/inspector/src/types.ts +32 -7
- rasa/core/channels/studio_chat.py +23 -41
- rasa/core/channels/voice_stream/asr/asr_event.py +1 -1
- rasa/core/channels/voice_stream/asr/azure.py +6 -3
- rasa/core/channels/voice_stream/asr/deepgram.py +1 -1
- rasa/core/channels/voice_stream/audiocodes.py +3 -0
- rasa/core/channels/voice_stream/browser_audio.py +55 -3
- rasa/core/channels/voice_stream/genesys.py +2 -1
- rasa/core/channels/voice_stream/jambonz.py +9 -1
- rasa/core/channels/voice_stream/twilio_media_streams.py +16 -0
- rasa/core/channels/voice_stream/voice_channel.py +61 -0
- rasa/core/concurrent_lock_store.py +66 -16
- rasa/core/constants.py +7 -0
- rasa/core/iam_credentials_providers/__init__.py +0 -0
- rasa/core/iam_credentials_providers/aws_iam_credentials_providers.py +226 -0
- rasa/core/iam_credentials_providers/credentials_provider_protocol.py +90 -0
- rasa/core/lock_store.py +46 -10
- rasa/core/nlg/generator.py +1 -1
- rasa/core/policies/flows/flow_executor.py +1 -1
- rasa/core/processor.py +32 -0
- rasa/core/redis_connection_factory.py +469 -0
- rasa/core/tracker_stores/redis_tracker_store.py +32 -14
- rasa/core/tracker_stores/sql_tracker_store.py +57 -1
- rasa/engine/graph.py +5 -1
- rasa/engine/loader.py +12 -0
- rasa/engine/storage/local_model_storage.py +41 -4
- rasa/model_manager/socket_bridge.py +1 -2
- rasa/model_manager/warm_rasa_process.py +13 -3
- rasa/shared/core/constants.py +1 -0
- rasa/shared/core/events.py +2 -0
- rasa/shared/core/flows/flow.py +1 -1
- rasa/shared/nlu/training_data/schemas/responses.yml +3 -0
- rasa/utils/pypred.py +38 -0
- rasa/validator.py +12 -8
- rasa/version.py +1 -1
- {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0.dev20250922.dist-info}/METADATA +19 -16
- {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0.dev20250922.dist-info}/RECORD +231 -266
- rasa/cli/project_templates/finance/actions/accounts/action_ask_account.py +0 -47
- rasa/cli/project_templates/finance/actions/accounts/action_check_balance.py +0 -40
- rasa/cli/project_templates/finance/actions/action_session_start.py +0 -74
- rasa/cli/project_templates/finance/actions/cards/action_ask_card.py +0 -48
- rasa/cli/project_templates/finance/actions/cards/action_check_card_existence.py +0 -36
- rasa/cli/project_templates/finance/actions/cards/action_update_card_status.py +0 -54
- rasa/cli/project_templates/finance/actions/database.py +0 -277
- rasa/cli/project_templates/finance/actions/transfers/action_add_payee.py +0 -52
- rasa/cli/project_templates/finance/actions/transfers/action_ask_account_from.py +0 -51
- rasa/cli/project_templates/finance/actions/transfers/action_check_payee_existence.py +0 -40
- rasa/cli/project_templates/finance/actions/transfers/action_check_sufficient_funds.py +0 -40
- rasa/cli/project_templates/finance/actions/transfers/action_list_payees.py +0 -46
- rasa/cli/project_templates/finance/actions/transfers/action_remove_payee.py +0 -49
- rasa/cli/project_templates/finance/actions/transfers/action_schedule_payment.py +0 -19
- rasa/cli/project_templates/finance/actions/transfers/action_validate_payment_date.py +0 -36
- rasa/cli/project_templates/finance/csvs/accounts.csv +0 -8
- rasa/cli/project_templates/finance/csvs/advisors.csv +0 -7
- rasa/cli/project_templates/finance/csvs/appointments.csv +0 -211
- rasa/cli/project_templates/finance/csvs/branches.csv +0 -10
- rasa/cli/project_templates/finance/csvs/cards.csv +0 -11
- rasa/cli/project_templates/finance/csvs/payees.csv +0 -11
- rasa/cli/project_templates/finance/csvs/transactions.csv +0 -71
- rasa/cli/project_templates/finance/csvs/users.csv +0 -4
- rasa/cli/project_templates/finance/data/cards/select_card.yml +0 -12
- rasa/cli/project_templates/finance/data/general/bot_identity.yml +0 -6
- rasa/cli/project_templates/finance/data/system/patterns/pattern_chitchat.yml +0 -5
- rasa/cli/project_templates/finance/data/system/source/accounts.json +0 -51
- rasa/cli/project_templates/finance/data/system/source/advisors.json +0 -44
- rasa/cli/project_templates/finance/data/system/source/appointments.json +0 -1474
- rasa/cli/project_templates/finance/data/system/source/branches.json +0 -47
- rasa/cli/project_templates/finance/data/system/source/cards.json +0 -72
- rasa/cli/project_templates/finance/data/system/source/payees.json +0 -74
- rasa/cli/project_templates/finance/data/system/source/transactions.json +0 -492
- rasa/cli/project_templates/finance/data/system/source/users.json +0 -29
- rasa/cli/project_templates/finance/data/transfers/add_payee.yml +0 -29
- rasa/cli/project_templates/finance/data/transfers/list_payees.yml +0 -5
- rasa/cli/project_templates/finance/data/transfers/remove_payee.yml +0 -21
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/consequences_of_blocking_card.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/reasons_to_block_card.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/recovering_from_card_fraud.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/tips_for_card_security.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/block_card/what_to_do_if_card_is_lost.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/account_balance_security.txt +0 -7
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/common_balance_inquiries.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/methods_to_check_balance.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/understanding_balance_updates.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/check_balance/what_to_do_if_balance_is_incorrect.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/benefits_of_authorised_payees.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/common_issues_with_payees.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/general_payee_information.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/payee_management_tips.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/manage_payees/understanding_payee_types.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/common_transfer_errors.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/fees_for_transfers.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/general_transfer_information.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/security_tips_for_transfers.txt +0 -8
- rasa/cli/project_templates/finance/docs/bank_of_rasa_faq/transfer_money/transfer_processing_times.txt +0 -8
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part1.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part10.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part11.txt +0 -48
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part12.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part13.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part14.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part15.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part16.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part17.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part18.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part19.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part2.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part20.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part21.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part22.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part23.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part24.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part25.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part26.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part27.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part28.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part29.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part3.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part30.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part31.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part32.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part33.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part34.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part35.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part36.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part37.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part38.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part39.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part4.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part40.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part41.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part42.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part43.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part44.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part45.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part46.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part47.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part48.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part49.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part5.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part50.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part51.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part52.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part53.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part54.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part55.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part56.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part57.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part58.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part59.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part6.txt +0 -47
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part60.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part61.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part7.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part8.txt +0 -50
- rasa/cli/project_templates/finance/docs/huggingface_alpaca_dataset/questions_part9.txt +0 -47
- rasa/cli/project_templates/finance/domain/cards/select_card.yml +0 -12
- rasa/cli/project_templates/finance/domain/general/assistant_details.yml +0 -12
- rasa/cli/project_templates/finance/domain/general/bot_identity.yml +0 -5
- rasa/cli/project_templates/finance/domain/general/defaults.yml +0 -24
- rasa/cli/project_templates/finance/domain/general/help.yml +0 -5
- rasa/cli/project_templates/finance/domain/general/utils.yml +0 -13
- rasa/cli/project_templates/finance/domain/transfers/add_payee.yml +0 -47
- rasa/cli/project_templates/finance/domain/transfers/list_payees.yml +0 -4
- rasa/cli/project_templates/finance/domain/transfers/remove_payee.yml +0 -16
- rasa/core/channels/inspector/dist/assets/channel-b9b536fc.js +0 -1
- rasa/core/channels/inspector/dist/assets/clone-78d2ddcf.js +0 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-8b09c060.js +0 -1
- /rasa/cli/project_templates/telco/domain/billing/{domain_undertand_bill.yml → understand_bill.yml} +0 -0
- /rasa/cli/project_templates/telco/domain/network/{domain_reboot_router.yml → reboot_router.yml} +0 -0
- /rasa/cli/project_templates/telco/domain/network/{domain_reset_router.yml → reset_router.yml} +0 -0
- /rasa/cli/project_templates/telco/domain/network/{domain_run_speed_test.yml → run_speed_test.yml} +0 -0
- /rasa/cli/project_templates/telco/domain/network/{domain_solve_internet_issue.yml → solve_internet_issue.yml} +0 -0
- {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0.dev20250922.dist-info}/NOTICE +0 -0
- {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0.dev20250922.dist-info}/WHEEL +0 -0
- {rasa_pro-3.14.0.dev20250901.dist-info → rasa_pro-3.14.0.dev20250922.dist-info}/entry_points.txt +0 -0
rasa/builder/jobs.py
CHANGED
|
@@ -16,10 +16,13 @@ from rasa.builder.models import (
|
|
|
16
16
|
JobStatusEvent,
|
|
17
17
|
)
|
|
18
18
|
from rasa.builder.project_generator import ProjectGenerator
|
|
19
|
-
from rasa.builder.training_service import
|
|
19
|
+
from rasa.builder.training_service import (
|
|
20
|
+
train_and_load_agent,
|
|
21
|
+
try_load_existing_agent,
|
|
22
|
+
update_agent,
|
|
23
|
+
)
|
|
20
24
|
from rasa.builder.validation_service import validate_project
|
|
21
25
|
from rasa.cli.scaffold import ProjectTemplateName
|
|
22
|
-
from rasa.core.channels.studio_chat import StudioChatInput
|
|
23
26
|
|
|
24
27
|
structlogger = structlog.get_logger()
|
|
25
28
|
|
|
@@ -45,7 +48,6 @@ async def run_prompt_to_bot_job(
|
|
|
45
48
|
prompt: The natural language prompt for bot generation.
|
|
46
49
|
"""
|
|
47
50
|
project_generator: ProjectGenerator = app.ctx.project_generator
|
|
48
|
-
input_channel: StudioChatInput = app.ctx.input_channel
|
|
49
51
|
|
|
50
52
|
await push_job_status_event(job, JobStatus.received)
|
|
51
53
|
|
|
@@ -60,10 +62,8 @@ async def run_prompt_to_bot_job(
|
|
|
60
62
|
|
|
61
63
|
# 2. Training
|
|
62
64
|
await push_job_status_event(job, JobStatus.training)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
)
|
|
66
|
-
input_channel.agent = app.ctx.agent
|
|
65
|
+
agent = await train_and_load_agent(project_generator.get_training_input())
|
|
66
|
+
update_agent(agent, app)
|
|
67
67
|
await push_job_status_event(job, JobStatus.train_success)
|
|
68
68
|
|
|
69
69
|
structlogger.info(
|
|
@@ -128,8 +128,7 @@ async def run_template_to_bot_job(
|
|
|
128
128
|
job: The job information instance.
|
|
129
129
|
template_name: The name of the template to use for bot generation.
|
|
130
130
|
"""
|
|
131
|
-
project_generator = app.ctx.project_generator
|
|
132
|
-
input_channel = app.ctx.input_channel
|
|
131
|
+
project_generator: ProjectGenerator = app.ctx.project_generator
|
|
133
132
|
|
|
134
133
|
await push_job_status_event(job, JobStatus.received)
|
|
135
134
|
|
|
@@ -142,10 +141,14 @@ async def run_template_to_bot_job(
|
|
|
142
141
|
|
|
143
142
|
# 2) Training
|
|
144
143
|
await push_job_status_event(job, JobStatus.training)
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
144
|
+
agent = await try_load_existing_agent(project_generator.project_folder)
|
|
145
|
+
if agent is None:
|
|
146
|
+
agent = await train_and_load_agent(project_generator.get_training_input())
|
|
147
|
+
else:
|
|
148
|
+
structlogger.info(
|
|
149
|
+
"bot_builder_service.template_to_bot.agent_loaded_from_cache",
|
|
150
|
+
)
|
|
151
|
+
update_agent(agent, app)
|
|
149
152
|
await push_job_status_event(job, JobStatus.train_success)
|
|
150
153
|
|
|
151
154
|
# 3) Done
|
|
@@ -204,17 +207,26 @@ async def run_template_to_bot_job(
|
|
|
204
207
|
job_manager.mark_done(job, error=str(exc))
|
|
205
208
|
|
|
206
209
|
|
|
207
|
-
async def
|
|
210
|
+
async def run_replace_all_files_job(
|
|
208
211
|
app: "Sanic",
|
|
209
212
|
job: JobInfo,
|
|
210
213
|
bot_files: dict,
|
|
211
214
|
) -> None:
|
|
215
|
+
"""Run the replace-all-files job in the background.
|
|
216
|
+
|
|
217
|
+
This replaces all bot files with the provided files and deletes any files
|
|
218
|
+
not included in the request (excluding .rasa/ and models/ directories).
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
app: The Sanic application instance.
|
|
222
|
+
job: The job information instance.
|
|
223
|
+
bot_files: Dictionary of file names to content for replacement.
|
|
224
|
+
"""
|
|
212
225
|
project_generator = app.ctx.project_generator
|
|
213
|
-
input_channel = app.ctx.input_channel
|
|
214
226
|
await push_job_status_event(job, JobStatus.received)
|
|
215
227
|
|
|
216
228
|
try:
|
|
217
|
-
project_generator.
|
|
229
|
+
project_generator.replace_all_bot_files(bot_files)
|
|
218
230
|
|
|
219
231
|
# 1. Validating
|
|
220
232
|
await push_job_status_event(job, JobStatus.validating)
|
|
@@ -226,8 +238,8 @@ async def run_update_files_job(
|
|
|
226
238
|
|
|
227
239
|
# 2. Training
|
|
228
240
|
await push_job_status_event(job, JobStatus.training)
|
|
229
|
-
|
|
230
|
-
|
|
241
|
+
agent = await train_and_load_agent(training_input)
|
|
242
|
+
update_agent(agent, app)
|
|
231
243
|
await push_job_status_event(job, JobStatus.train_success)
|
|
232
244
|
|
|
233
245
|
await push_job_status_event(job, JobStatus.done)
|
|
@@ -238,7 +250,7 @@ async def run_update_files_job(
|
|
|
238
250
|
if config.VALIDATION_FAIL_ON_WARNINGS:
|
|
239
251
|
log_levels.append("warning")
|
|
240
252
|
structlogger.debug(
|
|
241
|
-
"
|
|
253
|
+
"replace_all_files_job.validation_error",
|
|
242
254
|
job_id=job.id,
|
|
243
255
|
error=str(exc),
|
|
244
256
|
validation_logs=exc.validation_logs,
|
|
@@ -252,7 +264,7 @@ async def run_update_files_job(
|
|
|
252
264
|
|
|
253
265
|
except TrainingError as exc:
|
|
254
266
|
structlogger.debug(
|
|
255
|
-
"
|
|
267
|
+
"replace_all_files_job.train_error",
|
|
256
268
|
job_id=job.id,
|
|
257
269
|
error=str(exc),
|
|
258
270
|
)
|
|
@@ -262,7 +274,7 @@ async def run_update_files_job(
|
|
|
262
274
|
except Exception as exc:
|
|
263
275
|
# Capture full traceback for anything truly unexpected
|
|
264
276
|
structlogger.exception(
|
|
265
|
-
"
|
|
277
|
+
"replace_all_files_job.unexpected_error",
|
|
266
278
|
job_id=job.id,
|
|
267
279
|
error=str(exc),
|
|
268
280
|
)
|
rasa/builder/main.py
CHANGED
|
@@ -22,10 +22,9 @@ from rasa.builder.logging_utils import (
|
|
|
22
22
|
log_request_start,
|
|
23
23
|
)
|
|
24
24
|
from rasa.builder.service import bp, setup_project_generator
|
|
25
|
-
from rasa.
|
|
26
|
-
from rasa.core.available_endpoints import AvailableEndpoints
|
|
25
|
+
from rasa.builder.training_service import try_load_existing_agent, update_agent
|
|
27
26
|
from rasa.core.channels.studio_chat import StudioChatInput
|
|
28
|
-
from rasa.
|
|
27
|
+
from rasa.model_manager.warm_rasa_process import warmup
|
|
29
28
|
from rasa.server import configure_cors
|
|
30
29
|
from rasa.utils.common import configure_logging_and_warnings
|
|
31
30
|
from rasa.utils.log_utils import configure_structlog
|
|
@@ -60,63 +59,6 @@ def setup_input_channel() -> StudioChatInput:
|
|
|
60
59
|
return StudioChatInput.from_credentials(credentials=studio_chat_credentials)
|
|
61
60
|
|
|
62
61
|
|
|
63
|
-
async def try_load_existing_agent(project_folder: str) -> Optional[Agent]:
|
|
64
|
-
"""Try to load an existing agent from the project's models directory.
|
|
65
|
-
|
|
66
|
-
Args:
|
|
67
|
-
project_folder: Path to the project folder
|
|
68
|
-
|
|
69
|
-
Returns:
|
|
70
|
-
Loaded Agent instance if successful, None otherwise
|
|
71
|
-
"""
|
|
72
|
-
models_dir = os.path.join(project_folder, "models")
|
|
73
|
-
|
|
74
|
-
if not os.path.exists(models_dir) or not os.path.isdir(models_dir):
|
|
75
|
-
structlogger.debug("No models directory found", models_dir=models_dir)
|
|
76
|
-
return None
|
|
77
|
-
|
|
78
|
-
try:
|
|
79
|
-
# Find the latest model in the models directory
|
|
80
|
-
latest_model_path = get_latest_model(models_dir)
|
|
81
|
-
if not latest_model_path:
|
|
82
|
-
structlogger.debug(
|
|
83
|
-
"No models found in models directory", models_dir=models_dir
|
|
84
|
-
)
|
|
85
|
-
return None
|
|
86
|
-
|
|
87
|
-
structlogger.info(
|
|
88
|
-
"Found existing model, attempting to load", model_path=latest_model_path
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
# Get available endpoints for agent loading
|
|
92
|
-
available_endpoints = AvailableEndpoints.get_instance()
|
|
93
|
-
|
|
94
|
-
# Load the agent
|
|
95
|
-
agent = await load_agent(
|
|
96
|
-
model_path=latest_model_path, endpoints=available_endpoints
|
|
97
|
-
)
|
|
98
|
-
|
|
99
|
-
if agent and agent.is_ready():
|
|
100
|
-
structlogger.info(
|
|
101
|
-
"Successfully loaded existing agent", model_path=latest_model_path
|
|
102
|
-
)
|
|
103
|
-
return agent
|
|
104
|
-
else:
|
|
105
|
-
structlogger.warning(
|
|
106
|
-
"Agent loaded but not ready", model_path=latest_model_path
|
|
107
|
-
)
|
|
108
|
-
return None
|
|
109
|
-
|
|
110
|
-
except Exception as e:
|
|
111
|
-
structlogger.warning(
|
|
112
|
-
"Failed to load existing agent",
|
|
113
|
-
models_dir=models_dir,
|
|
114
|
-
error=str(e),
|
|
115
|
-
exc_info=True,
|
|
116
|
-
)
|
|
117
|
-
return None
|
|
118
|
-
|
|
119
|
-
|
|
120
62
|
def setup_middleware(app: Sanic) -> None:
|
|
121
63
|
"""Setup middleware for request/response processing."""
|
|
122
64
|
|
|
@@ -157,7 +99,6 @@ def create_app(project_folder: str) -> Sanic:
|
|
|
157
99
|
use_authentication=app.config.USE_AUTHENTICATION,
|
|
158
100
|
rasa_version=rasa.__version__,
|
|
159
101
|
)
|
|
160
|
-
app.ctx.agent = None
|
|
161
102
|
|
|
162
103
|
# Set up project generator and store in app context
|
|
163
104
|
app.ctx.project_generator = setup_project_generator(project_folder)
|
|
@@ -165,6 +106,8 @@ def create_app(project_folder: str) -> Sanic:
|
|
|
165
106
|
# Set up input channel and store in app context
|
|
166
107
|
app.ctx.input_channel = setup_input_channel()
|
|
167
108
|
|
|
109
|
+
update_agent(None, app)
|
|
110
|
+
|
|
168
111
|
# Register the blueprint
|
|
169
112
|
app.blueprint(bp)
|
|
170
113
|
|
|
@@ -196,7 +139,7 @@ def create_app(project_folder: str) -> Sanic:
|
|
|
196
139
|
try:
|
|
197
140
|
existing_agent = await try_load_existing_agent(project_folder)
|
|
198
141
|
if existing_agent:
|
|
199
|
-
app
|
|
142
|
+
update_agent(existing_agent, app)
|
|
200
143
|
structlogger.info("Agent loaded on server startup")
|
|
201
144
|
else:
|
|
202
145
|
structlogger.info(
|
|
@@ -208,6 +151,33 @@ def create_app(project_folder: str) -> Sanic:
|
|
|
208
151
|
return app
|
|
209
152
|
|
|
210
153
|
|
|
154
|
+
def _apply_llm_overrides_from_builder_env() -> None:
|
|
155
|
+
# Prefer a dedicated builder key, fall back to license if you proxy with it
|
|
156
|
+
if not config.HELLO_LLM_PROXY_BASE_URL:
|
|
157
|
+
return
|
|
158
|
+
|
|
159
|
+
structlogger.debug(
|
|
160
|
+
"builder.main.using_llm_proxy", base_url=config.HELLO_LLM_PROXY_BASE_URL
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
if not config.RASA_PRO_LICENSE:
|
|
164
|
+
structlogger.error(
|
|
165
|
+
"copilot.proxy_missing_license",
|
|
166
|
+
event_info=(
|
|
167
|
+
"HELLO_LLM_PROXY_BASE_URL is set but RASA_PRO_LICENSE is missing."
|
|
168
|
+
),
|
|
169
|
+
)
|
|
170
|
+
return
|
|
171
|
+
|
|
172
|
+
if not os.getenv("OPENAI_API_BASE") and not os.getenv("OPENAI_API_KEY"):
|
|
173
|
+
base_url = config.HELLO_LLM_PROXY_BASE_URL.rstrip("/")
|
|
174
|
+
# needed for litellm client
|
|
175
|
+
os.environ["OPENAI_API_BASE"] = base_url
|
|
176
|
+
# needed for openai async client
|
|
177
|
+
os.environ["OPENAI_BASE_URL"] = base_url
|
|
178
|
+
os.environ["OPENAI_API_KEY"] = config.RASA_PRO_LICENSE
|
|
179
|
+
|
|
180
|
+
|
|
211
181
|
def main(project_folder: Optional[str] = None) -> None:
|
|
212
182
|
"""Main entry point."""
|
|
213
183
|
try:
|
|
@@ -218,6 +188,12 @@ def main(project_folder: Optional[str] = None) -> None:
|
|
|
218
188
|
rasa.telemetry.initialize_telemetry()
|
|
219
189
|
rasa.telemetry.initialize_error_reporting(private_mode=False)
|
|
220
190
|
|
|
191
|
+
_apply_llm_overrides_from_builder_env()
|
|
192
|
+
|
|
193
|
+
if config.HELLO_RASA_PROJECT_ID:
|
|
194
|
+
# ensures long import times for modules are ahead of time
|
|
195
|
+
warmup()
|
|
196
|
+
|
|
221
197
|
# working directory needs to be the project folder, e.g.
|
|
222
198
|
# for relative paths (./docs) in a projects config to work
|
|
223
199
|
if not project_folder:
|
rasa/builder/models.py
CHANGED
|
@@ -6,7 +6,7 @@ from pathlib import Path
|
|
|
6
6
|
from typing import Any, Dict, List, Literal, Optional
|
|
7
7
|
|
|
8
8
|
import structlog
|
|
9
|
-
from pydantic import BaseModel, Field,
|
|
9
|
+
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
10
10
|
|
|
11
11
|
from rasa.cli.scaffold import ProjectTemplateName
|
|
12
12
|
from rasa.shared.importers.importer import TrainingDataImporter
|
|
@@ -21,7 +21,8 @@ class PromptRequest(BaseModel):
|
|
|
21
21
|
..., min_length=1, max_length=10000, description="The skill description prompt"
|
|
22
22
|
)
|
|
23
23
|
|
|
24
|
-
@
|
|
24
|
+
@field_validator("prompt")
|
|
25
|
+
@classmethod
|
|
25
26
|
def validate_prompt(cls, v: str) -> str:
|
|
26
27
|
if not v.strip():
|
|
27
28
|
raise ValueError("Prompt cannot be empty or whitespace only")
|
|
@@ -38,7 +39,8 @@ class TemplateRequest(BaseModel):
|
|
|
38
39
|
),
|
|
39
40
|
)
|
|
40
41
|
|
|
41
|
-
@
|
|
42
|
+
@field_validator("template_name")
|
|
43
|
+
@classmethod
|
|
42
44
|
def validate_template_name(cls, v: Any) -> Any:
|
|
43
45
|
if v not in ProjectTemplateName:
|
|
44
46
|
raise ValueError(
|
|
@@ -54,10 +56,8 @@ class BotDataUpdateRequest(BaseModel):
|
|
|
54
56
|
flows_yml: Optional[str] = Field(None, alias="flows.yml")
|
|
55
57
|
config_yml: Optional[str] = Field(None, alias="config.yml")
|
|
56
58
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
allow_population_by_field_name = True
|
|
59
|
+
# Allow using either field names or aliases when creating the model
|
|
60
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
class BotData(BaseModel):
|
|
@@ -3,30 +3,27 @@
|
|
|
3
3
|
import json
|
|
4
4
|
import os
|
|
5
5
|
import shutil
|
|
6
|
-
import tarfile
|
|
7
|
-
import tempfile
|
|
8
6
|
from pathlib import Path
|
|
9
7
|
from textwrap import dedent
|
|
10
8
|
from typing import Any, Dict, Generator, List, Optional
|
|
11
9
|
|
|
12
|
-
import aiofiles
|
|
13
|
-
import aiohttp
|
|
14
10
|
import structlog
|
|
15
11
|
|
|
16
|
-
import rasa.version
|
|
17
12
|
from rasa.builder import config
|
|
18
13
|
from rasa.builder.exceptions import ProjectGenerationError, ValidationError
|
|
19
14
|
from rasa.builder.llm_service import get_skill_generation_messages, llm_service
|
|
20
15
|
from rasa.builder.logging_utils import capture_exception_with_context
|
|
21
16
|
from rasa.builder.models import BotFiles
|
|
22
17
|
from rasa.builder.project_info import ProjectInfo, ensure_first_used, load_project_info
|
|
18
|
+
from rasa.builder.template_cache import copy_cache_for_template_if_available
|
|
23
19
|
from rasa.builder.training_service import TrainingInput
|
|
24
20
|
from rasa.builder.validation_service import validate_project
|
|
25
21
|
from rasa.cli.scaffold import ProjectTemplateName, create_initial_project
|
|
22
|
+
from rasa.shared.constants import DEFAULT_MODELS_PATH
|
|
26
23
|
from rasa.shared.core.flows import yaml_flows_io
|
|
27
24
|
from rasa.shared.importers.importer import TrainingDataImporter
|
|
28
25
|
from rasa.shared.utils.yaml import dump_obj_as_yaml_to_string
|
|
29
|
-
from rasa.utils.io import subpath
|
|
26
|
+
from rasa.utils.io import InvalidPathException, subpath
|
|
30
27
|
|
|
31
28
|
structlogger = structlog.get_logger()
|
|
32
29
|
|
|
@@ -48,12 +45,25 @@ class ProjectGenerator:
|
|
|
48
45
|
"""Get the project info."""
|
|
49
46
|
return load_project_info(self.project_folder)
|
|
50
47
|
|
|
48
|
+
def is_empty(self) -> bool:
|
|
49
|
+
"""Check if the project folder is empty.
|
|
50
|
+
|
|
51
|
+
Excluding hidden paths.
|
|
52
|
+
"""
|
|
53
|
+
return not any(
|
|
54
|
+
file.is_file()
|
|
55
|
+
for file in self.project_folder.iterdir()
|
|
56
|
+
if not file.name.startswith(".")
|
|
57
|
+
)
|
|
58
|
+
|
|
51
59
|
async def init_from_template(self, template: ProjectTemplateName) -> None:
|
|
52
60
|
"""Create the initial project files."""
|
|
53
61
|
self.cleanup()
|
|
54
62
|
create_initial_project(self.project_folder.as_posix(), template)
|
|
55
|
-
|
|
56
|
-
#
|
|
63
|
+
# If a local cache for this template exists, copy it into the project.
|
|
64
|
+
# We no longer download here to avoid blocking project creation.
|
|
65
|
+
await copy_cache_for_template_if_available(template, self.project_folder)
|
|
66
|
+
# needs to happen after caching, as we download/copy .rasa and that would
|
|
57
67
|
# overwrite the project info file in .rasa
|
|
58
68
|
ensure_first_used(self.project_folder)
|
|
59
69
|
|
|
@@ -225,25 +235,9 @@ class ProjectGenerator:
|
|
|
225
235
|
"""
|
|
226
236
|
bot_files: BotFiles = {}
|
|
227
237
|
|
|
228
|
-
for file in self.
|
|
229
|
-
# Skip directories
|
|
230
|
-
if not file.is_file():
|
|
231
|
-
continue
|
|
232
|
-
|
|
238
|
+
for file in self.bot_file_paths():
|
|
233
239
|
relative_path = file.relative_to(self.project_folder)
|
|
234
240
|
|
|
235
|
-
# Skip hidden files and directories (any path component starting with '.')
|
|
236
|
-
# as well as `__pycache__` folders
|
|
237
|
-
if any(part.startswith(".") for part in relative_path.parts):
|
|
238
|
-
continue
|
|
239
|
-
|
|
240
|
-
if "__pycache__" in relative_path.parts:
|
|
241
|
-
continue
|
|
242
|
-
|
|
243
|
-
# exclude the project_folder / models folder
|
|
244
|
-
if relative_path.parts[0] == "models":
|
|
245
|
-
continue
|
|
246
|
-
|
|
247
241
|
# Exclude the docs directory if specified
|
|
248
242
|
if exclude_docs_directory and relative_path.parts[0] == "docs":
|
|
249
243
|
continue
|
|
@@ -255,7 +249,6 @@ class ProjectGenerator:
|
|
|
255
249
|
]
|
|
256
250
|
if file.suffix.lstrip(".").lower() not in allowed_file_extensions:
|
|
257
251
|
continue
|
|
258
|
-
|
|
259
252
|
# Read file content and store with relative path as key
|
|
260
253
|
try:
|
|
261
254
|
bot_files[relative_path.as_posix()] = file.read_text(encoding="utf-8")
|
|
@@ -266,9 +259,40 @@ class ProjectGenerator:
|
|
|
266
259
|
file_path=file.as_posix(),
|
|
267
260
|
)
|
|
268
261
|
bot_files[relative_path.as_posix()] = None
|
|
269
|
-
|
|
270
262
|
return bot_files
|
|
271
263
|
|
|
264
|
+
def is_restricted_path(self, path: Path) -> bool:
|
|
265
|
+
"""Check if the path is restricted.
|
|
266
|
+
|
|
267
|
+
These paths are excluded from deletion and editing by the user.
|
|
268
|
+
"""
|
|
269
|
+
relative_path = path.relative_to(self.project_folder)
|
|
270
|
+
|
|
271
|
+
# Skip hidden files and directories (any path component starting with '.')
|
|
272
|
+
# as well as `__pycache__` folders
|
|
273
|
+
if any(part.startswith(".") for part in relative_path.parts):
|
|
274
|
+
return True
|
|
275
|
+
|
|
276
|
+
if "__pycache__" in relative_path.parts:
|
|
277
|
+
return True
|
|
278
|
+
|
|
279
|
+
# exclude the project_folder / models folder
|
|
280
|
+
if relative_path.parts[0] == DEFAULT_MODELS_PATH:
|
|
281
|
+
return True
|
|
282
|
+
|
|
283
|
+
return False
|
|
284
|
+
|
|
285
|
+
def bot_file_paths(
|
|
286
|
+
self,
|
|
287
|
+
) -> Generator[Path, None, None]:
|
|
288
|
+
"""Get the paths of all bot files."""
|
|
289
|
+
for file in self.project_folder.glob("**/*"):
|
|
290
|
+
# Skip directories
|
|
291
|
+
if not file.is_file() or self.is_restricted_path(file):
|
|
292
|
+
continue
|
|
293
|
+
|
|
294
|
+
yield file
|
|
295
|
+
|
|
272
296
|
def _get_bot_data_for_llm(self) -> Dict[str, Any]:
|
|
273
297
|
"""Get the current bot data for the LLM."""
|
|
274
298
|
file_importer = self._create_importer()
|
|
@@ -313,7 +337,7 @@ class ProjectGenerator:
|
|
|
313
337
|
def update_bot_files(self, files: Dict[str, Optional[str]]) -> None:
|
|
314
338
|
"""Update bot files with new content by writing to disk."""
|
|
315
339
|
for filename, content in files.items():
|
|
316
|
-
file_path = Path(subpath(self.project_folder, filename))
|
|
340
|
+
file_path = Path(subpath(str(self.project_folder), filename))
|
|
317
341
|
# Disallow updates inside .rasa project metadata directory
|
|
318
342
|
if any(
|
|
319
343
|
part.startswith(".")
|
|
@@ -324,6 +348,95 @@ class ProjectGenerator:
|
|
|
324
348
|
file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
325
349
|
file_path.write_text(content, encoding="utf-8")
|
|
326
350
|
|
|
351
|
+
def ensure_all_files_are_writable(self, files: Dict[str, Optional[str]]) -> None:
|
|
352
|
+
"""Ensure all files are writable."""
|
|
353
|
+
for filename, content in files.items():
|
|
354
|
+
file_path = Path(subpath(str(self.project_folder), filename))
|
|
355
|
+
if self.is_restricted_path(file_path):
|
|
356
|
+
raise InvalidPathException(
|
|
357
|
+
f"This file or folder is restricted from editing: {file_path}"
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
def replace_all_bot_files(self, files: Dict[str, Optional[str]]) -> None:
|
|
361
|
+
"""Replace all bot files with new content, deleting files not in the request.
|
|
362
|
+
|
|
363
|
+
Files/folders starting with .rasa/ or models/ are excluded from deletion.
|
|
364
|
+
|
|
365
|
+
Args:
|
|
366
|
+
files: Dictionary mapping file names to their content
|
|
367
|
+
"""
|
|
368
|
+
self.ensure_all_files_are_writable(files)
|
|
369
|
+
# Collect all existing files - any files not in the new `files` dict will be
|
|
370
|
+
# deleted from this set
|
|
371
|
+
existing_files = set(path.as_posix() for path in self.bot_file_paths())
|
|
372
|
+
|
|
373
|
+
# Write all new files
|
|
374
|
+
for filename, content in files.items():
|
|
375
|
+
if content is None:
|
|
376
|
+
continue
|
|
377
|
+
|
|
378
|
+
file_path = Path(subpath(str(self.project_folder), filename))
|
|
379
|
+
file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
380
|
+
|
|
381
|
+
try:
|
|
382
|
+
file_path.write_text(content, encoding="utf-8")
|
|
383
|
+
except Exception as e:
|
|
384
|
+
# Log write failure and avoid deleting an existing file by mistake
|
|
385
|
+
capture_exception_with_context(
|
|
386
|
+
e,
|
|
387
|
+
"project_generator.replace_all_bot_files.write_error",
|
|
388
|
+
extra={"file_path": file_path},
|
|
389
|
+
)
|
|
390
|
+
if file_path.as_posix() in existing_files:
|
|
391
|
+
# Keep the original file if it already existed
|
|
392
|
+
existing_files.discard(file_path.as_posix())
|
|
393
|
+
continue
|
|
394
|
+
|
|
395
|
+
# Remove from deletion set since this file is in the new set of files
|
|
396
|
+
existing_files.discard(file_path.as_posix())
|
|
397
|
+
|
|
398
|
+
# Delete files that weren't in the request
|
|
399
|
+
for file_to_delete in existing_files:
|
|
400
|
+
file_path = Path(file_to_delete)
|
|
401
|
+
try:
|
|
402
|
+
file_path.unlink()
|
|
403
|
+
except Exception as e:
|
|
404
|
+
capture_exception_with_context(
|
|
405
|
+
e,
|
|
406
|
+
"project_generator.replace_all_bot_files.delete_error",
|
|
407
|
+
extra={"file_path": file_path},
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
# Clean up empty directories (except excluded ones)
|
|
411
|
+
self._cleanup_empty_directories()
|
|
412
|
+
|
|
413
|
+
def _cleanup_empty_directories(self) -> None:
|
|
414
|
+
"""Remove empty directories from the project folder.
|
|
415
|
+
|
|
416
|
+
Excludes hidden files and directories, and models/ from cleanup.
|
|
417
|
+
"""
|
|
418
|
+
# Walk directories in reverse order (deepest first)
|
|
419
|
+
for dirpath, dirnames, filenames in os.walk(self.project_folder, topdown=False):
|
|
420
|
+
# Skip if this is the project root
|
|
421
|
+
if dirpath == str(self.project_folder):
|
|
422
|
+
continue
|
|
423
|
+
|
|
424
|
+
if self.is_restricted_path(Path(dirpath)):
|
|
425
|
+
continue
|
|
426
|
+
|
|
427
|
+
relative_path = Path(dirpath).relative_to(self.project_folder)
|
|
428
|
+
|
|
429
|
+
try:
|
|
430
|
+
# Only remove if directory is empty
|
|
431
|
+
if not os.listdir(dirpath):
|
|
432
|
+
os.rmdir(dirpath)
|
|
433
|
+
except Exception as e:
|
|
434
|
+
capture_exception_with_context(
|
|
435
|
+
e,
|
|
436
|
+
"project_generator.cleanup_empty_directories.error",
|
|
437
|
+
extra={"directory": relative_path.as_posix()},
|
|
438
|
+
)
|
|
439
|
+
|
|
327
440
|
def cleanup(self) -> None:
|
|
328
441
|
"""Cleanup the project folder."""
|
|
329
442
|
# remove all the files and folders in the project folder resulting
|
|
@@ -331,6 +444,8 @@ class ProjectGenerator:
|
|
|
331
444
|
for filename in os.listdir(self.project_folder):
|
|
332
445
|
file_path = os.path.join(self.project_folder, filename)
|
|
333
446
|
try:
|
|
447
|
+
if filename == "lost+found":
|
|
448
|
+
continue
|
|
334
449
|
if os.path.isfile(file_path) or os.path.islink(file_path):
|
|
335
450
|
os.unlink(file_path)
|
|
336
451
|
elif os.path.isdir(file_path):
|
|
@@ -341,122 +456,3 @@ class ProjectGenerator:
|
|
|
341
456
|
error=str(e),
|
|
342
457
|
file_path=file_path,
|
|
343
458
|
)
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
CACHE_BUCKET_URL = "https://trained-templates.s3.us-east-1.amazonaws.com"
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
def _safe_tar_members(
|
|
350
|
-
tar: tarfile.TarFile, destination_directory: Path
|
|
351
|
-
) -> Generator[tarfile.TarInfo, None, None]:
|
|
352
|
-
"""Yield safe members for extraction to prevent path traversal and links.
|
|
353
|
-
|
|
354
|
-
Args:
|
|
355
|
-
tar: Open tar file handle
|
|
356
|
-
destination_directory: Directory to which files will be extracted
|
|
357
|
-
|
|
358
|
-
Yields:
|
|
359
|
-
Members that are safe to extract within destination_directory
|
|
360
|
-
"""
|
|
361
|
-
base_path = destination_directory.resolve()
|
|
362
|
-
|
|
363
|
-
for member in tar.getmembers():
|
|
364
|
-
name = member.name
|
|
365
|
-
# Skip empty names and absolute paths
|
|
366
|
-
if not name or name.startswith("/") or name.startswith("\\"):
|
|
367
|
-
continue
|
|
368
|
-
|
|
369
|
-
# Disallow symlinks and hardlinks
|
|
370
|
-
if member.issym() or member.islnk():
|
|
371
|
-
continue
|
|
372
|
-
|
|
373
|
-
# Compute the final path and ensure it's within base_path
|
|
374
|
-
target_path = (base_path / name).resolve()
|
|
375
|
-
try:
|
|
376
|
-
target_path.relative_to(base_path)
|
|
377
|
-
except ValueError:
|
|
378
|
-
# Member would escape the destination directory
|
|
379
|
-
continue
|
|
380
|
-
|
|
381
|
-
yield member
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
async def download_cache_for_template(
|
|
385
|
-
template: ProjectTemplateName, project_folder: str
|
|
386
|
-
) -> None:
|
|
387
|
-
# get a temp path for the cache file download
|
|
388
|
-
temporary_cache_file = tempfile.NamedTemporaryFile(suffix=".tar.gz", delete=False)
|
|
389
|
-
|
|
390
|
-
try:
|
|
391
|
-
url = f"{CACHE_BUCKET_URL}/{rasa.version.__version__}-{template.value}.tar.gz"
|
|
392
|
-
async with aiohttp.ClientSession() as session:
|
|
393
|
-
async with session.get(url) as response:
|
|
394
|
-
response.raise_for_status()
|
|
395
|
-
async with aiofiles.open(temporary_cache_file.name, "wb") as f:
|
|
396
|
-
async for chunk in response.content.iter_chunked(1024 * 1024):
|
|
397
|
-
await f.write(chunk)
|
|
398
|
-
|
|
399
|
-
# extract the cache to the project folder using safe member filtering
|
|
400
|
-
with tarfile.open(temporary_cache_file.name, "r:gz") as tar:
|
|
401
|
-
destination = Path(project_folder)
|
|
402
|
-
destination.mkdir(parents=True, exist_ok=True)
|
|
403
|
-
tar.extractall(
|
|
404
|
-
path=destination,
|
|
405
|
-
members=_safe_tar_members(tar, destination),
|
|
406
|
-
)
|
|
407
|
-
|
|
408
|
-
structlogger.info(
|
|
409
|
-
"project_generator.download_cache_for_template.success",
|
|
410
|
-
template=template,
|
|
411
|
-
event_info=(
|
|
412
|
-
f"Downloaded cache for template, extracted to {project_folder}."
|
|
413
|
-
),
|
|
414
|
-
)
|
|
415
|
-
except aiohttp.ClientResponseError as e:
|
|
416
|
-
if e.status == 403:
|
|
417
|
-
structlogger.debug(
|
|
418
|
-
"project_generator.download_cache_for_template.no_cache_found",
|
|
419
|
-
template=template,
|
|
420
|
-
event_info=("No cache found for template, continuing without it."),
|
|
421
|
-
)
|
|
422
|
-
else:
|
|
423
|
-
structlogger.debug(
|
|
424
|
-
"project_generator.download_cache_for_template.response_error",
|
|
425
|
-
error=str(e),
|
|
426
|
-
status=e.status,
|
|
427
|
-
template=template,
|
|
428
|
-
event_info=(
|
|
429
|
-
"Failed to download cache for template, continuing without it."
|
|
430
|
-
),
|
|
431
|
-
)
|
|
432
|
-
capture_exception_with_context(
|
|
433
|
-
e,
|
|
434
|
-
"project_generator.download_cache_for_template.response_error",
|
|
435
|
-
tags={"template": template.value, "status": str(e.status)},
|
|
436
|
-
)
|
|
437
|
-
except Exception as exc:
|
|
438
|
-
structlogger.debug(
|
|
439
|
-
"project_generator.download_cache_for_template.unexpected_error",
|
|
440
|
-
error=str(exc),
|
|
441
|
-
template=template,
|
|
442
|
-
event_info=(
|
|
443
|
-
"Unexpected error when downloading cache for template, "
|
|
444
|
-
"continuing without it."
|
|
445
|
-
),
|
|
446
|
-
)
|
|
447
|
-
capture_exception_with_context(
|
|
448
|
-
exc,
|
|
449
|
-
"project_generator.download_cache_for_template.unexpected_error",
|
|
450
|
-
tags={"template": template.value},
|
|
451
|
-
)
|
|
452
|
-
finally:
|
|
453
|
-
# Clean up the temporary file
|
|
454
|
-
try:
|
|
455
|
-
Path(temporary_cache_file.name).unlink(missing_ok=True)
|
|
456
|
-
except Exception as exc:
|
|
457
|
-
structlogger.debug(
|
|
458
|
-
"project_generator.download_cache_for_template.cleanup_error",
|
|
459
|
-
error=str(exc),
|
|
460
|
-
template=template,
|
|
461
|
-
event_info=("Failed to cleanup cache for template, ignoring."),
|
|
462
|
-
)
|