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,197 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from functools import partial
|
|
3
|
+
import json
|
|
4
|
+
from typing import (
|
|
5
|
+
TYPE_CHECKING,
|
|
6
|
+
Any,
|
|
7
|
+
Awaitable,
|
|
8
|
+
Callable,
|
|
9
|
+
Dict,
|
|
10
|
+
Optional,
|
|
11
|
+
Set,
|
|
12
|
+
Text,
|
|
13
|
+
)
|
|
14
|
+
from socketio import AsyncServer
|
|
15
|
+
|
|
16
|
+
import structlog
|
|
17
|
+
from sanic import response
|
|
18
|
+
from sanic.request import Request
|
|
19
|
+
import websockets
|
|
20
|
+
|
|
21
|
+
from rasa.core.channels.channel import InputChannel, OutputChannel
|
|
22
|
+
from rasa.shared.core.trackers import EventVerbosity
|
|
23
|
+
from rasa.shared.utils.cli import print_info
|
|
24
|
+
from sanic import Blueprint, Websocket, Sanic # type: ignore[attr-defined]
|
|
25
|
+
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from rasa.core.channels.channel import UserMessage
|
|
28
|
+
from sanic.request import Request
|
|
29
|
+
from sanic.response import HTTPResponse
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
INSPECT_TEMPLATE_PATH = "inspector/dist"
|
|
33
|
+
|
|
34
|
+
structlogger = structlog.get_logger()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class DevelopmentInspectProxy(InputChannel):
|
|
38
|
+
"""Development inspector to inspect channel communication.
|
|
39
|
+
|
|
40
|
+
It wraps a Rasa Pro input / output providing an inspect ui showing
|
|
41
|
+
the state of the conversation.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
def __init__(self, underlying: InputChannel, is_voice: bool = False) -> None:
|
|
45
|
+
"""Initializes the DevelopmentInspectProxy channel."""
|
|
46
|
+
super().__init__()
|
|
47
|
+
self.underlying = underlying
|
|
48
|
+
self.is_voice = is_voice
|
|
49
|
+
self.processor = None
|
|
50
|
+
self.tracker_stream = TrackerStream(get_tracker=self.get_tracker_state)
|
|
51
|
+
|
|
52
|
+
def name(self) -> Text: # type: ignore[override]
|
|
53
|
+
"""Channel name."""
|
|
54
|
+
return self.underlying.name()
|
|
55
|
+
|
|
56
|
+
@classmethod
|
|
57
|
+
def from_credentials(cls, credentials: Optional[Dict[Text, Any]]) -> "InputChannel":
|
|
58
|
+
raise NotImplementedError(
|
|
59
|
+
"Method `from_credentials` not supported for the inspect proxy."
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
def url_prefix(self) -> Text:
|
|
63
|
+
return self.underlying.name()
|
|
64
|
+
|
|
65
|
+
def get_output_channel(self) -> Optional["OutputChannel"]:
|
|
66
|
+
return self.underlying.get_output_channel()
|
|
67
|
+
|
|
68
|
+
def get_metadata(self, request: Request) -> Optional[Dict[Text, Any]]:
|
|
69
|
+
return self.underlying.get_metadata(request)
|
|
70
|
+
|
|
71
|
+
@staticmethod
|
|
72
|
+
def inspect_html_path() -> Text:
|
|
73
|
+
"""Returns the path to the inspect.html file."""
|
|
74
|
+
import pkg_resources
|
|
75
|
+
|
|
76
|
+
return pkg_resources.resource_filename(__name__, INSPECT_TEMPLATE_PATH)
|
|
77
|
+
|
|
78
|
+
async def get_tracker_state(self, sender_id: str) -> str:
|
|
79
|
+
"""Returns the state of the tracker as a json string."""
|
|
80
|
+
if not self.processor:
|
|
81
|
+
return ""
|
|
82
|
+
|
|
83
|
+
tracker = await self.processor.get_tracker(sender_id)
|
|
84
|
+
state = tracker.current_state(EventVerbosity.AFTER_RESTART)
|
|
85
|
+
return json.dumps(state)
|
|
86
|
+
|
|
87
|
+
async def on_tracker_updated(self, sender_id: str) -> None:
|
|
88
|
+
"""Called when a tracker has been updated."""
|
|
89
|
+
if self.tracker_stream:
|
|
90
|
+
tracker_dump = await self.get_tracker_state(sender_id)
|
|
91
|
+
await self.tracker_stream.broadcast(tracker_dump)
|
|
92
|
+
|
|
93
|
+
async def on_message_proxy(
|
|
94
|
+
self,
|
|
95
|
+
on_new_message: Callable[["UserMessage"], Awaitable[Any]],
|
|
96
|
+
message: "UserMessage",
|
|
97
|
+
) -> None:
|
|
98
|
+
"""Proxies the on_new_message call to the underlying channel.
|
|
99
|
+
|
|
100
|
+
Triggers a tracker update notification after processing the message.
|
|
101
|
+
"""
|
|
102
|
+
await on_new_message(message)
|
|
103
|
+
await self.on_tracker_updated(message.sender_id)
|
|
104
|
+
|
|
105
|
+
@classmethod
|
|
106
|
+
async def serve_inspect_html(cls) -> "HTTPResponse":
|
|
107
|
+
"""Serves the inspect.html file."""
|
|
108
|
+
return await response.file(cls.inspect_html_path() + "/index.html")
|
|
109
|
+
|
|
110
|
+
def blueprint(
|
|
111
|
+
self, on_new_message: Callable[["UserMessage"], Awaitable[Any]]
|
|
112
|
+
) -> "Blueprint":
|
|
113
|
+
"""Defines a Sanic blueprint."""
|
|
114
|
+
self.sio = AsyncServer(async_mode="sanic", cors_allowed_origins=[])
|
|
115
|
+
underlying_webhook: "Blueprint" = self.underlying.blueprint(
|
|
116
|
+
partial(self.on_message_proxy, on_new_message)
|
|
117
|
+
)
|
|
118
|
+
underlying_webhook.static("/assets", self.inspect_html_path() + "/assets")
|
|
119
|
+
|
|
120
|
+
@underlying_webhook.route("/inspect.html", methods=["GET"], name="inspect")
|
|
121
|
+
async def inspect(_: "Request") -> "HTTPResponse":
|
|
122
|
+
return await self.serve_inspect_html()
|
|
123
|
+
|
|
124
|
+
@underlying_webhook.listener("after_server_start") # type: ignore[misc]
|
|
125
|
+
async def after_server_start(app: Sanic, _: asyncio.AbstractEventLoop) -> None:
|
|
126
|
+
"""Prints a message after the server has started with inspect URL."""
|
|
127
|
+
self.processor = app.ctx.agent.processor
|
|
128
|
+
|
|
129
|
+
inspect_path = app.url_for(f"{app.name}.{underlying_webhook.name}.inspect")
|
|
130
|
+
|
|
131
|
+
# replace 0.0.0.0 with localhost
|
|
132
|
+
serve_location = app.serve_location.replace("0.0.0.0", "localhost")
|
|
133
|
+
|
|
134
|
+
print_info(
|
|
135
|
+
f"Development inspector for channel {self.name()} is running. To "
|
|
136
|
+
f"inspect conversations, visit {serve_location}{inspect_path}"
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
underlying_webhook.add_websocket_route(
|
|
140
|
+
self.tracker_stream, "/tracker_stream", name="tracker_stream"
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
return underlying_webhook
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class TrackerStream:
|
|
147
|
+
"""Stream tracker state to connected clients."""
|
|
148
|
+
|
|
149
|
+
def __init__(self, get_tracker: Callable[[str], Awaitable[Dict[str, Any]]]) -> None:
|
|
150
|
+
"""Initializes the TrackerStream."""
|
|
151
|
+
self._connected_clients: Set[Websocket] = set()
|
|
152
|
+
self.get_tracker = get_tracker
|
|
153
|
+
|
|
154
|
+
def __name__(self) -> str:
|
|
155
|
+
"""Name of the stream."""
|
|
156
|
+
return "tracker_stream"
|
|
157
|
+
|
|
158
|
+
async def __call__(self, *args: Any, **kwargs: Any) -> None:
|
|
159
|
+
"""Starts the stream."""
|
|
160
|
+
await self.stream(*args, **kwargs)
|
|
161
|
+
|
|
162
|
+
async def stream(self, request: Request, ws: Websocket) -> None:
|
|
163
|
+
"""Handles connection of a new client."""
|
|
164
|
+
self._connected_clients.add(ws)
|
|
165
|
+
|
|
166
|
+
try:
|
|
167
|
+
async for message_str in ws:
|
|
168
|
+
message = json.loads(message_str)
|
|
169
|
+
if message.get("action") == "retrieve":
|
|
170
|
+
sender_id = message.get("sender_id")
|
|
171
|
+
if not sender_id:
|
|
172
|
+
structlogger.warning(
|
|
173
|
+
"Tried to retrieve tracker without sender_id."
|
|
174
|
+
)
|
|
175
|
+
continue
|
|
176
|
+
tracker_dump = await self.get_tracker(sender_id)
|
|
177
|
+
await self._send(ws, tracker_dump)
|
|
178
|
+
finally:
|
|
179
|
+
self._connected_clients.remove(ws)
|
|
180
|
+
|
|
181
|
+
async def _send(self, ws: Websocket, message: str) -> None:
|
|
182
|
+
"""Sends a message to a connected client."""
|
|
183
|
+
try:
|
|
184
|
+
await ws.send(message)
|
|
185
|
+
except websockets.exceptions.ConnectionClosed:
|
|
186
|
+
pass
|
|
187
|
+
|
|
188
|
+
async def broadcast(self, message: str) -> None:
|
|
189
|
+
"""Broadcasts a message to all connected clients."""
|
|
190
|
+
if not self._connected_clients:
|
|
191
|
+
return
|
|
192
|
+
await asyncio.wait(
|
|
193
|
+
[
|
|
194
|
+
asyncio.create_task(self._send(websocket, message))
|
|
195
|
+
for websocket in self._connected_clients
|
|
196
|
+
]
|
|
197
|
+
)
|
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
import hashlib
|
|
3
|
+
import hmac
|
|
4
|
+
import logging
|
|
5
|
+
import structlog
|
|
6
|
+
from fbmessenger import MessengerClient
|
|
7
|
+
from fbmessenger.attachments import Image
|
|
8
|
+
from fbmessenger.elements import Text as FBText
|
|
9
|
+
from fbmessenger.quick_replies import QuickReplies, QuickReply
|
|
10
|
+
from fbmessenger.sender_actions import SenderAction
|
|
11
|
+
|
|
12
|
+
import rasa.shared.utils.io
|
|
13
|
+
from sanic import Blueprint, response
|
|
14
|
+
from sanic.request import Request
|
|
15
|
+
from typing import Text, List, Dict, Any, Callable, Awaitable, Iterable, Optional, Union
|
|
16
|
+
|
|
17
|
+
from rasa.core.channels.channel import UserMessage, OutputChannel, InputChannel
|
|
18
|
+
from sanic.response import HTTPResponse
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
structlogger = structlog.get_logger()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Messenger:
|
|
25
|
+
"""Implement a fbmessenger to parse incoming webhooks and send msgs."""
|
|
26
|
+
|
|
27
|
+
@classmethod
|
|
28
|
+
def name(cls) -> Text:
|
|
29
|
+
return "facebook"
|
|
30
|
+
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
page_access_token: Text,
|
|
34
|
+
on_new_message: Callable[[UserMessage], Awaitable[Any]],
|
|
35
|
+
) -> None:
|
|
36
|
+
self.on_new_message = on_new_message
|
|
37
|
+
self.client = MessengerClient(page_access_token)
|
|
38
|
+
self.last_message: Dict[Text, Any] = {}
|
|
39
|
+
|
|
40
|
+
def get_user_id(self) -> Text:
|
|
41
|
+
return self.last_message.get("sender", {}).get("id", "")
|
|
42
|
+
|
|
43
|
+
@staticmethod
|
|
44
|
+
def _is_audio_message(message: Dict[Text, Any]) -> bool:
|
|
45
|
+
"""Check if the users message is a recorded voice message."""
|
|
46
|
+
return (
|
|
47
|
+
"message" in message
|
|
48
|
+
and "attachments" in message["message"]
|
|
49
|
+
and message["message"]["attachments"][0]["type"] == "audio"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
@staticmethod
|
|
53
|
+
def _is_image_message(message: Dict[Text, Any]) -> bool:
|
|
54
|
+
"""Check if the users message is an image."""
|
|
55
|
+
return (
|
|
56
|
+
"message" in message
|
|
57
|
+
and "attachments" in message["message"]
|
|
58
|
+
and message["message"]["attachments"][0]["type"] == "image"
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
@staticmethod
|
|
62
|
+
def _is_video_message(message: Dict[Text, Any]) -> bool:
|
|
63
|
+
"""Check if the users message is a video."""
|
|
64
|
+
return (
|
|
65
|
+
"message" in message
|
|
66
|
+
and "attachments" in message["message"]
|
|
67
|
+
and message["message"]["attachments"][0]["type"] == "video"
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
@staticmethod
|
|
71
|
+
def _is_file_message(message: Dict[Text, Any]) -> bool:
|
|
72
|
+
"""Check if the users message is a file."""
|
|
73
|
+
return (
|
|
74
|
+
"message" in message
|
|
75
|
+
and "attachments" in message["message"]
|
|
76
|
+
and message["message"]["attachments"][0]["type"] == "file"
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
@staticmethod
|
|
80
|
+
def _is_user_message(message: Dict[Text, Any]) -> bool:
|
|
81
|
+
"""Check if the message is a message from the user."""
|
|
82
|
+
return (
|
|
83
|
+
"message" in message
|
|
84
|
+
and "text" in message["message"]
|
|
85
|
+
and not message["message"].get("is_echo")
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
@staticmethod
|
|
89
|
+
def _is_quick_reply_message(message: Dict[Text, Any]) -> bool:
|
|
90
|
+
"""Check if the message is a quick reply message."""
|
|
91
|
+
return (
|
|
92
|
+
message.get("message") is not None
|
|
93
|
+
and message["message"].get("quick_reply") is not None
|
|
94
|
+
and message["message"]["quick_reply"].get("payload")
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
async def handle(self, payload: Dict, metadata: Optional[Dict[Text, Any]]) -> None:
|
|
98
|
+
for entry in payload["entry"]:
|
|
99
|
+
for message in entry["messaging"]:
|
|
100
|
+
self.last_message = message
|
|
101
|
+
if message.get("message"):
|
|
102
|
+
return await self.message(message, metadata)
|
|
103
|
+
elif message.get("postback"):
|
|
104
|
+
return await self.postback(message, metadata)
|
|
105
|
+
|
|
106
|
+
async def message(
|
|
107
|
+
self, message: Dict[Text, Any], metadata: Optional[Dict[Text, Any]]
|
|
108
|
+
) -> None:
|
|
109
|
+
"""Handle an incoming event from the fb webhook."""
|
|
110
|
+
# quick reply and user message both share 'text' attribute
|
|
111
|
+
# so quick reply should be checked first
|
|
112
|
+
if self._is_quick_reply_message(message):
|
|
113
|
+
text = message["message"]["quick_reply"]["payload"]
|
|
114
|
+
elif self._is_user_message(message):
|
|
115
|
+
text = message["message"]["text"]
|
|
116
|
+
elif self._is_audio_message(message):
|
|
117
|
+
attachment = message["message"]["attachments"][0]
|
|
118
|
+
text = attachment["payload"]["url"]
|
|
119
|
+
elif self._is_image_message(message):
|
|
120
|
+
attachment = message["message"]["attachments"][0]
|
|
121
|
+
text = attachment["payload"]["url"]
|
|
122
|
+
elif self._is_video_message(message):
|
|
123
|
+
attachment = message["message"]["attachments"][0]
|
|
124
|
+
text = attachment["payload"]["url"]
|
|
125
|
+
elif self._is_file_message(message):
|
|
126
|
+
attachment = message["message"]["attachments"][0]
|
|
127
|
+
text = attachment["payload"]["url"]
|
|
128
|
+
else:
|
|
129
|
+
structlogger.warning(
|
|
130
|
+
"facebook.message.cannot.handle", message=copy.deepcopy(message)
|
|
131
|
+
)
|
|
132
|
+
return
|
|
133
|
+
|
|
134
|
+
await self._handle_user_message(text, self.get_user_id(), metadata)
|
|
135
|
+
|
|
136
|
+
async def postback(
|
|
137
|
+
self, message: Dict[Text, Any], metadata: Optional[Dict[Text, Any]]
|
|
138
|
+
) -> None:
|
|
139
|
+
"""Handle a postback (e.g. quick reply button)."""
|
|
140
|
+
text = message["postback"]["payload"]
|
|
141
|
+
await self._handle_user_message(text, self.get_user_id(), metadata)
|
|
142
|
+
|
|
143
|
+
async def _handle_user_message(
|
|
144
|
+
self, text: Text, sender_id: Text, metadata: Optional[Dict[Text, Any]]
|
|
145
|
+
) -> None:
|
|
146
|
+
"""Pass on the text to the dialogue engine for processing."""
|
|
147
|
+
out_channel = MessengerBot(self.client)
|
|
148
|
+
await out_channel.send_action(sender_id, sender_action="mark_seen")
|
|
149
|
+
|
|
150
|
+
user_msg = UserMessage(
|
|
151
|
+
text, out_channel, sender_id, input_channel=self.name(), metadata=metadata
|
|
152
|
+
)
|
|
153
|
+
await out_channel.send_action(sender_id, sender_action="typing_on")
|
|
154
|
+
# noinspection PyBroadException
|
|
155
|
+
try:
|
|
156
|
+
await self.on_new_message(user_msg)
|
|
157
|
+
except Exception:
|
|
158
|
+
logger.exception(
|
|
159
|
+
"Exception when trying to handle webhook for facebook message."
|
|
160
|
+
)
|
|
161
|
+
pass
|
|
162
|
+
finally:
|
|
163
|
+
await out_channel.send_action(sender_id, sender_action="typing_off")
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class MessengerBot(OutputChannel):
|
|
167
|
+
"""A bot that uses fb-messenger to communicate."""
|
|
168
|
+
|
|
169
|
+
@classmethod
|
|
170
|
+
def name(cls) -> Text:
|
|
171
|
+
return "facebook"
|
|
172
|
+
|
|
173
|
+
def __init__(self, messenger_client: MessengerClient) -> None:
|
|
174
|
+
self.messenger_client = messenger_client
|
|
175
|
+
super().__init__()
|
|
176
|
+
|
|
177
|
+
def send(self, recipient_id: Text, element: Any) -> None:
|
|
178
|
+
"""Sends a message to the recipient using the messenger client."""
|
|
179
|
+
# this is a bit hacky, but the client doesn't have a proper API to
|
|
180
|
+
# send messages but instead expects the incoming sender to be present
|
|
181
|
+
# which we don't have as it is stored in the input channel.
|
|
182
|
+
self.messenger_client.send(element.to_dict(), recipient_id, "RESPONSE")
|
|
183
|
+
|
|
184
|
+
async def send_text_message(
|
|
185
|
+
self, recipient_id: Text, text: Text, **kwargs: Any
|
|
186
|
+
) -> None:
|
|
187
|
+
"""Send a message through this channel."""
|
|
188
|
+
for message_part in text.strip().split("\n\n"):
|
|
189
|
+
self.send(recipient_id, FBText(text=message_part))
|
|
190
|
+
|
|
191
|
+
async def send_image_url(
|
|
192
|
+
self, recipient_id: Text, image: Text, **kwargs: Any
|
|
193
|
+
) -> None:
|
|
194
|
+
"""Sends an image. Default will just post the url as a string."""
|
|
195
|
+
self.send(recipient_id, Image(url=image))
|
|
196
|
+
|
|
197
|
+
async def send_action(self, recipient_id: Text, sender_action: Text) -> None:
|
|
198
|
+
"""Sends a sender action to facebook (e.g. "typing_on").
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
recipient_id: recipient
|
|
202
|
+
sender_action: action to send, e.g. "typing_on" or "mark_seen"
|
|
203
|
+
"""
|
|
204
|
+
self.messenger_client.send_action(
|
|
205
|
+
SenderAction(sender_action).to_dict(), recipient_id
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
async def send_text_with_buttons(
|
|
209
|
+
self,
|
|
210
|
+
recipient_id: Text,
|
|
211
|
+
text: Text,
|
|
212
|
+
buttons: List[Dict[Text, Any]],
|
|
213
|
+
**kwargs: Any,
|
|
214
|
+
) -> None:
|
|
215
|
+
"""Sends buttons to the output."""
|
|
216
|
+
# buttons is a list of tuples: [(option_name,payload)]
|
|
217
|
+
if len(buttons) > 3:
|
|
218
|
+
rasa.shared.utils.io.raise_warning(
|
|
219
|
+
"Facebook API currently allows only up to 3 buttons. "
|
|
220
|
+
"If you add more, all will be ignored."
|
|
221
|
+
)
|
|
222
|
+
await self.send_text_message(recipient_id, text, **kwargs)
|
|
223
|
+
else:
|
|
224
|
+
self._add_postback_info(buttons)
|
|
225
|
+
|
|
226
|
+
# Currently there is no predefined way to create a message with
|
|
227
|
+
# buttons in the fbmessenger framework - so we need to create the
|
|
228
|
+
# payload on our own
|
|
229
|
+
payload = {
|
|
230
|
+
"attachment": {
|
|
231
|
+
"type": "template",
|
|
232
|
+
"payload": {
|
|
233
|
+
"template_type": "button",
|
|
234
|
+
"text": text,
|
|
235
|
+
"buttons": buttons,
|
|
236
|
+
},
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
self.messenger_client.send(payload, recipient_id, "RESPONSE")
|
|
240
|
+
|
|
241
|
+
async def send_quick_replies(
|
|
242
|
+
self,
|
|
243
|
+
recipient_id: Text,
|
|
244
|
+
text: Text,
|
|
245
|
+
quick_replies: List[Dict[Text, Any]],
|
|
246
|
+
**kwargs: Any,
|
|
247
|
+
) -> None:
|
|
248
|
+
"""Sends quick replies to the output."""
|
|
249
|
+
quick_replies = self._convert_to_quick_reply(quick_replies)
|
|
250
|
+
self.send(recipient_id, FBText(text=text, quick_replies=quick_replies))
|
|
251
|
+
|
|
252
|
+
async def send_elements(
|
|
253
|
+
self, recipient_id: Text, elements: Iterable[Dict[Text, Any]], **kwargs: Any
|
|
254
|
+
) -> None:
|
|
255
|
+
"""Sends elements to the output."""
|
|
256
|
+
for element in elements:
|
|
257
|
+
if "buttons" in element:
|
|
258
|
+
self._add_postback_info(element["buttons"])
|
|
259
|
+
|
|
260
|
+
payload = {
|
|
261
|
+
"attachment": {
|
|
262
|
+
"type": "template",
|
|
263
|
+
"payload": {"template_type": "generic", "elements": elements},
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
self.messenger_client.send(payload, recipient_id, "RESPONSE")
|
|
267
|
+
|
|
268
|
+
async def send_custom_json(
|
|
269
|
+
self,
|
|
270
|
+
recipient_id: Text,
|
|
271
|
+
json_message: Union[List, Dict[Text, Any]],
|
|
272
|
+
**kwargs: Any,
|
|
273
|
+
) -> None:
|
|
274
|
+
"""Sends custom json data to the output."""
|
|
275
|
+
if isinstance(json_message, dict) and "sender" in json_message.keys():
|
|
276
|
+
recipient_id = json_message.pop("sender", {}).pop("id", recipient_id)
|
|
277
|
+
elif isinstance(json_message, list):
|
|
278
|
+
for message in json_message:
|
|
279
|
+
if "sender" in message.keys():
|
|
280
|
+
recipient_id = message.pop("sender", {}).pop("id", recipient_id)
|
|
281
|
+
break
|
|
282
|
+
|
|
283
|
+
self.messenger_client.send(json_message, recipient_id, "RESPONSE")
|
|
284
|
+
|
|
285
|
+
@staticmethod
|
|
286
|
+
def _add_postback_info(buttons: List[Dict[Text, Any]]) -> None:
|
|
287
|
+
"""Make sure every button has a type. Modifications happen in place."""
|
|
288
|
+
for button in buttons:
|
|
289
|
+
if "type" not in button:
|
|
290
|
+
button["type"] = "postback"
|
|
291
|
+
|
|
292
|
+
@staticmethod
|
|
293
|
+
def _convert_to_quick_reply(quick_replies: List[Dict[Text, Any]]) -> QuickReplies:
|
|
294
|
+
"""Convert quick reply dictionary to FB QuickReplies object."""
|
|
295
|
+
fb_quick_replies = []
|
|
296
|
+
for quick_reply in quick_replies:
|
|
297
|
+
try:
|
|
298
|
+
fb_quick_replies.append(
|
|
299
|
+
QuickReply(
|
|
300
|
+
title=quick_reply["title"],
|
|
301
|
+
payload=quick_reply["payload"],
|
|
302
|
+
content_type=quick_reply.get("content_type"),
|
|
303
|
+
)
|
|
304
|
+
)
|
|
305
|
+
except KeyError as e:
|
|
306
|
+
raise ValueError(
|
|
307
|
+
'Facebook quick replies must define a "{}" field.'.format(e.args[0])
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
return QuickReplies(quick_replies=fb_quick_replies)
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
class FacebookInput(InputChannel):
|
|
314
|
+
"""Facebook input channel implementation. Based on the HTTPInputChannel."""
|
|
315
|
+
|
|
316
|
+
@classmethod
|
|
317
|
+
def name(cls) -> Text:
|
|
318
|
+
return "facebook"
|
|
319
|
+
|
|
320
|
+
@classmethod
|
|
321
|
+
def from_credentials(cls, credentials: Optional[Dict[Text, Any]]) -> InputChannel:
|
|
322
|
+
if not credentials:
|
|
323
|
+
cls.raise_missing_credentials_exception()
|
|
324
|
+
|
|
325
|
+
return cls(
|
|
326
|
+
credentials.get("verify"),
|
|
327
|
+
credentials.get("secret"),
|
|
328
|
+
credentials.get("page-access-token"),
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
def __init__(self, fb_verify: Text, fb_secret: Text, fb_access_token: Text) -> None:
|
|
332
|
+
"""Create a facebook input channel.
|
|
333
|
+
|
|
334
|
+
Needs a couple of settings to properly authenticate and validate
|
|
335
|
+
messages. Details to setup:
|
|
336
|
+
|
|
337
|
+
https://github.com/rehabstudio/fbmessenger#facebook-app-setup
|
|
338
|
+
|
|
339
|
+
Args:
|
|
340
|
+
fb_verify: FB Verification string
|
|
341
|
+
(can be chosen by yourself on webhook creation)
|
|
342
|
+
fb_secret: facebook application secret
|
|
343
|
+
fb_access_token: access token to post in the name of the FB page
|
|
344
|
+
"""
|
|
345
|
+
self.fb_verify = fb_verify
|
|
346
|
+
self.fb_secret = fb_secret
|
|
347
|
+
self.fb_access_token = fb_access_token
|
|
348
|
+
|
|
349
|
+
def blueprint(
|
|
350
|
+
self, on_new_message: Callable[[UserMessage], Awaitable[Any]]
|
|
351
|
+
) -> Blueprint:
|
|
352
|
+
fb_webhook = Blueprint("fb_webhook", __name__)
|
|
353
|
+
|
|
354
|
+
# noinspection PyUnusedLocal
|
|
355
|
+
@fb_webhook.route("/", methods=["GET"])
|
|
356
|
+
async def health(request: Request) -> HTTPResponse:
|
|
357
|
+
return response.json({"status": "ok"})
|
|
358
|
+
|
|
359
|
+
@fb_webhook.route("/webhook", methods=["GET"])
|
|
360
|
+
async def token_verification(request: Request) -> HTTPResponse:
|
|
361
|
+
if request.args.get("hub.verify_token") == self.fb_verify:
|
|
362
|
+
return response.text(request.args.get("hub.challenge"))
|
|
363
|
+
else:
|
|
364
|
+
logger.warning(
|
|
365
|
+
"Invalid fb verify token! Make sure this matches "
|
|
366
|
+
"your webhook settings on the facebook app."
|
|
367
|
+
)
|
|
368
|
+
return response.text("failure, invalid token")
|
|
369
|
+
|
|
370
|
+
@fb_webhook.route("/webhook", methods=["POST"])
|
|
371
|
+
async def webhook(request: Request) -> HTTPResponse:
|
|
372
|
+
signature = request.headers.get("X-Hub-Signature") or ""
|
|
373
|
+
if not self.validate_hub_signature(self.fb_secret, request.body, signature):
|
|
374
|
+
logger.warning(
|
|
375
|
+
"Wrong fb secret! Make sure this matches the "
|
|
376
|
+
"secret in your facebook app settings"
|
|
377
|
+
)
|
|
378
|
+
return response.text("not validated")
|
|
379
|
+
|
|
380
|
+
messenger = Messenger(self.fb_access_token, on_new_message)
|
|
381
|
+
|
|
382
|
+
metadata = self.get_metadata(request)
|
|
383
|
+
await messenger.handle(request.json, metadata)
|
|
384
|
+
return response.text("success")
|
|
385
|
+
|
|
386
|
+
return fb_webhook
|
|
387
|
+
|
|
388
|
+
@staticmethod
|
|
389
|
+
def validate_hub_signature(
|
|
390
|
+
app_secret: Text, request_payload: bytes, hub_signature_header: Text
|
|
391
|
+
) -> bool:
|
|
392
|
+
"""Make sure the incoming webhook requests are properly signed.
|
|
393
|
+
|
|
394
|
+
Args:
|
|
395
|
+
app_secret: Secret Key for application
|
|
396
|
+
request_payload: request body
|
|
397
|
+
hub_signature_header: X-Hub-Signature header sent with request
|
|
398
|
+
|
|
399
|
+
Returns:
|
|
400
|
+
bool: indicated that hub signature is validated
|
|
401
|
+
"""
|
|
402
|
+
# noinspection PyBroadException
|
|
403
|
+
try:
|
|
404
|
+
hash_method, hub_signature = hub_signature_header.split("=")
|
|
405
|
+
except Exception:
|
|
406
|
+
pass
|
|
407
|
+
else:
|
|
408
|
+
digest_module = getattr(hashlib, hash_method)
|
|
409
|
+
hmac_object = hmac.new(
|
|
410
|
+
bytearray(app_secret, "utf8"), request_payload, digest_module
|
|
411
|
+
)
|
|
412
|
+
generated_hash = hmac_object.hexdigest()
|
|
413
|
+
if hub_signature == generated_hash:
|
|
414
|
+
return True
|
|
415
|
+
return False
|
|
416
|
+
|
|
417
|
+
def get_output_channel(self) -> OutputChannel:
|
|
418
|
+
client = MessengerClient(self.fb_access_token)
|
|
419
|
+
return MessengerBot(client)
|