rasa-pro 3.8.18__py3-none-any.whl → 3.9.15__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 +6 -42
- rasa/__main__.py +14 -9
- rasa/anonymization/anonymization_pipeline.py +0 -1
- rasa/anonymization/anonymization_rule_executor.py +3 -3
- rasa/anonymization/utils.py +4 -3
- rasa/api.py +2 -2
- rasa/cli/arguments/default_arguments.py +1 -1
- rasa/cli/arguments/run.py +2 -2
- rasa/cli/arguments/test.py +1 -1
- rasa/cli/arguments/train.py +10 -10
- rasa/cli/e2e_test.py +27 -7
- rasa/cli/export.py +0 -1
- rasa/cli/license.py +3 -3
- rasa/cli/project_templates/calm/actions/action_template.py +1 -1
- rasa/cli/project_templates/calm/config.yml +1 -1
- rasa/cli/project_templates/calm/credentials.yml +1 -1
- rasa/cli/project_templates/calm/data/flows/add_contact.yml +1 -1
- rasa/cli/project_templates/calm/data/flows/remove_contact.yml +1 -1
- rasa/cli/project_templates/calm/domain/add_contact.yml +8 -2
- rasa/cli/project_templates/calm/domain/list_contacts.yml +3 -0
- rasa/cli/project_templates/calm/domain/remove_contact.yml +9 -2
- rasa/cli/project_templates/calm/domain/shared.yml +5 -0
- rasa/cli/project_templates/calm/endpoints.yml +4 -4
- rasa/cli/project_templates/default/actions/actions.py +1 -1
- rasa/cli/project_templates/default/config.yml +5 -5
- rasa/cli/project_templates/default/credentials.yml +1 -1
- rasa/cli/project_templates/default/endpoints.yml +4 -4
- rasa/cli/project_templates/default/tests/test_stories.yml +1 -1
- rasa/cli/project_templates/tutorial/config.yml +1 -1
- rasa/cli/project_templates/tutorial/credentials.yml +1 -1
- rasa/cli/project_templates/tutorial/data/patterns.yml +6 -0
- rasa/cli/project_templates/tutorial/domain.yml +4 -0
- rasa/cli/project_templates/tutorial/endpoints.yml +6 -6
- rasa/cli/run.py +0 -1
- rasa/cli/scaffold.py +3 -2
- rasa/cli/studio/download.py +11 -0
- rasa/cli/studio/studio.py +180 -24
- rasa/cli/studio/upload.py +0 -8
- rasa/cli/telemetry.py +18 -6
- rasa/cli/utils.py +21 -10
- rasa/cli/x.py +3 -2
- rasa/constants.py +1 -1
- rasa/core/actions/action.py +90 -315
- rasa/core/actions/action_exceptions.py +24 -0
- rasa/core/actions/constants.py +3 -0
- rasa/core/actions/custom_action_executor.py +188 -0
- rasa/core/actions/forms.py +11 -7
- 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 +3 -0
- rasa/core/actions/two_stage_fallback.py +1 -1
- rasa/core/agent.py +2 -4
- rasa/core/brokers/pika.py +1 -2
- rasa/core/channels/audiocodes.py +1 -1
- rasa/core/channels/botframework.py +0 -1
- rasa/core/channels/callback.py +0 -1
- rasa/core/channels/console.py +6 -8
- rasa/core/channels/development_inspector.py +1 -1
- rasa/core/channels/facebook.py +0 -3
- rasa/core/channels/hangouts.py +0 -6
- rasa/core/channels/inspector/dist/assets/{arc-5623b6dc.js → arc-b6e548fe.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-d0fbc5ce-685c106a.js → c4Diagram-d0fbc5ce-fa03ac9e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-936ed81e-8cbed007.js → classDiagram-936ed81e-ee67392a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-c3cb15f1-5889cf12.js → classDiagram-v2-c3cb15f1-9b283fae.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{createText-62fc7601-24c249d7.js → createText-62fc7601-8b6fcc2a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-f2ad444c-7dd06a75.js → edges-f2ad444c-22e77f4f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9d236eb7-62c1e54c.js → erDiagram-9d236eb7-60ffc87f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-1972c806-ce49b86f.js → flowDb-1972c806-9dd802e4.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-7ea5b25a-4067e48f.js → flowDiagram-7ea5b25a-5fa1912f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-1844e5a5.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-abe16c3d-59fe4051.js → flowchart-elk-definition-abe16c3d-622a1fd2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-9b5ea136-47e3a43b.js → ganttDiagram-9b5ea136-e285a63a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-99d0ae7c-5a2ac0d9.js → gitGraphDiagram-99d0ae7c-f237bdca.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-2c4b9a3b-dfb8efc4.js → index-2c4b9a3b-4b03d70e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-268a75c0.js → index-a5d3e69d.js} +4 -4
- rasa/core/channels/inspector/dist/assets/{infoDiagram-736b4530-b0c470f2.js → infoDiagram-736b4530-72a0fa5f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-df861f2b-2edb829a.js → journeyDiagram-df861f2b-82218c41.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-b6873d69.js → layout-78cff630.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-1efc5781.js → line-5038b469.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-661e9b94.js → linear-c4fc4098.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-beec6740-2d2e727f.js → mindmap-definition-beec6740-c33c8ea6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-dbbf0591-9d3ea93d.js → pieDiagram-dbbf0591-a8d03059.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-4d7f4fd6-06a178a2.js → quadrantDiagram-4d7f4fd6-6a0e56b2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-6fc4c22a-0bfedffc.js → requirementDiagram-6fc4c22a-2dc7c7bd.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-8f13d901-d76d0a04.js → sankeyDiagram-8f13d901-2360fe39.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-b655622a-37bb4341.js → sequenceDiagram-b655622a-41b9f9ad.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-59f0c015-f52f7f57.js → stateDiagram-59f0c015-0aad326f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-2b26beab-4a986a20.js → stateDiagram-v2-2b26beab-9847d984.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-080da4f6-7dd9ae12.js → styles-080da4f6-564d890e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-3dcbcfbf-46e1ca14.js → styles-3dcbcfbf-38957613.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9c745c82-4a97439a.js → styles-9c745c82-f0fc6921.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-4835440b-823917a3.js → svgDrawCommon-4835440b-ef3c5a77.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-5b62e21b-9ea72896.js → timeline-definition-5b62e21b-bf3e91c1.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-2b33534f-b631a8b6.js → xychartDiagram-2b33534f-4d4026c0.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +1 -1
- rasa/core/channels/inspector/src/components/DiagramFlow.tsx +10 -0
- rasa/core/channels/inspector/src/helpers/formatters.test.ts +4 -7
- rasa/core/channels/inspector/src/helpers/formatters.ts +3 -2
- rasa/core/channels/rest.py +36 -21
- rasa/core/channels/rocketchat.py +0 -1
- rasa/core/channels/socketio.py +1 -1
- rasa/core/channels/telegram.py +3 -3
- rasa/core/channels/webexteams.py +0 -1
- rasa/core/concurrent_lock_store.py +1 -1
- rasa/core/evaluation/marker_base.py +1 -3
- rasa/core/evaluation/marker_stats.py +1 -2
- rasa/core/featurizers/single_state_featurizer.py +3 -26
- rasa/core/featurizers/tracker_featurizers.py +18 -122
- rasa/core/information_retrieval/__init__.py +7 -0
- rasa/core/information_retrieval/faiss.py +9 -4
- rasa/core/information_retrieval/information_retrieval.py +64 -7
- rasa/core/information_retrieval/milvus.py +7 -14
- rasa/core/information_retrieval/qdrant.py +8 -15
- rasa/core/lock_store.py +0 -1
- rasa/core/migrate.py +1 -2
- rasa/core/nlg/callback.py +3 -4
- rasa/core/policies/enterprise_search_policy.py +86 -22
- rasa/core/policies/enterprise_search_prompt_template.jinja2 +4 -41
- rasa/core/policies/enterprise_search_prompt_with_citation_template.jinja2 +60 -0
- rasa/core/policies/flows/flow_executor.py +104 -2
- rasa/core/policies/intentless_policy.py +7 -9
- rasa/core/policies/memoization.py +3 -3
- rasa/core/policies/policy.py +18 -9
- rasa/core/policies/rule_policy.py +8 -11
- rasa/core/policies/ted_policy.py +61 -88
- rasa/core/policies/unexpected_intent_policy.py +8 -17
- rasa/core/processor.py +136 -47
- rasa/core/run.py +41 -25
- rasa/core/secrets_manager/endpoints.py +2 -2
- rasa/core/secrets_manager/vault.py +6 -8
- rasa/core/test.py +3 -5
- rasa/core/tracker_store.py +49 -14
- rasa/core/train.py +1 -3
- rasa/core/training/interactive.py +9 -6
- rasa/core/utils.py +5 -10
- rasa/dialogue_understanding/coexistence/intent_based_router.py +11 -4
- rasa/dialogue_understanding/coexistence/llm_based_router.py +2 -3
- rasa/dialogue_understanding/commands/__init__.py +4 -0
- rasa/dialogue_understanding/commands/can_not_handle_command.py +9 -0
- rasa/dialogue_understanding/commands/cancel_flow_command.py +9 -0
- rasa/dialogue_understanding/commands/change_flow_command.py +38 -0
- rasa/dialogue_understanding/commands/chit_chat_answer_command.py +9 -0
- rasa/dialogue_understanding/commands/clarify_command.py +9 -0
- rasa/dialogue_understanding/commands/correct_slots_command.py +9 -0
- rasa/dialogue_understanding/commands/error_command.py +12 -0
- rasa/dialogue_understanding/commands/handle_code_change_command.py +9 -0
- rasa/dialogue_understanding/commands/human_handoff_command.py +9 -0
- rasa/dialogue_understanding/commands/knowledge_answer_command.py +9 -0
- rasa/dialogue_understanding/commands/noop_command.py +9 -0
- rasa/dialogue_understanding/commands/set_slot_command.py +38 -3
- rasa/dialogue_understanding/commands/skip_question_command.py +9 -0
- rasa/dialogue_understanding/commands/start_flow_command.py +9 -0
- rasa/dialogue_understanding/generator/__init__.py +16 -1
- rasa/dialogue_understanding/generator/command_generator.py +92 -6
- rasa/dialogue_understanding/generator/constants.py +18 -0
- rasa/dialogue_understanding/generator/flow_retrieval.py +7 -5
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +467 -0
- rasa/dialogue_understanding/generator/llm_command_generator.py +39 -609
- 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 +69 -8
- rasa/dialogue_understanding/generator/single_step/__init__.py +0 -0
- rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +345 -0
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +36 -31
- rasa/dialogue_understanding/processor/command_processor.py +112 -3
- rasa/e2e_test/constants.py +1 -0
- rasa/e2e_test/e2e_test_case.py +44 -0
- rasa/e2e_test/e2e_test_runner.py +114 -11
- rasa/e2e_test/e2e_test_schema.yml +18 -0
- rasa/engine/caching.py +0 -1
- rasa/engine/graph.py +18 -6
- rasa/engine/recipes/config_files/default_config.yml +3 -3
- rasa/engine/recipes/default_components.py +1 -1
- rasa/engine/recipes/default_recipe.py +4 -5
- rasa/engine/recipes/recipe.py +1 -1
- rasa/engine/runner/dask.py +3 -9
- rasa/engine/storage/local_model_storage.py +0 -2
- rasa/engine/validation.py +179 -145
- rasa/exceptions.py +2 -2
- rasa/graph_components/validators/default_recipe_validator.py +3 -5
- rasa/hooks.py +0 -1
- rasa/model.py +1 -1
- rasa/model_training.py +1 -0
- rasa/nlu/classifiers/diet_classifier.py +33 -52
- rasa/nlu/classifiers/logistic_regression_classifier.py +9 -22
- rasa/nlu/classifiers/sklearn_intent_classifier.py +16 -37
- rasa/nlu/extractors/crf_entity_extractor.py +54 -97
- rasa/nlu/extractors/duckling_entity_extractor.py +1 -1
- rasa/nlu/featurizers/dense_featurizer/convert_featurizer.py +1 -5
- rasa/nlu/featurizers/dense_featurizer/lm_featurizer.py +0 -4
- rasa/nlu/featurizers/featurizer.py +1 -1
- rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +18 -49
- rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +26 -64
- rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +3 -5
- rasa/nlu/persistor.py +68 -26
- rasa/nlu/selectors/response_selector.py +7 -10
- rasa/nlu/test.py +0 -3
- rasa/nlu/utils/hugging_face/registry.py +1 -1
- rasa/nlu/utils/spacy_utils.py +1 -3
- rasa/server.py +22 -7
- rasa/shared/constants.py +12 -1
- rasa/shared/core/command_payload_reader.py +109 -0
- rasa/shared/core/constants.py +4 -5
- rasa/shared/core/domain.py +57 -56
- rasa/shared/core/events.py +4 -7
- rasa/shared/core/flows/flow.py +9 -0
- rasa/shared/core/flows/flows_list.py +12 -0
- rasa/shared/core/flows/steps/action.py +7 -2
- rasa/shared/core/generator.py +12 -11
- rasa/shared/core/slot_mappings.py +315 -24
- rasa/shared/core/slots.py +4 -2
- rasa/shared/core/trackers.py +32 -14
- rasa/shared/core/training_data/loading.py +0 -1
- rasa/shared/core/training_data/story_reader/story_reader.py +3 -3
- rasa/shared/core/training_data/story_reader/yaml_story_reader.py +11 -11
- rasa/shared/core/training_data/story_writer/yaml_story_writer.py +5 -3
- rasa/shared/core/training_data/structures.py +1 -1
- rasa/shared/core/training_data/visualization.py +1 -1
- rasa/shared/data.py +58 -1
- rasa/shared/exceptions.py +36 -2
- rasa/shared/importers/importer.py +1 -2
- rasa/shared/importers/rasa.py +0 -1
- rasa/shared/nlu/constants.py +2 -0
- rasa/shared/nlu/training_data/entities_parser.py +1 -2
- rasa/shared/nlu/training_data/features.py +2 -120
- rasa/shared/nlu/training_data/formats/dialogflow.py +3 -2
- rasa/shared/nlu/training_data/formats/rasa_yaml.py +3 -5
- rasa/shared/nlu/training_data/formats/readerwriter.py +0 -1
- rasa/shared/nlu/training_data/message.py +13 -0
- rasa/shared/nlu/training_data/training_data.py +0 -2
- rasa/shared/providers/openai/session_handler.py +2 -2
- rasa/shared/utils/constants.py +3 -0
- rasa/shared/utils/io.py +11 -1
- rasa/shared/utils/llm.py +1 -2
- rasa/shared/utils/pykwalify_extensions.py +1 -0
- rasa/shared/utils/schemas/domain.yml +3 -0
- rasa/shared/utils/yaml.py +44 -35
- rasa/studio/auth.py +26 -10
- rasa/studio/constants.py +2 -0
- rasa/studio/data_handler.py +114 -107
- rasa/studio/download.py +160 -27
- rasa/studio/results_logger.py +137 -0
- rasa/studio/train.py +6 -7
- rasa/studio/upload.py +159 -134
- rasa/telemetry.py +188 -34
- rasa/tracing/config.py +18 -3
- rasa/tracing/constants.py +26 -2
- rasa/tracing/instrumentation/attribute_extractors.py +50 -41
- rasa/tracing/instrumentation/instrumentation.py +290 -44
- rasa/tracing/instrumentation/intentless_policy_instrumentation.py +7 -5
- rasa/tracing/instrumentation/metrics.py +109 -21
- rasa/tracing/metric_instrument_provider.py +83 -3
- rasa/utils/cli.py +2 -1
- rasa/utils/common.py +1 -1
- rasa/utils/endpoints.py +1 -2
- rasa/utils/io.py +72 -6
- rasa/utils/licensing.py +246 -31
- rasa/utils/ml_utils.py +1 -1
- rasa/utils/tensorflow/data_generator.py +1 -1
- rasa/utils/tensorflow/environment.py +1 -1
- rasa/utils/tensorflow/model_data.py +201 -12
- rasa/utils/tensorflow/model_data_utils.py +499 -500
- rasa/utils/tensorflow/models.py +5 -6
- rasa/utils/tensorflow/rasa_layers.py +15 -15
- rasa/utils/train_utils.py +1 -1
- rasa/utils/url_tools.py +53 -0
- rasa/validator.py +305 -3
- rasa/version.py +1 -1
- {rasa_pro-3.8.18.dist-info → rasa_pro-3.9.15.dist-info}/METADATA +25 -61
- {rasa_pro-3.8.18.dist-info → rasa_pro-3.9.15.dist-info}/RECORD +276 -259
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-85583a23.js +0 -1
- rasa/utils/tensorflow/feature_array.py +0 -370
- /rasa/dialogue_understanding/generator/{command_prompt_template.jinja2 → single_step/command_prompt_template.jinja2} +0 -0
- {rasa_pro-3.8.18.dist-info → rasa_pro-3.9.15.dist-info}/NOTICE +0 -0
- {rasa_pro-3.8.18.dist-info → rasa_pro-3.9.15.dist-info}/WHEEL +0 -0
- {rasa_pro-3.8.18.dist-info → rasa_pro-3.9.15.dist-info}/entry_points.txt +0 -0
|
@@ -2,20 +2,27 @@ from typing import Dict, Text, Any, Optional, List
|
|
|
2
2
|
|
|
3
3
|
import structlog
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
from rasa.dialogue_understanding.commands import (
|
|
6
7
|
Command,
|
|
7
8
|
StartFlowCommand,
|
|
8
9
|
SetSlotCommand,
|
|
9
10
|
)
|
|
11
|
+
from rasa.dialogue_understanding.commands.set_slot_command import SetSlotExtractor
|
|
10
12
|
from rasa.dialogue_understanding.generator import CommandGenerator
|
|
11
13
|
from rasa.engine.graph import GraphComponent, ExecutionContext
|
|
12
14
|
from rasa.engine.recipes.default_recipe import DefaultV1Recipe
|
|
13
15
|
from rasa.engine.storage.resource import Resource
|
|
14
16
|
from rasa.engine.storage.storage import ModelStorage
|
|
15
17
|
from rasa.shared.constants import ROUTE_TO_CALM_SLOT
|
|
18
|
+
from rasa.shared.core.domain import Domain
|
|
16
19
|
from rasa.shared.core.flows.flows_list import FlowsList
|
|
20
|
+
from rasa.shared.core.slot_mappings import (
|
|
21
|
+
SlotFillingManager,
|
|
22
|
+
extract_slot_value,
|
|
23
|
+
)
|
|
17
24
|
from rasa.shared.core.trackers import DialogueStateTracker
|
|
18
|
-
from rasa.shared.nlu.constants import INTENT
|
|
25
|
+
from rasa.shared.nlu.constants import ENTITIES, INTENT
|
|
19
26
|
from rasa.shared.nlu.training_data.message import Message
|
|
20
27
|
from rasa.shared.nlu.training_data.training_data import TrainingData
|
|
21
28
|
|
|
@@ -76,6 +83,7 @@ class NLUCommandAdapter(GraphComponent, CommandGenerator):
|
|
|
76
83
|
message: Message,
|
|
77
84
|
flows: FlowsList,
|
|
78
85
|
tracker: Optional[DialogueStateTracker] = None,
|
|
86
|
+
**kwargs: Any,
|
|
79
87
|
) -> List[Command]:
|
|
80
88
|
"""Creates commands using the predicted intents.
|
|
81
89
|
|
|
@@ -83,6 +91,7 @@ class NLUCommandAdapter(GraphComponent, CommandGenerator):
|
|
|
83
91
|
message: The message from the user.
|
|
84
92
|
flows: The flows available to the user.
|
|
85
93
|
tracker: The tracker containing the current state of the conversation.
|
|
94
|
+
**kwargs: Keyword arguments for forward compatibility.
|
|
86
95
|
|
|
87
96
|
Returns:
|
|
88
97
|
The commands triggered by NLU.
|
|
@@ -91,9 +100,18 @@ class NLUCommandAdapter(GraphComponent, CommandGenerator):
|
|
|
91
100
|
# cannot do anything if there are no flows or no tracker
|
|
92
101
|
return []
|
|
93
102
|
|
|
94
|
-
|
|
103
|
+
domain = kwargs.get("domain", None)
|
|
104
|
+
commands = self.convert_nlu_to_commands(message, tracker, flows, domain)
|
|
105
|
+
|
|
106
|
+
commands_contain_start_flow = any(
|
|
107
|
+
isinstance(command, StartFlowCommand) for command in commands
|
|
108
|
+
)
|
|
95
109
|
|
|
96
|
-
if
|
|
110
|
+
if (
|
|
111
|
+
commands
|
|
112
|
+
and commands_contain_start_flow
|
|
113
|
+
and tracker.has_coexistence_routing_slot
|
|
114
|
+
):
|
|
97
115
|
# if the nlu command adapter will start a flow and the coexistence feature
|
|
98
116
|
# is used, make sure to set the routing slot
|
|
99
117
|
commands += [SetSlotCommand(ROUTE_TO_CALM_SLOT, True)]
|
|
@@ -121,15 +139,22 @@ class NLUCommandAdapter(GraphComponent, CommandGenerator):
|
|
|
121
139
|
|
|
122
140
|
@staticmethod
|
|
123
141
|
def convert_nlu_to_commands(
|
|
124
|
-
message: Message,
|
|
142
|
+
message: Message,
|
|
143
|
+
tracker: DialogueStateTracker,
|
|
144
|
+
flows: FlowsList,
|
|
145
|
+
domain: Optional[Domain] = None,
|
|
125
146
|
) -> List[Command]:
|
|
126
147
|
"""Converts the predicted intent to a command."""
|
|
127
148
|
if tracker is None or flows.is_empty():
|
|
128
149
|
# cannot do anything if there are no flows or no tracker
|
|
129
150
|
return []
|
|
130
151
|
|
|
131
|
-
if not
|
|
132
|
-
|
|
152
|
+
if not (
|
|
153
|
+
message.get(INTENT)
|
|
154
|
+
or message.get(INTENT, {}).get("name")
|
|
155
|
+
or message.get(ENTITIES)
|
|
156
|
+
):
|
|
157
|
+
# if the message does not have an intent or entities set
|
|
133
158
|
# no commands can be predicted
|
|
134
159
|
return []
|
|
135
160
|
|
|
@@ -139,8 +164,6 @@ class NLUCommandAdapter(GraphComponent, CommandGenerator):
|
|
|
139
164
|
if flow.nlu_triggers and flow.nlu_triggers.is_triggered(message):
|
|
140
165
|
commands.append(StartFlowCommand(flow.id))
|
|
141
166
|
|
|
142
|
-
structlogger.info("nlu_command_adapter.predict_commands", commands=commands)
|
|
143
|
-
|
|
144
167
|
# there should be just one flow that can be triggered by the predicted intent
|
|
145
168
|
# this is checked when loading the flows
|
|
146
169
|
# however we just doublecheck here and return the first command if there are
|
|
@@ -154,4 +177,42 @@ class NLUCommandAdapter(GraphComponent, CommandGenerator):
|
|
|
154
177
|
)
|
|
155
178
|
commands = [commands[0]]
|
|
156
179
|
|
|
180
|
+
set_slot_commands = _issue_set_slot_commands(message, tracker, flows, domain)
|
|
181
|
+
commands.extend(set_slot_commands)
|
|
182
|
+
|
|
183
|
+
structlogger.info("nlu_command_adapter.predict_commands", commands=commands)
|
|
184
|
+
|
|
157
185
|
return commands
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def _issue_set_slot_commands(
|
|
189
|
+
message: Message,
|
|
190
|
+
tracker: DialogueStateTracker,
|
|
191
|
+
flows: FlowsList,
|
|
192
|
+
domain: Optional[Domain] = None,
|
|
193
|
+
) -> List[Command]:
|
|
194
|
+
"""Issue SetSlotCommand for each slot that can be filled with NLU properties."""
|
|
195
|
+
commands: List[Command] = []
|
|
196
|
+
domain = domain if domain else Domain.empty()
|
|
197
|
+
slot_filling_manager = SlotFillingManager(domain, tracker, message)
|
|
198
|
+
available_slot_names = flows.available_slot_names()
|
|
199
|
+
|
|
200
|
+
for _, slot in tracker.slots.items():
|
|
201
|
+
# if a slot is not collected in available flows,
|
|
202
|
+
# it means that it is not a slot that can be filled by CALM,
|
|
203
|
+
# so we skip it
|
|
204
|
+
if slot.name not in available_slot_names:
|
|
205
|
+
structlogger.debug("nlu_command_adapter.skip_slot", slot=slot.name)
|
|
206
|
+
continue
|
|
207
|
+
|
|
208
|
+
slot_value, is_extracted = extract_slot_value(slot, slot_filling_manager)
|
|
209
|
+
if is_extracted:
|
|
210
|
+
commands.append(
|
|
211
|
+
SetSlotCommand(
|
|
212
|
+
name=slot.name,
|
|
213
|
+
value=slot_value,
|
|
214
|
+
extractor=SetSlotExtractor.NLU.value,
|
|
215
|
+
)
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
return commands
|
|
File without changes
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import importlib.resources
|
|
2
|
+
import re
|
|
3
|
+
import structlog
|
|
4
|
+
from typing import Dict, Any, List, Optional, Text
|
|
5
|
+
|
|
6
|
+
import rasa.shared.utils.io
|
|
7
|
+
from rasa.dialogue_understanding.commands import (
|
|
8
|
+
Command,
|
|
9
|
+
ErrorCommand,
|
|
10
|
+
SetSlotCommand,
|
|
11
|
+
CancelFlowCommand,
|
|
12
|
+
HumanHandoffCommand,
|
|
13
|
+
ChitChatAnswerCommand,
|
|
14
|
+
SkipQuestionCommand,
|
|
15
|
+
KnowledgeAnswerCommand,
|
|
16
|
+
ClarifyCommand,
|
|
17
|
+
CannotHandleCommand,
|
|
18
|
+
)
|
|
19
|
+
from rasa.dialogue_understanding.generator.llm_based_command_generator import (
|
|
20
|
+
LLMBasedCommandGenerator,
|
|
21
|
+
)
|
|
22
|
+
from rasa.dialogue_understanding.generator.constants import (
|
|
23
|
+
LLM_CONFIG_KEY,
|
|
24
|
+
USER_INPUT_CONFIG_KEY,
|
|
25
|
+
FLOW_RETRIEVAL_KEY,
|
|
26
|
+
)
|
|
27
|
+
from rasa.dialogue_understanding.generator.flow_retrieval import (
|
|
28
|
+
FlowRetrieval,
|
|
29
|
+
)
|
|
30
|
+
from rasa.dialogue_understanding.stack.utils import top_flow_frame
|
|
31
|
+
from rasa.engine.graph import ExecutionContext
|
|
32
|
+
from rasa.engine.recipes.default_recipe import DefaultV1Recipe
|
|
33
|
+
from rasa.engine.storage.resource import Resource
|
|
34
|
+
from rasa.engine.storage.storage import ModelStorage
|
|
35
|
+
from rasa.shared.constants import ROUTE_TO_CALM_SLOT
|
|
36
|
+
from rasa.shared.core.flows import FlowsList
|
|
37
|
+
from rasa.shared.core.trackers import DialogueStateTracker
|
|
38
|
+
from rasa.shared.nlu.constants import TEXT
|
|
39
|
+
from rasa.shared.nlu.training_data.message import Message
|
|
40
|
+
from rasa.shared.exceptions import ProviderClientAPIException
|
|
41
|
+
from rasa.shared.utils.io import deep_container_fingerprint
|
|
42
|
+
from rasa.shared.utils.llm import (
|
|
43
|
+
get_prompt_template,
|
|
44
|
+
tracker_as_readable_transcript,
|
|
45
|
+
sanitize_message_for_prompt,
|
|
46
|
+
)
|
|
47
|
+
from rasa.utils.log_utils import log_llm
|
|
48
|
+
|
|
49
|
+
COMMAND_PROMPT_FILE_NAME = "command_prompt.jinja2"
|
|
50
|
+
|
|
51
|
+
DEFAULT_COMMAND_PROMPT_TEMPLATE = importlib.resources.read_text(
|
|
52
|
+
"rasa.dialogue_understanding.generator.single_step",
|
|
53
|
+
"command_prompt_template.jinja2",
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
structlogger = structlog.get_logger()
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@DefaultV1Recipe.register(
|
|
60
|
+
[
|
|
61
|
+
DefaultV1Recipe.ComponentType.COMMAND_GENERATOR,
|
|
62
|
+
],
|
|
63
|
+
is_trainable=True,
|
|
64
|
+
)
|
|
65
|
+
class SingleStepLLMCommandGenerator(LLMBasedCommandGenerator):
|
|
66
|
+
"""A single step LLM-based command generator."""
|
|
67
|
+
|
|
68
|
+
def __init__(
|
|
69
|
+
self,
|
|
70
|
+
config: Dict[str, Any],
|
|
71
|
+
model_storage: ModelStorage,
|
|
72
|
+
resource: Resource,
|
|
73
|
+
prompt_template: Optional[Text] = None,
|
|
74
|
+
**kwargs: Any,
|
|
75
|
+
) -> None:
|
|
76
|
+
super().__init__(
|
|
77
|
+
config,
|
|
78
|
+
model_storage,
|
|
79
|
+
resource,
|
|
80
|
+
prompt_template=prompt_template,
|
|
81
|
+
**kwargs,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Set the prompt template
|
|
85
|
+
if config.get("prompt"):
|
|
86
|
+
structlogger.warning(
|
|
87
|
+
"single_step_llm_command_generator.init",
|
|
88
|
+
event_info=(
|
|
89
|
+
"The config parameter 'prompt' is deprecated "
|
|
90
|
+
"and will be removed in Rasa 4.0.0. "
|
|
91
|
+
"Please use the config parameter 'prompt_template' instead. "
|
|
92
|
+
),
|
|
93
|
+
)
|
|
94
|
+
config_prompt = config.get("prompt") or config.get("prompt_template") or None
|
|
95
|
+
self.prompt_template = prompt_template or get_prompt_template(
|
|
96
|
+
config_prompt,
|
|
97
|
+
DEFAULT_COMMAND_PROMPT_TEMPLATE,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
self.trace_prompt_tokens = self.config.get("trace_prompt_tokens", False)
|
|
101
|
+
|
|
102
|
+
### Implementations of LLMBasedCommandGenerator parent
|
|
103
|
+
@staticmethod
|
|
104
|
+
def get_default_config() -> Dict[str, Any]:
|
|
105
|
+
"""The component's default config (see parent class for full docstring)."""
|
|
106
|
+
return {
|
|
107
|
+
"prompt": None, # Legacy
|
|
108
|
+
"prompt_template": None,
|
|
109
|
+
USER_INPUT_CONFIG_KEY: None,
|
|
110
|
+
LLM_CONFIG_KEY: None,
|
|
111
|
+
FLOW_RETRIEVAL_KEY: FlowRetrieval.get_default_config(),
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@classmethod
|
|
115
|
+
def load(
|
|
116
|
+
cls: Any,
|
|
117
|
+
config: Dict[str, Any],
|
|
118
|
+
model_storage: ModelStorage,
|
|
119
|
+
resource: Resource,
|
|
120
|
+
execution_context: ExecutionContext,
|
|
121
|
+
**kwargs: Any,
|
|
122
|
+
) -> "SingleStepLLMCommandGenerator":
|
|
123
|
+
"""Loads trained component (see parent class for full docstring)."""
|
|
124
|
+
# load prompt template from the model storage.
|
|
125
|
+
prompt_template = cls.load_prompt_template_from_model_storage(
|
|
126
|
+
model_storage, resource, COMMAND_PROMPT_FILE_NAME
|
|
127
|
+
)
|
|
128
|
+
# init base command generator
|
|
129
|
+
command_generator = cls(config, model_storage, resource, prompt_template)
|
|
130
|
+
# load flow retrieval if enabled
|
|
131
|
+
if command_generator.enabled_flow_retrieval:
|
|
132
|
+
command_generator.flow_retrieval = cls.load_flow_retrival(
|
|
133
|
+
command_generator.config, model_storage, resource
|
|
134
|
+
)
|
|
135
|
+
return command_generator
|
|
136
|
+
|
|
137
|
+
def persist(self) -> None:
|
|
138
|
+
"""Persist this component to disk for future loading."""
|
|
139
|
+
# persist prompt template
|
|
140
|
+
with self._model_storage.write_to(self._resource) as path:
|
|
141
|
+
rasa.shared.utils.io.write_text_file(
|
|
142
|
+
self.prompt_template, path / COMMAND_PROMPT_FILE_NAME
|
|
143
|
+
)
|
|
144
|
+
# persist flow retrieval
|
|
145
|
+
if self.flow_retrieval is not None:
|
|
146
|
+
self.flow_retrieval.persist()
|
|
147
|
+
|
|
148
|
+
async def predict_commands(
|
|
149
|
+
self,
|
|
150
|
+
message: Message,
|
|
151
|
+
flows: FlowsList,
|
|
152
|
+
tracker: Optional[DialogueStateTracker] = None,
|
|
153
|
+
**kwargs: Any,
|
|
154
|
+
) -> List[Command]:
|
|
155
|
+
"""Predict commands using the LLM.
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
message: The message from the user.
|
|
159
|
+
flows: The flows available to the user.
|
|
160
|
+
tracker: The tracker containing the current state of the conversation.
|
|
161
|
+
**kwargs: Keyword arguments for forward compatibility.
|
|
162
|
+
|
|
163
|
+
Returns:
|
|
164
|
+
The commands generated by the llm.
|
|
165
|
+
"""
|
|
166
|
+
if tracker is None or flows.is_empty():
|
|
167
|
+
# cannot do anything if there are no flows or no tracker
|
|
168
|
+
return []
|
|
169
|
+
|
|
170
|
+
# retrieve flows
|
|
171
|
+
try:
|
|
172
|
+
filtered_flows = await self.filter_flows(message, flows, tracker)
|
|
173
|
+
except ProviderClientAPIException:
|
|
174
|
+
return [ErrorCommand()]
|
|
175
|
+
|
|
176
|
+
flow_prompt = self.render_template(message, tracker, filtered_flows, flows)
|
|
177
|
+
log_llm(
|
|
178
|
+
logger=structlogger,
|
|
179
|
+
log_module="SingleStepLLMCommandGenerator",
|
|
180
|
+
log_event="llm_command_generator.predict_commands.prompt_rendered",
|
|
181
|
+
prompt=flow_prompt,
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
try:
|
|
185
|
+
action_list = await self.invoke_llm(flow_prompt)
|
|
186
|
+
# The check for 'None' maintains compatibility with older versions
|
|
187
|
+
# of LLMCommandGenerator. In previous implementations, 'invoke_llm'
|
|
188
|
+
# might return 'None' to indicate a failure to generate actions.
|
|
189
|
+
if action_list is None:
|
|
190
|
+
return [ErrorCommand()]
|
|
191
|
+
except ProviderClientAPIException:
|
|
192
|
+
return [ErrorCommand()]
|
|
193
|
+
|
|
194
|
+
log_llm(
|
|
195
|
+
logger=structlogger,
|
|
196
|
+
log_module="SingleStepLLMCommandGenerator",
|
|
197
|
+
log_event="llm_command_generator.predict_commands.actions_generated",
|
|
198
|
+
action_list=action_list,
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
commands = self.parse_commands(action_list, tracker, flows)
|
|
202
|
+
|
|
203
|
+
if not commands:
|
|
204
|
+
# no commands are parsed or there's an invalid command
|
|
205
|
+
commands = [CannotHandleCommand()]
|
|
206
|
+
else:
|
|
207
|
+
# if the LLM command generator predicted valid commands and the
|
|
208
|
+
# coexistence feature is used, set the routing slot
|
|
209
|
+
if tracker.has_coexistence_routing_slot:
|
|
210
|
+
commands += [SetSlotCommand(ROUTE_TO_CALM_SLOT, True)]
|
|
211
|
+
|
|
212
|
+
log_llm(
|
|
213
|
+
logger=structlogger,
|
|
214
|
+
log_module="SingleStepLLMCommandGenerator",
|
|
215
|
+
log_event="llm_command_generator.predict_commands.finished",
|
|
216
|
+
commands=commands,
|
|
217
|
+
)
|
|
218
|
+
return commands
|
|
219
|
+
|
|
220
|
+
@classmethod
|
|
221
|
+
def parse_commands(
|
|
222
|
+
cls, actions: Optional[str], tracker: DialogueStateTracker, flows: FlowsList
|
|
223
|
+
) -> List[Command]:
|
|
224
|
+
"""Parse the actions returned by the llm into intent and entities.
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
actions: The actions returned by the llm.
|
|
228
|
+
tracker: The tracker containing the current state of the conversation.
|
|
229
|
+
flows: the list of flows
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
The parsed commands.
|
|
233
|
+
"""
|
|
234
|
+
if actions is None:
|
|
235
|
+
return []
|
|
236
|
+
|
|
237
|
+
commands: List[Command] = []
|
|
238
|
+
|
|
239
|
+
slot_set_re = re.compile(r"""SetSlot\(([a-zA-Z_][a-zA-Z0-9_-]*?), ?(.*)\)""")
|
|
240
|
+
start_flow_re = re.compile(r"StartFlow\(([a-zA-Z0-9_-]+?)\)")
|
|
241
|
+
cancel_flow_re = re.compile(r"CancelFlow\(\)")
|
|
242
|
+
chitchat_re = re.compile(r"ChitChat\(\)")
|
|
243
|
+
skip_question_re = re.compile(r"SkipQuestion\(\)")
|
|
244
|
+
knowledge_re = re.compile(r"SearchAndReply\(\)")
|
|
245
|
+
humand_handoff_re = re.compile(r"HumanHandoff\(\)")
|
|
246
|
+
clarify_re = re.compile(r"Clarify\(([a-zA-Z0-9_, ]+)\)")
|
|
247
|
+
|
|
248
|
+
for action in actions.strip().splitlines():
|
|
249
|
+
if match := slot_set_re.search(action):
|
|
250
|
+
slot_name = match.group(1).strip()
|
|
251
|
+
slot_value = cls.clean_extracted_value(match.group(2))
|
|
252
|
+
# error case where the llm tries to start a flow using a slot set
|
|
253
|
+
if slot_name == "flow_name":
|
|
254
|
+
commands.extend(cls.start_flow_by_name(slot_value, flows))
|
|
255
|
+
else:
|
|
256
|
+
typed_slot_value = cls.get_nullable_slot_value(slot_value)
|
|
257
|
+
commands.append(
|
|
258
|
+
SetSlotCommand(name=slot_name, value=typed_slot_value)
|
|
259
|
+
)
|
|
260
|
+
elif match := start_flow_re.search(action):
|
|
261
|
+
flow_name = match.group(1).strip()
|
|
262
|
+
commands.extend(cls.start_flow_by_name(flow_name, flows))
|
|
263
|
+
elif cancel_flow_re.search(action):
|
|
264
|
+
commands.append(CancelFlowCommand())
|
|
265
|
+
elif chitchat_re.search(action):
|
|
266
|
+
commands.append(ChitChatAnswerCommand())
|
|
267
|
+
elif skip_question_re.search(action):
|
|
268
|
+
commands.append(SkipQuestionCommand())
|
|
269
|
+
elif knowledge_re.search(action):
|
|
270
|
+
commands.append(KnowledgeAnswerCommand())
|
|
271
|
+
elif humand_handoff_re.search(action):
|
|
272
|
+
commands.append(HumanHandoffCommand())
|
|
273
|
+
elif match := clarify_re.search(action):
|
|
274
|
+
options = sorted([opt.strip() for opt in match.group(1).split(",")])
|
|
275
|
+
valid_options = [
|
|
276
|
+
flow for flow in options if flow in flows.user_flow_ids
|
|
277
|
+
]
|
|
278
|
+
if len(set(valid_options)) == 1:
|
|
279
|
+
commands.extend(cls.start_flow_by_name(valid_options[0], flows))
|
|
280
|
+
elif len(valid_options) > 1:
|
|
281
|
+
commands.append(ClarifyCommand(valid_options))
|
|
282
|
+
|
|
283
|
+
return commands
|
|
284
|
+
|
|
285
|
+
@classmethod
|
|
286
|
+
def fingerprint_addon(cls: Any, config: Dict[str, Any]) -> Optional[str]:
|
|
287
|
+
"""Add a fingerprint of the knowledge base for the graph."""
|
|
288
|
+
config_prompt = config.get("prompt") or config.get("prompt_template") or None
|
|
289
|
+
prompt_template = get_prompt_template(
|
|
290
|
+
config_prompt,
|
|
291
|
+
DEFAULT_COMMAND_PROMPT_TEMPLATE,
|
|
292
|
+
)
|
|
293
|
+
return deep_container_fingerprint(prompt_template)
|
|
294
|
+
|
|
295
|
+
### Helper methods
|
|
296
|
+
def render_template(
|
|
297
|
+
self,
|
|
298
|
+
message: Message,
|
|
299
|
+
tracker: DialogueStateTracker,
|
|
300
|
+
startable_flows: FlowsList,
|
|
301
|
+
all_flows: FlowsList,
|
|
302
|
+
) -> str:
|
|
303
|
+
"""Render the jinja template to create the prompt for the LLM.
|
|
304
|
+
|
|
305
|
+
Args:
|
|
306
|
+
message: The current message from the user.
|
|
307
|
+
tracker: The tracker containing the current state of the conversation.
|
|
308
|
+
startable_flows: The flows startable at this point in time by the user.
|
|
309
|
+
all_flows: all flows present in the assistant
|
|
310
|
+
|
|
311
|
+
Returns:
|
|
312
|
+
The rendered prompt template.
|
|
313
|
+
"""
|
|
314
|
+
# need to make this distinction here because current step of the
|
|
315
|
+
# top_calling_frame would be the call step, but we need the collect step from
|
|
316
|
+
# the called frame. If no call is active calling and called frame are the same.
|
|
317
|
+
top_calling_frame = top_flow_frame(tracker.stack)
|
|
318
|
+
top_called_frame = top_flow_frame(tracker.stack, ignore_call_frames=False)
|
|
319
|
+
|
|
320
|
+
top_flow = top_calling_frame.flow(all_flows) if top_calling_frame else None
|
|
321
|
+
current_step = top_called_frame.step(all_flows) if top_called_frame else None
|
|
322
|
+
|
|
323
|
+
flow_slots = self.prepare_current_flow_slots_for_template(
|
|
324
|
+
top_flow, current_step, tracker
|
|
325
|
+
)
|
|
326
|
+
current_slot, current_slot_description = self.prepare_current_slot_for_template(
|
|
327
|
+
current_step
|
|
328
|
+
)
|
|
329
|
+
current_conversation = tracker_as_readable_transcript(tracker)
|
|
330
|
+
latest_user_message = sanitize_message_for_prompt(message.get(TEXT))
|
|
331
|
+
current_conversation += f"\nUSER: {latest_user_message}"
|
|
332
|
+
|
|
333
|
+
inputs = {
|
|
334
|
+
"available_flows": self.prepare_flows_for_template(
|
|
335
|
+
startable_flows, tracker
|
|
336
|
+
),
|
|
337
|
+
"current_conversation": current_conversation,
|
|
338
|
+
"flow_slots": flow_slots,
|
|
339
|
+
"current_flow": top_flow.id if top_flow is not None else None,
|
|
340
|
+
"current_slot": current_slot,
|
|
341
|
+
"current_slot_description": current_slot_description,
|
|
342
|
+
"user_message": latest_user_message,
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return self.compile_template(self.prompt_template).render(**inputs)
|
|
@@ -11,7 +11,7 @@ responses:
|
|
|
11
11
|
template: jinja
|
|
12
12
|
|
|
13
13
|
utter_can_do_something_else:
|
|
14
|
-
- text: "What else I
|
|
14
|
+
- text: "What else can I help you with?"
|
|
15
15
|
metadata:
|
|
16
16
|
rephrase: True
|
|
17
17
|
|
|
@@ -100,11 +100,11 @@ slots:
|
|
|
100
100
|
confirm_correction:
|
|
101
101
|
type: bool
|
|
102
102
|
mappings:
|
|
103
|
-
- type:
|
|
103
|
+
- type: from_llm
|
|
104
104
|
|
|
105
105
|
flows:
|
|
106
106
|
pattern_cancel_flow:
|
|
107
|
-
description:
|
|
107
|
+
description: Conversation repair flow that starts when a flow is cancelled
|
|
108
108
|
name: pattern_cancel_flow
|
|
109
109
|
steps:
|
|
110
110
|
- action: action_cancel_flow
|
|
@@ -112,72 +112,77 @@ flows:
|
|
|
112
112
|
|
|
113
113
|
pattern_cannot_handle:
|
|
114
114
|
description: |
|
|
115
|
-
|
|
115
|
+
Conversation repair flow for addressing failed command generation scenarios
|
|
116
116
|
name: pattern cannot handle
|
|
117
117
|
steps:
|
|
118
118
|
- noop: true
|
|
119
119
|
next:
|
|
120
120
|
# chitchat fallback
|
|
121
|
-
- if: "'{{context.reason}}'
|
|
121
|
+
- if: "'{{context.reason}}' = 'cannot_handle_chitchat'"
|
|
122
122
|
then:
|
|
123
123
|
- action: utter_cannot_handle
|
|
124
124
|
next: "END"
|
|
125
|
+
# fallback for things that are not supported
|
|
126
|
+
- if: "'{{context.reason}}' = 'cannot_handle_not_supported'"
|
|
127
|
+
then:
|
|
128
|
+
- action: utter_cannot_handle
|
|
129
|
+
next: END
|
|
125
130
|
# default
|
|
126
131
|
- else:
|
|
127
132
|
- action: utter_ask_rephrase
|
|
128
|
-
next:
|
|
133
|
+
next: END
|
|
129
134
|
|
|
130
135
|
pattern_chitchat:
|
|
131
|
-
description:
|
|
136
|
+
description: Conversation repair flow for off-topic interactions that won't disrupt the main conversation
|
|
132
137
|
name: pattern chitchat
|
|
133
138
|
steps:
|
|
134
139
|
- action: action_trigger_chitchat
|
|
135
140
|
|
|
136
141
|
pattern_clarification:
|
|
137
|
-
description:
|
|
142
|
+
description: Conversation repair flow for handling ambiguous requests that could match multiple flows
|
|
138
143
|
name: pattern clarification
|
|
139
144
|
steps:
|
|
140
145
|
- action: action_clarify_flows
|
|
141
146
|
- action: utter_clarification_options_rasa
|
|
142
147
|
|
|
143
148
|
pattern_code_change:
|
|
144
|
-
description: flow
|
|
149
|
+
description: Conversation repair flow for cleaning the stack after an assistant update
|
|
145
150
|
name: pattern code change
|
|
146
151
|
steps:
|
|
147
152
|
- action: utter_inform_code_change
|
|
148
153
|
- action: action_clean_stack
|
|
149
154
|
|
|
150
155
|
pattern_collect_information:
|
|
151
|
-
description:
|
|
156
|
+
description: Flow for collecting information from users
|
|
152
157
|
name: pattern collect information
|
|
153
158
|
steps:
|
|
154
|
-
- id:
|
|
159
|
+
- id: start
|
|
155
160
|
action: action_run_slot_rejections
|
|
156
161
|
- action: validate_{{context.collect}}
|
|
157
162
|
next:
|
|
158
163
|
- if: "slots.{{context.collect}} is not null"
|
|
159
|
-
then:
|
|
160
|
-
- else:
|
|
161
|
-
- id:
|
|
164
|
+
then: END
|
|
165
|
+
- else: ask_collect
|
|
166
|
+
- id: ask_collect
|
|
162
167
|
action: "{{context.utter}}"
|
|
163
168
|
- action: "{{context.collect_action}}"
|
|
164
169
|
- action: action_listen
|
|
165
|
-
next:
|
|
170
|
+
next: start
|
|
166
171
|
|
|
167
172
|
pattern_completed:
|
|
168
|
-
description:
|
|
173
|
+
description: Flow that asks if the user needs more help after completing their initiated use cases
|
|
169
174
|
name: pattern completed
|
|
170
175
|
steps:
|
|
171
176
|
- action: utter_can_do_something_else
|
|
172
177
|
|
|
173
178
|
pattern_continue_interrupted:
|
|
174
|
-
description:
|
|
179
|
+
description: Conversation repair flow for managing when users switch between different flows
|
|
175
180
|
name: pattern continue interrupted
|
|
176
181
|
steps:
|
|
177
182
|
- action: utter_flow_continue_interrupted
|
|
178
183
|
|
|
179
184
|
pattern_correction:
|
|
180
|
-
description:
|
|
185
|
+
description: Conversation repair flow for managing user input changes or error corrections
|
|
181
186
|
name: pattern correction
|
|
182
187
|
steps:
|
|
183
188
|
- action: action_correct_flow_slot
|
|
@@ -185,36 +190,36 @@ flows:
|
|
|
185
190
|
- if: not context.is_reset_only
|
|
186
191
|
then:
|
|
187
192
|
- action: utter_corrected_previous_input
|
|
188
|
-
next:
|
|
189
|
-
- else:
|
|
193
|
+
next: END
|
|
194
|
+
- else: END
|
|
190
195
|
|
|
191
196
|
pattern_human_handoff:
|
|
192
|
-
description: human
|
|
197
|
+
description: Conversation repair flow for switching users to a human agent if their request can't be handled
|
|
193
198
|
name: pattern human handoff
|
|
194
199
|
steps:
|
|
195
200
|
- action: utter_human_handoff_not_available
|
|
196
201
|
|
|
197
202
|
pattern_internal_error:
|
|
198
|
-
description: internal
|
|
203
|
+
description: Conversation repair flow for informing users about internal errors
|
|
199
204
|
name: pattern internal error
|
|
200
205
|
steps:
|
|
201
206
|
- noop: true
|
|
202
207
|
next:
|
|
203
|
-
- if: "'{{context.error_type}}'
|
|
208
|
+
- if: "'{{context.error_type}}' = 'rasa_internal_error_user_input_too_long'"
|
|
204
209
|
then:
|
|
205
210
|
- action: utter_user_input_too_long_error_rasa
|
|
206
|
-
next:
|
|
207
|
-
- if: "'{{context.error_type}}'
|
|
211
|
+
next: END
|
|
212
|
+
- if: "'{{context.error_type}}' = 'rasa_internal_error_user_input_empty'"
|
|
208
213
|
then:
|
|
209
214
|
- action: utter_user_input_empty_error_rasa
|
|
210
|
-
next:
|
|
215
|
+
next: END
|
|
211
216
|
- else:
|
|
212
217
|
- action: utter_internal_error_rasa
|
|
213
|
-
next:
|
|
218
|
+
next: END
|
|
214
219
|
|
|
215
220
|
|
|
216
221
|
pattern_restart:
|
|
217
|
-
description:
|
|
222
|
+
description: Flow for restarting the conversation
|
|
218
223
|
name: pattern restart
|
|
219
224
|
nlu_trigger:
|
|
220
225
|
- intent: restart
|
|
@@ -222,14 +227,14 @@ flows:
|
|
|
222
227
|
- action: action_restart
|
|
223
228
|
|
|
224
229
|
pattern_search:
|
|
225
|
-
description:
|
|
230
|
+
description: Flow for handling knowledge-based questions
|
|
226
231
|
name: pattern search
|
|
227
232
|
steps:
|
|
228
233
|
- action: utter_no_knowledge_base
|
|
229
234
|
# - action: action_trigger_search to use doc search policy if present
|
|
230
235
|
|
|
231
236
|
pattern_session_start:
|
|
232
|
-
description:
|
|
237
|
+
description: Flow for starting the conversation
|
|
233
238
|
name: pattern session start
|
|
234
239
|
nlu_trigger:
|
|
235
240
|
- intent: session_start
|
|
@@ -237,7 +242,7 @@ flows:
|
|
|
237
242
|
- action: action_session_start
|
|
238
243
|
|
|
239
244
|
pattern_skip_question:
|
|
240
|
-
description: flow
|
|
245
|
+
description: Conversation repair flow for managing user intents to skip questions (steps)
|
|
241
246
|
name: pattern skip question
|
|
242
247
|
steps:
|
|
243
248
|
- action: utter_skip_question_answer
|