rasa-pro 3.8.16__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 +380 -0
- rasa/__init__.py +10 -0
- rasa/__main__.py +151 -0
- rasa/anonymization/__init__.py +2 -0
- rasa/anonymization/anonymisation_rule_yaml_reader.py +91 -0
- rasa/anonymization/anonymization_pipeline.py +287 -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 +117 -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 +566 -0
- rasa/cli/evaluate.py +222 -0
- rasa/cli/export.py +251 -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 +33 -0
- rasa/cli/project_templates/calm/domain/list_contacts.yml +14 -0
- rasa/cli/project_templates/calm/domain/remove_contact.yml +31 -0
- rasa/cli/project_templates/calm/domain/shared.yml +5 -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/domain.yml +17 -0
- rasa/cli/project_templates/tutorial/endpoints.yml +45 -0
- rasa/cli/run.py +136 -0
- rasa/cli/scaffold.py +268 -0
- rasa/cli/shell.py +141 -0
- rasa/cli/studio/__init__.py +0 -0
- rasa/cli/studio/download.py +51 -0
- rasa/cli/studio/studio.py +110 -0
- rasa/cli/studio/train.py +59 -0
- rasa/cli/studio/upload.py +85 -0
- rasa/cli/telemetry.py +90 -0
- rasa/cli/test.py +280 -0
- rasa/cli/train.py +260 -0
- rasa/cli/utils.py +453 -0
- rasa/cli/visualize.py +40 -0
- rasa/cli/x.py +205 -0
- rasa/constants.py +37 -0
- rasa/core/__init__.py +17 -0
- rasa/core/actions/__init__.py +0 -0
- rasa/core/actions/action.py +1450 -0
- rasa/core/actions/action_clean_stack.py +59 -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 +2 -0
- rasa/core/actions/forms.py +737 -0
- rasa/core/actions/loops.py +111 -0
- rasa/core/actions/two_stage_fallback.py +186 -0
- rasa/core/agent.py +557 -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 +387 -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 +339 -0
- rasa/core/channels/callback.py +85 -0
- rasa/core/channels/channel.py +419 -0
- rasa/core/channels/console.py +243 -0
- rasa/core/channels/development_inspector.py +93 -0
- rasa/core/channels/facebook.py +422 -0
- rasa/core/channels/hangouts.py +335 -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-5623b6dc.js +1 -0
- rasa/core/channels/inspector/dist/assets/array-9f3ba611.js +1 -0
- rasa/core/channels/inspector/dist/assets/c4Diagram-d0fbc5ce-685c106a.js +10 -0
- rasa/core/channels/inspector/dist/assets/classDiagram-936ed81e-8cbed007.js +2 -0
- rasa/core/channels/inspector/dist/assets/classDiagram-v2-c3cb15f1-5889cf12.js +2 -0
- rasa/core/channels/inspector/dist/assets/createText-62fc7601-24c249d7.js +7 -0
- rasa/core/channels/inspector/dist/assets/edges-f2ad444c-7dd06a75.js +4 -0
- rasa/core/channels/inspector/dist/assets/erDiagram-9d236eb7-62c1e54c.js +51 -0
- rasa/core/channels/inspector/dist/assets/flowDb-1972c806-ce49b86f.js +6 -0
- rasa/core/channels/inspector/dist/assets/flowDiagram-7ea5b25a-4067e48f.js +4 -0
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-85583a23.js +1 -0
- rasa/core/channels/inspector/dist/assets/flowchart-elk-definition-abe16c3d-59fe4051.js +139 -0
- rasa/core/channels/inspector/dist/assets/ganttDiagram-9b5ea136-47e3a43b.js +266 -0
- rasa/core/channels/inspector/dist/assets/gitGraphDiagram-99d0ae7c-5a2ac0d9.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-268a75c0.js +1040 -0
- rasa/core/channels/inspector/dist/assets/index-2c4b9a3b-dfb8efc4.js +1 -0
- rasa/core/channels/inspector/dist/assets/index-3ee28881.css +1 -0
- rasa/core/channels/inspector/dist/assets/infoDiagram-736b4530-b0c470f2.js +7 -0
- rasa/core/channels/inspector/dist/assets/init-77b53fdd.js +1 -0
- rasa/core/channels/inspector/dist/assets/journeyDiagram-df861f2b-2edb829a.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-b6873d69.js +1 -0
- rasa/core/channels/inspector/dist/assets/line-1efc5781.js +1 -0
- rasa/core/channels/inspector/dist/assets/linear-661e9b94.js +1 -0
- rasa/core/channels/inspector/dist/assets/mindmap-definition-beec6740-2d2e727f.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-9d3ea93d.js +35 -0
- rasa/core/channels/inspector/dist/assets/quadrantDiagram-4d7f4fd6-06a178a2.js +7 -0
- rasa/core/channels/inspector/dist/assets/requirementDiagram-6fc4c22a-0bfedffc.js +52 -0
- rasa/core/channels/inspector/dist/assets/sankeyDiagram-8f13d901-d76d0a04.js +8 -0
- rasa/core/channels/inspector/dist/assets/sequenceDiagram-b655622a-37bb4341.js +122 -0
- rasa/core/channels/inspector/dist/assets/stateDiagram-59f0c015-f52f7f57.js +1 -0
- rasa/core/channels/inspector/dist/assets/stateDiagram-v2-2b26beab-4a986a20.js +1 -0
- rasa/core/channels/inspector/dist/assets/styles-080da4f6-7dd9ae12.js +110 -0
- rasa/core/channels/inspector/dist/assets/styles-3dcbcfbf-46e1ca14.js +159 -0
- rasa/core/channels/inspector/dist/assets/styles-9c745c82-4a97439a.js +207 -0
- rasa/core/channels/inspector/dist/assets/svgDrawCommon-4835440b-823917a3.js +1 -0
- rasa/core/channels/inspector/dist/assets/timeline-definition-5b62e21b-9ea72896.js +61 -0
- rasa/core/channels/inspector/dist/assets/xychartDiagram-2b33534f-b631a8b6.js +7 -0
- rasa/core/channels/inspector/dist/index.html +39 -0
- rasa/core/channels/inspector/index.html +37 -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 +97 -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 +385 -0
- rasa/core/channels/inspector/src/helpers/formatters.ts +239 -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 +210 -0
- rasa/core/channels/rocketchat.py +175 -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 +135 -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 +925 -0
- rasa/core/evaluation/marker_stats.py +294 -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 +402 -0
- rasa/core/featurizers/tracker_featurizers.py +1172 -0
- rasa/core/http_interpreter.py +89 -0
- rasa/core/information_retrieval/__init__.py +0 -0
- rasa/core/information_retrieval/faiss.py +116 -0
- rasa/core/information_retrieval/information_retrieval.py +72 -0
- rasa/core/information_retrieval/milvus.py +59 -0
- rasa/core/information_retrieval/qdrant.py +102 -0
- rasa/core/jobs.py +63 -0
- rasa/core/lock.py +139 -0
- rasa/core/lock_store.py +344 -0
- rasa/core/migrate.py +404 -0
- rasa/core/nlg/__init__.py +3 -0
- rasa/core/nlg/callback.py +147 -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 +717 -0
- rasa/core/policies/enterprise_search_prompt_template.jinja2 +62 -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 +582 -0
- rasa/core/policies/flows/flow_step_result.py +43 -0
- rasa/core/policies/intentless_policy.py +924 -0
- rasa/core/policies/intentless_prompt_template.jinja2 +22 -0
- rasa/core/policies/memoization.py +538 -0
- rasa/core/policies/policy.py +716 -0
- rasa/core/policies/rule_policy.py +1276 -0
- rasa/core/policies/ted_policy.py +2146 -0
- rasa/core/policies/unexpected_intent_policy.py +1015 -0
- rasa/core/processor.py +1331 -0
- rasa/core/run.py +315 -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 +576 -0
- rasa/core/test.py +1337 -0
- rasa/core/tracker_store.py +1664 -0
- rasa/core/train.py +107 -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 +1742 -0
- rasa/core/training/story_conflict.py +381 -0
- rasa/core/training/training.py +93 -0
- rasa/core/utils.py +344 -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 +189 -0
- rasa/dialogue_understanding/coexistence/llm_based_router.py +261 -0
- rasa/dialogue_understanding/coexistence/router_template.jinja2 +12 -0
- rasa/dialogue_understanding/commands/__init__.py +45 -0
- rasa/dialogue_understanding/commands/can_not_handle_command.py +61 -0
- rasa/dialogue_understanding/commands/cancel_flow_command.py +116 -0
- rasa/dialogue_understanding/commands/chit_chat_answer_command.py +48 -0
- rasa/dialogue_understanding/commands/clarify_command.py +77 -0
- rasa/dialogue_understanding/commands/command.py +85 -0
- rasa/dialogue_understanding/commands/correct_slots_command.py +288 -0
- rasa/dialogue_understanding/commands/error_command.py +67 -0
- rasa/dialogue_understanding/commands/free_form_answer_command.py +9 -0
- rasa/dialogue_understanding/commands/handle_code_change_command.py +64 -0
- rasa/dialogue_understanding/commands/human_handoff_command.py +57 -0
- rasa/dialogue_understanding/commands/knowledge_answer_command.py +48 -0
- rasa/dialogue_understanding/commands/noop_command.py +45 -0
- rasa/dialogue_understanding/commands/set_slot_command.py +125 -0
- rasa/dialogue_understanding/commands/skip_question_command.py +66 -0
- rasa/dialogue_understanding/commands/start_flow_command.py +98 -0
- rasa/dialogue_understanding/generator/__init__.py +6 -0
- rasa/dialogue_understanding/generator/command_generator.py +257 -0
- rasa/dialogue_understanding/generator/command_prompt_template.jinja2 +57 -0
- rasa/dialogue_understanding/generator/flow_document_template.jinja2 +4 -0
- rasa/dialogue_understanding/generator/flow_retrieval.py +410 -0
- rasa/dialogue_understanding/generator/llm_command_generator.py +637 -0
- rasa/dialogue_understanding/generator/nlu_command_adapter.py +157 -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 +243 -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 +578 -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 +10 -0
- rasa/e2e_test/e2e_test_case.py +322 -0
- rasa/e2e_test/e2e_test_result.py +34 -0
- rasa/e2e_test/e2e_test_runner.py +659 -0
- rasa/e2e_test/e2e_test_schema.yml +67 -0
- rasa/engine/__init__.py +0 -0
- rasa/engine/caching.py +464 -0
- rasa/engine/constants.py +17 -0
- rasa/engine/exceptions.py +14 -0
- rasa/engine/graph.py +625 -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 +1252 -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 +256 -0
- rasa/engine/runner/interface.py +49 -0
- rasa/engine/storage/__init__.py +0 -0
- rasa/engine/storage/local_model_storage.py +248 -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 +839 -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 +552 -0
- rasa/graph_components/validators/finetuning_validator.py +302 -0
- rasa/hooks.py +113 -0
- rasa/jupyter.py +63 -0
- rasa/keys +1 -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 +535 -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 +1874 -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 +240 -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 +309 -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 +672 -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 +449 -0
- rasa/nlu/featurizers/dense_featurizer/dense_featurizer.py +57 -0
- rasa/nlu/featurizers/dense_featurizer/lm_featurizer.py +772 -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 +840 -0
- rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +539 -0
- rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +269 -0
- rasa/nlu/featurizers/sparse_featurizer/sparse_featurizer.py +9 -0
- rasa/nlu/model.py +24 -0
- rasa/nlu/persistor.py +240 -0
- rasa/nlu/run.py +27 -0
- rasa/nlu/selectors/__init__.py +0 -0
- rasa/nlu/selectors/response_selector.py +990 -0
- rasa/nlu/test.py +1943 -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 +312 -0
- rasa/plugin.py +90 -0
- rasa/server.py +1536 -0
- rasa/shared/__init__.py +0 -0
- rasa/shared/constants.py +181 -0
- rasa/shared/core/__init__.py +0 -0
- rasa/shared/core/constants.py +168 -0
- rasa/shared/core/conversation.py +46 -0
- rasa/shared/core/domain.py +2106 -0
- rasa/shared/core/events.py +2507 -0
- rasa/shared/core/flows/__init__.py +7 -0
- rasa/shared/core/flows/flow.py +353 -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 +211 -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 +51 -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 +907 -0
- rasa/shared/core/slot_mappings.py +235 -0
- rasa/shared/core/slots.py +647 -0
- rasa/shared/core/trackers.py +1159 -0
- rasa/shared/core/training_data/__init__.py +0 -0
- rasa/shared/core/training_data/loading.py +90 -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 +442 -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 +192 -0
- rasa/shared/engine/__init__.py +0 -0
- rasa/shared/engine/caching.py +26 -0
- rasa/shared/exceptions.py +129 -0
- rasa/shared/importers/__init__.py +0 -0
- rasa/shared/importers/importer.py +705 -0
- rasa/shared/importers/multi_project.py +203 -0
- rasa/shared/importers/rasa.py +100 -0
- rasa/shared/importers/utils.py +34 -0
- rasa/shared/nlu/__init__.py +0 -0
- rasa/shared/nlu/constants.py +45 -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 +209 -0
- rasa/shared/nlu/training_data/features.py +374 -0
- rasa/shared/nlu/training_data/formats/__init__.py +10 -0
- rasa/shared/nlu/training_data/formats/dialogflow.py +162 -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 +605 -0
- rasa/shared/nlu/training_data/formats/readerwriter.py +245 -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 +477 -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 +732 -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 +1 -0
- rasa/shared/utils/io.py +403 -0
- rasa/shared/utils/llm.py +405 -0
- rasa/shared/utils/pykwalify_extensions.py +26 -0
- rasa/shared/utils/schemas/__init__.py +0 -0
- rasa/shared/utils/schemas/config.yml +2 -0
- rasa/shared/utils/schemas/domain.yml +142 -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 +777 -0
- rasa/studio/__init__.py +0 -0
- rasa/studio/auth.py +252 -0
- rasa/studio/config.py +127 -0
- rasa/studio/constants.py +16 -0
- rasa/studio/data_handler.py +352 -0
- rasa/studio/download.py +350 -0
- rasa/studio/train.py +136 -0
- rasa/studio/upload.py +408 -0
- rasa/telemetry.py +1583 -0
- rasa/tracing/__init__.py +0 -0
- rasa/tracing/config.py +338 -0
- rasa/tracing/constants.py +38 -0
- rasa/tracing/instrumentation/__init__.py +0 -0
- rasa/tracing/instrumentation/attribute_extractors.py +663 -0
- rasa/tracing/instrumentation/instrumentation.py +939 -0
- rasa/tracing/instrumentation/intentless_policy_instrumentation.py +142 -0
- rasa/tracing/instrumentation/metrics.py +206 -0
- rasa/tracing/metric_instrument_provider.py +125 -0
- rasa/utils/__init__.py +0 -0
- rasa/utils/beta.py +83 -0
- rasa/utils/cli.py +27 -0
- rasa/utils/common.py +635 -0
- rasa/utils/converter.py +53 -0
- rasa/utils/endpoints.py +303 -0
- rasa/utils/io.py +326 -0
- rasa/utils/licensing.py +319 -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/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 +991 -0
- rasa/utils/tensorflow/model_data_utils.py +500 -0
- rasa/utils/tensorflow/models.py +936 -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/yaml.py +54 -0
- rasa/validator.py +1035 -0
- rasa/version.py +3 -0
- rasa_pro-3.8.16.dist-info/METADATA +528 -0
- rasa_pro-3.8.16.dist-info/NOTICE +5 -0
- rasa_pro-3.8.16.dist-info/RECORD +644 -0
- rasa_pro-3.8.16.dist-info/WHEEL +4 -0
- rasa_pro-3.8.16.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,603 @@
|
|
|
1
|
+
from collections import defaultdict, deque
|
|
2
|
+
|
|
3
|
+
import random
|
|
4
|
+
from typing import (
|
|
5
|
+
Any,
|
|
6
|
+
Text,
|
|
7
|
+
List,
|
|
8
|
+
Deque,
|
|
9
|
+
Dict,
|
|
10
|
+
Optional,
|
|
11
|
+
Set,
|
|
12
|
+
TYPE_CHECKING,
|
|
13
|
+
Union,
|
|
14
|
+
cast,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
import rasa.shared.utils.io
|
|
18
|
+
from rasa.shared.constants import INTENT_MESSAGE_PREFIX
|
|
19
|
+
from rasa.shared.core.constants import ACTION_LISTEN_NAME
|
|
20
|
+
from rasa.shared.core.domain import Domain
|
|
21
|
+
from rasa.shared.core.events import UserUttered, ActionExecuted, Event
|
|
22
|
+
from rasa.shared.core.generator import TrainingDataGenerator
|
|
23
|
+
from rasa.shared.core.training_data.structures import StoryGraph, StoryStep
|
|
24
|
+
from rasa.shared.nlu.constants import (
|
|
25
|
+
ENTITY_ATTRIBUTE_VALUE,
|
|
26
|
+
INTENT,
|
|
27
|
+
TEXT,
|
|
28
|
+
ENTITY_ATTRIBUTE_TYPE,
|
|
29
|
+
INTENT_NAME_KEY,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
if TYPE_CHECKING:
|
|
33
|
+
from rasa.shared.nlu.training_data.training_data import TrainingData
|
|
34
|
+
from rasa.shared.nlu.training_data.message import Message
|
|
35
|
+
import networkx
|
|
36
|
+
|
|
37
|
+
EDGE_NONE_LABEL = "NONE"
|
|
38
|
+
|
|
39
|
+
START_NODE_ID = 0
|
|
40
|
+
END_NODE_ID = -1
|
|
41
|
+
TMP_NODE_ID = -2
|
|
42
|
+
|
|
43
|
+
VISUALIZATION_TEMPLATE_PATH = "visualization.html"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class UserMessageGenerator:
|
|
47
|
+
def __init__(self, nlu_training_data: "TrainingData") -> None:
|
|
48
|
+
self.nlu_training_data = nlu_training_data
|
|
49
|
+
self.mapping = self._create_reverse_mapping(self.nlu_training_data)
|
|
50
|
+
|
|
51
|
+
@staticmethod
|
|
52
|
+
def _create_reverse_mapping(
|
|
53
|
+
data: "TrainingData",
|
|
54
|
+
) -> Dict[Dict[Text, Any], List["Message"]]:
|
|
55
|
+
"""Create a mapping from intent to messages.
|
|
56
|
+
|
|
57
|
+
This allows a faster intent lookup.
|
|
58
|
+
"""
|
|
59
|
+
d = defaultdict(list)
|
|
60
|
+
for example in data.training_examples:
|
|
61
|
+
if example.get(INTENT, {}) is not None:
|
|
62
|
+
d[example.get(INTENT, {})].append(example)
|
|
63
|
+
return d
|
|
64
|
+
|
|
65
|
+
@staticmethod
|
|
66
|
+
def _contains_same_entity(entities: Dict[Text, Any], e: Dict[Text, Any]) -> bool:
|
|
67
|
+
return entities.get(e.get(ENTITY_ATTRIBUTE_TYPE)) is None or entities.get(
|
|
68
|
+
e.get(ENTITY_ATTRIBUTE_TYPE)
|
|
69
|
+
) != e.get(ENTITY_ATTRIBUTE_VALUE)
|
|
70
|
+
|
|
71
|
+
def message_for_data(self, structured_info: Dict[Text, Any]) -> Any:
|
|
72
|
+
"""Find a data sample with the same intent."""
|
|
73
|
+
if structured_info.get(INTENT) is not None:
|
|
74
|
+
intent_name = structured_info.get(INTENT, {}).get(INTENT_NAME_KEY)
|
|
75
|
+
usable_examples = self.mapping.get(intent_name, [])[:]
|
|
76
|
+
random.shuffle(usable_examples)
|
|
77
|
+
|
|
78
|
+
if usable_examples:
|
|
79
|
+
return usable_examples[0].get(TEXT)
|
|
80
|
+
|
|
81
|
+
return structured_info.get(TEXT)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _fingerprint_node(
|
|
85
|
+
graph: "networkx.MultiDiGraph", node: int, max_history: int
|
|
86
|
+
) -> Set[Text]:
|
|
87
|
+
"""Fingerprint a node in a graph.
|
|
88
|
+
|
|
89
|
+
Can be used to identify nodes that are similar and can be merged within the
|
|
90
|
+
graph.
|
|
91
|
+
Generates all paths starting at `node` following the directed graph up to
|
|
92
|
+
the length of `max_history`, and returns a set of strings describing the
|
|
93
|
+
found paths. If the fingerprint creation for two nodes results in the same
|
|
94
|
+
sets these nodes are indistinguishable if we walk along the path and only
|
|
95
|
+
remember max history number of nodes we have visited. Hence, if we randomly
|
|
96
|
+
walk on our directed graph, always only remembering the last `max_history`
|
|
97
|
+
nodes we have visited, we can never remember if we have visited node A or
|
|
98
|
+
node B if both have the same fingerprint.
|
|
99
|
+
"""
|
|
100
|
+
# the candidate list contains all node paths that haven't been
|
|
101
|
+
# extended till `max_history` length yet.
|
|
102
|
+
candidates: Deque = deque()
|
|
103
|
+
candidates.append([node])
|
|
104
|
+
continuations = []
|
|
105
|
+
while len(candidates) > 0:
|
|
106
|
+
candidate = candidates.pop()
|
|
107
|
+
last = candidate[-1]
|
|
108
|
+
empty = True
|
|
109
|
+
for _, succ_node in graph.out_edges(last):
|
|
110
|
+
next_candidate = candidate[:]
|
|
111
|
+
next_candidate.append(succ_node)
|
|
112
|
+
# if the path is already long enough, we add it to the results,
|
|
113
|
+
# otherwise we add it to the candidates
|
|
114
|
+
# that we still need to visit
|
|
115
|
+
if len(next_candidate) == max_history:
|
|
116
|
+
continuations.append(next_candidate)
|
|
117
|
+
else:
|
|
118
|
+
candidates.append(next_candidate)
|
|
119
|
+
empty = False
|
|
120
|
+
if empty:
|
|
121
|
+
continuations.append(candidate)
|
|
122
|
+
return {
|
|
123
|
+
" - ".join([graph.nodes[node]["label"] for node in continuation])
|
|
124
|
+
for continuation in continuations
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def _incoming_edges(graph: "networkx.MultiDiGraph", node: int) -> set:
|
|
129
|
+
return {(prev_node, k) for prev_node, _, k in graph.in_edges(node, keys=True)}
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _outgoing_edges(graph: "networkx.MultiDiGraph", node: int) -> set:
|
|
133
|
+
return {(succ_node, k) for _, succ_node, k in graph.out_edges(node, keys=True)}
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _outgoing_edges_are_similar(
|
|
137
|
+
graph: "networkx.MultiDiGraph", node_a: int, node_b: int
|
|
138
|
+
) -> bool:
|
|
139
|
+
"""If the outgoing edges from the two nodes are similar enough,
|
|
140
|
+
it doesn't matter if you are in a or b.
|
|
141
|
+
|
|
142
|
+
As your path will be the same because the outgoing edges will lead you to
|
|
143
|
+
the same nodes anyways.
|
|
144
|
+
"""
|
|
145
|
+
ignored = {node_b, node_a}
|
|
146
|
+
a_edges = {
|
|
147
|
+
(target, k)
|
|
148
|
+
for target, k in _outgoing_edges(graph, node_a)
|
|
149
|
+
if target not in ignored
|
|
150
|
+
}
|
|
151
|
+
b_edges = {
|
|
152
|
+
(target, k)
|
|
153
|
+
for target, k in _outgoing_edges(graph, node_b)
|
|
154
|
+
if target not in ignored
|
|
155
|
+
}
|
|
156
|
+
return a_edges == b_edges or not a_edges or not b_edges
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def _nodes_are_equivalent(
|
|
160
|
+
graph: "networkx.MultiDiGraph", node_a: int, node_b: int, max_history: int
|
|
161
|
+
) -> bool:
|
|
162
|
+
"""Decides if two nodes are equivalent based on their fingerprints."""
|
|
163
|
+
return graph.nodes[node_a]["label"] == graph.nodes[node_b]["label"] and (
|
|
164
|
+
_outgoing_edges_are_similar(graph, node_a, node_b)
|
|
165
|
+
or _incoming_edges(graph, node_a) == _incoming_edges(graph, node_b)
|
|
166
|
+
or _fingerprint_node(graph, node_a, max_history)
|
|
167
|
+
== _fingerprint_node(graph, node_b, max_history)
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def _add_edge(
|
|
172
|
+
graph: "networkx.MultiDiGraph",
|
|
173
|
+
u: int,
|
|
174
|
+
v: int,
|
|
175
|
+
key: Optional[Text],
|
|
176
|
+
label: Optional[Text] = None,
|
|
177
|
+
**kwargs: Any,
|
|
178
|
+
) -> None:
|
|
179
|
+
"""Adds an edge to the graph if the edge is not already present. Uses the
|
|
180
|
+
label as the key.
|
|
181
|
+
"""
|
|
182
|
+
if key is None:
|
|
183
|
+
key = EDGE_NONE_LABEL
|
|
184
|
+
|
|
185
|
+
if key == EDGE_NONE_LABEL:
|
|
186
|
+
label = ""
|
|
187
|
+
|
|
188
|
+
if not graph.has_edge(u, v, key=EDGE_NONE_LABEL):
|
|
189
|
+
graph.add_edge(u, v, key=key, label=label, **kwargs)
|
|
190
|
+
else:
|
|
191
|
+
d = graph.get_edge_data(u, v, key=EDGE_NONE_LABEL)
|
|
192
|
+
_transfer_style(kwargs, d)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def _transfer_style(
|
|
196
|
+
source: Dict[Text, Any], target: Dict[Text, Any]
|
|
197
|
+
) -> Dict[Text, Any]:
|
|
198
|
+
"""Copy over class names from source to target for all special classes.
|
|
199
|
+
|
|
200
|
+
Used if a node is highlighted and merged with another node.
|
|
201
|
+
"""
|
|
202
|
+
clazzes = source.get("class", "")
|
|
203
|
+
|
|
204
|
+
special_classes = {"dashed", "active"}
|
|
205
|
+
|
|
206
|
+
if "class" not in target:
|
|
207
|
+
target["class"] = ""
|
|
208
|
+
|
|
209
|
+
for c in special_classes:
|
|
210
|
+
if c in clazzes and c not in target["class"]:
|
|
211
|
+
target["class"] += " " + c
|
|
212
|
+
|
|
213
|
+
target["class"] = target["class"].strip()
|
|
214
|
+
return target
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def _merge_equivalent_nodes(graph: "networkx.MultiDiGraph", max_history: int) -> None:
|
|
218
|
+
"""Searches for equivalent nodes in the graph and merges them."""
|
|
219
|
+
changed = True
|
|
220
|
+
# every node merge changes the graph and can trigger previously
|
|
221
|
+
# impossible node merges - we need to repeat until
|
|
222
|
+
# the graph doesn't change anymore
|
|
223
|
+
while changed:
|
|
224
|
+
changed = False
|
|
225
|
+
remaining_node_ids = [n for n in graph.nodes() if n > 0]
|
|
226
|
+
for idx, i in enumerate(remaining_node_ids):
|
|
227
|
+
if graph.has_node(i):
|
|
228
|
+
# assumes node equivalence is cumulative
|
|
229
|
+
for j in remaining_node_ids[idx + 1 :]:
|
|
230
|
+
if graph.has_node(j) and _nodes_are_equivalent(
|
|
231
|
+
graph, i, j, max_history
|
|
232
|
+
):
|
|
233
|
+
# make sure we keep special styles
|
|
234
|
+
_transfer_style(
|
|
235
|
+
graph.nodes(data=True)[j], graph.nodes(data=True)[i]
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
changed = True
|
|
239
|
+
# moves all outgoing edges to the other node
|
|
240
|
+
j_outgoing_edges = list(
|
|
241
|
+
graph.out_edges(j, keys=True, data=True)
|
|
242
|
+
)
|
|
243
|
+
for _, succ_node, k, d in j_outgoing_edges:
|
|
244
|
+
_add_edge(
|
|
245
|
+
graph,
|
|
246
|
+
i,
|
|
247
|
+
succ_node,
|
|
248
|
+
k,
|
|
249
|
+
d.get("label"),
|
|
250
|
+
**{"class": d.get("class", "")},
|
|
251
|
+
)
|
|
252
|
+
graph.remove_edge(j, succ_node)
|
|
253
|
+
# moves all incoming edges to the other node
|
|
254
|
+
j_incoming_edges = list(graph.in_edges(j, keys=True, data=True))
|
|
255
|
+
for prev_node, _, k, d in j_incoming_edges:
|
|
256
|
+
_add_edge(
|
|
257
|
+
graph,
|
|
258
|
+
prev_node,
|
|
259
|
+
i,
|
|
260
|
+
k,
|
|
261
|
+
d.get("label"),
|
|
262
|
+
**{"class": d.get("class", "")},
|
|
263
|
+
)
|
|
264
|
+
graph.remove_edge(prev_node, j)
|
|
265
|
+
graph.remove_node(j)
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def _replace_edge_labels_with_nodes(
|
|
269
|
+
graph: "networkx.MultiDiGraph", next_id: int, nlu_training_data: "TrainingData"
|
|
270
|
+
) -> None:
|
|
271
|
+
"""Replaces edge labels with nodes.
|
|
272
|
+
|
|
273
|
+
User messages are created as edge labels. This removes the labels and
|
|
274
|
+
creates nodes instead.
|
|
275
|
+
|
|
276
|
+
The algorithms (e.g. merging) are simpler if the user messages are labels
|
|
277
|
+
on the edges. But it sometimes
|
|
278
|
+
looks better if in the final graphs the user messages are nodes instead
|
|
279
|
+
of edge labels.
|
|
280
|
+
"""
|
|
281
|
+
if nlu_training_data:
|
|
282
|
+
message_generator = UserMessageGenerator(nlu_training_data)
|
|
283
|
+
else:
|
|
284
|
+
message_generator = None
|
|
285
|
+
|
|
286
|
+
edges = list(graph.edges(keys=True, data=True))
|
|
287
|
+
for s, e, k, d in edges:
|
|
288
|
+
if k != EDGE_NONE_LABEL:
|
|
289
|
+
label = d.get("label", k)
|
|
290
|
+
|
|
291
|
+
if message_generator:
|
|
292
|
+
parsed_info = {TEXT: label}
|
|
293
|
+
if label.startswith(INTENT_MESSAGE_PREFIX):
|
|
294
|
+
parsed_info[INTENT] = {INTENT_NAME_KEY: label[1:]}
|
|
295
|
+
|
|
296
|
+
label = message_generator.message_for_data(parsed_info)
|
|
297
|
+
next_id += 1
|
|
298
|
+
graph.remove_edge(s, e, k)
|
|
299
|
+
graph.add_node(
|
|
300
|
+
next_id,
|
|
301
|
+
label=label,
|
|
302
|
+
shape="rect",
|
|
303
|
+
style="filled",
|
|
304
|
+
fillcolor="lightblue",
|
|
305
|
+
**_transfer_style(d, {"class": "intent"}),
|
|
306
|
+
)
|
|
307
|
+
graph.add_edge(s, next_id, **{"class": d.get("class", "")})
|
|
308
|
+
graph.add_edge(next_id, e, **{"class": d.get("class", "")})
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
def visualization_html_path() -> Text:
|
|
312
|
+
import importlib
|
|
313
|
+
|
|
314
|
+
with importlib.resources.path(__package__, VISUALIZATION_TEMPLATE_PATH) as r:
|
|
315
|
+
return str(r)
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
def persist_graph(graph: "networkx.Graph", output_file: Text) -> None:
|
|
319
|
+
"""Plots the graph and persists it into a html file."""
|
|
320
|
+
import networkx as nx
|
|
321
|
+
|
|
322
|
+
expg = nx.nx_pydot.to_pydot(graph)
|
|
323
|
+
|
|
324
|
+
template = rasa.shared.utils.io.read_file(visualization_html_path())
|
|
325
|
+
|
|
326
|
+
# Insert graph into template
|
|
327
|
+
template = template.replace("// { is-client }", "isClient = true", 1)
|
|
328
|
+
graph_as_text = expg.to_string()
|
|
329
|
+
# escape backslashes
|
|
330
|
+
graph_as_text = graph_as_text.replace("\\", "\\\\")
|
|
331
|
+
template = template.replace("// { graph-content }", f"graph = `{graph_as_text}`", 1)
|
|
332
|
+
|
|
333
|
+
rasa.shared.utils.io.write_text_file(template, output_file)
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
def _length_of_common_action_prefix(this: List[Event], other: List[Event]) -> int:
|
|
337
|
+
"""Calculate number of actions that two conversations have in common."""
|
|
338
|
+
num_common_actions = 0
|
|
339
|
+
t_cleaned = cast(
|
|
340
|
+
List[Union[ActionExecuted, UserUttered]],
|
|
341
|
+
[e for e in this if e.type_name in {"user", "action"}],
|
|
342
|
+
)
|
|
343
|
+
o_cleaned = cast(
|
|
344
|
+
List[Union[ActionExecuted, UserUttered]],
|
|
345
|
+
[e for e in other if e.type_name in {"user", "action"}],
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
for i, e in enumerate(t_cleaned):
|
|
349
|
+
o = o_cleaned[i]
|
|
350
|
+
if i == len(o_cleaned):
|
|
351
|
+
break
|
|
352
|
+
elif isinstance(e, UserUttered) and isinstance(o, UserUttered):
|
|
353
|
+
continue
|
|
354
|
+
elif (
|
|
355
|
+
isinstance(e, ActionExecuted)
|
|
356
|
+
and isinstance(o, ActionExecuted)
|
|
357
|
+
and o.action_name == e.action_name
|
|
358
|
+
):
|
|
359
|
+
num_common_actions += 1
|
|
360
|
+
else:
|
|
361
|
+
break
|
|
362
|
+
return num_common_actions
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
def _add_default_nodes(graph: "networkx.MultiDiGraph", fontsize: int = 12) -> None:
|
|
366
|
+
"""Add the standard nodes we need."""
|
|
367
|
+
graph.add_node(
|
|
368
|
+
START_NODE_ID,
|
|
369
|
+
label="START",
|
|
370
|
+
fillcolor="green",
|
|
371
|
+
style="filled",
|
|
372
|
+
fontsize=fontsize,
|
|
373
|
+
**{"class": "start active"},
|
|
374
|
+
)
|
|
375
|
+
graph.add_node(
|
|
376
|
+
END_NODE_ID,
|
|
377
|
+
label="END",
|
|
378
|
+
fillcolor="red",
|
|
379
|
+
style="filled",
|
|
380
|
+
fontsize=fontsize,
|
|
381
|
+
**{"class": "end"},
|
|
382
|
+
)
|
|
383
|
+
graph.add_node(TMP_NODE_ID, label="TMP", style="invis", **{"class": "invisible"})
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
def _create_graph(fontsize: int = 12) -> "networkx.MultiDiGraph":
|
|
387
|
+
"""Create a graph and adds the default nodes."""
|
|
388
|
+
import networkx as nx
|
|
389
|
+
|
|
390
|
+
graph = nx.MultiDiGraph()
|
|
391
|
+
_add_default_nodes(graph, fontsize)
|
|
392
|
+
return graph
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
def _add_message_edge(
|
|
396
|
+
graph: "networkx.MultiDiGraph",
|
|
397
|
+
message: Optional[Dict[Text, Any]],
|
|
398
|
+
current_node: int,
|
|
399
|
+
next_node_idx: int,
|
|
400
|
+
is_current: bool,
|
|
401
|
+
) -> None:
|
|
402
|
+
"""Create an edge based on the user message."""
|
|
403
|
+
if message:
|
|
404
|
+
message_key = message.get("intent", {}).get("name", None)
|
|
405
|
+
message_label = message.get("text", None)
|
|
406
|
+
else:
|
|
407
|
+
message_key = None
|
|
408
|
+
message_label = None
|
|
409
|
+
|
|
410
|
+
_add_edge(
|
|
411
|
+
graph,
|
|
412
|
+
current_node,
|
|
413
|
+
next_node_idx,
|
|
414
|
+
message_key,
|
|
415
|
+
message_label,
|
|
416
|
+
**{"class": "active" if is_current else ""},
|
|
417
|
+
)
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
def visualize_neighborhood(
|
|
421
|
+
current: Optional[List[Event]],
|
|
422
|
+
event_sequences: List[List[Event]],
|
|
423
|
+
output_file: Optional[Text] = None,
|
|
424
|
+
max_history: int = 2,
|
|
425
|
+
nlu_training_data: Optional["TrainingData"] = None,
|
|
426
|
+
should_merge_nodes: bool = True,
|
|
427
|
+
max_distance: int = 1,
|
|
428
|
+
fontsize: int = 12,
|
|
429
|
+
) -> "networkx.MultiDiGraph":
|
|
430
|
+
"""Given a set of event lists, visualizing the flows."""
|
|
431
|
+
graph = _create_graph(fontsize)
|
|
432
|
+
_add_default_nodes(graph)
|
|
433
|
+
|
|
434
|
+
next_node_idx = START_NODE_ID
|
|
435
|
+
special_node_idx = -3
|
|
436
|
+
path_ellipsis_ends = set()
|
|
437
|
+
|
|
438
|
+
for events in event_sequences:
|
|
439
|
+
if current and max_distance:
|
|
440
|
+
prefix = _length_of_common_action_prefix(current, events)
|
|
441
|
+
else:
|
|
442
|
+
prefix = len(events)
|
|
443
|
+
|
|
444
|
+
message = None
|
|
445
|
+
current_node = START_NODE_ID
|
|
446
|
+
idx = 0
|
|
447
|
+
is_current = events == current
|
|
448
|
+
|
|
449
|
+
for idx, el in enumerate(events):
|
|
450
|
+
if not prefix:
|
|
451
|
+
idx -= 1
|
|
452
|
+
break
|
|
453
|
+
if isinstance(el, UserUttered):
|
|
454
|
+
message = el.parse_data
|
|
455
|
+
message[TEXT] = f"{INTENT_MESSAGE_PREFIX}{el.intent_name}" # type: ignore[literal-required] # noqa: E501
|
|
456
|
+
elif (
|
|
457
|
+
isinstance(el, ActionExecuted) and el.action_name != ACTION_LISTEN_NAME
|
|
458
|
+
):
|
|
459
|
+
next_node_idx += 1
|
|
460
|
+
graph.add_node(
|
|
461
|
+
next_node_idx,
|
|
462
|
+
label=el.action_name,
|
|
463
|
+
fontsize=fontsize,
|
|
464
|
+
**{"class": "active" if is_current else ""},
|
|
465
|
+
)
|
|
466
|
+
|
|
467
|
+
_add_message_edge(
|
|
468
|
+
graph, message, current_node, next_node_idx, is_current
|
|
469
|
+
)
|
|
470
|
+
current_node = next_node_idx
|
|
471
|
+
|
|
472
|
+
message = None
|
|
473
|
+
prefix -= 1
|
|
474
|
+
|
|
475
|
+
# determine what the end node of the conversation is going to be
|
|
476
|
+
# this can either be an ellipsis "...", the conversation end node
|
|
477
|
+
# "END" or a "TMP" node if this is the active conversation
|
|
478
|
+
if is_current:
|
|
479
|
+
event_idx = events[idx]
|
|
480
|
+
if (
|
|
481
|
+
isinstance(event_idx, ActionExecuted)
|
|
482
|
+
and event_idx.action_name == ACTION_LISTEN_NAME
|
|
483
|
+
):
|
|
484
|
+
next_node_idx += 1
|
|
485
|
+
if message is None:
|
|
486
|
+
label = " ? "
|
|
487
|
+
else:
|
|
488
|
+
intent = cast(dict, message).get("intent", {})
|
|
489
|
+
label = intent.get("name", " ? ")
|
|
490
|
+
graph.add_node(
|
|
491
|
+
next_node_idx,
|
|
492
|
+
label=label,
|
|
493
|
+
shape="rect",
|
|
494
|
+
**{"class": "intent dashed active"},
|
|
495
|
+
)
|
|
496
|
+
target = next_node_idx
|
|
497
|
+
elif current_node:
|
|
498
|
+
d = graph.nodes(data=True)[current_node]
|
|
499
|
+
d["class"] = "dashed active"
|
|
500
|
+
target = TMP_NODE_ID
|
|
501
|
+
else:
|
|
502
|
+
target = TMP_NODE_ID
|
|
503
|
+
elif idx == len(events) - 1:
|
|
504
|
+
target = END_NODE_ID
|
|
505
|
+
elif current_node and current_node not in path_ellipsis_ends:
|
|
506
|
+
graph.add_node(special_node_idx, label="...", **{"class": "ellipsis"})
|
|
507
|
+
target = special_node_idx
|
|
508
|
+
path_ellipsis_ends.add(current_node)
|
|
509
|
+
special_node_idx -= 1
|
|
510
|
+
else:
|
|
511
|
+
target = END_NODE_ID
|
|
512
|
+
|
|
513
|
+
_add_message_edge(graph, message, current_node, target, is_current)
|
|
514
|
+
|
|
515
|
+
if should_merge_nodes:
|
|
516
|
+
_merge_equivalent_nodes(graph, max_history)
|
|
517
|
+
_replace_edge_labels_with_nodes(graph, next_node_idx, nlu_training_data)
|
|
518
|
+
|
|
519
|
+
_remove_auxiliary_nodes(graph, special_node_idx)
|
|
520
|
+
|
|
521
|
+
if output_file:
|
|
522
|
+
persist_graph(graph, output_file)
|
|
523
|
+
return graph
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
def _remove_auxiliary_nodes(
|
|
527
|
+
graph: "networkx.MultiDiGraph", special_node_idx: int
|
|
528
|
+
) -> None:
|
|
529
|
+
"""Remove any temporary or unused nodes."""
|
|
530
|
+
graph.remove_node(TMP_NODE_ID)
|
|
531
|
+
|
|
532
|
+
if not graph.predecessors(END_NODE_ID):
|
|
533
|
+
graph.remove_node(END_NODE_ID)
|
|
534
|
+
|
|
535
|
+
# remove duplicated "..." nodes after merging
|
|
536
|
+
predecessors_seen = set()
|
|
537
|
+
for i in range(special_node_idx + 1, TMP_NODE_ID):
|
|
538
|
+
predecessors = graph.predecessors(i)
|
|
539
|
+
for pred in predecessors:
|
|
540
|
+
if pred in predecessors_seen:
|
|
541
|
+
graph.remove_node(i)
|
|
542
|
+
predecessors_seen.update(predecessors)
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
def visualize_stories(
|
|
546
|
+
story_steps: List[StoryStep],
|
|
547
|
+
domain: Domain,
|
|
548
|
+
output_file: Optional[Text],
|
|
549
|
+
max_history: int,
|
|
550
|
+
nlu_training_data: Optional["TrainingData"] = None,
|
|
551
|
+
should_merge_nodes: bool = True,
|
|
552
|
+
fontsize: int = 12,
|
|
553
|
+
) -> "networkx.MultiDiGraph":
|
|
554
|
+
"""Given a set of stories, generates a graph visualizing the flows in the stories.
|
|
555
|
+
|
|
556
|
+
Visualization is always a trade off between making the graph as small as
|
|
557
|
+
possible while
|
|
558
|
+
at the same time making sure the meaning doesn't change to "much". The
|
|
559
|
+
algorithm will
|
|
560
|
+
compress the graph generated from the stories to merge nodes that are
|
|
561
|
+
similar. Hence,
|
|
562
|
+
the algorithm might create paths through the graph that aren't actually
|
|
563
|
+
specified in the
|
|
564
|
+
stories, but we try to minimize that.
|
|
565
|
+
|
|
566
|
+
Output file defines if and where a file containing the plotted graph
|
|
567
|
+
should be stored.
|
|
568
|
+
|
|
569
|
+
The history defines how much 'memory' the graph has. This influences in
|
|
570
|
+
which situations the
|
|
571
|
+
algorithm will merge nodes. Nodes will only be merged if they are equal
|
|
572
|
+
within the history, this
|
|
573
|
+
means the larger the history is we take into account the less likely it
|
|
574
|
+
is we merge any nodes.
|
|
575
|
+
|
|
576
|
+
The training data parameter can be used to pass in a Rasa NLU training
|
|
577
|
+
data instance. It will
|
|
578
|
+
be used to replace the user messages from the story file with actual
|
|
579
|
+
messages from the training data.
|
|
580
|
+
"""
|
|
581
|
+
story_graph = StoryGraph(story_steps)
|
|
582
|
+
|
|
583
|
+
g = TrainingDataGenerator(
|
|
584
|
+
story_graph,
|
|
585
|
+
domain,
|
|
586
|
+
use_story_concatenation=False,
|
|
587
|
+
tracker_limit=100,
|
|
588
|
+
augmentation_factor=0,
|
|
589
|
+
)
|
|
590
|
+
completed_trackers = g.generate()
|
|
591
|
+
event_sequences = [t.events for t in completed_trackers]
|
|
592
|
+
|
|
593
|
+
graph = visualize_neighborhood(
|
|
594
|
+
None,
|
|
595
|
+
event_sequences,
|
|
596
|
+
output_file,
|
|
597
|
+
max_history,
|
|
598
|
+
nlu_training_data,
|
|
599
|
+
should_merge_nodes,
|
|
600
|
+
max_distance=1,
|
|
601
|
+
fontsize=fontsize,
|
|
602
|
+
)
|
|
603
|
+
return graph
|