rasa-pro 3.12.0.dev1__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.
- README.md +41 -0
- rasa/__init__.py +9 -0
- rasa/__main__.py +177 -0
- rasa/anonymization/__init__.py +2 -0
- rasa/anonymization/anonymisation_rule_yaml_reader.py +91 -0
- rasa/anonymization/anonymization_pipeline.py +286 -0
- rasa/anonymization/anonymization_rule_executor.py +260 -0
- rasa/anonymization/anonymization_rule_orchestrator.py +120 -0
- rasa/anonymization/schemas/config.yml +47 -0
- rasa/anonymization/utils.py +118 -0
- rasa/api.py +160 -0
- rasa/cli/__init__.py +5 -0
- rasa/cli/arguments/__init__.py +0 -0
- rasa/cli/arguments/data.py +106 -0
- rasa/cli/arguments/default_arguments.py +207 -0
- rasa/cli/arguments/evaluate.py +65 -0
- rasa/cli/arguments/export.py +51 -0
- rasa/cli/arguments/interactive.py +74 -0
- rasa/cli/arguments/run.py +219 -0
- rasa/cli/arguments/shell.py +17 -0
- rasa/cli/arguments/test.py +211 -0
- rasa/cli/arguments/train.py +279 -0
- rasa/cli/arguments/visualize.py +34 -0
- rasa/cli/arguments/x.py +30 -0
- rasa/cli/data.py +354 -0
- rasa/cli/dialogue_understanding_test.py +251 -0
- rasa/cli/e2e_test.py +259 -0
- rasa/cli/evaluate.py +222 -0
- rasa/cli/export.py +250 -0
- rasa/cli/inspect.py +75 -0
- rasa/cli/interactive.py +166 -0
- rasa/cli/license.py +65 -0
- rasa/cli/llm_fine_tuning.py +403 -0
- rasa/cli/markers.py +78 -0
- rasa/cli/project_templates/__init__.py +0 -0
- rasa/cli/project_templates/calm/actions/__init__.py +0 -0
- rasa/cli/project_templates/calm/actions/action_template.py +27 -0
- rasa/cli/project_templates/calm/actions/add_contact.py +30 -0
- rasa/cli/project_templates/calm/actions/db.py +57 -0
- rasa/cli/project_templates/calm/actions/list_contacts.py +22 -0
- rasa/cli/project_templates/calm/actions/remove_contact.py +35 -0
- rasa/cli/project_templates/calm/config.yml +10 -0
- rasa/cli/project_templates/calm/credentials.yml +33 -0
- rasa/cli/project_templates/calm/data/flows/add_contact.yml +31 -0
- rasa/cli/project_templates/calm/data/flows/list_contacts.yml +14 -0
- rasa/cli/project_templates/calm/data/flows/remove_contact.yml +29 -0
- rasa/cli/project_templates/calm/db/contacts.json +10 -0
- rasa/cli/project_templates/calm/domain/add_contact.yml +39 -0
- rasa/cli/project_templates/calm/domain/list_contacts.yml +17 -0
- rasa/cli/project_templates/calm/domain/remove_contact.yml +38 -0
- rasa/cli/project_templates/calm/domain/shared.yml +10 -0
- rasa/cli/project_templates/calm/e2e_tests/cancelations/user_cancels_during_a_correction.yml +16 -0
- rasa/cli/project_templates/calm/e2e_tests/cancelations/user_changes_mind_on_a_whim.yml +7 -0
- rasa/cli/project_templates/calm/e2e_tests/corrections/user_corrects_contact_handle.yml +20 -0
- rasa/cli/project_templates/calm/e2e_tests/corrections/user_corrects_contact_name.yml +19 -0
- rasa/cli/project_templates/calm/e2e_tests/happy_paths/user_adds_contact_to_their_list.yml +15 -0
- rasa/cli/project_templates/calm/e2e_tests/happy_paths/user_lists_contacts.yml +5 -0
- rasa/cli/project_templates/calm/e2e_tests/happy_paths/user_removes_contact.yml +11 -0
- rasa/cli/project_templates/calm/e2e_tests/happy_paths/user_removes_contact_from_list.yml +12 -0
- rasa/cli/project_templates/calm/endpoints.yml +58 -0
- rasa/cli/project_templates/default/actions/__init__.py +0 -0
- rasa/cli/project_templates/default/actions/actions.py +27 -0
- rasa/cli/project_templates/default/config.yml +44 -0
- rasa/cli/project_templates/default/credentials.yml +33 -0
- rasa/cli/project_templates/default/data/nlu.yml +91 -0
- rasa/cli/project_templates/default/data/rules.yml +13 -0
- rasa/cli/project_templates/default/data/stories.yml +30 -0
- rasa/cli/project_templates/default/domain.yml +34 -0
- rasa/cli/project_templates/default/endpoints.yml +42 -0
- rasa/cli/project_templates/default/tests/test_stories.yml +91 -0
- rasa/cli/project_templates/tutorial/actions/__init__.py +0 -0
- rasa/cli/project_templates/tutorial/actions/actions.py +22 -0
- rasa/cli/project_templates/tutorial/config.yml +12 -0
- rasa/cli/project_templates/tutorial/credentials.yml +33 -0
- rasa/cli/project_templates/tutorial/data/flows.yml +8 -0
- rasa/cli/project_templates/tutorial/data/patterns.yml +11 -0
- rasa/cli/project_templates/tutorial/domain.yml +35 -0
- rasa/cli/project_templates/tutorial/endpoints.yml +55 -0
- rasa/cli/run.py +143 -0
- rasa/cli/scaffold.py +273 -0
- rasa/cli/shell.py +141 -0
- rasa/cli/studio/__init__.py +0 -0
- rasa/cli/studio/download.py +62 -0
- rasa/cli/studio/studio.py +296 -0
- rasa/cli/studio/train.py +59 -0
- rasa/cli/studio/upload.py +62 -0
- rasa/cli/telemetry.py +102 -0
- rasa/cli/test.py +280 -0
- rasa/cli/train.py +278 -0
- rasa/cli/utils.py +484 -0
- rasa/cli/visualize.py +40 -0
- rasa/cli/x.py +206 -0
- rasa/constants.py +45 -0
- rasa/core/__init__.py +17 -0
- rasa/core/actions/__init__.py +0 -0
- rasa/core/actions/action.py +1318 -0
- rasa/core/actions/action_clean_stack.py +59 -0
- rasa/core/actions/action_exceptions.py +24 -0
- rasa/core/actions/action_hangup.py +29 -0
- rasa/core/actions/action_repeat_bot_messages.py +89 -0
- rasa/core/actions/action_run_slot_rejections.py +210 -0
- rasa/core/actions/action_trigger_chitchat.py +31 -0
- rasa/core/actions/action_trigger_flow.py +109 -0
- rasa/core/actions/action_trigger_search.py +31 -0
- rasa/core/actions/constants.py +5 -0
- rasa/core/actions/custom_action_executor.py +191 -0
- rasa/core/actions/direct_custom_actions_executor.py +109 -0
- rasa/core/actions/e2e_stub_custom_action_executor.py +72 -0
- rasa/core/actions/forms.py +741 -0
- rasa/core/actions/grpc_custom_action_executor.py +251 -0
- rasa/core/actions/http_custom_action_executor.py +145 -0
- rasa/core/actions/loops.py +114 -0
- rasa/core/actions/two_stage_fallback.py +186 -0
- rasa/core/agent.py +559 -0
- rasa/core/auth_retry_tracker_store.py +122 -0
- rasa/core/brokers/__init__.py +0 -0
- rasa/core/brokers/broker.py +126 -0
- rasa/core/brokers/file.py +58 -0
- rasa/core/brokers/kafka.py +324 -0
- rasa/core/brokers/pika.py +388 -0
- rasa/core/brokers/sql.py +86 -0
- rasa/core/channels/__init__.py +61 -0
- rasa/core/channels/botframework.py +338 -0
- rasa/core/channels/callback.py +84 -0
- rasa/core/channels/channel.py +456 -0
- rasa/core/channels/console.py +241 -0
- rasa/core/channels/development_inspector.py +197 -0
- rasa/core/channels/facebook.py +419 -0
- rasa/core/channels/hangouts.py +329 -0
- rasa/core/channels/inspector/.eslintrc.cjs +25 -0
- rasa/core/channels/inspector/.gitignore +23 -0
- rasa/core/channels/inspector/README.md +54 -0
- rasa/core/channels/inspector/assets/favicon.ico +0 -0
- rasa/core/channels/inspector/assets/rasa-chat.js +2 -0
- rasa/core/channels/inspector/custom.d.ts +3 -0
- rasa/core/channels/inspector/dist/assets/arc-861ddd57.js +1 -0
- rasa/core/channels/inspector/dist/assets/array-9f3ba611.js +1 -0
- rasa/core/channels/inspector/dist/assets/c4Diagram-d0fbc5ce-921f02db.js +10 -0
- rasa/core/channels/inspector/dist/assets/classDiagram-936ed81e-b436c4f8.js +2 -0
- rasa/core/channels/inspector/dist/assets/classDiagram-v2-c3cb15f1-511a23cb.js +2 -0
- rasa/core/channels/inspector/dist/assets/createText-62fc7601-ef476ecd.js +7 -0
- rasa/core/channels/inspector/dist/assets/edges-f2ad444c-f1878e0a.js +4 -0
- rasa/core/channels/inspector/dist/assets/erDiagram-9d236eb7-fac75185.js +51 -0
- rasa/core/channels/inspector/dist/assets/flowDb-1972c806-201c5bbc.js +6 -0
- rasa/core/channels/inspector/dist/assets/flowDiagram-7ea5b25a-f904ae41.js +4 -0
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-b080d6f2.js +1 -0
- rasa/core/channels/inspector/dist/assets/flowchart-elk-definition-abe16c3d-1813da66.js +139 -0
- rasa/core/channels/inspector/dist/assets/ganttDiagram-9b5ea136-872af172.js +266 -0
- rasa/core/channels/inspector/dist/assets/gitGraphDiagram-99d0ae7c-34a0af5a.js +70 -0
- rasa/core/channels/inspector/dist/assets/ibm-plex-mono-v4-latin-regular-128cfa44.ttf +0 -0
- rasa/core/channels/inspector/dist/assets/ibm-plex-mono-v4-latin-regular-21dbcb97.woff +0 -0
- rasa/core/channels/inspector/dist/assets/ibm-plex-mono-v4-latin-regular-222b5e26.svg +329 -0
- rasa/core/channels/inspector/dist/assets/ibm-plex-mono-v4-latin-regular-9ad89b2a.woff2 +0 -0
- rasa/core/channels/inspector/dist/assets/index-2c4b9a3b-42ba3e3d.js +1 -0
- rasa/core/channels/inspector/dist/assets/index-37817b51.js +1317 -0
- rasa/core/channels/inspector/dist/assets/index-3ee28881.css +1 -0
- rasa/core/channels/inspector/dist/assets/infoDiagram-736b4530-6b731386.js +7 -0
- rasa/core/channels/inspector/dist/assets/init-77b53fdd.js +1 -0
- rasa/core/channels/inspector/dist/assets/journeyDiagram-df861f2b-e8579ac6.js +139 -0
- rasa/core/channels/inspector/dist/assets/lato-v14-latin-700-60c05ee4.woff +0 -0
- rasa/core/channels/inspector/dist/assets/lato-v14-latin-700-8335d9b8.svg +438 -0
- rasa/core/channels/inspector/dist/assets/lato-v14-latin-700-9cc39c75.ttf +0 -0
- rasa/core/channels/inspector/dist/assets/lato-v14-latin-700-ead13ccf.woff2 +0 -0
- rasa/core/channels/inspector/dist/assets/lato-v14-latin-regular-16705655.woff2 +0 -0
- rasa/core/channels/inspector/dist/assets/lato-v14-latin-regular-5aeb07f9.woff +0 -0
- rasa/core/channels/inspector/dist/assets/lato-v14-latin-regular-9c459044.ttf +0 -0
- rasa/core/channels/inspector/dist/assets/lato-v14-latin-regular-9e2898a4.svg +435 -0
- rasa/core/channels/inspector/dist/assets/layout-89e6403a.js +1 -0
- rasa/core/channels/inspector/dist/assets/line-dc73d3fc.js +1 -0
- rasa/core/channels/inspector/dist/assets/linear-f5b1d2bc.js +1 -0
- rasa/core/channels/inspector/dist/assets/mindmap-definition-beec6740-82cb74fa.js +109 -0
- rasa/core/channels/inspector/dist/assets/ordinal-ba9b4969.js +1 -0
- rasa/core/channels/inspector/dist/assets/path-53f90ab3.js +1 -0
- rasa/core/channels/inspector/dist/assets/pieDiagram-dbbf0591-bdf5f29b.js +35 -0
- rasa/core/channels/inspector/dist/assets/quadrantDiagram-4d7f4fd6-c7a0cbe4.js +7 -0
- rasa/core/channels/inspector/dist/assets/requirementDiagram-6fc4c22a-7ec5410f.js +52 -0
- rasa/core/channels/inspector/dist/assets/sankeyDiagram-8f13d901-caee5554.js +8 -0
- rasa/core/channels/inspector/dist/assets/sequenceDiagram-b655622a-2935f8db.js +122 -0
- rasa/core/channels/inspector/dist/assets/stateDiagram-59f0c015-8f5d9693.js +1 -0
- rasa/core/channels/inspector/dist/assets/stateDiagram-v2-2b26beab-d565d1de.js +1 -0
- rasa/core/channels/inspector/dist/assets/styles-080da4f6-75ad421d.js +110 -0
- rasa/core/channels/inspector/dist/assets/styles-3dcbcfbf-7e764226.js +159 -0
- rasa/core/channels/inspector/dist/assets/styles-9c745c82-7a4e0e61.js +207 -0
- rasa/core/channels/inspector/dist/assets/svgDrawCommon-4835440b-4019d1bf.js +1 -0
- rasa/core/channels/inspector/dist/assets/timeline-definition-5b62e21b-01ea12df.js +61 -0
- rasa/core/channels/inspector/dist/assets/xychartDiagram-2b33534f-89407137.js +7 -0
- rasa/core/channels/inspector/dist/index.html +42 -0
- rasa/core/channels/inspector/index.html +40 -0
- rasa/core/channels/inspector/jest.config.ts +13 -0
- rasa/core/channels/inspector/package.json +52 -0
- rasa/core/channels/inspector/setupTests.ts +2 -0
- rasa/core/channels/inspector/src/App.tsx +220 -0
- rasa/core/channels/inspector/src/components/Chat.tsx +95 -0
- rasa/core/channels/inspector/src/components/DiagramFlow.tsx +108 -0
- rasa/core/channels/inspector/src/components/DialogueInformation.tsx +187 -0
- rasa/core/channels/inspector/src/components/DialogueStack.tsx +136 -0
- rasa/core/channels/inspector/src/components/ExpandIcon.tsx +16 -0
- rasa/core/channels/inspector/src/components/FullscreenButton.tsx +45 -0
- rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +22 -0
- rasa/core/channels/inspector/src/components/NoActiveFlow.tsx +21 -0
- rasa/core/channels/inspector/src/components/RasaLogo.tsx +32 -0
- rasa/core/channels/inspector/src/components/SaraDiagrams.tsx +39 -0
- rasa/core/channels/inspector/src/components/Slots.tsx +91 -0
- rasa/core/channels/inspector/src/components/Welcome.tsx +54 -0
- rasa/core/channels/inspector/src/helpers/audiostream.ts +191 -0
- rasa/core/channels/inspector/src/helpers/formatters.test.ts +392 -0
- rasa/core/channels/inspector/src/helpers/formatters.ts +306 -0
- rasa/core/channels/inspector/src/helpers/utils.ts +127 -0
- rasa/core/channels/inspector/src/main.tsx +13 -0
- rasa/core/channels/inspector/src/theme/Button/Button.ts +29 -0
- rasa/core/channels/inspector/src/theme/Heading/Heading.ts +31 -0
- rasa/core/channels/inspector/src/theme/Input/Input.ts +27 -0
- rasa/core/channels/inspector/src/theme/Link/Link.ts +10 -0
- rasa/core/channels/inspector/src/theme/Modal/Modal.ts +47 -0
- rasa/core/channels/inspector/src/theme/Table/Table.tsx +38 -0
- rasa/core/channels/inspector/src/theme/Tooltip/Tooltip.ts +12 -0
- rasa/core/channels/inspector/src/theme/base/breakpoints.ts +8 -0
- rasa/core/channels/inspector/src/theme/base/colors.ts +88 -0
- rasa/core/channels/inspector/src/theme/base/fonts/fontFaces.css +29 -0
- rasa/core/channels/inspector/src/theme/base/fonts/ibm-plex-mono-v4-latin/ibm-plex-mono-v4-latin-regular.eot +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/ibm-plex-mono-v4-latin/ibm-plex-mono-v4-latin-regular.svg +329 -0
- rasa/core/channels/inspector/src/theme/base/fonts/ibm-plex-mono-v4-latin/ibm-plex-mono-v4-latin-regular.ttf +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/ibm-plex-mono-v4-latin/ibm-plex-mono-v4-latin-regular.woff +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/ibm-plex-mono-v4-latin/ibm-plex-mono-v4-latin-regular.woff2 +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-700.eot +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-700.svg +438 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-700.ttf +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-700.woff +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-700.woff2 +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-regular.eot +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-regular.svg +435 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-regular.ttf +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-regular.woff +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-regular.woff2 +0 -0
- rasa/core/channels/inspector/src/theme/base/radii.ts +9 -0
- rasa/core/channels/inspector/src/theme/base/shadows.ts +7 -0
- rasa/core/channels/inspector/src/theme/base/sizes.ts +7 -0
- rasa/core/channels/inspector/src/theme/base/space.ts +15 -0
- rasa/core/channels/inspector/src/theme/base/styles.ts +13 -0
- rasa/core/channels/inspector/src/theme/base/typography.ts +24 -0
- rasa/core/channels/inspector/src/theme/base/zIndices.ts +19 -0
- rasa/core/channels/inspector/src/theme/index.ts +101 -0
- rasa/core/channels/inspector/src/types.ts +84 -0
- rasa/core/channels/inspector/src/vite-env.d.ts +1 -0
- rasa/core/channels/inspector/tests/__mocks__/fileMock.ts +1 -0
- rasa/core/channels/inspector/tests/__mocks__/matchMedia.ts +16 -0
- rasa/core/channels/inspector/tests/__mocks__/styleMock.ts +1 -0
- rasa/core/channels/inspector/tests/renderWithProviders.tsx +14 -0
- rasa/core/channels/inspector/tsconfig.json +26 -0
- rasa/core/channels/inspector/tsconfig.node.json +10 -0
- rasa/core/channels/inspector/vite.config.ts +8 -0
- rasa/core/channels/inspector/yarn.lock +6249 -0
- rasa/core/channels/mattermost.py +229 -0
- rasa/core/channels/rasa_chat.py +126 -0
- rasa/core/channels/rest.py +230 -0
- rasa/core/channels/rocketchat.py +174 -0
- rasa/core/channels/slack.py +620 -0
- rasa/core/channels/socketio.py +302 -0
- rasa/core/channels/telegram.py +298 -0
- rasa/core/channels/twilio.py +169 -0
- rasa/core/channels/vier_cvg.py +374 -0
- rasa/core/channels/voice_ready/__init__.py +0 -0
- rasa/core/channels/voice_ready/audiocodes.py +501 -0
- rasa/core/channels/voice_ready/jambonz.py +121 -0
- rasa/core/channels/voice_ready/jambonz_protocol.py +396 -0
- rasa/core/channels/voice_ready/twilio_voice.py +403 -0
- rasa/core/channels/voice_ready/utils.py +37 -0
- rasa/core/channels/voice_stream/__init__.py +0 -0
- rasa/core/channels/voice_stream/asr/__init__.py +0 -0
- rasa/core/channels/voice_stream/asr/asr_engine.py +89 -0
- rasa/core/channels/voice_stream/asr/asr_event.py +18 -0
- rasa/core/channels/voice_stream/asr/azure.py +130 -0
- rasa/core/channels/voice_stream/asr/deepgram.py +90 -0
- rasa/core/channels/voice_stream/audio_bytes.py +8 -0
- rasa/core/channels/voice_stream/browser_audio.py +107 -0
- rasa/core/channels/voice_stream/call_state.py +23 -0
- rasa/core/channels/voice_stream/tts/__init__.py +0 -0
- rasa/core/channels/voice_stream/tts/azure.py +106 -0
- rasa/core/channels/voice_stream/tts/cartesia.py +118 -0
- rasa/core/channels/voice_stream/tts/tts_cache.py +27 -0
- rasa/core/channels/voice_stream/tts/tts_engine.py +58 -0
- rasa/core/channels/voice_stream/twilio_media_streams.py +173 -0
- rasa/core/channels/voice_stream/util.py +57 -0
- rasa/core/channels/voice_stream/voice_channel.py +427 -0
- rasa/core/channels/webexteams.py +134 -0
- rasa/core/concurrent_lock_store.py +210 -0
- rasa/core/constants.py +112 -0
- rasa/core/evaluation/__init__.py +0 -0
- rasa/core/evaluation/marker.py +267 -0
- rasa/core/evaluation/marker_base.py +923 -0
- rasa/core/evaluation/marker_stats.py +293 -0
- rasa/core/evaluation/marker_tracker_loader.py +103 -0
- rasa/core/exceptions.py +29 -0
- rasa/core/exporter.py +284 -0
- rasa/core/featurizers/__init__.py +0 -0
- rasa/core/featurizers/precomputation.py +410 -0
- rasa/core/featurizers/single_state_featurizer.py +421 -0
- rasa/core/featurizers/tracker_featurizers.py +1262 -0
- rasa/core/http_interpreter.py +89 -0
- rasa/core/information_retrieval/__init__.py +7 -0
- rasa/core/information_retrieval/faiss.py +124 -0
- rasa/core/information_retrieval/information_retrieval.py +137 -0
- rasa/core/information_retrieval/milvus.py +59 -0
- rasa/core/information_retrieval/qdrant.py +96 -0
- rasa/core/jobs.py +63 -0
- rasa/core/lock.py +139 -0
- rasa/core/lock_store.py +343 -0
- rasa/core/migrate.py +403 -0
- rasa/core/nlg/__init__.py +3 -0
- rasa/core/nlg/callback.py +146 -0
- rasa/core/nlg/contextual_response_rephraser.py +320 -0
- rasa/core/nlg/generator.py +230 -0
- rasa/core/nlg/interpolator.py +143 -0
- rasa/core/nlg/response.py +155 -0
- rasa/core/nlg/summarize.py +70 -0
- rasa/core/persistor.py +538 -0
- rasa/core/policies/__init__.py +0 -0
- rasa/core/policies/ensemble.py +329 -0
- rasa/core/policies/enterprise_search_policy.py +905 -0
- rasa/core/policies/enterprise_search_prompt_template.jinja2 +25 -0
- rasa/core/policies/enterprise_search_prompt_with_citation_template.jinja2 +60 -0
- rasa/core/policies/flow_policy.py +205 -0
- rasa/core/policies/flows/__init__.py +0 -0
- rasa/core/policies/flows/flow_exceptions.py +44 -0
- rasa/core/policies/flows/flow_executor.py +754 -0
- rasa/core/policies/flows/flow_step_result.py +43 -0
- rasa/core/policies/intentless_policy.py +1031 -0
- rasa/core/policies/intentless_prompt_template.jinja2 +22 -0
- rasa/core/policies/memoization.py +538 -0
- rasa/core/policies/policy.py +725 -0
- rasa/core/policies/rule_policy.py +1273 -0
- rasa/core/policies/ted_policy.py +2169 -0
- rasa/core/policies/unexpected_intent_policy.py +1022 -0
- rasa/core/processor.py +1465 -0
- rasa/core/run.py +342 -0
- rasa/core/secrets_manager/__init__.py +0 -0
- rasa/core/secrets_manager/constants.py +36 -0
- rasa/core/secrets_manager/endpoints.py +391 -0
- rasa/core/secrets_manager/factory.py +241 -0
- rasa/core/secrets_manager/secret_manager.py +262 -0
- rasa/core/secrets_manager/vault.py +584 -0
- rasa/core/test.py +1335 -0
- rasa/core/tracker_store.py +1703 -0
- rasa/core/train.py +105 -0
- rasa/core/training/__init__.py +89 -0
- rasa/core/training/converters/__init__.py +0 -0
- rasa/core/training/converters/responses_prefix_converter.py +119 -0
- rasa/core/training/interactive.py +1744 -0
- rasa/core/training/story_conflict.py +381 -0
- rasa/core/training/training.py +93 -0
- rasa/core/utils.py +366 -0
- rasa/core/visualize.py +70 -0
- rasa/dialogue_understanding/__init__.py +0 -0
- rasa/dialogue_understanding/coexistence/__init__.py +0 -0
- rasa/dialogue_understanding/coexistence/constants.py +4 -0
- rasa/dialogue_understanding/coexistence/intent_based_router.py +196 -0
- rasa/dialogue_understanding/coexistence/llm_based_router.py +327 -0
- rasa/dialogue_understanding/coexistence/router_template.jinja2 +12 -0
- rasa/dialogue_understanding/commands/__init__.py +61 -0
- rasa/dialogue_understanding/commands/can_not_handle_command.py +70 -0
- rasa/dialogue_understanding/commands/cancel_flow_command.py +125 -0
- rasa/dialogue_understanding/commands/change_flow_command.py +44 -0
- rasa/dialogue_understanding/commands/chit_chat_answer_command.py +57 -0
- rasa/dialogue_understanding/commands/clarify_command.py +86 -0
- rasa/dialogue_understanding/commands/command.py +85 -0
- rasa/dialogue_understanding/commands/correct_slots_command.py +297 -0
- rasa/dialogue_understanding/commands/error_command.py +79 -0
- rasa/dialogue_understanding/commands/free_form_answer_command.py +9 -0
- rasa/dialogue_understanding/commands/handle_code_change_command.py +73 -0
- rasa/dialogue_understanding/commands/human_handoff_command.py +66 -0
- rasa/dialogue_understanding/commands/knowledge_answer_command.py +57 -0
- rasa/dialogue_understanding/commands/noop_command.py +54 -0
- rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +60 -0
- rasa/dialogue_understanding/commands/restart_command.py +58 -0
- rasa/dialogue_understanding/commands/session_end_command.py +61 -0
- rasa/dialogue_understanding/commands/session_start_command.py +59 -0
- rasa/dialogue_understanding/commands/set_slot_command.py +160 -0
- rasa/dialogue_understanding/commands/skip_question_command.py +75 -0
- rasa/dialogue_understanding/commands/start_flow_command.py +107 -0
- rasa/dialogue_understanding/commands/user_silence_command.py +59 -0
- rasa/dialogue_understanding/commands/utils.py +45 -0
- rasa/dialogue_understanding/generator/__init__.py +21 -0
- rasa/dialogue_understanding/generator/command_generator.py +464 -0
- rasa/dialogue_understanding/generator/constants.py +27 -0
- rasa/dialogue_understanding/generator/flow_document_template.jinja2 +4 -0
- rasa/dialogue_understanding/generator/flow_retrieval.py +466 -0
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +500 -0
- rasa/dialogue_understanding/generator/llm_command_generator.py +67 -0
- rasa/dialogue_understanding/generator/multi_step/__init__.py +0 -0
- rasa/dialogue_understanding/generator/multi_step/fill_slots_prompt.jinja2 +62 -0
- rasa/dialogue_understanding/generator/multi_step/handle_flows_prompt.jinja2 +38 -0
- rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +920 -0
- rasa/dialogue_understanding/generator/nlu_command_adapter.py +261 -0
- rasa/dialogue_understanding/generator/single_step/__init__.py +0 -0
- rasa/dialogue_understanding/generator/single_step/command_prompt_template.jinja2 +60 -0
- rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +486 -0
- rasa/dialogue_understanding/patterns/__init__.py +0 -0
- rasa/dialogue_understanding/patterns/cancel.py +111 -0
- rasa/dialogue_understanding/patterns/cannot_handle.py +43 -0
- rasa/dialogue_understanding/patterns/chitchat.py +37 -0
- rasa/dialogue_understanding/patterns/clarify.py +97 -0
- rasa/dialogue_understanding/patterns/code_change.py +41 -0
- rasa/dialogue_understanding/patterns/collect_information.py +90 -0
- rasa/dialogue_understanding/patterns/completed.py +40 -0
- rasa/dialogue_understanding/patterns/continue_interrupted.py +42 -0
- rasa/dialogue_understanding/patterns/correction.py +278 -0
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +301 -0
- rasa/dialogue_understanding/patterns/human_handoff.py +37 -0
- rasa/dialogue_understanding/patterns/internal_error.py +47 -0
- rasa/dialogue_understanding/patterns/repeat.py +37 -0
- rasa/dialogue_understanding/patterns/restart.py +37 -0
- rasa/dialogue_understanding/patterns/search.py +37 -0
- rasa/dialogue_understanding/patterns/session_start.py +37 -0
- rasa/dialogue_understanding/patterns/skip_question.py +38 -0
- rasa/dialogue_understanding/patterns/user_silence.py +37 -0
- rasa/dialogue_understanding/processor/__init__.py +0 -0
- rasa/dialogue_understanding/processor/command_processor.py +720 -0
- rasa/dialogue_understanding/processor/command_processor_component.py +43 -0
- rasa/dialogue_understanding/stack/__init__.py +0 -0
- rasa/dialogue_understanding/stack/dialogue_stack.py +178 -0
- rasa/dialogue_understanding/stack/frames/__init__.py +19 -0
- rasa/dialogue_understanding/stack/frames/chit_chat_frame.py +27 -0
- rasa/dialogue_understanding/stack/frames/dialogue_stack_frame.py +137 -0
- rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +157 -0
- rasa/dialogue_understanding/stack/frames/pattern_frame.py +10 -0
- rasa/dialogue_understanding/stack/frames/search_frame.py +27 -0
- rasa/dialogue_understanding/stack/utils.py +211 -0
- rasa/dialogue_understanding/utils.py +14 -0
- rasa/dialogue_understanding_test/__init__.py +0 -0
- rasa/dialogue_understanding_test/command_metric_calculation.py +12 -0
- rasa/dialogue_understanding_test/constants.py +17 -0
- rasa/dialogue_understanding_test/du_test_case.py +118 -0
- rasa/dialogue_understanding_test/du_test_result.py +11 -0
- rasa/dialogue_understanding_test/du_test_runner.py +93 -0
- rasa/dialogue_understanding_test/io.py +54 -0
- rasa/dialogue_understanding_test/validation.py +22 -0
- rasa/e2e_test/__init__.py +0 -0
- rasa/e2e_test/aggregate_test_stats_calculator.py +134 -0
- rasa/e2e_test/assertions.py +1345 -0
- rasa/e2e_test/assertions_schema.yml +129 -0
- rasa/e2e_test/constants.py +31 -0
- rasa/e2e_test/e2e_config.py +220 -0
- rasa/e2e_test/e2e_config_schema.yml +26 -0
- rasa/e2e_test/e2e_test_case.py +569 -0
- rasa/e2e_test/e2e_test_converter.py +363 -0
- rasa/e2e_test/e2e_test_converter_prompt.jinja2 +70 -0
- rasa/e2e_test/e2e_test_coverage_report.py +364 -0
- rasa/e2e_test/e2e_test_result.py +54 -0
- rasa/e2e_test/e2e_test_runner.py +1192 -0
- rasa/e2e_test/e2e_test_schema.yml +181 -0
- rasa/e2e_test/pykwalify_extensions.py +39 -0
- rasa/e2e_test/stub_custom_action.py +70 -0
- rasa/e2e_test/utils/__init__.py +0 -0
- rasa/e2e_test/utils/e2e_yaml_utils.py +55 -0
- rasa/e2e_test/utils/io.py +598 -0
- rasa/e2e_test/utils/validation.py +178 -0
- rasa/engine/__init__.py +0 -0
- rasa/engine/caching.py +463 -0
- rasa/engine/constants.py +17 -0
- rasa/engine/exceptions.py +14 -0
- rasa/engine/graph.py +642 -0
- rasa/engine/loader.py +48 -0
- rasa/engine/recipes/__init__.py +0 -0
- rasa/engine/recipes/config_files/default_config.yml +41 -0
- rasa/engine/recipes/default_components.py +97 -0
- rasa/engine/recipes/default_recipe.py +1272 -0
- rasa/engine/recipes/graph_recipe.py +79 -0
- rasa/engine/recipes/recipe.py +93 -0
- rasa/engine/runner/__init__.py +0 -0
- rasa/engine/runner/dask.py +250 -0
- rasa/engine/runner/interface.py +49 -0
- rasa/engine/storage/__init__.py +0 -0
- rasa/engine/storage/local_model_storage.py +244 -0
- rasa/engine/storage/resource.py +110 -0
- rasa/engine/storage/storage.py +199 -0
- rasa/engine/training/__init__.py +0 -0
- rasa/engine/training/components.py +176 -0
- rasa/engine/training/fingerprinting.py +64 -0
- rasa/engine/training/graph_trainer.py +256 -0
- rasa/engine/training/hooks.py +164 -0
- rasa/engine/validation.py +1451 -0
- rasa/env.py +14 -0
- rasa/exceptions.py +69 -0
- rasa/graph_components/__init__.py +0 -0
- rasa/graph_components/converters/__init__.py +0 -0
- rasa/graph_components/converters/nlu_message_converter.py +48 -0
- rasa/graph_components/providers/__init__.py +0 -0
- rasa/graph_components/providers/domain_for_core_training_provider.py +87 -0
- rasa/graph_components/providers/domain_provider.py +71 -0
- rasa/graph_components/providers/flows_provider.py +74 -0
- rasa/graph_components/providers/forms_provider.py +44 -0
- rasa/graph_components/providers/nlu_training_data_provider.py +56 -0
- rasa/graph_components/providers/responses_provider.py +44 -0
- rasa/graph_components/providers/rule_only_provider.py +49 -0
- rasa/graph_components/providers/story_graph_provider.py +96 -0
- rasa/graph_components/providers/training_tracker_provider.py +55 -0
- rasa/graph_components/validators/__init__.py +0 -0
- rasa/graph_components/validators/default_recipe_validator.py +550 -0
- rasa/graph_components/validators/finetuning_validator.py +302 -0
- rasa/hooks.py +111 -0
- rasa/jupyter.py +63 -0
- rasa/llm_fine_tuning/__init__.py +0 -0
- rasa/llm_fine_tuning/annotation_module.py +241 -0
- rasa/llm_fine_tuning/conversations.py +144 -0
- rasa/llm_fine_tuning/llm_data_preparation_module.py +178 -0
- rasa/llm_fine_tuning/paraphrasing/__init__.py +0 -0
- rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +281 -0
- rasa/llm_fine_tuning/paraphrasing/default_rephrase_prompt_template.jina2 +44 -0
- rasa/llm_fine_tuning/paraphrasing/rephrase_validator.py +121 -0
- rasa/llm_fine_tuning/paraphrasing/rephrased_user_message.py +10 -0
- rasa/llm_fine_tuning/paraphrasing_module.py +128 -0
- rasa/llm_fine_tuning/storage.py +174 -0
- rasa/llm_fine_tuning/train_test_split_module.py +441 -0
- rasa/markers/__init__.py +0 -0
- rasa/markers/marker.py +269 -0
- rasa/markers/marker_base.py +828 -0
- rasa/markers/upload.py +74 -0
- rasa/markers/validate.py +21 -0
- rasa/model.py +118 -0
- rasa/model_manager/__init__.py +0 -0
- rasa/model_manager/config.py +40 -0
- rasa/model_manager/model_api.py +559 -0
- rasa/model_manager/runner_service.py +286 -0
- rasa/model_manager/socket_bridge.py +146 -0
- rasa/model_manager/studio_jwt_auth.py +86 -0
- rasa/model_manager/trainer_service.py +325 -0
- rasa/model_manager/utils.py +87 -0
- rasa/model_manager/warm_rasa_process.py +187 -0
- rasa/model_service.py +112 -0
- rasa/model_testing.py +457 -0
- rasa/model_training.py +596 -0
- rasa/nlu/__init__.py +7 -0
- rasa/nlu/classifiers/__init__.py +3 -0
- rasa/nlu/classifiers/classifier.py +5 -0
- rasa/nlu/classifiers/diet_classifier.py +1881 -0
- rasa/nlu/classifiers/fallback_classifier.py +192 -0
- rasa/nlu/classifiers/keyword_intent_classifier.py +188 -0
- rasa/nlu/classifiers/logistic_regression_classifier.py +253 -0
- rasa/nlu/classifiers/mitie_intent_classifier.py +156 -0
- rasa/nlu/classifiers/regex_message_handler.py +56 -0
- rasa/nlu/classifiers/sklearn_intent_classifier.py +330 -0
- rasa/nlu/constants.py +77 -0
- rasa/nlu/convert.py +40 -0
- rasa/nlu/emulators/__init__.py +0 -0
- rasa/nlu/emulators/dialogflow.py +55 -0
- rasa/nlu/emulators/emulator.py +49 -0
- rasa/nlu/emulators/luis.py +86 -0
- rasa/nlu/emulators/no_emulator.py +10 -0
- rasa/nlu/emulators/wit.py +56 -0
- rasa/nlu/extractors/__init__.py +0 -0
- rasa/nlu/extractors/crf_entity_extractor.py +715 -0
- rasa/nlu/extractors/duckling_entity_extractor.py +206 -0
- rasa/nlu/extractors/entity_synonyms.py +178 -0
- rasa/nlu/extractors/extractor.py +470 -0
- rasa/nlu/extractors/mitie_entity_extractor.py +293 -0
- rasa/nlu/extractors/regex_entity_extractor.py +220 -0
- rasa/nlu/extractors/spacy_entity_extractor.py +95 -0
- rasa/nlu/featurizers/__init__.py +0 -0
- rasa/nlu/featurizers/dense_featurizer/__init__.py +0 -0
- rasa/nlu/featurizers/dense_featurizer/convert_featurizer.py +445 -0
- rasa/nlu/featurizers/dense_featurizer/dense_featurizer.py +57 -0
- rasa/nlu/featurizers/dense_featurizer/lm_featurizer.py +768 -0
- rasa/nlu/featurizers/dense_featurizer/mitie_featurizer.py +170 -0
- rasa/nlu/featurizers/dense_featurizer/spacy_featurizer.py +132 -0
- rasa/nlu/featurizers/featurizer.py +89 -0
- rasa/nlu/featurizers/sparse_featurizer/__init__.py +0 -0
- rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +867 -0
- rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +571 -0
- rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +271 -0
- rasa/nlu/featurizers/sparse_featurizer/sparse_featurizer.py +9 -0
- rasa/nlu/model.py +24 -0
- rasa/nlu/run.py +27 -0
- rasa/nlu/selectors/__init__.py +0 -0
- rasa/nlu/selectors/response_selector.py +987 -0
- rasa/nlu/test.py +1940 -0
- rasa/nlu/tokenizers/__init__.py +0 -0
- rasa/nlu/tokenizers/jieba_tokenizer.py +148 -0
- rasa/nlu/tokenizers/mitie_tokenizer.py +75 -0
- rasa/nlu/tokenizers/spacy_tokenizer.py +72 -0
- rasa/nlu/tokenizers/tokenizer.py +239 -0
- rasa/nlu/tokenizers/whitespace_tokenizer.py +95 -0
- rasa/nlu/utils/__init__.py +35 -0
- rasa/nlu/utils/bilou_utils.py +462 -0
- rasa/nlu/utils/hugging_face/__init__.py +0 -0
- rasa/nlu/utils/hugging_face/registry.py +108 -0
- rasa/nlu/utils/hugging_face/transformers_pre_post_processors.py +311 -0
- rasa/nlu/utils/mitie_utils.py +113 -0
- rasa/nlu/utils/pattern_utils.py +168 -0
- rasa/nlu/utils/spacy_utils.py +310 -0
- rasa/plugin.py +90 -0
- rasa/server.py +1588 -0
- rasa/shared/__init__.py +0 -0
- rasa/shared/constants.py +311 -0
- rasa/shared/core/__init__.py +0 -0
- rasa/shared/core/command_payload_reader.py +109 -0
- rasa/shared/core/constants.py +180 -0
- rasa/shared/core/conversation.py +46 -0
- rasa/shared/core/domain.py +2172 -0
- rasa/shared/core/events.py +2559 -0
- rasa/shared/core/flows/__init__.py +7 -0
- rasa/shared/core/flows/flow.py +562 -0
- rasa/shared/core/flows/flow_path.py +84 -0
- rasa/shared/core/flows/flow_step.py +146 -0
- rasa/shared/core/flows/flow_step_links.py +319 -0
- rasa/shared/core/flows/flow_step_sequence.py +70 -0
- rasa/shared/core/flows/flows_list.py +258 -0
- rasa/shared/core/flows/flows_yaml_schema.json +303 -0
- rasa/shared/core/flows/nlu_trigger.py +117 -0
- rasa/shared/core/flows/steps/__init__.py +24 -0
- rasa/shared/core/flows/steps/action.py +56 -0
- rasa/shared/core/flows/steps/call.py +64 -0
- rasa/shared/core/flows/steps/collect.py +112 -0
- rasa/shared/core/flows/steps/constants.py +5 -0
- rasa/shared/core/flows/steps/continuation.py +36 -0
- rasa/shared/core/flows/steps/end.py +22 -0
- rasa/shared/core/flows/steps/internal.py +44 -0
- rasa/shared/core/flows/steps/link.py +51 -0
- rasa/shared/core/flows/steps/no_operation.py +48 -0
- rasa/shared/core/flows/steps/set_slots.py +50 -0
- rasa/shared/core/flows/steps/start.py +30 -0
- rasa/shared/core/flows/utils.py +39 -0
- rasa/shared/core/flows/validation.py +735 -0
- rasa/shared/core/flows/yaml_flows_io.py +405 -0
- rasa/shared/core/generator.py +908 -0
- rasa/shared/core/slot_mappings.py +526 -0
- rasa/shared/core/slots.py +654 -0
- rasa/shared/core/trackers.py +1183 -0
- rasa/shared/core/training_data/__init__.py +0 -0
- rasa/shared/core/training_data/loading.py +89 -0
- rasa/shared/core/training_data/story_reader/__init__.py +0 -0
- rasa/shared/core/training_data/story_reader/story_reader.py +129 -0
- rasa/shared/core/training_data/story_reader/story_step_builder.py +168 -0
- rasa/shared/core/training_data/story_reader/yaml_story_reader.py +888 -0
- rasa/shared/core/training_data/story_writer/__init__.py +0 -0
- rasa/shared/core/training_data/story_writer/story_writer.py +76 -0
- rasa/shared/core/training_data/story_writer/yaml_story_writer.py +444 -0
- rasa/shared/core/training_data/structures.py +858 -0
- rasa/shared/core/training_data/visualization.html +146 -0
- rasa/shared/core/training_data/visualization.py +603 -0
- rasa/shared/data.py +249 -0
- rasa/shared/engine/__init__.py +0 -0
- rasa/shared/engine/caching.py +26 -0
- rasa/shared/exceptions.py +167 -0
- rasa/shared/importers/__init__.py +0 -0
- rasa/shared/importers/importer.py +770 -0
- rasa/shared/importers/multi_project.py +215 -0
- rasa/shared/importers/rasa.py +108 -0
- rasa/shared/importers/remote_importer.py +196 -0
- rasa/shared/importers/utils.py +36 -0
- rasa/shared/nlu/__init__.py +0 -0
- rasa/shared/nlu/constants.py +53 -0
- rasa/shared/nlu/interpreter.py +10 -0
- rasa/shared/nlu/training_data/__init__.py +0 -0
- rasa/shared/nlu/training_data/entities_parser.py +208 -0
- rasa/shared/nlu/training_data/features.py +492 -0
- rasa/shared/nlu/training_data/formats/__init__.py +10 -0
- rasa/shared/nlu/training_data/formats/dialogflow.py +163 -0
- rasa/shared/nlu/training_data/formats/luis.py +87 -0
- rasa/shared/nlu/training_data/formats/rasa.py +135 -0
- rasa/shared/nlu/training_data/formats/rasa_yaml.py +618 -0
- rasa/shared/nlu/training_data/formats/readerwriter.py +244 -0
- rasa/shared/nlu/training_data/formats/wit.py +52 -0
- rasa/shared/nlu/training_data/loading.py +137 -0
- rasa/shared/nlu/training_data/lookup_tables_parser.py +30 -0
- rasa/shared/nlu/training_data/message.py +490 -0
- rasa/shared/nlu/training_data/schemas/__init__.py +0 -0
- rasa/shared/nlu/training_data/schemas/data_schema.py +85 -0
- rasa/shared/nlu/training_data/schemas/nlu.yml +53 -0
- rasa/shared/nlu/training_data/schemas/responses.yml +70 -0
- rasa/shared/nlu/training_data/synonyms_parser.py +42 -0
- rasa/shared/nlu/training_data/training_data.py +729 -0
- rasa/shared/nlu/training_data/util.py +223 -0
- rasa/shared/providers/__init__.py +0 -0
- rasa/shared/providers/_configs/__init__.py +0 -0
- rasa/shared/providers/_configs/azure_openai_client_config.py +677 -0
- rasa/shared/providers/_configs/client_config.py +59 -0
- rasa/shared/providers/_configs/default_litellm_client_config.py +132 -0
- rasa/shared/providers/_configs/huggingface_local_embedding_client_config.py +236 -0
- rasa/shared/providers/_configs/litellm_router_client_config.py +222 -0
- rasa/shared/providers/_configs/model_group_config.py +173 -0
- rasa/shared/providers/_configs/openai_client_config.py +177 -0
- rasa/shared/providers/_configs/rasa_llm_client_config.py +75 -0
- rasa/shared/providers/_configs/self_hosted_llm_client_config.py +178 -0
- rasa/shared/providers/_configs/utils.py +117 -0
- rasa/shared/providers/_ssl_verification_utils.py +124 -0
- rasa/shared/providers/_utils.py +79 -0
- rasa/shared/providers/constants.py +7 -0
- rasa/shared/providers/embedding/__init__.py +0 -0
- rasa/shared/providers/embedding/_base_litellm_embedding_client.py +243 -0
- rasa/shared/providers/embedding/_langchain_embedding_client_adapter.py +74 -0
- rasa/shared/providers/embedding/azure_openai_embedding_client.py +335 -0
- rasa/shared/providers/embedding/default_litellm_embedding_client.py +126 -0
- rasa/shared/providers/embedding/embedding_client.py +90 -0
- rasa/shared/providers/embedding/embedding_response.py +41 -0
- rasa/shared/providers/embedding/huggingface_local_embedding_client.py +191 -0
- rasa/shared/providers/embedding/litellm_router_embedding_client.py +138 -0
- rasa/shared/providers/embedding/openai_embedding_client.py +172 -0
- rasa/shared/providers/llm/__init__.py +0 -0
- rasa/shared/providers/llm/_base_litellm_client.py +265 -0
- rasa/shared/providers/llm/azure_openai_llm_client.py +415 -0
- rasa/shared/providers/llm/default_litellm_llm_client.py +110 -0
- rasa/shared/providers/llm/litellm_router_llm_client.py +202 -0
- rasa/shared/providers/llm/llm_client.py +78 -0
- rasa/shared/providers/llm/llm_response.py +50 -0
- rasa/shared/providers/llm/openai_llm_client.py +161 -0
- rasa/shared/providers/llm/rasa_llm_client.py +120 -0
- rasa/shared/providers/llm/self_hosted_llm_client.py +276 -0
- rasa/shared/providers/mappings.py +94 -0
- rasa/shared/providers/router/__init__.py +0 -0
- rasa/shared/providers/router/_base_litellm_router_client.py +185 -0
- rasa/shared/providers/router/router_client.py +75 -0
- rasa/shared/utils/__init__.py +0 -0
- rasa/shared/utils/cli.py +102 -0
- rasa/shared/utils/common.py +324 -0
- rasa/shared/utils/constants.py +4 -0
- rasa/shared/utils/health_check/__init__.py +0 -0
- rasa/shared/utils/health_check/embeddings_health_check_mixin.py +31 -0
- rasa/shared/utils/health_check/health_check.py +258 -0
- rasa/shared/utils/health_check/llm_health_check_mixin.py +31 -0
- rasa/shared/utils/io.py +499 -0
- rasa/shared/utils/llm.py +764 -0
- rasa/shared/utils/pykwalify_extensions.py +27 -0
- rasa/shared/utils/schemas/__init__.py +0 -0
- rasa/shared/utils/schemas/config.yml +2 -0
- rasa/shared/utils/schemas/domain.yml +145 -0
- rasa/shared/utils/schemas/events.py +214 -0
- rasa/shared/utils/schemas/model_config.yml +36 -0
- rasa/shared/utils/schemas/stories.yml +173 -0
- rasa/shared/utils/yaml.py +1068 -0
- rasa/studio/__init__.py +0 -0
- rasa/studio/auth.py +270 -0
- rasa/studio/config.py +136 -0
- rasa/studio/constants.py +19 -0
- rasa/studio/data_handler.py +368 -0
- rasa/studio/download.py +489 -0
- rasa/studio/results_logger.py +137 -0
- rasa/studio/train.py +134 -0
- rasa/studio/upload.py +563 -0
- rasa/telemetry.py +1876 -0
- rasa/tracing/__init__.py +0 -0
- rasa/tracing/config.py +355 -0
- rasa/tracing/constants.py +62 -0
- rasa/tracing/instrumentation/__init__.py +0 -0
- rasa/tracing/instrumentation/attribute_extractors.py +765 -0
- rasa/tracing/instrumentation/instrumentation.py +1306 -0
- rasa/tracing/instrumentation/intentless_policy_instrumentation.py +144 -0
- rasa/tracing/instrumentation/metrics.py +294 -0
- rasa/tracing/metric_instrument_provider.py +205 -0
- rasa/utils/__init__.py +0 -0
- rasa/utils/beta.py +83 -0
- rasa/utils/cli.py +28 -0
- rasa/utils/common.py +639 -0
- rasa/utils/converter.py +53 -0
- rasa/utils/endpoints.py +331 -0
- rasa/utils/io.py +252 -0
- rasa/utils/json_utils.py +60 -0
- rasa/utils/licensing.py +542 -0
- rasa/utils/log_utils.py +181 -0
- rasa/utils/mapper.py +210 -0
- rasa/utils/ml_utils.py +147 -0
- rasa/utils/plotting.py +362 -0
- rasa/utils/sanic_error_handler.py +32 -0
- rasa/utils/singleton.py +23 -0
- rasa/utils/tensorflow/__init__.py +0 -0
- rasa/utils/tensorflow/callback.py +112 -0
- rasa/utils/tensorflow/constants.py +116 -0
- rasa/utils/tensorflow/crf.py +492 -0
- rasa/utils/tensorflow/data_generator.py +440 -0
- rasa/utils/tensorflow/environment.py +161 -0
- rasa/utils/tensorflow/exceptions.py +5 -0
- rasa/utils/tensorflow/feature_array.py +366 -0
- rasa/utils/tensorflow/layers.py +1565 -0
- rasa/utils/tensorflow/layers_utils.py +113 -0
- rasa/utils/tensorflow/metrics.py +281 -0
- rasa/utils/tensorflow/model_data.py +798 -0
- rasa/utils/tensorflow/model_data_utils.py +499 -0
- rasa/utils/tensorflow/models.py +935 -0
- rasa/utils/tensorflow/rasa_layers.py +1094 -0
- rasa/utils/tensorflow/transformer.py +640 -0
- rasa/utils/tensorflow/types.py +6 -0
- rasa/utils/train_utils.py +572 -0
- rasa/utils/url_tools.py +53 -0
- rasa/utils/yaml.py +54 -0
- rasa/validator.py +1644 -0
- rasa/version.py +3 -0
- rasa_pro-3.12.0.dev1.dist-info/METADATA +199 -0
- rasa_pro-3.12.0.dev1.dist-info/NOTICE +5 -0
- rasa_pro-3.12.0.dev1.dist-info/RECORD +790 -0
- rasa_pro-3.12.0.dev1.dist-info/WHEEL +4 -0
- rasa_pro-3.12.0.dev1.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Any, Dict, Optional
|
|
3
|
+
import shutil
|
|
4
|
+
import structlog
|
|
5
|
+
import subprocess
|
|
6
|
+
from rasa.constants import MODEL_ARCHIVE_EXTENSION
|
|
7
|
+
from rasa.model_manager.utils import (
|
|
8
|
+
models_base_path,
|
|
9
|
+
subpath,
|
|
10
|
+
write_encoded_data_to_file,
|
|
11
|
+
)
|
|
12
|
+
from pydantic import BaseModel, ConfigDict
|
|
13
|
+
from enum import Enum
|
|
14
|
+
|
|
15
|
+
from rasa.model_manager import config
|
|
16
|
+
from rasa.model_manager.warm_rasa_process import (
|
|
17
|
+
start_rasa_process,
|
|
18
|
+
)
|
|
19
|
+
from rasa.model_training import generate_random_model_name
|
|
20
|
+
from rasa.model_manager.utils import ensure_base_directory_exists, logs_path
|
|
21
|
+
|
|
22
|
+
structlogger = structlog.get_logger()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class TrainingSessionStatus(str, Enum):
|
|
26
|
+
"""Enum for the training status."""
|
|
27
|
+
|
|
28
|
+
RUNNING = "running"
|
|
29
|
+
STOPPED = "stopped"
|
|
30
|
+
DONE = "done"
|
|
31
|
+
ERROR = "error"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class TrainingSession(BaseModel):
|
|
35
|
+
"""Store information about a training session."""
|
|
36
|
+
|
|
37
|
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
38
|
+
|
|
39
|
+
training_id: str
|
|
40
|
+
assistant_id: str
|
|
41
|
+
client_id: Optional[str]
|
|
42
|
+
progress: int
|
|
43
|
+
model_name: str
|
|
44
|
+
status: TrainingSessionStatus
|
|
45
|
+
process: subprocess.Popen
|
|
46
|
+
log_id: str
|
|
47
|
+
|
|
48
|
+
def is_status_indicating_alive(self) -> bool:
|
|
49
|
+
"""Check if the training is running."""
|
|
50
|
+
return self.status == TrainingSessionStatus.RUNNING
|
|
51
|
+
|
|
52
|
+
def model_path(self) -> str:
|
|
53
|
+
"""Return the path to the model."""
|
|
54
|
+
return subpath(models_base_path(), f"{self.model_name}.tar.gz")
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def train_path(training_id: str) -> str:
|
|
58
|
+
"""Return the path to the training directory for a given training id."""
|
|
59
|
+
return subpath(config.SERVER_BASE_WORKING_DIRECTORY + "/trainings", training_id)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def cache_for_assistant_path(assistant_id: str) -> str:
|
|
63
|
+
"""Return the path to the cache directory for a given assistant id."""
|
|
64
|
+
return subpath(config.SERVER_BASE_WORKING_DIRECTORY + "/caches", assistant_id)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def terminate_training(training: TrainingSession) -> None:
|
|
68
|
+
if not training.is_status_indicating_alive():
|
|
69
|
+
# no-op if the training is not running
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
structlogger.info(
|
|
73
|
+
"model_trainer.user_stopping_training", training_id=training.training_id
|
|
74
|
+
)
|
|
75
|
+
try:
|
|
76
|
+
training.process.terminate()
|
|
77
|
+
training.status = TrainingSessionStatus.STOPPED
|
|
78
|
+
except ProcessLookupError:
|
|
79
|
+
structlogger.debug(
|
|
80
|
+
"model_trainer.training_process_not_found",
|
|
81
|
+
training_id=training.training_id,
|
|
82
|
+
)
|
|
83
|
+
finally:
|
|
84
|
+
clean_up_after_training(training)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def update_training_status(training: TrainingSession) -> None:
|
|
88
|
+
if not training.is_status_indicating_alive():
|
|
89
|
+
# skip if the training is not running
|
|
90
|
+
return
|
|
91
|
+
if training.process.poll() is None:
|
|
92
|
+
# process is still running
|
|
93
|
+
return
|
|
94
|
+
|
|
95
|
+
complete_training(training)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def complete_training(training: TrainingSession) -> None:
|
|
99
|
+
"""Complete a training session.
|
|
100
|
+
|
|
101
|
+
Transitions the status of a training process to "done" if the process has
|
|
102
|
+
finished successfully, and to "error" if the process has finished with an
|
|
103
|
+
error.
|
|
104
|
+
"""
|
|
105
|
+
if training.process.returncode == 0:
|
|
106
|
+
training.status = TrainingSessionStatus.DONE
|
|
107
|
+
else:
|
|
108
|
+
training.status = TrainingSessionStatus.ERROR
|
|
109
|
+
|
|
110
|
+
training.progress = 100
|
|
111
|
+
|
|
112
|
+
structlogger.info(
|
|
113
|
+
"model_trainer.training_finished",
|
|
114
|
+
training_id=training.training_id,
|
|
115
|
+
status=training.status,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
# persist the assistant cache to speed up future training runs for this
|
|
119
|
+
# assistant
|
|
120
|
+
persist_rasa_cache(training.assistant_id, train_path(training.training_id))
|
|
121
|
+
move_model_to_local_storage(training)
|
|
122
|
+
|
|
123
|
+
clean_up_after_training(training)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def clean_up_after_training(training: TrainingSession) -> None:
|
|
127
|
+
"""Clean up the training directory."""
|
|
128
|
+
structlogger.debug(
|
|
129
|
+
"model_trainer.cleaning_up_training", training_id=training.training_id
|
|
130
|
+
)
|
|
131
|
+
shutil.rmtree(train_path(training.training_id), ignore_errors=True)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def move_model_to_local_storage(training: TrainingSession) -> None:
|
|
135
|
+
"""Persist the model to the remote storage."""
|
|
136
|
+
ensure_base_directory_exists(models_base_path())
|
|
137
|
+
|
|
138
|
+
model_path = subpath(
|
|
139
|
+
train_path(training.training_id) + "/models",
|
|
140
|
+
f"{training.model_name}.{MODEL_ARCHIVE_EXTENSION}",
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
if os.path.exists(model_path):
|
|
144
|
+
structlogger.debug(
|
|
145
|
+
"model_trainer.persisting_model_to_models_dir",
|
|
146
|
+
training_model_path=model_path,
|
|
147
|
+
storage_model_path=models_base_path(),
|
|
148
|
+
)
|
|
149
|
+
shutil.move(model_path, models_base_path())
|
|
150
|
+
else:
|
|
151
|
+
structlogger.warning(
|
|
152
|
+
"model_trainer.model_not_found_after_training",
|
|
153
|
+
training_id=training.training_id,
|
|
154
|
+
model_path=model_path,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def seed_training_directory_with_rasa_cache(
|
|
159
|
+
training_base_path: str, assistant_id: str
|
|
160
|
+
) -> None:
|
|
161
|
+
"""Populate the training directory with the cache of a previous training."""
|
|
162
|
+
# check if there is a cache for this assistant
|
|
163
|
+
cache_path = cache_for_assistant_path(assistant_id)
|
|
164
|
+
|
|
165
|
+
if os.path.exists(cache_path):
|
|
166
|
+
structlogger.debug(
|
|
167
|
+
"model_trainer.populating_training_dir_with_cache",
|
|
168
|
+
assistant_id=assistant_id,
|
|
169
|
+
training_base_path=training_base_path,
|
|
170
|
+
)
|
|
171
|
+
# copy the cache to the training directory
|
|
172
|
+
shutil.copytree(src=cache_path, dst=subpath(training_base_path, ".rasa"))
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def persist_rasa_cache(assistant_id: str, training_base_path: str) -> None:
|
|
176
|
+
"""Persist the cache of a training session to speed up future trainings."""
|
|
177
|
+
# copy the cache from the training directory to the cache directory
|
|
178
|
+
# cache files are stored inside of `/.rasa/` of the training folder
|
|
179
|
+
structlogger.debug(
|
|
180
|
+
"model_trainer.persisting_assistant_cache", assistant_id=assistant_id
|
|
181
|
+
)
|
|
182
|
+
cache_path = cache_for_assistant_path(assistant_id)
|
|
183
|
+
|
|
184
|
+
# if the training failed and didn't create a cache, skip this step
|
|
185
|
+
if not os.path.exists(subpath(training_base_path, ".rasa")):
|
|
186
|
+
return
|
|
187
|
+
|
|
188
|
+
# clean up the cache directory first
|
|
189
|
+
shutil.rmtree(cache_path, ignore_errors=True)
|
|
190
|
+
shutil.copytree(src=subpath(training_base_path, ".rasa"), dst=cache_path)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def write_training_data_to_files(
|
|
194
|
+
encoded_training_data: Dict[str, Any], training_base_path: str
|
|
195
|
+
) -> None:
|
|
196
|
+
"""Write the training data to files in the training directory.
|
|
197
|
+
|
|
198
|
+
Incoming data format, all keys being optional:
|
|
199
|
+
````
|
|
200
|
+
{
|
|
201
|
+
"domain": "base64 encoded domain.yml",
|
|
202
|
+
"credentials": "base64 encoded credentials.yml",
|
|
203
|
+
"endpoints": "base64 encoded endpoints.yml",
|
|
204
|
+
"flows": "base64 encoded flows.yml",
|
|
205
|
+
"config": "base64 encoded config.yml",
|
|
206
|
+
"stories": "base64 encoded stories.yml",
|
|
207
|
+
"rules": "base64 encoded rules.yml",
|
|
208
|
+
"nlu": "base64 encoded nlu.yml"
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
"""
|
|
212
|
+
data_to_be_written_to_files = {
|
|
213
|
+
"domain": "domain.yml",
|
|
214
|
+
"credentials": "credentials.yml",
|
|
215
|
+
"endpoints": "endpoints.yml",
|
|
216
|
+
"flows": "data/flows.yml",
|
|
217
|
+
"config": "config.yml",
|
|
218
|
+
"stories": "data/stories.yml",
|
|
219
|
+
"rules": "data/rules.yml",
|
|
220
|
+
"nlu": "data/nlu.yml",
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
for key, file in data_to_be_written_to_files.items():
|
|
224
|
+
parent_path, file_name = os.path.split(file)
|
|
225
|
+
|
|
226
|
+
write_encoded_data_to_file(
|
|
227
|
+
encoded_training_data.get(key, ""),
|
|
228
|
+
subpath(training_base_path + "/" + parent_path, file_name),
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def prepare_training_directory(
|
|
233
|
+
training_base_path: str, assistant_id: str, encoded_training_data: Dict[str, Any]
|
|
234
|
+
) -> None:
|
|
235
|
+
"""Prepare the training directory for a new training session."""
|
|
236
|
+
# create a new working directory and store the training data from the
|
|
237
|
+
# request there. the training data in the request is base64 encoded
|
|
238
|
+
os.makedirs(training_base_path, exist_ok=True)
|
|
239
|
+
|
|
240
|
+
seed_training_directory_with_rasa_cache(training_base_path, assistant_id)
|
|
241
|
+
write_training_data_to_files(encoded_training_data, training_base_path)
|
|
242
|
+
structlogger.debug("model_trainer.prepared_training", path=training_base_path)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def start_training_process(
|
|
246
|
+
training_id: str,
|
|
247
|
+
assistant_id: str,
|
|
248
|
+
client_id: str,
|
|
249
|
+
training_base_path: str,
|
|
250
|
+
) -> TrainingSession:
|
|
251
|
+
model_name = generate_random_model_name()
|
|
252
|
+
# Start the training in a subprocess
|
|
253
|
+
# set the working directory to the training directory
|
|
254
|
+
# run the rasa train command as a subprocess, activating poetry before running
|
|
255
|
+
# pipe the stdout and stderr to the same file
|
|
256
|
+
arguments = [
|
|
257
|
+
"train",
|
|
258
|
+
"--debug",
|
|
259
|
+
"--data",
|
|
260
|
+
"data",
|
|
261
|
+
"--config",
|
|
262
|
+
"config.yml",
|
|
263
|
+
"--domain",
|
|
264
|
+
"domain.yml",
|
|
265
|
+
"--endpoints",
|
|
266
|
+
"endpoints.yml",
|
|
267
|
+
"--fixed-model-name",
|
|
268
|
+
f"{model_name}.{MODEL_ARCHIVE_EXTENSION}",
|
|
269
|
+
"--out",
|
|
270
|
+
"models",
|
|
271
|
+
]
|
|
272
|
+
|
|
273
|
+
if config.SERVER_MODEL_REMOTE_STORAGE:
|
|
274
|
+
arguments.extend(
|
|
275
|
+
[
|
|
276
|
+
"--keep-local-model-copy",
|
|
277
|
+
"--remote-storage",
|
|
278
|
+
config.SERVER_MODEL_REMOTE_STORAGE,
|
|
279
|
+
]
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
structlogger.debug(
|
|
283
|
+
"model_trainer.training_arguments", arguments=" ".join(arguments)
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
warm_process = start_rasa_process(cwd=training_base_path, arguments=arguments)
|
|
287
|
+
|
|
288
|
+
structlogger.info(
|
|
289
|
+
"model_trainer.training_started",
|
|
290
|
+
training_id=training_id,
|
|
291
|
+
assistant_id=assistant_id,
|
|
292
|
+
model_name=model_name,
|
|
293
|
+
client_id=client_id,
|
|
294
|
+
log=logs_path(warm_process.log_id),
|
|
295
|
+
pid=warm_process.process.pid,
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
return TrainingSession(
|
|
299
|
+
training_id=training_id,
|
|
300
|
+
assistant_id=assistant_id,
|
|
301
|
+
client_id=client_id,
|
|
302
|
+
model_name=model_name,
|
|
303
|
+
progress=0,
|
|
304
|
+
status=TrainingSessionStatus.RUNNING,
|
|
305
|
+
process=warm_process.process, # Store the process handle
|
|
306
|
+
log_id=warm_process.log_id,
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def run_training(
|
|
311
|
+
training_id: str,
|
|
312
|
+
assistant_id: str,
|
|
313
|
+
client_id: str,
|
|
314
|
+
encoded_training_data: Dict,
|
|
315
|
+
) -> TrainingSession:
|
|
316
|
+
"""Run a training session."""
|
|
317
|
+
training_base_path = train_path(training_id)
|
|
318
|
+
|
|
319
|
+
prepare_training_directory(training_base_path, assistant_id, encoded_training_data)
|
|
320
|
+
return start_training_process(
|
|
321
|
+
training_id=training_id,
|
|
322
|
+
assistant_id=assistant_id,
|
|
323
|
+
client_id=client_id,
|
|
324
|
+
training_base_path=training_base_path,
|
|
325
|
+
)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import base64
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
import structlog
|
|
6
|
+
|
|
7
|
+
from rasa.model_manager import config
|
|
8
|
+
from rasa.shared.exceptions import RasaException
|
|
9
|
+
|
|
10
|
+
structlogger = structlog.get_logger()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class InvalidPathException(RasaException):
|
|
14
|
+
"""Raised if a path is invalid - e.g. path traversal is detected."""
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def write_encoded_data_to_file(encoded_data: bytes, file: str) -> None:
|
|
18
|
+
"""Write base64 encoded data to a file."""
|
|
19
|
+
# create the directory if it does not exist of the parent directory
|
|
20
|
+
os.makedirs(os.path.dirname(file), exist_ok=True)
|
|
21
|
+
|
|
22
|
+
with open(file, "w") as f:
|
|
23
|
+
decoded = base64.b64decode(encoded_data)
|
|
24
|
+
text = decoded.decode("utf-8")
|
|
25
|
+
f.write(text)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def logs_base_path() -> str:
|
|
29
|
+
"""Return the path to the logs' directory."""
|
|
30
|
+
return subpath(config.SERVER_BASE_WORKING_DIRECTORY, "logs")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def ensure_base_directory_exists(directory: str) -> None:
|
|
34
|
+
"""Ensure that a files parent directory exists.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
directory: The directory to check.
|
|
38
|
+
"""
|
|
39
|
+
os.makedirs(os.path.dirname(directory), exist_ok=True)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def models_base_path() -> str:
|
|
43
|
+
"""Return the path to the models' directory."""
|
|
44
|
+
return subpath(config.SERVER_BASE_WORKING_DIRECTORY, "models")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def logs_path(action_id: str) -> str:
|
|
48
|
+
"""Return the path to the log file for a given action id.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
action_id: can either be a training_id or a deployment_id
|
|
52
|
+
"""
|
|
53
|
+
return subpath(logs_base_path(), f"{action_id}.txt")
|
|
54
|
+
|
|
55
|
+
|
|
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
|
+
def get_logs_content(action_id: str) -> Optional[str]:
|
|
81
|
+
"""Return the content of the log file for a given action id."""
|
|
82
|
+
try:
|
|
83
|
+
with open(logs_path(action_id), "r") as file:
|
|
84
|
+
return file.read()
|
|
85
|
+
except FileNotFoundError:
|
|
86
|
+
structlogger.debug("model_service.logs.not_found", action_id=action_id)
|
|
87
|
+
return None
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import shlex
|
|
2
|
+
import subprocess
|
|
3
|
+
from rasa.__main__ import main
|
|
4
|
+
import os
|
|
5
|
+
from typing import List
|
|
6
|
+
import structlog
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
import uuid
|
|
9
|
+
|
|
10
|
+
from rasa.model_manager import config
|
|
11
|
+
from rasa.model_manager.utils import ensure_base_directory_exists, logs_path
|
|
12
|
+
|
|
13
|
+
structlogger = structlog.get_logger(__name__)
|
|
14
|
+
|
|
15
|
+
warm_rasa_processes: List["WarmRasaProcess"] = []
|
|
16
|
+
|
|
17
|
+
NUMBER_OF_INITIAL_PROCESSES = 3
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class WarmRasaProcess:
|
|
22
|
+
"""Data class to store a warm Rasa process.
|
|
23
|
+
|
|
24
|
+
A "warm" Rasa process is one where we've done the heavy lifting of
|
|
25
|
+
importing key modules ahead of time (e.g. litellm). This is to avoid
|
|
26
|
+
long import times when we actually want to run a command.
|
|
27
|
+
|
|
28
|
+
This is a started process waiting for a Rasa CLI command. It's
|
|
29
|
+
output is stored in a log file identified by `log_id`.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
process: subprocess.Popen
|
|
33
|
+
log_id: str
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _create_warm_rasa_process() -> WarmRasaProcess:
|
|
37
|
+
"""Create a new warm Rasa process."""
|
|
38
|
+
command = [
|
|
39
|
+
config.RASA_PYTHON_PATH,
|
|
40
|
+
"-m",
|
|
41
|
+
"rasa.model_manager.warm_rasa_process",
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
envs = os.environ.copy()
|
|
45
|
+
envs["RASA_TELEMETRY_ENABLED"] = "false"
|
|
46
|
+
|
|
47
|
+
log_id = uuid.uuid4().hex
|
|
48
|
+
log_path = logs_path(log_id)
|
|
49
|
+
|
|
50
|
+
ensure_base_directory_exists(log_path)
|
|
51
|
+
|
|
52
|
+
process = subprocess.Popen(
|
|
53
|
+
command,
|
|
54
|
+
stdout=open(log_path, "w"),
|
|
55
|
+
stderr=subprocess.STDOUT,
|
|
56
|
+
stdin=subprocess.PIPE,
|
|
57
|
+
env=envs,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
structlogger.debug(
|
|
61
|
+
"model_trainer.created_warm_rasa_process",
|
|
62
|
+
pid=process.pid,
|
|
63
|
+
command=command,
|
|
64
|
+
log_path=log_path,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
return WarmRasaProcess(process=process, log_id=log_id)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def initialize_warm_rasa_process() -> None:
|
|
71
|
+
"""Initialize the warm Rasa processes."""
|
|
72
|
+
global warm_rasa_processes
|
|
73
|
+
for _ in range(NUMBER_OF_INITIAL_PROCESSES):
|
|
74
|
+
warm_rasa_processes.append(_create_warm_rasa_process())
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def shutdown_warm_rasa_processes() -> None:
|
|
78
|
+
"""Shutdown all warm Rasa processes."""
|
|
79
|
+
global warm_rasa_processes
|
|
80
|
+
for warm_rasa_process in warm_rasa_processes:
|
|
81
|
+
warm_rasa_process.process.terminate()
|
|
82
|
+
warm_rasa_processes = []
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def start_rasa_process(cwd: str, arguments: List[str]) -> WarmRasaProcess:
|
|
86
|
+
"""Start a Rasa process.
|
|
87
|
+
|
|
88
|
+
This will start a Rasa process with the given current working directory
|
|
89
|
+
and arguments. The process will be a warm one, meaning that it has already
|
|
90
|
+
imported all necessary modules.
|
|
91
|
+
"""
|
|
92
|
+
warm_rasa_process = _get_warm_rasa_process()
|
|
93
|
+
_pass_arguments_to_process(warm_rasa_process.process, cwd, arguments)
|
|
94
|
+
return warm_rasa_process
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _get_warm_rasa_process() -> WarmRasaProcess:
|
|
98
|
+
"""Get a warm Rasa process.
|
|
99
|
+
|
|
100
|
+
This will return a warm Rasa process from the pool and create a
|
|
101
|
+
new one to replace it.
|
|
102
|
+
"""
|
|
103
|
+
global warm_rasa_processes
|
|
104
|
+
|
|
105
|
+
if not warm_rasa_processes:
|
|
106
|
+
warm_rasa_processes = [_create_warm_rasa_process()]
|
|
107
|
+
|
|
108
|
+
previous_warm_rasa_process = warm_rasa_processes.pop(0)
|
|
109
|
+
|
|
110
|
+
if previous_warm_rasa_process.process.poll() is not None:
|
|
111
|
+
# process has finished (for some reason...)
|
|
112
|
+
# back up plan is to create a new one on the spot.
|
|
113
|
+
# this should not happen, but let's be safe
|
|
114
|
+
structlogger.warning(
|
|
115
|
+
"model_trainer.warm_rasa_process_finished_unexpectedly",
|
|
116
|
+
pid=previous_warm_rasa_process.process.pid,
|
|
117
|
+
)
|
|
118
|
+
previous_warm_rasa_process = _create_warm_rasa_process()
|
|
119
|
+
|
|
120
|
+
warm_rasa_processes.append(_create_warm_rasa_process())
|
|
121
|
+
return previous_warm_rasa_process
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _pass_arguments_to_process(
|
|
125
|
+
process: subprocess.Popen, cwd: str, arguments: List[str]
|
|
126
|
+
) -> None:
|
|
127
|
+
"""Pass arguments to a warm Rasa process.
|
|
128
|
+
|
|
129
|
+
The process is waiting for input on stdin. We pass the current working
|
|
130
|
+
directory and the arguments to run a Rasa CLI command.
|
|
131
|
+
"""
|
|
132
|
+
arguments_string = " ".join(arguments)
|
|
133
|
+
# send arguments to stdin
|
|
134
|
+
process.stdin.write(cwd.encode()) # type: ignore[union-attr]
|
|
135
|
+
process.stdin.write("\n".encode()) # type: ignore[union-attr]
|
|
136
|
+
process.stdin.write(arguments_string.encode()) # type: ignore[union-attr]
|
|
137
|
+
process.stdin.write("\n".encode()) # type: ignore[union-attr]
|
|
138
|
+
process.stdin.flush() # type: ignore[union-attr]
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def warmup() -> None:
|
|
142
|
+
"""Import all necessary modules to warm up the process.
|
|
143
|
+
|
|
144
|
+
This should include all the modules that take a long time to import.
|
|
145
|
+
We import them now, so that the training / deployment can later
|
|
146
|
+
directly start.
|
|
147
|
+
"""
|
|
148
|
+
try:
|
|
149
|
+
import presidio_analyzer # noqa: F401
|
|
150
|
+
import litellm # noqa: F401
|
|
151
|
+
import langchain # noqa: F401
|
|
152
|
+
import tensorflow # noqa: F401
|
|
153
|
+
import matplotlib # noqa: F401
|
|
154
|
+
import pandas # noqa: F401
|
|
155
|
+
import numpy # noqa: F401
|
|
156
|
+
import spacy # noqa: F401
|
|
157
|
+
import rasa.validator # noqa: F401
|
|
158
|
+
except ImportError:
|
|
159
|
+
pass
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def warm_rasa_main() -> None:
|
|
163
|
+
"""Entry point for processes waiting for their command to run.
|
|
164
|
+
|
|
165
|
+
The process will wait for the current working directory and the command
|
|
166
|
+
to run. These will be send on stdin by the parent process. After receiving
|
|
167
|
+
the input, we will kick things of starting or running a bot.
|
|
168
|
+
|
|
169
|
+
Uses the normal Rasa CLI entry point (e.g. `rasa train --data ...`).
|
|
170
|
+
"""
|
|
171
|
+
warmup()
|
|
172
|
+
|
|
173
|
+
cwd = input()
|
|
174
|
+
|
|
175
|
+
# this should be `train --data ...` or similar
|
|
176
|
+
cli_arguments_str = input()
|
|
177
|
+
# splits the arguments string into a list of arguments as expected by `argparse`
|
|
178
|
+
arguments = shlex.split(cli_arguments_str)
|
|
179
|
+
|
|
180
|
+
# needed to make sure the passed arguments are relative to the working directory
|
|
181
|
+
os.chdir(cwd)
|
|
182
|
+
|
|
183
|
+
main(arguments)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
if __name__ == "__main__":
|
|
187
|
+
warm_rasa_main()
|