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
rasa/utils/licensing.py
ADDED
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
from asyncio import AbstractEventLoop
|
|
2
|
+
import hashlib
|
|
3
|
+
import os
|
|
4
|
+
import random
|
|
5
|
+
import re
|
|
6
|
+
import time
|
|
7
|
+
import typing
|
|
8
|
+
import uuid
|
|
9
|
+
from datetime import datetime, timezone
|
|
10
|
+
from typing import Any, Callable, Dict, Optional, Set, Text, TypeVar
|
|
11
|
+
|
|
12
|
+
import jwt
|
|
13
|
+
from dotenv import dotenv_values
|
|
14
|
+
from sanic import Sanic
|
|
15
|
+
import structlog
|
|
16
|
+
from rasa import telemetry
|
|
17
|
+
|
|
18
|
+
from rasa.core import jobs
|
|
19
|
+
from rasa.shared.utils.cli import print_error_and_exit
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
if typing.TYPE_CHECKING:
|
|
23
|
+
from rasa.core.tracker_store import TrackerStore
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
LICENSE_ENV_VAR = "RASA_PRO_LICENSE"
|
|
27
|
+
ALGORITHM = "RS256"
|
|
28
|
+
# deepcode ignore HardcodedKey: This is a public key - not a security issue.
|
|
29
|
+
PUBLIC_KEY = """-----BEGIN PUBLIC KEY-----
|
|
30
|
+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6L90HBMIeiEUkLw85aRx
|
|
31
|
+
L8qisVwiJwy3E4E/MPKHEuzguUJG3KwQE3Yb37HWi6I8EXOI5UfP2RvbNPKbmYFo
|
|
32
|
+
90P27rKpvhZRCG9sy3cNu3Xr1XcQ6Eue2e12LWBAgzBZSqjzwkCOtt+L6LIm3lPf
|
|
33
|
+
2QYSFORTZR9PtOvI1b677W1lVjioRrbg1IG6UXGVOTCmeSFT/JzbsYzR7QFzFdWe
|
|
34
|
+
ytjHVgeb/R9inY1/LeiP2KCHYcYUF2sGc+6CsGvr9Kkio5KS10jBF27EeBaeVpXO
|
|
35
|
+
JH5viXVuRPCu5ymvnih5Rk4VYK3X3rG1rf5oju9OBDPLq7lKklY1pPZjBHADPU3o
|
|
36
|
+
/QIDAQAB
|
|
37
|
+
-----END PUBLIC KEY-----"""
|
|
38
|
+
|
|
39
|
+
# If a license must be revoked before expiration, add its JTI to this list.
|
|
40
|
+
# Adding to this list requires cutting a new release for the change to affect users.
|
|
41
|
+
# Versions prior to the one including the blocked JTI will still
|
|
42
|
+
# be available to blocked users until the regular expiration date
|
|
43
|
+
JTI_BLOCKLIST: Set[Text] = set([])
|
|
44
|
+
|
|
45
|
+
SCOPE_DELIMITER = ":"
|
|
46
|
+
PRODUCT_AREA = "rasa:pro:plus"
|
|
47
|
+
VOICE_SCOPE = "rasa:voice"
|
|
48
|
+
CHAMPION_SERVER_LIMITED_SCOPE = "rasa:pro:champion-server-limited"
|
|
49
|
+
CHAMPION_SERVER_INTERNAL_SCOPE = "rasa:pro:champion-server-internal"
|
|
50
|
+
# defines multiple of the soft limit that triggers the hard limit
|
|
51
|
+
HARD_LIMIT_FACTOR = 10
|
|
52
|
+
structlogger = structlog.get_logger()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class LicenseValidationException(Exception):
|
|
56
|
+
"""Parent class for exceptions raised when handling licenses."""
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class LicenseSchemaException(LicenseValidationException):
|
|
60
|
+
"""Exception raised when a license does not contain the correct fields."""
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class LicenseScopeException(LicenseValidationException):
|
|
64
|
+
"""Exception raised when a license does not contain the correct scope."""
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class LicenseEncodingException(LicenseValidationException):
|
|
68
|
+
"""Exception raised when the JWT representing a license is not well-formed."""
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class LicenseSignatureInvalidException(LicenseValidationException):
|
|
72
|
+
"""Exception raised when a license signature could not be verified."""
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class LicenseExpiredException(LicenseValidationException):
|
|
76
|
+
"""Exception raised when a license has expired (exp)."""
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class LicenseNotYetValidException(LicenseValidationException):
|
|
80
|
+
"""Exception raised when a license is not valid yet (nbf)."""
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class LicenseNotFoundException(LicenseValidationException):
|
|
84
|
+
"""Exception raised when a license is not available."""
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class License:
|
|
88
|
+
"""Represents a Rasa Pro license.
|
|
89
|
+
|
|
90
|
+
There a are two ways of instancing an `License` object:
|
|
91
|
+
- Via `decode`: This is the option that should be used 99% of the times.
|
|
92
|
+
This option allows callers to decode a JWT into an `License`
|
|
93
|
+
object, which means that only correctly signed JWT will be decodable.
|
|
94
|
+
Other checks will be performed on the JWT as well. This implies that any
|
|
95
|
+
`License` obtained via `decode` is guaranteed to represent a
|
|
96
|
+
valid license, that is, a license that was obtained via a
|
|
97
|
+
contract/deal/etc. with Rasa Inc (i.e. the owner of the private key).
|
|
98
|
+
- Via `__init__`: This creates an `License` object directly, without
|
|
99
|
+
performing any validations. Useful only for creating new licenses (which
|
|
100
|
+
requires access to the private key to then encode) or for testing
|
|
101
|
+
purposes.
|
|
102
|
+
|
|
103
|
+
The scopes of the license define what it unlocks. The scopes are
|
|
104
|
+
hierarchical, meaning that a license with a scope `rasa:pro` also
|
|
105
|
+
unlocks the scopes `rasa:pro:plus`.
|
|
106
|
+
|
|
107
|
+
Scopes can be used to enable or disable features in Rasa, the following
|
|
108
|
+
scopes are used:
|
|
109
|
+
|
|
110
|
+
- `rasa:pro` - Rasa Pro features
|
|
111
|
+
- `rasa:pro:plus` - Rasa Pro Plus features
|
|
112
|
+
- `rasa:voice` - Voice features
|
|
113
|
+
|
|
114
|
+
In addition to scopes focused on feature flagging, there are also scopes
|
|
115
|
+
that are used to limited by the license agreement they are issued under:
|
|
116
|
+
|
|
117
|
+
- `rasa:pro:champion` - Champion license, can only be used for local
|
|
118
|
+
development
|
|
119
|
+
|
|
120
|
+
- `rasa:pro:champion-server-internal` - Champion license, can be used
|
|
121
|
+
to deploy an assistant on a server for an internal use case. The license
|
|
122
|
+
limits the number of conversations per month to 100.
|
|
123
|
+
|
|
124
|
+
- `rasa:pro:champion-server-limited` - Champion license, can be used
|
|
125
|
+
to deploy an assistant on a server for a limited external use case.
|
|
126
|
+
The license allows for a maximum of 1000 conversations per month.
|
|
127
|
+
|
|
128
|
+
The champion scopes on their own do not unlock any features, they are
|
|
129
|
+
used to limit the use of the license to the agreed upon number of
|
|
130
|
+
conversations. The champion scopes can be combined with the feature
|
|
131
|
+
scopes to enable the features for the champion license, e.g.
|
|
132
|
+
`rasa:pro:champion rasa:pro` would enable the champion license for
|
|
133
|
+
local development and the Rasa Pro features.
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
__slots__ = ["jti", "iat", "nbf", "scope", "exp", "email", "company"]
|
|
137
|
+
|
|
138
|
+
def __init__(
|
|
139
|
+
self,
|
|
140
|
+
*,
|
|
141
|
+
company: Text,
|
|
142
|
+
email: Text,
|
|
143
|
+
exp: int,
|
|
144
|
+
scope: Text,
|
|
145
|
+
jti: Optional[Text] = None,
|
|
146
|
+
iat: Optional[int] = None,
|
|
147
|
+
nbf: Optional[int] = None,
|
|
148
|
+
) -> None:
|
|
149
|
+
"""Initializes an instance of `License`.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
company: Company this license is issued to.
|
|
153
|
+
email: Contact email for this license.
|
|
154
|
+
exp: Expiration date (UNIX epoch time).
|
|
155
|
+
scope: The license scope
|
|
156
|
+
jti: JWT unique identifier - a unique identifier for this
|
|
157
|
+
license. Defaults to a UUID4 if not set.
|
|
158
|
+
iat: Created at (UNIX epoch time).
|
|
159
|
+
Defaults to current time if not set.
|
|
160
|
+
nbf: Time at which the license starts being valid (UNIX epoch time).
|
|
161
|
+
Defaults to current time if not set.
|
|
162
|
+
"""
|
|
163
|
+
self.company = company
|
|
164
|
+
self.email = email
|
|
165
|
+
self.exp = exp
|
|
166
|
+
self.jti = jti or str(uuid.uuid4())
|
|
167
|
+
self.iat = iat or int(time.time())
|
|
168
|
+
self.nbf = nbf or self.iat
|
|
169
|
+
self.scope = scope
|
|
170
|
+
|
|
171
|
+
def as_dict(self) -> Dict[Text, Any]:
|
|
172
|
+
"""Returns this license as a dictionary object.
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
License represented using a `dict`.
|
|
176
|
+
"""
|
|
177
|
+
return {attr: getattr(self, attr) for attr in License.__slots__}
|
|
178
|
+
|
|
179
|
+
def __str__(self) -> Text:
|
|
180
|
+
"""Returns a text representation of this license.
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
String representing this license.
|
|
184
|
+
"""
|
|
185
|
+
return f"License <{self.as_dict()}>"
|
|
186
|
+
|
|
187
|
+
@staticmethod
|
|
188
|
+
def decode(
|
|
189
|
+
encoded_license: Text,
|
|
190
|
+
check_not_before: Optional[bool] = True,
|
|
191
|
+
check_expiration: Optional[bool] = True,
|
|
192
|
+
product_area: Text = PRODUCT_AREA,
|
|
193
|
+
) -> "License":
|
|
194
|
+
"""Returns an instance of `License` from an encoded JWT.
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
encoded_license: JWT in encoded form.
|
|
198
|
+
check_not_before: Check if not_before is in the future.
|
|
199
|
+
check_expiration: Check if token has expired.
|
|
200
|
+
product_area: The product scope of the license.
|
|
201
|
+
|
|
202
|
+
Raises:
|
|
203
|
+
LicenseSignatureInvalidException: If the license signature could
|
|
204
|
+
not be validated.
|
|
205
|
+
LicenseNotYetValidException: If the license is not valid yet.
|
|
206
|
+
LicenseExpiredException: If the license has expired, or has been
|
|
207
|
+
blocklisted.
|
|
208
|
+
LicenseEncodingException: If the JWT was not correctly encoded.
|
|
209
|
+
LicenseSchemaException: If the license contains unknown or extra
|
|
210
|
+
fields, or if it is missing fields.
|
|
211
|
+
|
|
212
|
+
Returns:
|
|
213
|
+
A validated enterprise license.
|
|
214
|
+
"""
|
|
215
|
+
try:
|
|
216
|
+
decoded = jwt.decode(
|
|
217
|
+
encoded_license,
|
|
218
|
+
key=PUBLIC_KEY,
|
|
219
|
+
algorithms=[ALGORITHM],
|
|
220
|
+
options={
|
|
221
|
+
"verify_nbf": check_not_before,
|
|
222
|
+
"verify_exp": check_expiration,
|
|
223
|
+
},
|
|
224
|
+
)
|
|
225
|
+
except jwt.exceptions.InvalidSignatureError:
|
|
226
|
+
raise LicenseSignatureInvalidException(
|
|
227
|
+
"Could not verify the license's signature."
|
|
228
|
+
)
|
|
229
|
+
except jwt.exceptions.ImmatureSignatureError:
|
|
230
|
+
raise LicenseNotYetValidException("The license is not valid yet (nbf).")
|
|
231
|
+
except jwt.exceptions.ExpiredSignatureError:
|
|
232
|
+
raise LicenseExpiredException("The license has already expired (exp).")
|
|
233
|
+
except jwt.exceptions.DecodeError:
|
|
234
|
+
# Handle `DecodeError` last since other more specific exceptions
|
|
235
|
+
# such as `InvalidSignatureError` inherit from it.
|
|
236
|
+
raise LicenseEncodingException("Could not decode license as JWT.")
|
|
237
|
+
|
|
238
|
+
if set(decoded.keys()) != set(License.__slots__):
|
|
239
|
+
raise LicenseSchemaException("Invalid license schema.")
|
|
240
|
+
|
|
241
|
+
license_scope = decoded.get("scope", "")
|
|
242
|
+
if not is_valid_license_scope(product_area, license_scope):
|
|
243
|
+
raise LicenseScopeException(
|
|
244
|
+
f"The product scope of your issued license does not "
|
|
245
|
+
f"include {product_area}."
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
if decoded["jti"] in JTI_BLOCKLIST:
|
|
249
|
+
raise LicenseExpiredException("The license has already expired.")
|
|
250
|
+
|
|
251
|
+
return License(**decoded)
|
|
252
|
+
|
|
253
|
+
def encode(self, private_key: Text) -> Text:
|
|
254
|
+
"""Encodes this license into a JWT.
|
|
255
|
+
|
|
256
|
+
NOTE: This method is only useful in the context of testing, or when
|
|
257
|
+
using administrative scripts such as `license.py`. It
|
|
258
|
+
should not be used otherwise.
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
private_key: Private key to use. Should correspond to `PUBLIC_KEY`.
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
Encoded license.
|
|
265
|
+
"""
|
|
266
|
+
return jwt.encode(self.as_dict(), key=private_key, algorithm=ALGORITHM)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def retrieve_license_from_env() -> Text:
|
|
270
|
+
"""Return the license found in the env var."""
|
|
271
|
+
stored_env_values = dotenv_values(".env")
|
|
272
|
+
license_from_env = os.environ.get(LICENSE_ENV_VAR)
|
|
273
|
+
license = license_from_env or stored_env_values.get(LICENSE_ENV_VAR)
|
|
274
|
+
if not license:
|
|
275
|
+
raise LicenseNotFoundException()
|
|
276
|
+
return license
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def is_license_expiring_soon(license: License) -> bool:
|
|
280
|
+
"""Check if the license is about to expire in less than 30 days."""
|
|
281
|
+
return license.exp - time.time() < 30 * 24 * 60 * 60
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def validate_license_from_env(product_area: Text = PRODUCT_AREA) -> None:
|
|
285
|
+
try:
|
|
286
|
+
license_text = retrieve_license_from_env()
|
|
287
|
+
license = License.decode(license_text, product_area=product_area)
|
|
288
|
+
|
|
289
|
+
if is_license_expiring_soon(license):
|
|
290
|
+
structlogger.warning(
|
|
291
|
+
"license.expiration.warning",
|
|
292
|
+
event_info=(
|
|
293
|
+
"Your license is about to expire. "
|
|
294
|
+
"Please contact Rasa for a renewal."
|
|
295
|
+
),
|
|
296
|
+
expiration_date=datetime.fromtimestamp(
|
|
297
|
+
license.exp, timezone.utc
|
|
298
|
+
).isoformat(),
|
|
299
|
+
)
|
|
300
|
+
except LicenseNotFoundException:
|
|
301
|
+
structlogger.error("license.not_found.error")
|
|
302
|
+
raise SystemExit(
|
|
303
|
+
f"A Rasa Pro license is required. "
|
|
304
|
+
f"Please set the environmental variable "
|
|
305
|
+
f"`{LICENSE_ENV_VAR}` to a valid license string. "
|
|
306
|
+
)
|
|
307
|
+
except LicenseValidationException as e:
|
|
308
|
+
structlogger.error("license.validation.error", error=e)
|
|
309
|
+
raise SystemExit(
|
|
310
|
+
f"Failed to validate Rasa Pro license "
|
|
311
|
+
f"which was read from environmental variable `{LICENSE_ENV_VAR}`. "
|
|
312
|
+
f"Please ensure `{LICENSE_ENV_VAR}` is set to a valid license string. "
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def get_license_expiration_date() -> Text:
|
|
317
|
+
"""Return the expiration date of the license."""
|
|
318
|
+
license_exp = property_of_active_license(lambda active_license: active_license.exp)
|
|
319
|
+
return datetime.fromtimestamp(license_exp, timezone.utc).isoformat()
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
def is_valid_license_scope(product_area: Text, license_scope: Text) -> bool:
|
|
323
|
+
"""Verifies that the license scope matches the rasa-plus product area."""
|
|
324
|
+
required_scopes = derive_scope_hierarchy(product_area)
|
|
325
|
+
licensed_product_areas = derive_scope_hierarchy(license_scope)
|
|
326
|
+
|
|
327
|
+
# update scopes that are required but not present in the license scope
|
|
328
|
+
required_scopes.difference_update(licensed_product_areas)
|
|
329
|
+
|
|
330
|
+
# this is dependent on a format where each product area is separated
|
|
331
|
+
# by whitespace in the license scope field value
|
|
332
|
+
licensed_scopes = license_scope.split()
|
|
333
|
+
|
|
334
|
+
# initialise a variable to count matches of
|
|
335
|
+
# licensed sub product scope pattern found in the required scopes set
|
|
336
|
+
sub_product_scope_match_count = 0
|
|
337
|
+
|
|
338
|
+
for required in required_scopes:
|
|
339
|
+
for licensed in licensed_scopes:
|
|
340
|
+
if re.search(licensed, required) is not None:
|
|
341
|
+
sub_product_scope_match_count += 1
|
|
342
|
+
|
|
343
|
+
return sub_product_scope_match_count == len(required_scopes)
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
def derive_scope_hierarchy(scope: Text) -> Set[Text]:
|
|
347
|
+
"""Derives all upper levels of the specified scopes and adds to a resulting set.
|
|
348
|
+
|
|
349
|
+
For example, the `rasa:pro:plus` scope would result in the following set:
|
|
350
|
+
{rasa, rasa:pro, rasa:pro:plus}.
|
|
351
|
+
"""
|
|
352
|
+
product_hierarchy = [area.split(SCOPE_DELIMITER) for area in scope.split()]
|
|
353
|
+
required_scopes = [
|
|
354
|
+
SCOPE_DELIMITER.join(hierarchy[0:end])
|
|
355
|
+
for hierarchy in product_hierarchy
|
|
356
|
+
for end in range(1, len(hierarchy) + 1)
|
|
357
|
+
]
|
|
358
|
+
|
|
359
|
+
return set(required_scopes)
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
T = TypeVar("T")
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
def property_of_active_license(prop: Callable[[License], T]) -> Optional[T]:
|
|
366
|
+
"""Return a property for this installation based on license.
|
|
367
|
+
|
|
368
|
+
Returns:
|
|
369
|
+
The property of the license if it exists, otherwise None.
|
|
370
|
+
"""
|
|
371
|
+
try:
|
|
372
|
+
retrieved_license = retrieve_license_from_env()
|
|
373
|
+
if not retrieved_license:
|
|
374
|
+
return None
|
|
375
|
+
decoded = License.decode(retrieved_license)
|
|
376
|
+
return prop(decoded)
|
|
377
|
+
except LicenseNotFoundException:
|
|
378
|
+
return None
|
|
379
|
+
except LicenseValidationException as e:
|
|
380
|
+
structlogger.warn("licensing.active_license.invalid", error=e)
|
|
381
|
+
return None
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
def get_license_hash() -> Optional[Text]:
|
|
385
|
+
"""Return the hash of the current active license."""
|
|
386
|
+
license_value = retrieve_license_from_env()
|
|
387
|
+
return hashlib.sha256(license_value.encode("utf-8")).hexdigest()
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
def is_champion_server_license() -> bool:
|
|
391
|
+
"""Return whether the current license is a developer license."""
|
|
392
|
+
|
|
393
|
+
def has_developer_license_scope(license: License) -> bool:
|
|
394
|
+
if CHAMPION_SERVER_LIMITED_SCOPE in license.scope:
|
|
395
|
+
return True
|
|
396
|
+
if CHAMPION_SERVER_INTERNAL_SCOPE in license.scope:
|
|
397
|
+
return True
|
|
398
|
+
return False
|
|
399
|
+
|
|
400
|
+
# or False is needed to handle the case where the license is not set
|
|
401
|
+
# this is to please the type checker
|
|
402
|
+
return property_of_active_license(has_developer_license_scope) or False
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
def conversation_limit_for_license() -> Optional[int]:
|
|
406
|
+
def conversations_limit(license: License) -> Optional[int]:
|
|
407
|
+
"""Return maximum number of conversations per month for this license."""
|
|
408
|
+
scope = license.scope
|
|
409
|
+
|
|
410
|
+
if CHAMPION_SERVER_LIMITED_SCOPE in scope:
|
|
411
|
+
return 1000
|
|
412
|
+
if CHAMPION_SERVER_INTERNAL_SCOPE in scope:
|
|
413
|
+
return 100
|
|
414
|
+
return None
|
|
415
|
+
|
|
416
|
+
return property_of_active_license(conversations_limit)
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
async def validate_limited_server_license(app: Sanic, loop: AbstractEventLoop) -> None:
|
|
420
|
+
"""Validate a limited server license and schedule conversation counting job."""
|
|
421
|
+
max_number_conversations = conversation_limit_for_license()
|
|
422
|
+
|
|
423
|
+
if app.ctx.agent:
|
|
424
|
+
if max_number_conversations is None:
|
|
425
|
+
structlogger.debug("licensing.server_limit.unlimited")
|
|
426
|
+
else:
|
|
427
|
+
store = app.ctx.agent.tracker_store
|
|
428
|
+
await run_conversation_counting(store, max_number_conversations)
|
|
429
|
+
await _schedule_conversation_counting(app, store, max_number_conversations)
|
|
430
|
+
else:
|
|
431
|
+
structlogger.warn("licensing.validate_limited_server_license.no_agent")
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
async def handle_soft_limit_reached(
|
|
435
|
+
conversation_count: int, max_number_conversations: int, month: datetime
|
|
436
|
+
) -> None:
|
|
437
|
+
"""Log a warning when the number of conversations exceeds the soft limit."""
|
|
438
|
+
structlogger.error(
|
|
439
|
+
"licensing.conversation_count.exceeded",
|
|
440
|
+
event_info=(
|
|
441
|
+
"The number of conversations has exceeded the limit granted "
|
|
442
|
+
"by your license. Please contact us to upgrade your license."
|
|
443
|
+
),
|
|
444
|
+
conversation_count=conversation_count,
|
|
445
|
+
max_number_conversations=max_number_conversations,
|
|
446
|
+
)
|
|
447
|
+
telemetry.track_conversation_count_soft_limit(conversation_count, month)
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
async def handle_hard_limit_reached(
|
|
451
|
+
conversation_count: int, max_number_conversations: int, month: datetime
|
|
452
|
+
) -> None:
|
|
453
|
+
"""Log an error when the number of conversations exceeds the hard limit."""
|
|
454
|
+
structlogger.error(
|
|
455
|
+
"licensing.conversation_count.exceeded",
|
|
456
|
+
event_info=(
|
|
457
|
+
"The number of conversations has exceeded the limit granted "
|
|
458
|
+
"by your license. Please contact us to upgrade your license."
|
|
459
|
+
),
|
|
460
|
+
conversation_count=conversation_count,
|
|
461
|
+
max_number_conversations=max_number_conversations,
|
|
462
|
+
)
|
|
463
|
+
telemetry.track_conversation_count_hard_limit(conversation_count, month)
|
|
464
|
+
print_error_and_exit(
|
|
465
|
+
"The number of conversations has exceeded the limit granted by your "
|
|
466
|
+
"license. Please contact us to upgrade your license."
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
def current_utc_month() -> datetime:
|
|
471
|
+
"""Return the current month in UTC timezone."""
|
|
472
|
+
return datetime.now(timezone.utc).replace(
|
|
473
|
+
day=1, hour=0, minute=0, second=0, microsecond=0
|
|
474
|
+
)
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
async def run_conversation_counting(
|
|
478
|
+
tracker_store: Optional["TrackerStore"], max_number_conversations: int
|
|
479
|
+
) -> None:
|
|
480
|
+
"""Count the number of conversations started in the current month and log it."""
|
|
481
|
+
start_of_month_utc = current_utc_month()
|
|
482
|
+
start_of_month_timestamp = start_of_month_utc.timestamp()
|
|
483
|
+
|
|
484
|
+
conversation_count = await _count_conversations_after(
|
|
485
|
+
tracker_store, start_of_month_timestamp
|
|
486
|
+
)
|
|
487
|
+
|
|
488
|
+
if conversation_count >= max_number_conversations * HARD_LIMIT_FACTOR:
|
|
489
|
+
# user is above the hard limit
|
|
490
|
+
await handle_hard_limit_reached(
|
|
491
|
+
conversation_count, max_number_conversations, start_of_month_utc
|
|
492
|
+
)
|
|
493
|
+
elif conversation_count > max_number_conversations:
|
|
494
|
+
await handle_soft_limit_reached(
|
|
495
|
+
conversation_count, max_number_conversations, start_of_month_utc
|
|
496
|
+
)
|
|
497
|
+
|
|
498
|
+
structlogger.debug(
|
|
499
|
+
"licensing.conversation_count",
|
|
500
|
+
conversation_count=conversation_count,
|
|
501
|
+
max_number_conversations=max_number_conversations,
|
|
502
|
+
)
|
|
503
|
+
telemetry.track_conversation_count(conversation_count, start_of_month_utc)
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
async def _schedule_conversation_counting(
|
|
507
|
+
app: Sanic, tracker_store: Optional["TrackerStore"], max_number_conversations: int
|
|
508
|
+
) -> None:
|
|
509
|
+
"""Schedule a job counting the number of conversations in the current month."""
|
|
510
|
+
|
|
511
|
+
async def conversation_counting_job(
|
|
512
|
+
app: Sanic,
|
|
513
|
+
tracker_store: Optional["TrackerStore"],
|
|
514
|
+
max_number_conversations: int,
|
|
515
|
+
) -> None:
|
|
516
|
+
try:
|
|
517
|
+
await run_conversation_counting(tracker_store, max_number_conversations)
|
|
518
|
+
except SystemExit:
|
|
519
|
+
# we've reached the conversation limit
|
|
520
|
+
app.stop()
|
|
521
|
+
|
|
522
|
+
(await jobs.scheduler()).add_job(
|
|
523
|
+
conversation_counting_job,
|
|
524
|
+
"interval",
|
|
525
|
+
# every 24 hours with a random offset of max 1 hour
|
|
526
|
+
# clusters tend to get started at the same time, this avoids them
|
|
527
|
+
# doing the "conversation counting work" at exactly the same time
|
|
528
|
+
seconds=24 * 60 * 60 + random.randint(0, 60 * 60),
|
|
529
|
+
args=[app, tracker_store, max_number_conversations],
|
|
530
|
+
id="count-conversations",
|
|
531
|
+
replace_existing=True,
|
|
532
|
+
)
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
async def _count_conversations_after(
|
|
536
|
+
tracker_store: Optional["TrackerStore"], after_timestamp: float
|
|
537
|
+
) -> int:
|
|
538
|
+
"""Count the number of conversations started in the current month."""
|
|
539
|
+
if tracker_store is None:
|
|
540
|
+
return 0
|
|
541
|
+
|
|
542
|
+
return await tracker_store.count_conversations(after_timestamp=after_timestamp)
|