rasa-pro 3.9.18__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 +415 -0
- rasa/__init__.py +10 -0
- rasa/__main__.py +156 -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 +146 -0
- rasa/cli/__init__.py +5 -0
- rasa/cli/arguments/__init__.py +0 -0
- rasa/cli/arguments/data.py +81 -0
- rasa/cli/arguments/default_arguments.py +165 -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 +204 -0
- rasa/cli/arguments/shell.py +13 -0
- rasa/cli/arguments/test.py +211 -0
- rasa/cli/arguments/train.py +263 -0
- rasa/cli/arguments/visualize.py +34 -0
- rasa/cli/arguments/x.py +30 -0
- rasa/cli/data.py +292 -0
- rasa/cli/e2e_test.py +586 -0
- rasa/cli/evaluate.py +222 -0
- rasa/cli/export.py +250 -0
- rasa/cli/inspect.py +63 -0
- rasa/cli/interactive.py +164 -0
- rasa/cli/license.py +65 -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 +12 -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 +45 -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.py +22 -0
- rasa/cli/project_templates/tutorial/config.yml +11 -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 +6 -0
- rasa/cli/project_templates/tutorial/domain.yml +21 -0
- rasa/cli/project_templates/tutorial/endpoints.yml +45 -0
- rasa/cli/run.py +135 -0
- rasa/cli/scaffold.py +269 -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 +266 -0
- rasa/cli/studio/train.py +59 -0
- rasa/cli/studio/upload.py +77 -0
- rasa/cli/telemetry.py +102 -0
- rasa/cli/test.py +280 -0
- rasa/cli/train.py +260 -0
- rasa/cli/utils.py +464 -0
- rasa/cli/visualize.py +40 -0
- rasa/cli/x.py +206 -0
- rasa/constants.py +37 -0
- rasa/core/__init__.py +17 -0
- rasa/core/actions/__init__.py +0 -0
- rasa/core/actions/action.py +1225 -0
- rasa/core/actions/action_clean_stack.py +59 -0
- rasa/core/actions/action_exceptions.py +24 -0
- rasa/core/actions/action_run_slot_rejections.py +207 -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 +188 -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 +140 -0
- rasa/core/actions/loops.py +114 -0
- rasa/core/actions/two_stage_fallback.py +186 -0
- rasa/core/agent.py +555 -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 +322 -0
- rasa/core/brokers/pika.py +386 -0
- rasa/core/brokers/sql.py +86 -0
- rasa/core/channels/__init__.py +55 -0
- rasa/core/channels/audiocodes.py +463 -0
- rasa/core/channels/botframework.py +338 -0
- rasa/core/channels/callback.py +84 -0
- rasa/core/channels/channel.py +419 -0
- rasa/core/channels/console.py +241 -0
- rasa/core/channels/development_inspector.py +93 -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-b6e548fe.js +1 -0
- rasa/core/channels/inspector/dist/assets/array-9f3ba611.js +1 -0
- rasa/core/channels/inspector/dist/assets/c4Diagram-d0fbc5ce-fa03ac9e.js +10 -0
- rasa/core/channels/inspector/dist/assets/classDiagram-936ed81e-ee67392a.js +2 -0
- rasa/core/channels/inspector/dist/assets/classDiagram-v2-c3cb15f1-9b283fae.js +2 -0
- rasa/core/channels/inspector/dist/assets/createText-62fc7601-8b6fcc2a.js +7 -0
- rasa/core/channels/inspector/dist/assets/edges-f2ad444c-22e77f4f.js +4 -0
- rasa/core/channels/inspector/dist/assets/erDiagram-9d236eb7-60ffc87f.js +51 -0
- rasa/core/channels/inspector/dist/assets/flowDb-1972c806-9dd802e4.js +6 -0
- rasa/core/channels/inspector/dist/assets/flowDiagram-7ea5b25a-5fa1912f.js +4 -0
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-1844e5a5.js +1 -0
- rasa/core/channels/inspector/dist/assets/flowchart-elk-definition-abe16c3d-622a1fd2.js +139 -0
- rasa/core/channels/inspector/dist/assets/ganttDiagram-9b5ea136-e285a63a.js +266 -0
- rasa/core/channels/inspector/dist/assets/gitGraphDiagram-99d0ae7c-f237bdca.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-4b03d70e.js +1 -0
- rasa/core/channels/inspector/dist/assets/index-3ee28881.css +1 -0
- rasa/core/channels/inspector/dist/assets/index-a5d3e69d.js +1040 -0
- rasa/core/channels/inspector/dist/assets/infoDiagram-736b4530-72a0fa5f.js +7 -0
- rasa/core/channels/inspector/dist/assets/init-77b53fdd.js +1 -0
- rasa/core/channels/inspector/dist/assets/journeyDiagram-df861f2b-82218c41.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-78cff630.js +1 -0
- rasa/core/channels/inspector/dist/assets/line-5038b469.js +1 -0
- rasa/core/channels/inspector/dist/assets/linear-c4fc4098.js +1 -0
- rasa/core/channels/inspector/dist/assets/mindmap-definition-beec6740-c33c8ea6.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-a8d03059.js +35 -0
- rasa/core/channels/inspector/dist/assets/quadrantDiagram-4d7f4fd6-6a0e56b2.js +7 -0
- rasa/core/channels/inspector/dist/assets/requirementDiagram-6fc4c22a-2dc7c7bd.js +52 -0
- rasa/core/channels/inspector/dist/assets/sankeyDiagram-8f13d901-2360fe39.js +8 -0
- rasa/core/channels/inspector/dist/assets/sequenceDiagram-b655622a-41b9f9ad.js +122 -0
- rasa/core/channels/inspector/dist/assets/stateDiagram-59f0c015-0aad326f.js +1 -0
- rasa/core/channels/inspector/dist/assets/stateDiagram-v2-2b26beab-9847d984.js +1 -0
- rasa/core/channels/inspector/dist/assets/styles-080da4f6-564d890e.js +110 -0
- rasa/core/channels/inspector/dist/assets/styles-3dcbcfbf-38957613.js +159 -0
- rasa/core/channels/inspector/dist/assets/styles-9c745c82-f0fc6921.js +207 -0
- rasa/core/channels/inspector/dist/assets/svgDrawCommon-4835440b-ef3c5a77.js +1 -0
- rasa/core/channels/inspector/dist/assets/timeline-definition-5b62e21b-bf3e91c1.js +61 -0
- rasa/core/channels/inspector/dist/assets/xychartDiagram-2b33534f-4d4026c0.js +7 -0
- rasa/core/channels/inspector/dist/index.html +41 -0
- rasa/core/channels/inspector/index.html +39 -0
- rasa/core/channels/inspector/jest.config.ts +13 -0
- rasa/core/channels/inspector/package.json +48 -0
- rasa/core/channels/inspector/setupTests.ts +2 -0
- rasa/core/channels/inspector/src/App.tsx +170 -0
- rasa/core/channels/inspector/src/components/DiagramFlow.tsx +107 -0
- rasa/core/channels/inspector/src/components/DialogueInformation.tsx +187 -0
- rasa/core/channels/inspector/src/components/DialogueStack.tsx +151 -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 +19 -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/formatters.test.ts +382 -0
- rasa/core/channels/inspector/src/helpers/formatters.ts +240 -0
- rasa/core/channels/inspector/src/helpers/utils.ts +42 -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 +64 -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 +6156 -0
- rasa/core/channels/mattermost.py +229 -0
- rasa/core/channels/rasa_chat.py +126 -0
- rasa/core/channels/rest.py +225 -0
- rasa/core/channels/rocketchat.py +174 -0
- rasa/core/channels/slack.py +620 -0
- rasa/core/channels/socketio.py +274 -0
- rasa/core/channels/telegram.py +298 -0
- rasa/core/channels/twilio.py +169 -0
- rasa/core/channels/twilio_voice.py +367 -0
- rasa/core/channels/vier_cvg.py +374 -0
- rasa/core/channels/webexteams.py +134 -0
- rasa/core/concurrent_lock_store.py +210 -0
- rasa/core/constants.py +107 -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 +121 -0
- rasa/core/information_retrieval/information_retrieval.py +129 -0
- rasa/core/information_retrieval/milvus.py +52 -0
- rasa/core/information_retrieval/qdrant.py +95 -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 +270 -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 +69 -0
- rasa/core/policies/__init__.py +0 -0
- rasa/core/policies/ensemble.py +329 -0
- rasa/core/policies/enterprise_search_policy.py +781 -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 +705 -0
- rasa/core/policies/flows/flow_step_result.py +43 -0
- rasa/core/policies/intentless_policy.py +922 -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 +1422 -0
- rasa/core/run.py +331 -0
- rasa/core/secrets_manager/__init__.py +0 -0
- rasa/core/secrets_manager/constants.py +32 -0
- rasa/core/secrets_manager/endpoints.py +391 -0
- rasa/core/secrets_manager/factory.py +233 -0
- rasa/core/secrets_manager/secret_manager.py +262 -0
- rasa/core/secrets_manager/vault.py +574 -0
- rasa/core/test.py +1335 -0
- rasa/core/tracker_store.py +1699 -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 +1745 -0
- rasa/core/training/story_conflict.py +381 -0
- rasa/core/training/training.py +93 -0
- rasa/core/utils.py +339 -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 +260 -0
- rasa/dialogue_understanding/coexistence/router_template.jinja2 +12 -0
- rasa/dialogue_understanding/commands/__init__.py +49 -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/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/generator/__init__.py +21 -0
- rasa/dialogue_understanding/generator/command_generator.py +343 -0
- rasa/dialogue_understanding/generator/constants.py +18 -0
- rasa/dialogue_understanding/generator/flow_document_template.jinja2 +4 -0
- rasa/dialogue_understanding/generator/flow_retrieval.py +412 -0
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +467 -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 +827 -0
- rasa/dialogue_understanding/generator/nlu_command_adapter.py +218 -0
- rasa/dialogue_understanding/generator/single_step/__init__.py +0 -0
- rasa/dialogue_understanding/generator/single_step/command_prompt_template.jinja2 +57 -0
- rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +345 -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 +248 -0
- rasa/dialogue_understanding/patterns/human_handoff.py +37 -0
- rasa/dialogue_understanding/patterns/internal_error.py +47 -0
- rasa/dialogue_understanding/patterns/search.py +37 -0
- rasa/dialogue_understanding/patterns/skip_question.py +38 -0
- rasa/dialogue_understanding/processor/__init__.py +0 -0
- rasa/dialogue_understanding/processor/command_processor.py +687 -0
- rasa/dialogue_understanding/processor/command_processor_component.py +39 -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/e2e_test/__init__.py +0 -0
- rasa/e2e_test/constants.py +11 -0
- rasa/e2e_test/e2e_test_case.py +366 -0
- rasa/e2e_test/e2e_test_result.py +34 -0
- rasa/e2e_test/e2e_test_runner.py +768 -0
- rasa/e2e_test/e2e_test_schema.yml +85 -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 +637 -0
- rasa/engine/loader.py +36 -0
- rasa/engine/recipes/__init__.py +0 -0
- rasa/engine/recipes/config_files/default_config.yml +44 -0
- rasa/engine/recipes/default_components.py +99 -0
- rasa/engine/recipes/default_recipe.py +1251 -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 +246 -0
- rasa/engine/storage/resource.py +110 -0
- rasa/engine/storage/storage.py +203 -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 +873 -0
- rasa/env.py +5 -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 +43 -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 +112 -0
- rasa/jupyter.py +63 -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_testing.py +457 -0
- rasa/model_training.py +536 -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/llm_intent_classifier.py +519 -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/persistor.py +282 -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 +106 -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 +1551 -0
- rasa/shared/__init__.py +0 -0
- rasa/shared/constants.py +192 -0
- rasa/shared/core/__init__.py +0 -0
- rasa/shared/core/command_payload_reader.py +109 -0
- rasa/shared/core/constants.py +167 -0
- rasa/shared/core/conversation.py +46 -0
- rasa/shared/core/domain.py +2107 -0
- rasa/shared/core/events.py +2504 -0
- rasa/shared/core/flows/__init__.py +7 -0
- rasa/shared/core/flows/flow.py +362 -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 +223 -0
- rasa/shared/core/flows/flows_yaml_schema.json +217 -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/validation.py +527 -0
- rasa/shared/core/flows/yaml_flows_io.py +278 -0
- rasa/shared/core/generator.py +908 -0
- rasa/shared/core/slot_mappings.py +526 -0
- rasa/shared/core/slots.py +649 -0
- rasa/shared/core/trackers.py +1177 -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 +838 -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 +163 -0
- rasa/shared/importers/__init__.py +0 -0
- rasa/shared/importers/importer.py +704 -0
- rasa/shared/importers/multi_project.py +203 -0
- rasa/shared/importers/rasa.py +99 -0
- rasa/shared/importers/utils.py +34 -0
- rasa/shared/nlu/__init__.py +0 -0
- rasa/shared/nlu/constants.py +47 -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 +603 -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 +730 -0
- rasa/shared/nlu/training_data/util.py +223 -0
- rasa/shared/providers/__init__.py +0 -0
- rasa/shared/providers/openai/__init__.py +0 -0
- rasa/shared/providers/openai/clients.py +43 -0
- rasa/shared/providers/openai/session_handler.py +110 -0
- rasa/shared/utils/__init__.py +0 -0
- rasa/shared/utils/cli.py +72 -0
- rasa/shared/utils/common.py +308 -0
- rasa/shared/utils/constants.py +4 -0
- rasa/shared/utils/io.py +415 -0
- rasa/shared/utils/llm.py +404 -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 +212 -0
- rasa/shared/utils/schemas/model_config.yml +46 -0
- rasa/shared/utils/schemas/stories.yml +173 -0
- rasa/shared/utils/yaml.py +786 -0
- rasa/studio/__init__.py +0 -0
- rasa/studio/auth.py +268 -0
- rasa/studio/config.py +127 -0
- rasa/studio/constants.py +18 -0
- rasa/studio/data_handler.py +359 -0
- rasa/studio/download.py +483 -0
- rasa/studio/results_logger.py +137 -0
- rasa/studio/train.py +135 -0
- rasa/studio/upload.py +433 -0
- rasa/telemetry.py +1737 -0
- rasa/tracing/__init__.py +0 -0
- rasa/tracing/config.py +353 -0
- rasa/tracing/constants.py +62 -0
- rasa/tracing/instrumentation/__init__.py +0 -0
- rasa/tracing/instrumentation/attribute_extractors.py +672 -0
- rasa/tracing/instrumentation/instrumentation.py +1185 -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 +635 -0
- rasa/utils/converter.py +53 -0
- rasa/utils/endpoints.py +302 -0
- rasa/utils/io.py +260 -0
- rasa/utils/licensing.py +534 -0
- rasa/utils/log_utils.py +174 -0
- rasa/utils/mapper.py +210 -0
- rasa/utils/ml_utils.py +145 -0
- rasa/utils/plotting.py +362 -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 +1337 -0
- rasa/version.py +3 -0
- rasa_pro-3.9.18.dist-info/METADATA +563 -0
- rasa_pro-3.9.18.dist-info/NOTICE +5 -0
- rasa_pro-3.9.18.dist-info/RECORD +662 -0
- rasa_pro-3.9.18.dist-info/WHEEL +4 -0
- rasa_pro-3.9.18.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
from typing import List, Optional, Set, Tuple
|
|
2
|
+
import typing
|
|
3
|
+
from rasa.dialogue_understanding.patterns.collect_information import (
|
|
4
|
+
CollectInformationPatternFlowStackFrame,
|
|
5
|
+
)
|
|
6
|
+
from rasa.dialogue_understanding.stack.frames import BaseFlowStackFrame
|
|
7
|
+
from rasa.dialogue_understanding.stack.dialogue_stack import DialogueStack
|
|
8
|
+
from rasa.dialogue_understanding.stack.frames import UserFlowStackFrame
|
|
9
|
+
from rasa.dialogue_understanding.stack.frames.flow_stack_frame import FlowStackFrameType
|
|
10
|
+
from rasa.dialogue_understanding.stack.frames.pattern_frame import PatternFlowStackFrame
|
|
11
|
+
from rasa.shared.core.flows.steps.collect import CollectInformationFlowStep
|
|
12
|
+
from rasa.shared.core.flows.steps.constants import END_STEP
|
|
13
|
+
from rasa.shared.core.flows.steps.continuation import ContinueFlowStep
|
|
14
|
+
from rasa.shared.core.flows import FlowsList
|
|
15
|
+
|
|
16
|
+
if typing.TYPE_CHECKING:
|
|
17
|
+
from rasa.shared.core.trackers import DialogueStateTracker
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def top_flow_frame(
|
|
21
|
+
dialogue_stack: DialogueStack,
|
|
22
|
+
ignore_collect_information_pattern: bool = True,
|
|
23
|
+
ignore_call_frames: bool = True,
|
|
24
|
+
) -> Optional[BaseFlowStackFrame]:
|
|
25
|
+
"""Returns the topmost flow frame from the tracker.
|
|
26
|
+
|
|
27
|
+
By default, the topmost flow frame is ignored if it is the
|
|
28
|
+
`pattern_collect_information`. This is because the `pattern_collect_information`
|
|
29
|
+
is a special flow frame that is used to collect information from the user
|
|
30
|
+
and commonly, is not what you are looking for when you want the topmost frame.
|
|
31
|
+
|
|
32
|
+
Also excludes frames created by a call step. They are treated as if they are
|
|
33
|
+
directly part of the flow that called them.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
dialogue_stack: The dialogue stack to use.
|
|
37
|
+
ignore_collect_information_pattern: Whether to ignore the
|
|
38
|
+
`pattern_collect_information` frame.
|
|
39
|
+
ignore_call_frames: Whether to ignore user frames of type `call`
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
The topmost flow frame from the tracker. `None` if there
|
|
43
|
+
is no frame on the stack.
|
|
44
|
+
"""
|
|
45
|
+
for frame in reversed(dialogue_stack.frames):
|
|
46
|
+
if ignore_collect_information_pattern and isinstance(
|
|
47
|
+
frame, CollectInformationPatternFlowStackFrame
|
|
48
|
+
):
|
|
49
|
+
continue
|
|
50
|
+
if ignore_call_frames and (
|
|
51
|
+
isinstance(frame, UserFlowStackFrame)
|
|
52
|
+
and frame.frame_type == FlowStackFrameType.CALL
|
|
53
|
+
):
|
|
54
|
+
continue
|
|
55
|
+
if isinstance(frame, BaseFlowStackFrame):
|
|
56
|
+
return frame
|
|
57
|
+
return None
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def top_user_flow_frame(dialogue_stack: DialogueStack) -> Optional[UserFlowStackFrame]:
|
|
61
|
+
"""Returns the topmost user flow frame from the tracker.
|
|
62
|
+
|
|
63
|
+
User flows are flows that are created by developers of an assistant and
|
|
64
|
+
describe tasks the assistant can fulfil. The topmost user flow frame is
|
|
65
|
+
the topmost frame on the stack for one of these user flows. While looking
|
|
66
|
+
for this topmost user flow, other frame types such as PatternFrames,
|
|
67
|
+
SearchFrames, ChitchatFrames, and user flows started through call steps
|
|
68
|
+
are skipped. The latter are treated as part of the calling user flow.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
dialogue_stack: The dialogue stack to use.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
The topmost user flow frame from the tracker.
|
|
75
|
+
"""
|
|
76
|
+
for frame in reversed(dialogue_stack.frames):
|
|
77
|
+
if (
|
|
78
|
+
isinstance(frame, UserFlowStackFrame)
|
|
79
|
+
and frame.frame_type != FlowStackFrameType.CALL
|
|
80
|
+
):
|
|
81
|
+
return frame
|
|
82
|
+
return None
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def filled_slots_for_active_flow(
|
|
86
|
+
tracker: "DialogueStateTracker", all_flows: FlowsList
|
|
87
|
+
) -> Tuple[Set[str], Optional[str]]:
|
|
88
|
+
"""Get all slots that have been filled for the 'current user flow'.
|
|
89
|
+
|
|
90
|
+
All patterns that sit ontop of that user flow as well as
|
|
91
|
+
flows called by this flow, are also included.
|
|
92
|
+
|
|
93
|
+
Any collect information step that is part of a pattern on top of the current
|
|
94
|
+
user flow are also included.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
tracker: The tracker to get the filled slots from.
|
|
98
|
+
all_flows: All flows.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
All slots that have been filled for the current flow and the id of the currently
|
|
102
|
+
active flow.
|
|
103
|
+
"""
|
|
104
|
+
stack = tracker.stack
|
|
105
|
+
user_frame = top_user_flow_frame(stack)
|
|
106
|
+
active_flow = user_frame.flow_id if user_frame else None
|
|
107
|
+
|
|
108
|
+
filled_slots = set()
|
|
109
|
+
for collect_step, _ in previous_collect_steps_for_active_flow(tracker, all_flows):
|
|
110
|
+
filled_slots.add(collect_step.collect)
|
|
111
|
+
|
|
112
|
+
return filled_slots, active_flow
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def previous_collect_steps_for_active_flow(
|
|
116
|
+
tracker: "DialogueStateTracker", all_flows: FlowsList
|
|
117
|
+
) -> List[Tuple[CollectInformationFlowStep, str]]:
|
|
118
|
+
stack = tracker.stack
|
|
119
|
+
user_frame = top_user_flow_frame(stack)
|
|
120
|
+
|
|
121
|
+
if not user_frame:
|
|
122
|
+
return []
|
|
123
|
+
|
|
124
|
+
collect_steps: List[Tuple[CollectInformationFlowStep, str]] = []
|
|
125
|
+
|
|
126
|
+
active_frames = {frame.frame_id for frame in stack.frames}
|
|
127
|
+
|
|
128
|
+
for previous_stack in tracker.previous_stack_states():
|
|
129
|
+
active_frame = top_user_flow_frame(previous_stack)
|
|
130
|
+
if not active_frame or active_frame.frame_id != user_frame.frame_id:
|
|
131
|
+
continue
|
|
132
|
+
|
|
133
|
+
top_frame = previous_stack.top()
|
|
134
|
+
if not isinstance(top_frame, BaseFlowStackFrame):
|
|
135
|
+
continue
|
|
136
|
+
|
|
137
|
+
step = top_frame.step(all_flows)
|
|
138
|
+
if not isinstance(step, CollectInformationFlowStep):
|
|
139
|
+
continue
|
|
140
|
+
|
|
141
|
+
if isinstance(top_frame, UserFlowStackFrame):
|
|
142
|
+
collect_steps.append((step, top_frame.flow_id))
|
|
143
|
+
elif (
|
|
144
|
+
isinstance(top_frame, PatternFlowStackFrame)
|
|
145
|
+
and top_frame.frame_id in active_frames
|
|
146
|
+
):
|
|
147
|
+
# if this is a pattern, it is only relevant if it is still
|
|
148
|
+
# active in the current state of the conversation.
|
|
149
|
+
# completed patterns in the past are not relevant
|
|
150
|
+
collect_steps.append((step, top_frame.flow_id))
|
|
151
|
+
|
|
152
|
+
return collect_steps
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def user_flows_on_the_stack(dialogue_stack: DialogueStack) -> Set[str]:
|
|
156
|
+
"""Get all user flows that are currently on the stack.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
dialogue_stack: The dialogue stack.
|
|
160
|
+
|
|
161
|
+
Returns:
|
|
162
|
+
All user flows that are currently on the stack.
|
|
163
|
+
"""
|
|
164
|
+
return {
|
|
165
|
+
f.flow_id for f in dialogue_stack.frames if isinstance(f, UserFlowStackFrame)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def end_top_user_flow(stack: DialogueStack) -> DialogueStack:
|
|
170
|
+
"""Ends all frames on top of the stack including the topmost user frame.
|
|
171
|
+
|
|
172
|
+
Ends all flows until the next user flow is reached. This is useful
|
|
173
|
+
if you want to end all flows that are currently on the stack and
|
|
174
|
+
the user flow that triggered them.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
stack: The dialogue stack.
|
|
178
|
+
"""
|
|
179
|
+
updated_stack = stack.copy()
|
|
180
|
+
|
|
181
|
+
for frame in reversed(updated_stack.frames):
|
|
182
|
+
if isinstance(frame, BaseFlowStackFrame):
|
|
183
|
+
frame.step_id = ContinueFlowStep.continue_step_for_id(END_STEP)
|
|
184
|
+
if isinstance(frame, UserFlowStackFrame):
|
|
185
|
+
break
|
|
186
|
+
return updated_stack
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def get_collect_steps_excluding_ask_before_filling_for_active_flow(
|
|
190
|
+
dialogue_stack: DialogueStack, all_flows: FlowsList
|
|
191
|
+
) -> Set[str]:
|
|
192
|
+
"""Get all collect steps that are part of the current flow, without
|
|
193
|
+
considering the collect steps that has to be asked before filling.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
dialogue_stack: The dialogue stack.
|
|
197
|
+
all_flows: All flows.
|
|
198
|
+
|
|
199
|
+
Returns:
|
|
200
|
+
All collect steps that are part of the current active flow,
|
|
201
|
+
excluding the collect steps that have to be asked before filling.
|
|
202
|
+
"""
|
|
203
|
+
active_frame = top_user_flow_frame(dialogue_stack)
|
|
204
|
+
if active_frame is None:
|
|
205
|
+
return set()
|
|
206
|
+
active_flow = active_frame.flow(all_flows)
|
|
207
|
+
return set(
|
|
208
|
+
step.collect
|
|
209
|
+
for step in active_flow.get_collect_steps()
|
|
210
|
+
if not step.ask_before_filling
|
|
211
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
SCHEMA_FILE_PATH = "e2e_test/e2e_test_schema.yml"
|
|
2
|
+
|
|
3
|
+
KEY_FIXTURES = "fixtures"
|
|
4
|
+
KEY_USER_INPUT = "user"
|
|
5
|
+
KEY_BOT_INPUT = "bot"
|
|
6
|
+
KEY_BOT_UTTERED = "utter"
|
|
7
|
+
KEY_SLOT_SET = "slot_was_set"
|
|
8
|
+
KEY_SLOT_NOT_SET = "slot_was_not_set"
|
|
9
|
+
KEY_STEPS = "steps"
|
|
10
|
+
KEY_TEST_CASE = "test_case"
|
|
11
|
+
KEY_METADATA = "metadata"
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from typing import Any, Dict, List, Optional, Text, Union
|
|
4
|
+
|
|
5
|
+
from rasa.shared.core.events import BotUttered, SlotSet, UserUttered
|
|
6
|
+
|
|
7
|
+
from rasa.e2e_test.constants import (
|
|
8
|
+
KEY_BOT_INPUT,
|
|
9
|
+
KEY_BOT_UTTERED,
|
|
10
|
+
KEY_FIXTURES,
|
|
11
|
+
KEY_METADATA,
|
|
12
|
+
KEY_SLOT_NOT_SET,
|
|
13
|
+
KEY_SLOT_SET,
|
|
14
|
+
KEY_STEPS,
|
|
15
|
+
KEY_TEST_CASE,
|
|
16
|
+
KEY_USER_INPUT,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass(frozen=True)
|
|
23
|
+
class Fixture:
|
|
24
|
+
"""Class for storing an input fixture."""
|
|
25
|
+
|
|
26
|
+
name: Text
|
|
27
|
+
slots_set: Dict[Text, Any]
|
|
28
|
+
|
|
29
|
+
@staticmethod
|
|
30
|
+
def from_dict(fixture_dict: Dict[Text, Any]) -> "Fixture":
|
|
31
|
+
"""Creates a fixture from a dictionary.
|
|
32
|
+
|
|
33
|
+
Example:
|
|
34
|
+
>>> Fixture.from_dict({"some_fixture": [{"slot_name": "slot_value"}]})
|
|
35
|
+
Fixture(name="some_fixture", slots_set={"slot_name": "slot_value"})
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
fixture_dict: Dictionary containing the fixture.
|
|
39
|
+
"""
|
|
40
|
+
return Fixture(
|
|
41
|
+
name=next(iter(fixture_dict.keys())),
|
|
42
|
+
slots_set={
|
|
43
|
+
slot_name: slot_value
|
|
44
|
+
for slots_list in fixture_dict.values()
|
|
45
|
+
for slot_dict in slots_list
|
|
46
|
+
for slot_name, slot_value in slot_dict.items()
|
|
47
|
+
},
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@dataclass(frozen=True)
|
|
52
|
+
class TestStep:
|
|
53
|
+
"""Class for storing the input test step.
|
|
54
|
+
|
|
55
|
+
Instances are frozen to make sure the underlying dictionary stays in sync
|
|
56
|
+
with the text and actor attributes.
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
actor: Text
|
|
60
|
+
text: Optional[Text] = None
|
|
61
|
+
template: Optional[Text] = None
|
|
62
|
+
line: Optional[int] = None
|
|
63
|
+
slot_was_set: bool = False
|
|
64
|
+
slot_was_not_set: bool = False
|
|
65
|
+
_slot_instance: Optional[Union[Text, Dict[Text, Any]]] = None
|
|
66
|
+
_underlying: Optional[Dict[Text, Any]] = None
|
|
67
|
+
metadata_name: Optional[Text] = None
|
|
68
|
+
|
|
69
|
+
@staticmethod
|
|
70
|
+
def from_dict(test_step_dict: Dict[Text, Any]) -> "TestStep":
|
|
71
|
+
"""Creates a test step from a dictionary.
|
|
72
|
+
|
|
73
|
+
Example:
|
|
74
|
+
>>> TestStep.from_dict({"user": "hello"})
|
|
75
|
+
TestStep(text="hello", actor="user")
|
|
76
|
+
>>> TestStep.from_dict({"user": "hello", metadata: "some_metadata"})
|
|
77
|
+
TestStep(text="hello", actor="user", metadata_name="some_metadata")
|
|
78
|
+
>>> TestStep.from_dict({"bot": "hello world"})
|
|
79
|
+
TestStep(text="hello world", actor="bot")
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
test_step_dict: Dictionary containing the test step.
|
|
83
|
+
"""
|
|
84
|
+
TestStep._validate_input_dict(test_step_dict)
|
|
85
|
+
slot_instance = test_step_dict.get(KEY_SLOT_SET)
|
|
86
|
+
if test_step_dict.get(KEY_SLOT_NOT_SET):
|
|
87
|
+
slot_instance = test_step_dict.get(KEY_SLOT_NOT_SET)
|
|
88
|
+
|
|
89
|
+
return TestStep(
|
|
90
|
+
text=test_step_dict.get(
|
|
91
|
+
KEY_USER_INPUT, test_step_dict.get(KEY_BOT_INPUT, "")
|
|
92
|
+
).strip()
|
|
93
|
+
or None,
|
|
94
|
+
template=test_step_dict.get(KEY_BOT_UTTERED),
|
|
95
|
+
actor=KEY_USER_INPUT if KEY_USER_INPUT in test_step_dict else KEY_BOT_INPUT,
|
|
96
|
+
line=test_step_dict.lc.line + 1 if hasattr(test_step_dict, "lc") else None,
|
|
97
|
+
slot_was_set=bool(test_step_dict.get(KEY_SLOT_SET)),
|
|
98
|
+
slot_was_not_set=bool(test_step_dict.get(KEY_SLOT_NOT_SET)),
|
|
99
|
+
_slot_instance=slot_instance,
|
|
100
|
+
_underlying=test_step_dict,
|
|
101
|
+
metadata_name=test_step_dict.get(KEY_METADATA, ""),
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
@staticmethod
|
|
105
|
+
def _validate_input_dict(test_step_dict: Dict[Text, Any]) -> None:
|
|
106
|
+
if (
|
|
107
|
+
KEY_USER_INPUT not in test_step_dict
|
|
108
|
+
and KEY_BOT_INPUT not in test_step_dict
|
|
109
|
+
and KEY_BOT_UTTERED not in test_step_dict
|
|
110
|
+
and KEY_SLOT_SET not in test_step_dict
|
|
111
|
+
and KEY_SLOT_NOT_SET not in test_step_dict
|
|
112
|
+
):
|
|
113
|
+
raise ValueError(
|
|
114
|
+
f"Test step is missing either the {KEY_USER_INPUT}, {KEY_BOT_INPUT}, "
|
|
115
|
+
f"{KEY_SLOT_NOT_SET}, {KEY_SLOT_SET} "
|
|
116
|
+
f"or {KEY_BOT_UTTERED} key: {test_step_dict}"
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
if (
|
|
120
|
+
test_step_dict.get(KEY_SLOT_SET) is not None
|
|
121
|
+
and test_step_dict.get(KEY_SLOT_NOT_SET) is not None
|
|
122
|
+
):
|
|
123
|
+
raise ValueError(
|
|
124
|
+
f"Test step has both {KEY_SLOT_SET} and {KEY_SLOT_NOT_SET} keys: "
|
|
125
|
+
f"{test_step_dict}. You must only use one of the keys in a test step."
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
def as_dict(self) -> Dict[Text, Any]:
|
|
129
|
+
"""Returns the underlying dictionary of the test step."""
|
|
130
|
+
return self._underlying or {}
|
|
131
|
+
|
|
132
|
+
def matches_event(self, other: Union[BotUttered, SlotSet, None]) -> bool:
|
|
133
|
+
"""Compares the test step with BotUttered or SlotSet event.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
other: BotUttered or SlotSet event to compare with.
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
`True` if the event and step match, `False` otherwise.
|
|
140
|
+
"""
|
|
141
|
+
if other is None or self.actor != "bot":
|
|
142
|
+
return False
|
|
143
|
+
|
|
144
|
+
if isinstance(other, BotUttered):
|
|
145
|
+
return self._do_utterances_match(other)
|
|
146
|
+
elif isinstance(other, SlotSet):
|
|
147
|
+
return self._do_slots_match(other)
|
|
148
|
+
|
|
149
|
+
return False
|
|
150
|
+
|
|
151
|
+
def _do_utterances_match(self, other: BotUttered) -> bool:
|
|
152
|
+
if self.text:
|
|
153
|
+
return other.text == self.text
|
|
154
|
+
elif self.template:
|
|
155
|
+
# we do set this utter_action metadata in the `ActionBotResponse`
|
|
156
|
+
# action, so we can check if the template is the same
|
|
157
|
+
return other.metadata.get("utter_action") == self.template
|
|
158
|
+
|
|
159
|
+
return False
|
|
160
|
+
|
|
161
|
+
def _do_slots_match(self, other: SlotSet) -> bool:
|
|
162
|
+
if self._slot_instance:
|
|
163
|
+
slot_name, slot_value = self.get_slot_name(), self.get_slot_value()
|
|
164
|
+
if isinstance(self._slot_instance, dict):
|
|
165
|
+
return other.key == slot_name and other.value == slot_value
|
|
166
|
+
return other.key == slot_name
|
|
167
|
+
|
|
168
|
+
return False
|
|
169
|
+
|
|
170
|
+
def get_slot_name(self) -> Optional[Text]:
|
|
171
|
+
"""Returns the slot name if the test step is a slot action."""
|
|
172
|
+
if isinstance(self._slot_instance, str):
|
|
173
|
+
return self._slot_instance
|
|
174
|
+
if isinstance(self._slot_instance, dict):
|
|
175
|
+
return next(iter(self._slot_instance.keys()))
|
|
176
|
+
return None
|
|
177
|
+
|
|
178
|
+
def get_slot_value(self) -> Optional[Any]:
|
|
179
|
+
"""Returns the slot value if the test step is a slot action."""
|
|
180
|
+
if isinstance(self._slot_instance, dict):
|
|
181
|
+
return next(iter(self._slot_instance.values()))
|
|
182
|
+
return None
|
|
183
|
+
|
|
184
|
+
def is_slot_instance_dict(self) -> bool:
|
|
185
|
+
"""Asserts if the slot instance is a dictionary."""
|
|
186
|
+
return isinstance(self._slot_instance, dict)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
@dataclass
|
|
190
|
+
class ActualStepOutput:
|
|
191
|
+
"""Class for storing the events that are generated as a response from the bot."""
|
|
192
|
+
|
|
193
|
+
actor: Text
|
|
194
|
+
text: Optional[Text]
|
|
195
|
+
events: List[Union[BotUttered, UserUttered, SlotSet]]
|
|
196
|
+
bot_uttered_events: List[BotUttered]
|
|
197
|
+
user_uttered_events: List[UserUttered]
|
|
198
|
+
slot_set_events: List[SlotSet]
|
|
199
|
+
|
|
200
|
+
@staticmethod
|
|
201
|
+
def from_test_step(
|
|
202
|
+
test_step: TestStep,
|
|
203
|
+
events: List[Union[BotUttered, UserUttered, SlotSet]],
|
|
204
|
+
) -> "ActualStepOutput":
|
|
205
|
+
"""Creates a test step response from a test step and events.
|
|
206
|
+
|
|
207
|
+
Example:
|
|
208
|
+
>>> ActualStepOutput.from_test_step(TestStep(text="hello", actor="bot"))
|
|
209
|
+
ActualStepOutput(text="hello", actor="bot")
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
test_step: Test step.
|
|
213
|
+
events: Events generated by the bot.
|
|
214
|
+
"""
|
|
215
|
+
bot_uttered_events, user_uttered_events, slot_set_events = [], [], []
|
|
216
|
+
for event in events or []:
|
|
217
|
+
if isinstance(event, BotUttered):
|
|
218
|
+
bot_uttered_events.append(event)
|
|
219
|
+
elif isinstance(event, UserUttered):
|
|
220
|
+
user_uttered_events.append(event)
|
|
221
|
+
elif isinstance(event, SlotSet):
|
|
222
|
+
slot_set_events.append(event)
|
|
223
|
+
|
|
224
|
+
return ActualStepOutput(
|
|
225
|
+
text=test_step.text,
|
|
226
|
+
actor=test_step.actor,
|
|
227
|
+
events=events,
|
|
228
|
+
bot_uttered_events=bot_uttered_events,
|
|
229
|
+
user_uttered_events=user_uttered_events,
|
|
230
|
+
slot_set_events=slot_set_events,
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
def remove_bot_uttered_event(self, bot_utter: BotUttered) -> None:
|
|
234
|
+
"""Removes bot_uttered_event from the ActualStepOutput."""
|
|
235
|
+
if bot_utter in self.bot_uttered_events:
|
|
236
|
+
self.bot_uttered_events.remove(bot_utter)
|
|
237
|
+
self.events.remove(bot_utter)
|
|
238
|
+
|
|
239
|
+
def remove_user_uttered_event(self, user_utter: UserUttered) -> None:
|
|
240
|
+
"""Removes user_uttered_event from the ActualStepOutput."""
|
|
241
|
+
if user_utter in self.user_uttered_events:
|
|
242
|
+
self.user_uttered_events.remove(user_utter)
|
|
243
|
+
self.events.remove(user_utter)
|
|
244
|
+
|
|
245
|
+
def remove_slot_set_event(self, slot_set: SlotSet) -> None:
|
|
246
|
+
"""Removes slot_set_event from the ActualStepOutput."""
|
|
247
|
+
if slot_set in self.slot_set_events:
|
|
248
|
+
self.slot_set_events.remove(slot_set)
|
|
249
|
+
self.events.remove(slot_set)
|
|
250
|
+
|
|
251
|
+
def get_user_uttered_event(self) -> Optional[UserUttered]:
|
|
252
|
+
"""Returns the user_uttered_event from the ActualStepOutput."""
|
|
253
|
+
if self.user_uttered_events:
|
|
254
|
+
# we assume that there is only one user_uttered_event
|
|
255
|
+
# in the ActualStepOutput since the response is
|
|
256
|
+
# only from one TestStep with one user utterance
|
|
257
|
+
try:
|
|
258
|
+
return self.user_uttered_events[0]
|
|
259
|
+
except IndexError:
|
|
260
|
+
logger.debug(
|
|
261
|
+
f"Could not find `UserUttered` event in the ActualStepOutput: "
|
|
262
|
+
f"{self}"
|
|
263
|
+
)
|
|
264
|
+
return None
|
|
265
|
+
return None
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
@dataclass
|
|
269
|
+
class TestCase:
|
|
270
|
+
"""Class for storing the input test case."""
|
|
271
|
+
|
|
272
|
+
name: Text
|
|
273
|
+
steps: List[TestStep]
|
|
274
|
+
file: Optional[Text] = None
|
|
275
|
+
line: Optional[int] = None
|
|
276
|
+
fixture_names: Optional[List[Text]] = None
|
|
277
|
+
metadata_name: Optional[Text] = None
|
|
278
|
+
|
|
279
|
+
@staticmethod
|
|
280
|
+
def from_dict(
|
|
281
|
+
input_test_case: Dict[Text, Any], file: Optional[Text] = None
|
|
282
|
+
) -> "TestCase":
|
|
283
|
+
"""Creates a test case from a dictionary.
|
|
284
|
+
|
|
285
|
+
Example:
|
|
286
|
+
>>> TestCase.from_dict({"test_case": "test", "steps": [{"user": "hello"}]})
|
|
287
|
+
TestCase(name="test", steps=[TestStep(text="hello", actor="user")])
|
|
288
|
+
|
|
289
|
+
Args:
|
|
290
|
+
input_test_case: Dictionary containing the test case.
|
|
291
|
+
file: File name of the test case.
|
|
292
|
+
|
|
293
|
+
Returns:
|
|
294
|
+
Test case object.
|
|
295
|
+
"""
|
|
296
|
+
steps = []
|
|
297
|
+
|
|
298
|
+
for step in input_test_case.get(KEY_STEPS, []):
|
|
299
|
+
if KEY_SLOT_SET in step:
|
|
300
|
+
for slot in step[KEY_SLOT_SET]:
|
|
301
|
+
step_copy = step.copy()
|
|
302
|
+
step_copy[KEY_SLOT_SET] = slot
|
|
303
|
+
steps.append(TestStep.from_dict(step_copy))
|
|
304
|
+
elif KEY_SLOT_NOT_SET in step:
|
|
305
|
+
for slot in step[KEY_SLOT_NOT_SET]:
|
|
306
|
+
step_copy = step.copy()
|
|
307
|
+
step_copy[KEY_SLOT_NOT_SET] = slot
|
|
308
|
+
steps.append(TestStep.from_dict(step_copy))
|
|
309
|
+
else:
|
|
310
|
+
steps.append(TestStep.from_dict(step))
|
|
311
|
+
|
|
312
|
+
return TestCase(
|
|
313
|
+
name=input_test_case.get(KEY_TEST_CASE, "default"),
|
|
314
|
+
steps=steps,
|
|
315
|
+
file=file,
|
|
316
|
+
line=input_test_case.lc.line + 1
|
|
317
|
+
if hasattr(input_test_case, "lc")
|
|
318
|
+
else None,
|
|
319
|
+
fixture_names=input_test_case.get(KEY_FIXTURES),
|
|
320
|
+
metadata_name=input_test_case.get(KEY_METADATA),
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
def file_with_line(self) -> Text:
|
|
324
|
+
"""Returns the file name and line number of the test case."""
|
|
325
|
+
if not self.file:
|
|
326
|
+
return ""
|
|
327
|
+
|
|
328
|
+
line = str(self.line) if self.line is not None else ""
|
|
329
|
+
return f"{self.file}:{line}"
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
@dataclass(frozen=True)
|
|
333
|
+
class Metadata:
|
|
334
|
+
"""Class for storing an input metadata."""
|
|
335
|
+
|
|
336
|
+
name: Text
|
|
337
|
+
metadata: Dict[Text, Any]
|
|
338
|
+
|
|
339
|
+
@staticmethod
|
|
340
|
+
def from_dict(metadata_dict: Dict[Text, Any]) -> "Metadata":
|
|
341
|
+
"""Creates a metadata from a dictionary.
|
|
342
|
+
|
|
343
|
+
Example:
|
|
344
|
+
>>> Metadata.from_dict({"some_metadata": {"room": "test_room"}})
|
|
345
|
+
Metadata(name="some_metadata", metadata={"room": "test_room"})
|
|
346
|
+
|
|
347
|
+
Args:
|
|
348
|
+
metadata_dict: Dictionary containing the metadata.
|
|
349
|
+
"""
|
|
350
|
+
return Metadata(
|
|
351
|
+
name=next(iter(metadata_dict.keys())),
|
|
352
|
+
metadata={
|
|
353
|
+
metadata_name: metadata_value
|
|
354
|
+
for metadata in metadata_dict.values()
|
|
355
|
+
for metadata_name, metadata_value in metadata.items()
|
|
356
|
+
},
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
@dataclass(frozen=True)
|
|
361
|
+
class TestSuite:
|
|
362
|
+
"""Class for representing all top level test suite keys."""
|
|
363
|
+
|
|
364
|
+
test_cases: List[TestCase]
|
|
365
|
+
fixtures: List[Fixture]
|
|
366
|
+
metadata: List[Metadata]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Any, Dict, List, Optional, Text
|
|
3
|
+
|
|
4
|
+
from rasa.e2e_test.e2e_test_case import TestCase
|
|
5
|
+
|
|
6
|
+
NO_RESPONSE = "* No Bot Response *"
|
|
7
|
+
NO_SLOT = "* No Slot Set *"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class TestResult:
|
|
12
|
+
"""Class for storing results of every test case run."""
|
|
13
|
+
|
|
14
|
+
test_case: TestCase
|
|
15
|
+
pass_status: bool
|
|
16
|
+
difference: List[Text]
|
|
17
|
+
error_line: Optional[int] = None
|
|
18
|
+
|
|
19
|
+
def as_dict(self) -> Dict[Text, Any]:
|
|
20
|
+
"""Returns the test result as a dictionary."""
|
|
21
|
+
return {
|
|
22
|
+
"name": self.test_case.name,
|
|
23
|
+
"pass_status": self.pass_status,
|
|
24
|
+
"expected_steps": [s.as_dict() for s in self.test_case.steps],
|
|
25
|
+
"difference": self.difference,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class TestFailure:
|
|
31
|
+
"""Class for storing the test case failure."""
|
|
32
|
+
|
|
33
|
+
test_case: TestCase
|
|
34
|
+
error_line: Optional[int]
|