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,741 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
from typing import Text, List, Optional, Union, Any, Dict, Set
|
|
3
|
+
import itertools
|
|
4
|
+
import logging
|
|
5
|
+
import structlog
|
|
6
|
+
import json
|
|
7
|
+
|
|
8
|
+
from rasa.core.actions import action
|
|
9
|
+
from rasa.core.actions.loops import LoopAction
|
|
10
|
+
from rasa.core.channels import OutputChannel
|
|
11
|
+
from rasa.shared.core.domain import Domain, KEY_SLOTS
|
|
12
|
+
from rasa.shared.core.constants import SlotMappingType, SLOT_MAPPINGS, MAPPING_TYPE
|
|
13
|
+
|
|
14
|
+
from rasa.core.actions.action import RemoteAction
|
|
15
|
+
from rasa.core.actions.action_exceptions import ActionExecutionRejection
|
|
16
|
+
from rasa.shared.core.constants import (
|
|
17
|
+
ACTION_EXTRACT_SLOTS,
|
|
18
|
+
ACTION_LISTEN_NAME,
|
|
19
|
+
REQUESTED_SLOT,
|
|
20
|
+
)
|
|
21
|
+
from rasa.shared.constants import UTTER_PREFIX
|
|
22
|
+
from rasa.shared.core.events import (
|
|
23
|
+
Event,
|
|
24
|
+
SlotSet,
|
|
25
|
+
ActionExecuted,
|
|
26
|
+
ActiveLoop,
|
|
27
|
+
ActionExecutionRejected,
|
|
28
|
+
Restarted,
|
|
29
|
+
)
|
|
30
|
+
from rasa.core.nlg import NaturalLanguageGenerator
|
|
31
|
+
from rasa.shared.core.slot_mappings import SlotMapping
|
|
32
|
+
from rasa.shared.core.slots import ListSlot
|
|
33
|
+
from rasa.shared.core.trackers import DialogueStateTracker
|
|
34
|
+
from rasa.utils.endpoints import EndpointConfig
|
|
35
|
+
|
|
36
|
+
logger = logging.getLogger(__name__)
|
|
37
|
+
structlogger = structlog.get_logger()
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class FormAction(LoopAction):
|
|
41
|
+
"""Action which implements and executes the form logic."""
|
|
42
|
+
|
|
43
|
+
def __init__(
|
|
44
|
+
self, form_name: Text, action_endpoint: Optional[EndpointConfig]
|
|
45
|
+
) -> None:
|
|
46
|
+
"""Creates a `FormAction`.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
form_name: Name of the form.
|
|
50
|
+
action_endpoint: Endpoint to execute custom actions.
|
|
51
|
+
"""
|
|
52
|
+
self._form_name = form_name
|
|
53
|
+
self.action_endpoint = action_endpoint
|
|
54
|
+
# creating it requires domain, which we don't have in init
|
|
55
|
+
# we'll create it on the first call
|
|
56
|
+
self._unique_entity_mappings: Set[Text] = set()
|
|
57
|
+
self._have_unique_entity_mappings_been_initialized = False
|
|
58
|
+
|
|
59
|
+
def name(self) -> Text:
|
|
60
|
+
"""Return the form name."""
|
|
61
|
+
return self._form_name
|
|
62
|
+
|
|
63
|
+
def required_slots(self, domain: Domain) -> List[Text]:
|
|
64
|
+
"""A list of required slots that the form has to fill.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
A list of slot names.
|
|
68
|
+
"""
|
|
69
|
+
return domain.required_slots_for_form(self.name())
|
|
70
|
+
|
|
71
|
+
def from_entity(
|
|
72
|
+
self,
|
|
73
|
+
entity: Text,
|
|
74
|
+
intent: Optional[Union[Text, List[Text]]] = None,
|
|
75
|
+
not_intent: Optional[Union[Text, List[Text]]] = None,
|
|
76
|
+
role: Optional[Text] = None,
|
|
77
|
+
group: Optional[Text] = None,
|
|
78
|
+
) -> Dict[Text, Any]:
|
|
79
|
+
"""A dictionary for slot mapping to extract slot value.
|
|
80
|
+
|
|
81
|
+
From:
|
|
82
|
+
- an extracted entity
|
|
83
|
+
- conditioned on
|
|
84
|
+
- intent if it is not None
|
|
85
|
+
- not_intent if it is not None,
|
|
86
|
+
meaning user intent should not be this intent
|
|
87
|
+
- role if it is not None
|
|
88
|
+
- group if it is not None
|
|
89
|
+
"""
|
|
90
|
+
intent, not_intent = (
|
|
91
|
+
SlotMapping.to_list(intent),
|
|
92
|
+
SlotMapping.to_list(not_intent),
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
"type": str(SlotMappingType.FROM_ENTITY),
|
|
97
|
+
"entity": entity,
|
|
98
|
+
"intent": intent,
|
|
99
|
+
"not_intent": not_intent,
|
|
100
|
+
"role": role,
|
|
101
|
+
"group": group,
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
def get_mappings_for_slot(
|
|
105
|
+
self, slot_to_fill: Text, domain: Domain
|
|
106
|
+
) -> List[Dict[Text, Any]]:
|
|
107
|
+
"""Get mappings for requested slot.
|
|
108
|
+
|
|
109
|
+
If None, map requested slot to an entity with the same name
|
|
110
|
+
"""
|
|
111
|
+
domain_slots = domain.as_dict().get(KEY_SLOTS, {})
|
|
112
|
+
requested_slot_mappings = domain_slots.get(slot_to_fill, {}).get("mappings", [])
|
|
113
|
+
|
|
114
|
+
# check provided slot mappings
|
|
115
|
+
for requested_slot_mapping in requested_slot_mappings:
|
|
116
|
+
if (
|
|
117
|
+
not isinstance(requested_slot_mapping, dict)
|
|
118
|
+
or requested_slot_mapping.get("type") is None
|
|
119
|
+
):
|
|
120
|
+
raise TypeError("Provided incompatible slot mapping")
|
|
121
|
+
|
|
122
|
+
return requested_slot_mappings
|
|
123
|
+
|
|
124
|
+
def _create_unique_entity_mappings(self, domain: Domain) -> Set[Text]:
|
|
125
|
+
"""Finds mappings of type `from_entity` that uniquely set a slot.
|
|
126
|
+
|
|
127
|
+
For example in the following form:
|
|
128
|
+
some_form:
|
|
129
|
+
departure_city:
|
|
130
|
+
- type: from_entity
|
|
131
|
+
entity: city
|
|
132
|
+
role: from
|
|
133
|
+
- type: from_entity
|
|
134
|
+
entity: city
|
|
135
|
+
arrival_city:
|
|
136
|
+
- type: from_entity
|
|
137
|
+
entity: city
|
|
138
|
+
role: to
|
|
139
|
+
- type: from_entity
|
|
140
|
+
entity: city
|
|
141
|
+
|
|
142
|
+
An entity `city` with a role `from` uniquely sets the slot `departure_city`
|
|
143
|
+
and an entity `city` with a role `to` uniquely sets the slot `arrival_city`,
|
|
144
|
+
so corresponding mappings are unique.
|
|
145
|
+
But an entity `city` without a role can fill both `departure_city`
|
|
146
|
+
and `arrival_city`, so corresponding mapping is not unique.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
domain: The domain.
|
|
150
|
+
|
|
151
|
+
Returns:
|
|
152
|
+
A set of json dumps of unique mappings of type `from_entity`.
|
|
153
|
+
"""
|
|
154
|
+
unique_entity_slot_mappings: Set[Text] = set()
|
|
155
|
+
duplicate_entity_slot_mappings: Set[Text] = set()
|
|
156
|
+
domain_slots = domain.as_dict().get(KEY_SLOTS, {})
|
|
157
|
+
for slot in domain.required_slots_for_form(self.name()):
|
|
158
|
+
for slot_mapping in domain_slots.get(slot, {}).get(SLOT_MAPPINGS, []):
|
|
159
|
+
if slot_mapping.get(MAPPING_TYPE) == str(SlotMappingType.FROM_ENTITY):
|
|
160
|
+
mapping_as_string = json.dumps(slot_mapping, sort_keys=True)
|
|
161
|
+
if mapping_as_string in unique_entity_slot_mappings:
|
|
162
|
+
unique_entity_slot_mappings.remove(mapping_as_string)
|
|
163
|
+
duplicate_entity_slot_mappings.add(mapping_as_string)
|
|
164
|
+
elif mapping_as_string not in duplicate_entity_slot_mappings:
|
|
165
|
+
unique_entity_slot_mappings.add(mapping_as_string)
|
|
166
|
+
|
|
167
|
+
return unique_entity_slot_mappings
|
|
168
|
+
|
|
169
|
+
def entity_mapping_is_unique(
|
|
170
|
+
self, slot_mapping: Dict[Text, Any], domain: Domain
|
|
171
|
+
) -> bool:
|
|
172
|
+
"""Verifies if the from_entity mapping is unique."""
|
|
173
|
+
if not self._have_unique_entity_mappings_been_initialized:
|
|
174
|
+
# create unique entity mappings on the first call
|
|
175
|
+
self._unique_entity_mappings = self._create_unique_entity_mappings(domain)
|
|
176
|
+
self._have_unique_entity_mappings_been_initialized = True
|
|
177
|
+
|
|
178
|
+
mapping_as_string = json.dumps(slot_mapping, sort_keys=True)
|
|
179
|
+
return mapping_as_string in self._unique_entity_mappings
|
|
180
|
+
|
|
181
|
+
@staticmethod
|
|
182
|
+
def get_entity_value_for_slot(
|
|
183
|
+
name: Text,
|
|
184
|
+
tracker: "DialogueStateTracker",
|
|
185
|
+
slot_to_be_filled: Text,
|
|
186
|
+
role: Optional[Text] = None,
|
|
187
|
+
group: Optional[Text] = None,
|
|
188
|
+
) -> Any:
|
|
189
|
+
"""Extract entities for given name and optional role and group.
|
|
190
|
+
|
|
191
|
+
Args:
|
|
192
|
+
name: entity type (name) of interest
|
|
193
|
+
tracker: the tracker
|
|
194
|
+
slot_to_be_filled: Slot which is supposed to be filled by this entity.
|
|
195
|
+
role: optional entity role of interest
|
|
196
|
+
group: optional entity group of interest
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
Value of entity.
|
|
200
|
+
"""
|
|
201
|
+
# list is used to cover the case of list slot type
|
|
202
|
+
value = list(
|
|
203
|
+
tracker.get_latest_entity_values(name, entity_group=group, entity_role=role)
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
if isinstance(tracker.slots.get(slot_to_be_filled), ListSlot):
|
|
207
|
+
return value
|
|
208
|
+
|
|
209
|
+
if len(value) == 0:
|
|
210
|
+
return None
|
|
211
|
+
|
|
212
|
+
if len(value) == 1:
|
|
213
|
+
return value[0]
|
|
214
|
+
|
|
215
|
+
return value
|
|
216
|
+
|
|
217
|
+
def get_slot_to_fill(self, tracker: "DialogueStateTracker") -> Optional[str]:
|
|
218
|
+
"""Gets the name of the slot which should be filled next.
|
|
219
|
+
|
|
220
|
+
When switching to another form, the requested slot setting is still from the
|
|
221
|
+
previous form and must be ignored.
|
|
222
|
+
|
|
223
|
+
Returns:
|
|
224
|
+
The slot name or `None`
|
|
225
|
+
"""
|
|
226
|
+
return (
|
|
227
|
+
tracker.get_slot(REQUESTED_SLOT)
|
|
228
|
+
if tracker.active_loop_name == self.name()
|
|
229
|
+
else None
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
async def validate_slots(
|
|
233
|
+
self,
|
|
234
|
+
slot_candidates: Dict[Text, Any],
|
|
235
|
+
tracker: "DialogueStateTracker",
|
|
236
|
+
domain: Domain,
|
|
237
|
+
output_channel: OutputChannel,
|
|
238
|
+
nlg: NaturalLanguageGenerator,
|
|
239
|
+
) -> List[Union[SlotSet, Event]]:
|
|
240
|
+
"""Validate the extracted slots.
|
|
241
|
+
|
|
242
|
+
If a custom action is available for validating the slots, we call it to validate
|
|
243
|
+
them. Otherwise there is no validation.
|
|
244
|
+
|
|
245
|
+
Args:
|
|
246
|
+
slot_candidates: Extracted slots which are candidates to fill the slots
|
|
247
|
+
required by the form.
|
|
248
|
+
tracker: The current conversation tracker.
|
|
249
|
+
domain: The current model domain.
|
|
250
|
+
output_channel: The output channel which can be used to send messages
|
|
251
|
+
to the user.
|
|
252
|
+
nlg: `NaturalLanguageGenerator` to use for response generation.
|
|
253
|
+
|
|
254
|
+
Returns:
|
|
255
|
+
The validation events including potential bot messages and `SlotSet` events
|
|
256
|
+
for the validated slots, if the custom form validation action is present in
|
|
257
|
+
domain actions.
|
|
258
|
+
Otherwise, returns empty list since the extracted slots already have
|
|
259
|
+
corresponding `SlotSet` events in the tracker.
|
|
260
|
+
"""
|
|
261
|
+
structlogger.debug(
|
|
262
|
+
"forms.slots.validate", slot_candidates=copy.deepcopy(slot_candidates)
|
|
263
|
+
)
|
|
264
|
+
events: List[Union[SlotSet, Event]] = [
|
|
265
|
+
SlotSet(slot_name, value) for slot_name, value in slot_candidates.items()
|
|
266
|
+
]
|
|
267
|
+
|
|
268
|
+
validate_name = f"validate_{self.name()}"
|
|
269
|
+
|
|
270
|
+
if validate_name not in domain.action_names_or_texts:
|
|
271
|
+
return []
|
|
272
|
+
|
|
273
|
+
# create temporary tracker with only the SlotSet events added
|
|
274
|
+
# since last user utterance
|
|
275
|
+
_tracker = self._temporary_tracker(tracker, events, domain)
|
|
276
|
+
|
|
277
|
+
_action = RemoteAction(validate_name, self.action_endpoint)
|
|
278
|
+
validate_events = await _action.run(output_channel, nlg, _tracker, domain)
|
|
279
|
+
|
|
280
|
+
# Only return the validated SlotSet events by the custom form validation action
|
|
281
|
+
# to avoid adding duplicate SlotSet events for slots that are already valid.
|
|
282
|
+
return validate_events
|
|
283
|
+
|
|
284
|
+
def _temporary_tracker(
|
|
285
|
+
self,
|
|
286
|
+
current_tracker: DialogueStateTracker,
|
|
287
|
+
additional_events: List[Event],
|
|
288
|
+
domain: Domain,
|
|
289
|
+
) -> DialogueStateTracker:
|
|
290
|
+
return DialogueStateTracker.from_events(
|
|
291
|
+
current_tracker.sender_id,
|
|
292
|
+
current_tracker.events_after_latest_restart()
|
|
293
|
+
# Insert SlotSet event to make sure REQUESTED_SLOT belongs to active form.
|
|
294
|
+
+ [SlotSet(REQUESTED_SLOT, self.get_slot_to_fill(current_tracker))]
|
|
295
|
+
# Insert form execution event so that it's clearly distinguishable which
|
|
296
|
+
# events were newly added.
|
|
297
|
+
+ [ActionExecuted(self.name())]
|
|
298
|
+
+ additional_events,
|
|
299
|
+
slots=domain.slots,
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
def _user_rejected_manually(self, validation_events: List[Event]) -> bool:
|
|
303
|
+
"""Checks if user rejected the form execution during a slot_validation.
|
|
304
|
+
|
|
305
|
+
Args:
|
|
306
|
+
validation_events: Events returned by the custom slot_validation action
|
|
307
|
+
|
|
308
|
+
Returns:
|
|
309
|
+
True if the validation_events include an ActionExecutionRejected event,
|
|
310
|
+
else False.
|
|
311
|
+
"""
|
|
312
|
+
return any(
|
|
313
|
+
isinstance(event, ActionExecutionRejected) for event in validation_events
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
@staticmethod
|
|
317
|
+
def _get_events_since_last_user_uttered(
|
|
318
|
+
tracker: "DialogueStateTracker",
|
|
319
|
+
) -> List[SlotSet]:
|
|
320
|
+
# TODO: Better way to get this latest_message index is through an instance
|
|
321
|
+
# variable, eg. tracker.latest_message_index
|
|
322
|
+
index_from_end = next(
|
|
323
|
+
(
|
|
324
|
+
i
|
|
325
|
+
for i, event in enumerate(reversed(tracker.events))
|
|
326
|
+
if event == Restarted() or event == tracker.latest_message
|
|
327
|
+
),
|
|
328
|
+
len(tracker.events) - 1,
|
|
329
|
+
)
|
|
330
|
+
index = len(tracker.events) - index_from_end - 1
|
|
331
|
+
events_since_last_user_uttered = [
|
|
332
|
+
event
|
|
333
|
+
for event in itertools.islice(tracker.events, index, None)
|
|
334
|
+
if isinstance(event, SlotSet)
|
|
335
|
+
]
|
|
336
|
+
|
|
337
|
+
return events_since_last_user_uttered
|
|
338
|
+
|
|
339
|
+
def _update_slot_values(
|
|
340
|
+
self,
|
|
341
|
+
event: SlotSet,
|
|
342
|
+
tracker: "DialogueStateTracker",
|
|
343
|
+
domain: Domain,
|
|
344
|
+
slot_values: Dict[Text, Any],
|
|
345
|
+
) -> Dict[Text, Any]:
|
|
346
|
+
slot_values[event.key] = event.value
|
|
347
|
+
|
|
348
|
+
return slot_values
|
|
349
|
+
|
|
350
|
+
def _add_dynamic_slots_requested_by_dynamic_forms(
|
|
351
|
+
self, tracker: "DialogueStateTracker", domain: Domain
|
|
352
|
+
) -> Set[Text]:
|
|
353
|
+
required_slots = set(self.required_slots(domain))
|
|
354
|
+
requested_slot = self.get_slot_to_fill(tracker)
|
|
355
|
+
|
|
356
|
+
if requested_slot:
|
|
357
|
+
required_slots.add(requested_slot)
|
|
358
|
+
|
|
359
|
+
return required_slots
|
|
360
|
+
|
|
361
|
+
def _get_slot_extractions(
|
|
362
|
+
self, tracker: "DialogueStateTracker", domain: Domain
|
|
363
|
+
) -> Dict[Text, Any]:
|
|
364
|
+
events_since_last_user_uttered = FormAction._get_events_since_last_user_uttered(
|
|
365
|
+
tracker
|
|
366
|
+
)
|
|
367
|
+
slot_values: Dict[Text, Any] = {}
|
|
368
|
+
|
|
369
|
+
required_slots = self._add_dynamic_slots_requested_by_dynamic_forms(
|
|
370
|
+
tracker, domain
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
for event in events_since_last_user_uttered:
|
|
374
|
+
if event.key not in required_slots:
|
|
375
|
+
continue
|
|
376
|
+
|
|
377
|
+
slot_values = self._update_slot_values(event, tracker, domain, slot_values)
|
|
378
|
+
|
|
379
|
+
return slot_values
|
|
380
|
+
|
|
381
|
+
async def validate(
|
|
382
|
+
self,
|
|
383
|
+
tracker: "DialogueStateTracker",
|
|
384
|
+
domain: Domain,
|
|
385
|
+
output_channel: OutputChannel,
|
|
386
|
+
nlg: NaturalLanguageGenerator,
|
|
387
|
+
) -> List[Union[SlotSet, Event]]:
|
|
388
|
+
"""Extract and validate value of requested slot and other slots.
|
|
389
|
+
|
|
390
|
+
Returns:
|
|
391
|
+
The new validation events created by the custom form validation action
|
|
392
|
+
|
|
393
|
+
Raises:
|
|
394
|
+
ActionExecutionRejection exception to reject execution of form action
|
|
395
|
+
if nothing was extracted.
|
|
396
|
+
|
|
397
|
+
Subclass this method to add custom validation and rejection logic.
|
|
398
|
+
"""
|
|
399
|
+
extracted_slot_values = self._get_slot_extractions(tracker, domain)
|
|
400
|
+
|
|
401
|
+
validation_events = await self.validate_slots(
|
|
402
|
+
extracted_slot_values, tracker, domain, output_channel, nlg
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
some_slots_were_validated = any(
|
|
406
|
+
isinstance(event, SlotSet) and not event.key == REQUESTED_SLOT
|
|
407
|
+
for event in validation_events
|
|
408
|
+
# Ignore `SlotSet`s for `REQUESTED_SLOT` as that's not a slot which needs
|
|
409
|
+
# to be filled by the user.
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
# extract requested slot
|
|
413
|
+
slot_to_fill = self.get_slot_to_fill(tracker)
|
|
414
|
+
|
|
415
|
+
if (
|
|
416
|
+
slot_to_fill
|
|
417
|
+
and not extracted_slot_values
|
|
418
|
+
and not some_slots_were_validated
|
|
419
|
+
and not self._user_rejected_manually(validation_events)
|
|
420
|
+
):
|
|
421
|
+
# reject to execute the form action
|
|
422
|
+
# if some slot was requested but nothing was extracted
|
|
423
|
+
# it will allow other policies to predict another action
|
|
424
|
+
#
|
|
425
|
+
# don't raise it here if the user rejected manually, to allow slots other
|
|
426
|
+
# than the requested slot to be filled.
|
|
427
|
+
#
|
|
428
|
+
raise ActionExecutionRejection(
|
|
429
|
+
self.name(),
|
|
430
|
+
f"Failed to extract slot {slot_to_fill} with action {self.name()}",
|
|
431
|
+
)
|
|
432
|
+
return validation_events
|
|
433
|
+
|
|
434
|
+
async def request_next_slot(
|
|
435
|
+
self,
|
|
436
|
+
tracker: "DialogueStateTracker",
|
|
437
|
+
domain: Domain,
|
|
438
|
+
output_channel: OutputChannel,
|
|
439
|
+
nlg: NaturalLanguageGenerator,
|
|
440
|
+
events_so_far: List[Event],
|
|
441
|
+
) -> List[Union[SlotSet, Event]]:
|
|
442
|
+
"""Request the next slot and response if needed, else return `None`."""
|
|
443
|
+
request_slot_events: List[Event] = []
|
|
444
|
+
|
|
445
|
+
if await self.is_done(output_channel, nlg, tracker, domain, events_so_far):
|
|
446
|
+
# The custom action for slot validation decided to stop the form early
|
|
447
|
+
return [SlotSet(REQUESTED_SLOT, None)]
|
|
448
|
+
|
|
449
|
+
slot_to_request = next(
|
|
450
|
+
(
|
|
451
|
+
event.value
|
|
452
|
+
for event in events_so_far
|
|
453
|
+
if isinstance(event, SlotSet) and event.key == REQUESTED_SLOT
|
|
454
|
+
),
|
|
455
|
+
None,
|
|
456
|
+
)
|
|
457
|
+
|
|
458
|
+
temp_tracker = self._temporary_tracker(tracker, events_so_far, domain)
|
|
459
|
+
|
|
460
|
+
if not slot_to_request:
|
|
461
|
+
slot_to_request = self._find_next_slot_to_request(temp_tracker, domain)
|
|
462
|
+
request_slot_events.append(SlotSet(REQUESTED_SLOT, slot_to_request))
|
|
463
|
+
|
|
464
|
+
if slot_to_request:
|
|
465
|
+
bot_message_events = await self._ask_for_slot(
|
|
466
|
+
domain, nlg, output_channel, slot_to_request, temp_tracker
|
|
467
|
+
)
|
|
468
|
+
return request_slot_events + bot_message_events
|
|
469
|
+
|
|
470
|
+
# no more required slots to fill
|
|
471
|
+
return [SlotSet(REQUESTED_SLOT, None)]
|
|
472
|
+
|
|
473
|
+
def _find_next_slot_to_request(
|
|
474
|
+
self, tracker: DialogueStateTracker, domain: Domain
|
|
475
|
+
) -> Optional[Text]:
|
|
476
|
+
return next(
|
|
477
|
+
(
|
|
478
|
+
slot
|
|
479
|
+
for slot in self.required_slots(domain)
|
|
480
|
+
if self._should_request_slot(tracker, slot)
|
|
481
|
+
),
|
|
482
|
+
None,
|
|
483
|
+
)
|
|
484
|
+
|
|
485
|
+
def _name_of_utterance(self, domain: Domain, slot_name: Text) -> Optional[Text]:
|
|
486
|
+
search_path = [
|
|
487
|
+
f"action_ask_{self._form_name}_{slot_name}",
|
|
488
|
+
f"{UTTER_PREFIX}ask_{self._form_name}_{slot_name}",
|
|
489
|
+
f"action_ask_{slot_name}",
|
|
490
|
+
f"{UTTER_PREFIX}ask_{slot_name}",
|
|
491
|
+
]
|
|
492
|
+
|
|
493
|
+
found_actions = (
|
|
494
|
+
action_name
|
|
495
|
+
for action_name in search_path
|
|
496
|
+
if action_name in domain.action_names_or_texts
|
|
497
|
+
)
|
|
498
|
+
|
|
499
|
+
return next(found_actions, None)
|
|
500
|
+
|
|
501
|
+
async def _ask_for_slot(
|
|
502
|
+
self,
|
|
503
|
+
domain: Domain,
|
|
504
|
+
nlg: NaturalLanguageGenerator,
|
|
505
|
+
output_channel: OutputChannel,
|
|
506
|
+
slot_name: Text,
|
|
507
|
+
tracker: DialogueStateTracker,
|
|
508
|
+
) -> List[Event]:
|
|
509
|
+
logger.debug(f"Request next slot '{slot_name}'")
|
|
510
|
+
|
|
511
|
+
action_name_to_ask_for_next_slot = self._name_of_utterance(domain, slot_name)
|
|
512
|
+
if not action_name_to_ask_for_next_slot:
|
|
513
|
+
# Use a debug log as the user might have asked as part of a custom action
|
|
514
|
+
logger.debug(
|
|
515
|
+
f"There was no action found to ask for slot '{slot_name}' "
|
|
516
|
+
f"name to be filled."
|
|
517
|
+
)
|
|
518
|
+
return []
|
|
519
|
+
|
|
520
|
+
action_to_ask_for_next_slot = action.action_for_name_or_text(
|
|
521
|
+
action_name_to_ask_for_next_slot, domain, self.action_endpoint
|
|
522
|
+
)
|
|
523
|
+
return await action_to_ask_for_next_slot.run(
|
|
524
|
+
output_channel, nlg, tracker, domain
|
|
525
|
+
)
|
|
526
|
+
|
|
527
|
+
async def _validate_if_required(
|
|
528
|
+
self,
|
|
529
|
+
tracker: "DialogueStateTracker",
|
|
530
|
+
domain: Domain,
|
|
531
|
+
output_channel: OutputChannel,
|
|
532
|
+
nlg: NaturalLanguageGenerator,
|
|
533
|
+
) -> List[Event]:
|
|
534
|
+
"""Return a list of events from `self.validate(...)`.
|
|
535
|
+
|
|
536
|
+
Validation is required if:
|
|
537
|
+
- the form is active
|
|
538
|
+
- the form is called after `action_listen`
|
|
539
|
+
- form validation was not cancelled
|
|
540
|
+
"""
|
|
541
|
+
# no active_loop means that it is called during activation
|
|
542
|
+
needs_validation = not tracker.active_loop or (
|
|
543
|
+
tracker.latest_action_name == ACTION_LISTEN_NAME
|
|
544
|
+
and not tracker.is_active_loop_interrupted
|
|
545
|
+
)
|
|
546
|
+
|
|
547
|
+
if needs_validation:
|
|
548
|
+
structlogger.debug(
|
|
549
|
+
"forms.validation.required",
|
|
550
|
+
tracker_latest_message=copy.deepcopy(tracker.latest_message),
|
|
551
|
+
)
|
|
552
|
+
return await self.validate(tracker, domain, output_channel, nlg)
|
|
553
|
+
else:
|
|
554
|
+
# Needed to determine which slots to request although there are no slots
|
|
555
|
+
# to actually validate, which happens when coming back to the form after
|
|
556
|
+
# an unhappy path
|
|
557
|
+
return await self.validate_slots({}, tracker, domain, output_channel, nlg)
|
|
558
|
+
|
|
559
|
+
@staticmethod
|
|
560
|
+
def _should_request_slot(tracker: "DialogueStateTracker", slot_name: Text) -> bool:
|
|
561
|
+
"""Check whether form action should request given slot."""
|
|
562
|
+
return tracker.get_slot(slot_name) is None
|
|
563
|
+
|
|
564
|
+
async def activate(
|
|
565
|
+
self,
|
|
566
|
+
output_channel: "OutputChannel",
|
|
567
|
+
nlg: "NaturalLanguageGenerator",
|
|
568
|
+
tracker: "DialogueStateTracker",
|
|
569
|
+
domain: "Domain",
|
|
570
|
+
metadata: Optional[Dict[Text, Any]] = None,
|
|
571
|
+
) -> List[Event]:
|
|
572
|
+
"""Activate form if the form is called for the first time.
|
|
573
|
+
|
|
574
|
+
If activating, run action_extract_slots to fill slots with
|
|
575
|
+
mapping conditions from trigger intents.
|
|
576
|
+
Validate any required slots that can be filled, and return any `SlotSet`
|
|
577
|
+
events from the extraction and validation of these pre-filled slots.
|
|
578
|
+
|
|
579
|
+
Args:
|
|
580
|
+
output_channel: The output channel which can be used to send messages
|
|
581
|
+
to the user.
|
|
582
|
+
nlg: `NaturalLanguageGenerator` to use for response generation.
|
|
583
|
+
tracker: Current conversation tracker of the user.
|
|
584
|
+
domain: Current model domain.
|
|
585
|
+
|
|
586
|
+
Returns:
|
|
587
|
+
Events from the activation.
|
|
588
|
+
"""
|
|
589
|
+
logger.debug(f"Activated the form '{self.name()}'.")
|
|
590
|
+
# collect values of required slots filled before activation
|
|
591
|
+
prefilled_slots = {}
|
|
592
|
+
|
|
593
|
+
action_extract_slots = action.action_for_name_or_text(
|
|
594
|
+
ACTION_EXTRACT_SLOTS, domain, self.action_endpoint
|
|
595
|
+
)
|
|
596
|
+
|
|
597
|
+
logger.debug(
|
|
598
|
+
f"Executing default action '{ACTION_EXTRACT_SLOTS}' at form activation."
|
|
599
|
+
)
|
|
600
|
+
|
|
601
|
+
extraction_events = await action_extract_slots.run(
|
|
602
|
+
output_channel, nlg, tracker, domain, metadata
|
|
603
|
+
)
|
|
604
|
+
|
|
605
|
+
events_as_str = "\n".join(str(e) for e in extraction_events)
|
|
606
|
+
logger.debug(
|
|
607
|
+
f"The execution of '{ACTION_EXTRACT_SLOTS}' resulted in "
|
|
608
|
+
f"these events: {events_as_str}."
|
|
609
|
+
)
|
|
610
|
+
|
|
611
|
+
tracker.update_with_events(extraction_events)
|
|
612
|
+
|
|
613
|
+
for slot_name in self.required_slots(domain):
|
|
614
|
+
if not self._should_request_slot(tracker, slot_name):
|
|
615
|
+
prefilled_slots[slot_name] = tracker.get_slot(slot_name)
|
|
616
|
+
|
|
617
|
+
if not prefilled_slots:
|
|
618
|
+
logger.debug("No pre-filled required slots to validate.")
|
|
619
|
+
else:
|
|
620
|
+
structlogger.debug(
|
|
621
|
+
"forms.validate.prefilled_slots",
|
|
622
|
+
prefilled_slots=copy.deepcopy(prefilled_slots),
|
|
623
|
+
)
|
|
624
|
+
|
|
625
|
+
validate_name = f"validate_{self.name()}"
|
|
626
|
+
|
|
627
|
+
if validate_name not in domain.action_names_or_texts:
|
|
628
|
+
logger.debug(
|
|
629
|
+
f"There is no validation action '{validate_name}' "
|
|
630
|
+
f"to execute at form activation."
|
|
631
|
+
)
|
|
632
|
+
return [event for event in extraction_events if isinstance(event, SlotSet)]
|
|
633
|
+
|
|
634
|
+
logger.debug(
|
|
635
|
+
f"Executing validation action '{validate_name}' at form activation."
|
|
636
|
+
)
|
|
637
|
+
|
|
638
|
+
validated_events = await self.validate_slots(
|
|
639
|
+
prefilled_slots, tracker, domain, output_channel, nlg
|
|
640
|
+
)
|
|
641
|
+
|
|
642
|
+
validated_slot_names = [
|
|
643
|
+
event.key for event in validated_events if isinstance(event, SlotSet)
|
|
644
|
+
]
|
|
645
|
+
|
|
646
|
+
return validated_events + [
|
|
647
|
+
event
|
|
648
|
+
for event in extraction_events
|
|
649
|
+
if isinstance(event, SlotSet) and event.key not in validated_slot_names
|
|
650
|
+
]
|
|
651
|
+
|
|
652
|
+
async def do(
|
|
653
|
+
self,
|
|
654
|
+
output_channel: "OutputChannel",
|
|
655
|
+
nlg: "NaturalLanguageGenerator",
|
|
656
|
+
tracker: "DialogueStateTracker",
|
|
657
|
+
domain: "Domain",
|
|
658
|
+
events_so_far: List[Event],
|
|
659
|
+
) -> List[Event]:
|
|
660
|
+
"""Executes form loop after activation."""
|
|
661
|
+
events: List[Event] = []
|
|
662
|
+
"""
|
|
663
|
+
Call to validation is not required when the slots are already validated
|
|
664
|
+
at the time of form activation.
|
|
665
|
+
events_so_far:
|
|
666
|
+
- empty when slots have not been validated.
|
|
667
|
+
- has SlotSet objects when already validated.
|
|
668
|
+
- ActiveLoop object when events have not been validated.
|
|
669
|
+
Hence the events are filtered to remove ActiveLoop object that was added
|
|
670
|
+
at the time of form activation.
|
|
671
|
+
"""
|
|
672
|
+
filtered_events = [
|
|
673
|
+
event for event in events_so_far if not isinstance(event, ActiveLoop)
|
|
674
|
+
]
|
|
675
|
+
if not filtered_events:
|
|
676
|
+
events = await self._validate_if_required(
|
|
677
|
+
tracker, domain, output_channel, nlg
|
|
678
|
+
)
|
|
679
|
+
|
|
680
|
+
if not self._user_rejected_manually(events):
|
|
681
|
+
events += await self.request_next_slot(
|
|
682
|
+
tracker, domain, output_channel, nlg, events_so_far + events
|
|
683
|
+
)
|
|
684
|
+
|
|
685
|
+
return events
|
|
686
|
+
|
|
687
|
+
async def is_done(
|
|
688
|
+
self,
|
|
689
|
+
output_channel: "OutputChannel",
|
|
690
|
+
nlg: "NaturalLanguageGenerator",
|
|
691
|
+
tracker: "DialogueStateTracker",
|
|
692
|
+
domain: "Domain",
|
|
693
|
+
events_so_far: List[Event],
|
|
694
|
+
) -> bool:
|
|
695
|
+
"""Checks if loop can be terminated."""
|
|
696
|
+
if any(isinstance(event, ActionExecutionRejected) for event in events_so_far):
|
|
697
|
+
return False
|
|
698
|
+
|
|
699
|
+
# Custom validation actions can decide to terminate the loop early by
|
|
700
|
+
# setting the requested slot to `None` or setting `ActiveLoop(None)`.
|
|
701
|
+
# We explicitly check only the last occurrences for each possible termination
|
|
702
|
+
# event instead of doing `return event in events_so_far` to make it possible
|
|
703
|
+
# to override termination events which were returned earlier.
|
|
704
|
+
return next(
|
|
705
|
+
(
|
|
706
|
+
event
|
|
707
|
+
for event in reversed(events_so_far)
|
|
708
|
+
if isinstance(event, SlotSet) and event.key == REQUESTED_SLOT
|
|
709
|
+
),
|
|
710
|
+
None,
|
|
711
|
+
) == SlotSet(REQUESTED_SLOT, None) or next(
|
|
712
|
+
(
|
|
713
|
+
event
|
|
714
|
+
for event in reversed(events_so_far)
|
|
715
|
+
if isinstance(event, ActiveLoop)
|
|
716
|
+
),
|
|
717
|
+
None,
|
|
718
|
+
) == ActiveLoop(None)
|
|
719
|
+
|
|
720
|
+
async def deactivate(self, *args: Any, **kwargs: Any) -> List[Event]:
|
|
721
|
+
"""Deactivates form."""
|
|
722
|
+
logger.debug(f"Deactivating the form '{self.name()}'")
|
|
723
|
+
return []
|
|
724
|
+
|
|
725
|
+
async def _activate_loop(
|
|
726
|
+
self,
|
|
727
|
+
output_channel: "OutputChannel",
|
|
728
|
+
nlg: "NaturalLanguageGenerator",
|
|
729
|
+
tracker: "DialogueStateTracker",
|
|
730
|
+
domain: "Domain",
|
|
731
|
+
metadata: Optional[Dict[Text, Any]] = None,
|
|
732
|
+
) -> List[Event]:
|
|
733
|
+
events = self._default_activation_events()
|
|
734
|
+
|
|
735
|
+
temp_tracker = tracker.copy()
|
|
736
|
+
temp_tracker.update_with_events(events)
|
|
737
|
+
events += await self.activate(
|
|
738
|
+
output_channel, nlg, temp_tracker, domain, metadata
|
|
739
|
+
)
|
|
740
|
+
|
|
741
|
+
return events
|