rasa-pro 3.11.5__py3-none-any.whl → 3.12.0__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 +10 -13
- rasa/__main__.py +7 -7
- rasa/anonymization/anonymisation_rule_yaml_reader.py +1 -1
- rasa/anonymization/anonymization_pipeline.py +3 -3
- rasa/anonymization/anonymization_rule_executor.py +17 -11
- rasa/anonymization/anonymization_rule_orchestrator.py +2 -3
- rasa/cli/arguments/data.py +2 -2
- rasa/cli/arguments/default_arguments.py +1 -1
- rasa/cli/arguments/evaluate.py +2 -1
- rasa/cli/arguments/interactive.py +1 -1
- rasa/cli/arguments/run.py +1 -1
- rasa/cli/arguments/test.py +7 -5
- rasa/cli/arguments/train.py +3 -3
- rasa/cli/arguments/visualize.py +2 -2
- rasa/cli/arguments/x.py +1 -0
- rasa/cli/data.py +20 -3
- rasa/cli/dialogue_understanding_test.py +386 -0
- rasa/cli/evaluate.py +1 -1
- rasa/cli/export.py +6 -6
- rasa/cli/inspect.py +20 -1
- rasa/cli/interactive.py +4 -5
- rasa/cli/llm_fine_tuning.py +51 -16
- rasa/cli/markers.py +1 -2
- rasa/cli/project_templates/calm/actions/add_contact.py +1 -1
- rasa/cli/project_templates/calm/config.yml +2 -2
- rasa/cli/project_templates/calm/domain/list_contacts.yml +1 -2
- rasa/cli/project_templates/calm/domain/remove_contact.yml +1 -2
- rasa/cli/project_templates/calm/domain/shared.yml +1 -4
- rasa/cli/project_templates/calm/endpoints.yml +2 -2
- rasa/cli/project_templates/tutorial/actions/actions.py +3 -2
- rasa/cli/shell.py +5 -6
- rasa/cli/studio/download.py +1 -2
- rasa/cli/studio/studio.py +2 -3
- rasa/cli/studio/train.py +0 -1
- rasa/cli/telemetry.py +2 -2
- rasa/cli/test.py +11 -11
- rasa/cli/train.py +3 -0
- rasa/cli/utils.py +25 -5
- rasa/constants.py +0 -1
- rasa/core/__init__.py +0 -1
- rasa/core/actions/action.py +135 -208
- rasa/core/actions/action_handle_digressions.py +164 -0
- rasa/core/actions/action_hangup.py +1 -1
- rasa/core/actions/action_repeat_bot_messages.py +2 -2
- rasa/core/actions/action_run_slot_rejections.py +18 -6
- rasa/core/actions/action_trigger_chitchat.py +1 -1
- rasa/core/actions/action_trigger_flow.py +5 -5
- rasa/core/actions/action_trigger_search.py +1 -1
- rasa/core/actions/custom_action_executor.py +1 -1
- rasa/core/actions/direct_custom_actions_executor.py +1 -0
- rasa/core/actions/forms.py +22 -15
- rasa/core/actions/http_custom_action_executor.py +8 -1
- rasa/core/actions/loops.py +3 -3
- rasa/core/actions/two_stage_fallback.py +13 -13
- rasa/core/auth_retry_tracker_store.py +1 -2
- rasa/core/brokers/broker.py +2 -1
- rasa/core/brokers/file.py +1 -1
- rasa/core/brokers/kafka.py +8 -8
- rasa/core/brokers/pika.py +8 -9
- rasa/core/brokers/sql.py +4 -3
- rasa/core/channels/__init__.py +7 -0
- rasa/core/channels/botframework.py +2 -2
- rasa/core/channels/callback.py +4 -4
- rasa/core/channels/channel.py +11 -11
- rasa/core/channels/console.py +0 -1
- rasa/core/channels/development_inspector.py +80 -24
- rasa/core/channels/facebook.py +5 -5
- rasa/core/channels/hangouts.py +7 -8
- rasa/core/channels/inspector/dist/assets/{arc-f0f8bd46.js → arc-9f1365dc.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-7162c77d.js → blockDiagram-38ab4fdb-e0f81b12.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-b1d0d098.js → c4Diagram-3d4e48cf-9deaee1c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/channel-44956714.js +1 -0
- rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-807a1b27.js → classDiagram-70f12bd4-20450a96.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-5238dcdb.js → classDiagram-v2-f2320105-749d2abf.js} +1 -1
- rasa/core/channels/inspector/dist/assets/clone-a9475142.js +1 -0
- rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-75dfaa67.js → createText-2e5e7dd3-bef0b38c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-df20501d.js → edges-e0da2a9e-943801a7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-13cf4797.js → erDiagram-9861fffd-d523a948.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-a4991264.js → flowDb-956e92f1-54e4cf19.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-ccecf773.js → flowDiagram-66a62f08-48bfbbe8.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-43fa749a.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-b5801783.js → flowchart-elk-definition-4a651766-17c30827.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-161e079a.js → ganttDiagram-c361ad54-43086f2d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-f38e86a4.js → gitGraphDiagram-72cf32ee-5c8b693e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{graph-be6ef5d8.js → graph-41a90d26.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-3862675e-d9ce8994.js → index-3862675e-b43eeae9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-7794b245.js → index-e8affe45.js} +155 -155
- rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-5000a3dc.js → infoDiagram-f8f76790-0b20676b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-8ef0a17a.js → journeyDiagram-49397b02-39bce7b5.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-d649bc98.js → layout-dc8eeea4.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-95add810.js → line-c4d2e756.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-f6025094.js → linear-86f6f2d9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-2e8531c4.js → mindmap-definition-fc14e90a-4216f771.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-918adfdb.js → pieDiagram-8a3498a8-1a0cfa96.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-cbd01797.js → quadrantDiagram-120e2f19-f91e67cf.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-6a8b877b.js → requirementDiagram-deff3bca-d4046bed.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-c377c3fe.js → sankeyDiagram-04a897e0-2cf6d1d7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-ab9e9b7f.js → sequenceDiagram-704730f1-751ac4f5.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-5e6ae67d.js → stateDiagram-587899a1-f734f4d4.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-40643476.js → stateDiagram-v2-d93cdb3a-91c65710.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-afb8d108.js → styles-6aaf32cf-e0cff7be.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9a916d00-7edc9423.js → styles-9a916d00-c8029e5d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-c10674c1-c1d8f7e9.js → styles-c10674c1-114f312a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-f494b2ef.js → svgDrawCommon-08f97a94-b7b9dc00.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-11c7cdd0.js → timeline-definition-85554ec2-9536d189.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-3f191ec1.js → xychartDiagram-e933f94c-bf3b0f36.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +1 -1
- rasa/core/channels/inspector/package.json +1 -0
- rasa/core/channels/inspector/src/App.tsx +15 -2
- rasa/core/channels/inspector/src/components/RasaLogo.tsx +31 -0
- rasa/core/channels/inspector/src/components/RecruitmentPanel.tsx +68 -0
- rasa/core/channels/inspector/src/components/Welcome.tsx +19 -13
- rasa/core/channels/inspector/yarn.lock +5 -0
- rasa/core/channels/mattermost.py +4 -4
- rasa/core/channels/rasa_chat.py +4 -4
- rasa/core/channels/rest.py +11 -12
- rasa/core/channels/rocketchat.py +4 -3
- rasa/core/channels/slack.py +6 -5
- rasa/core/channels/socketio.py +8 -28
- rasa/core/channels/studio_chat.py +212 -0
- rasa/core/channels/telegram.py +105 -55
- rasa/core/channels/twilio.py +3 -3
- rasa/core/channels/vier_cvg.py +2 -2
- rasa/core/channels/voice_ready/audiocodes.py +9 -9
- rasa/core/channels/voice_ready/jambonz.py +5 -5
- rasa/core/channels/voice_ready/jambonz_protocol.py +3 -4
- rasa/core/channels/voice_ready/twilio_voice.py +9 -8
- rasa/core/channels/voice_ready/utils.py +2 -2
- rasa/core/channels/voice_stream/asr/asr_engine.py +12 -6
- rasa/core/channels/voice_stream/asr/asr_event.py +5 -0
- rasa/core/channels/voice_stream/asr/azure.py +16 -3
- rasa/core/channels/voice_stream/asr/deepgram.py +76 -19
- rasa/core/channels/voice_stream/audiocodes.py +292 -0
- rasa/core/channels/voice_stream/browser_audio.py +14 -7
- rasa/core/channels/voice_stream/call_state.py +6 -2
- rasa/core/channels/voice_stream/genesys.py +320 -0
- rasa/core/channels/voice_stream/tts/azure.py +13 -5
- rasa/core/channels/voice_stream/tts/cartesia.py +34 -14
- rasa/core/channels/voice_stream/tts/tts_cache.py +3 -2
- rasa/core/channels/voice_stream/tts/tts_engine.py +1 -1
- rasa/core/channels/voice_stream/twilio_media_streams.py +12 -8
- rasa/core/channels/voice_stream/util.py +1 -1
- rasa/core/channels/voice_stream/voice_channel.py +100 -56
- rasa/core/channels/webexteams.py +3 -4
- rasa/core/constants.py +2 -0
- rasa/core/evaluation/marker.py +7 -6
- rasa/core/evaluation/marker_base.py +15 -16
- rasa/core/evaluation/marker_stats.py +3 -4
- rasa/core/evaluation/marker_tracker_loader.py +5 -4
- rasa/core/exporter.py +4 -4
- rasa/core/featurizers/precomputation.py +8 -8
- rasa/core/featurizers/single_state_featurizer.py +7 -7
- rasa/core/featurizers/tracker_featurizers.py +13 -13
- rasa/core/http_interpreter.py +3 -4
- rasa/core/information_retrieval/__init__.py +1 -1
- rasa/core/information_retrieval/faiss.py +4 -4
- rasa/core/information_retrieval/information_retrieval.py +2 -2
- rasa/core/information_retrieval/milvus.py +3 -3
- rasa/core/information_retrieval/qdrant.py +3 -3
- rasa/core/jobs.py +1 -0
- rasa/core/lock.py +2 -3
- rasa/core/lock_store.py +3 -3
- rasa/core/migrate.py +12 -9
- rasa/core/nlg/__init__.py +1 -1
- rasa/core/nlg/callback.py +2 -3
- rasa/core/nlg/contextual_response_rephraser.py +82 -14
- rasa/core/nlg/generator.py +85 -17
- rasa/core/nlg/interpolator.py +4 -3
- rasa/core/nlg/response.py +9 -7
- rasa/core/nlg/summarize.py +1 -0
- rasa/core/nlg/translate.py +55 -0
- rasa/core/persistor.py +3 -3
- rasa/core/policies/ensemble.py +10 -9
- rasa/core/policies/enterprise_search_policy.py +87 -21
- rasa/core/policies/enterprise_search_prompt_with_citation_template.jinja2 +1 -1
- rasa/core/policies/flow_policy.py +13 -14
- rasa/core/policies/flows/flow_executor.py +85 -55
- rasa/core/policies/intentless_policy.py +6 -7
- rasa/core/policies/memoization.py +22 -20
- rasa/core/policies/policy.py +24 -22
- rasa/core/policies/rule_policy.py +37 -36
- rasa/core/policies/ted_policy.py +87 -85
- rasa/core/policies/unexpected_intent_policy.py +77 -75
- rasa/core/processor.py +167 -74
- rasa/core/run.py +5 -4
- rasa/core/secrets_manager/endpoints.py +2 -3
- rasa/core/secrets_manager/factory.py +2 -3
- rasa/core/secrets_manager/secret_manager.py +2 -3
- rasa/core/secrets_manager/vault.py +2 -2
- rasa/core/test.py +30 -30
- rasa/core/tracker_store.py +138 -49
- rasa/core/train.py +1 -1
- rasa/core/training/__init__.py +2 -2
- rasa/core/training/converters/responses_prefix_converter.py +1 -2
- rasa/core/training/interactive.py +13 -13
- rasa/core/training/story_conflict.py +4 -5
- rasa/core/training/training.py +3 -5
- rasa/core/utils.py +5 -5
- rasa/core/visualize.py +1 -1
- rasa/dialogue_understanding/coexistence/intent_based_router.py +2 -2
- rasa/dialogue_understanding/coexistence/llm_based_router.py +5 -5
- rasa/dialogue_understanding/commands/__init__.py +22 -22
- rasa/dialogue_understanding/commands/can_not_handle_command.py +38 -1
- rasa/dialogue_understanding/commands/cancel_flow_command.py +96 -9
- rasa/dialogue_understanding/commands/change_flow_command.py +36 -2
- rasa/dialogue_understanding/commands/chit_chat_answer_command.py +36 -4
- rasa/dialogue_understanding/commands/clarify_command.py +46 -4
- rasa/dialogue_understanding/commands/command.py +3 -2
- rasa/dialogue_understanding/commands/command_syntax_manager.py +55 -0
- rasa/dialogue_understanding/commands/correct_slots_command.py +14 -5
- rasa/dialogue_understanding/commands/error_command.py +1 -1
- rasa/dialogue_understanding/commands/free_form_answer_command.py +2 -1
- rasa/dialogue_understanding/commands/handle_code_change_command.py +2 -2
- rasa/dialogue_understanding/commands/handle_digressions_command.py +144 -0
- rasa/dialogue_understanding/commands/human_handoff_command.py +34 -4
- rasa/dialogue_understanding/commands/knowledge_answer_command.py +36 -4
- rasa/dialogue_understanding/commands/noop_command.py +2 -1
- rasa/dialogue_understanding/commands/prompt_command.py +94 -0
- rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +34 -4
- rasa/dialogue_understanding/commands/restart_command.py +2 -5
- rasa/dialogue_understanding/commands/session_end_command.py +3 -5
- rasa/dialogue_understanding/commands/session_start_command.py +3 -5
- rasa/dialogue_understanding/commands/set_slot_command.py +55 -16
- rasa/dialogue_understanding/commands/skip_question_command.py +34 -4
- rasa/dialogue_understanding/commands/start_flow_command.py +78 -2
- rasa/dialogue_understanding/commands/user_silence_command.py +3 -5
- rasa/dialogue_understanding/commands/utils.py +126 -43
- rasa/dialogue_understanding/constants.py +2 -0
- rasa/dialogue_understanding/generator/__init__.py +2 -0
- rasa/dialogue_understanding/generator/command_generator.py +120 -79
- rasa/dialogue_understanding/generator/command_parser.py +245 -0
- rasa/dialogue_understanding/generator/constants.py +12 -4
- rasa/dialogue_understanding/generator/flow_retrieval.py +7 -7
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +187 -59
- rasa/dialogue_understanding/generator/llm_command_generator.py +6 -3
- rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +106 -110
- rasa/dialogue_understanding/generator/nlu_command_adapter.py +53 -11
- rasa/dialogue_understanding/generator/prompt_templates/__init__.py +0 -0
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +58 -0
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +57 -0
- rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +574 -0
- rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +41 -386
- rasa/dialogue_understanding/generator/utils.py +76 -0
- rasa/dialogue_understanding/patterns/cancel.py +2 -1
- rasa/dialogue_understanding/patterns/cannot_handle.py +1 -0
- rasa/dialogue_understanding/patterns/chitchat.py +1 -1
- rasa/dialogue_understanding/patterns/clarify.py +2 -1
- rasa/dialogue_understanding/patterns/code_change.py +2 -0
- rasa/dialogue_understanding/patterns/collect_information.py +7 -4
- rasa/dialogue_understanding/patterns/completed.py +1 -1
- rasa/dialogue_understanding/patterns/continue_interrupted.py +1 -1
- rasa/dialogue_understanding/patterns/correction.py +17 -3
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +78 -2
- rasa/dialogue_understanding/patterns/handle_digressions.py +81 -0
- rasa/dialogue_understanding/patterns/human_handoff.py +1 -1
- rasa/dialogue_understanding/patterns/internal_error.py +1 -0
- rasa/dialogue_understanding/patterns/search.py +1 -1
- rasa/dialogue_understanding/patterns/session_start.py +1 -1
- rasa/dialogue_understanding/patterns/skip_question.py +1 -0
- rasa/dialogue_understanding/patterns/user_silence.py +1 -1
- rasa/dialogue_understanding/patterns/validate_slot.py +65 -0
- rasa/dialogue_understanding/processor/command_processor.py +193 -43
- rasa/dialogue_understanding/processor/command_processor_component.py +1 -1
- rasa/dialogue_understanding/stack/dialogue_stack.py +4 -3
- rasa/dialogue_understanding/stack/frames/__init__.py +2 -2
- rasa/dialogue_understanding/stack/frames/chit_chat_frame.py +4 -1
- rasa/dialogue_understanding/stack/frames/dialogue_stack_frame.py +2 -3
- rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +5 -2
- rasa/dialogue_understanding/stack/frames/search_frame.py +4 -1
- rasa/dialogue_understanding/stack/utils.py +56 -10
- rasa/dialogue_understanding/utils.py +164 -0
- rasa/dialogue_understanding_test/README.md +429 -0
- rasa/dialogue_understanding_test/__init__.py +0 -0
- rasa/dialogue_understanding_test/command_comparison.py +60 -0
- rasa/dialogue_understanding_test/command_metric_calculation.py +122 -0
- rasa/dialogue_understanding_test/constants.py +22 -0
- rasa/dialogue_understanding_test/du_test_case.py +448 -0
- rasa/dialogue_understanding_test/du_test_result.py +390 -0
- rasa/dialogue_understanding_test/du_test_runner.py +322 -0
- rasa/dialogue_understanding_test/du_test_schema.yml +161 -0
- rasa/dialogue_understanding_test/io.py +443 -0
- rasa/dialogue_understanding_test/test_case_simulation/__init__.py +0 -0
- rasa/dialogue_understanding_test/test_case_simulation/exception.py +28 -0
- rasa/dialogue_understanding_test/test_case_simulation/test_case_tracker_simulator.py +336 -0
- rasa/dialogue_understanding_test/utils.py +70 -0
- rasa/dialogue_understanding_test/validation.py +77 -0
- rasa/e2e_test/aggregate_test_stats_calculator.py +1 -1
- rasa/e2e_test/assertions.py +202 -175
- rasa/e2e_test/assertions_schema.yml +6 -0
- rasa/e2e_test/constants.py +16 -1
- rasa/e2e_test/e2e_config.py +102 -41
- rasa/e2e_test/e2e_config_schema.yml +28 -10
- rasa/e2e_test/e2e_test_case.py +5 -5
- rasa/e2e_test/e2e_test_converter.py +2 -3
- rasa/e2e_test/e2e_test_coverage_report.py +6 -6
- rasa/e2e_test/e2e_test_result.py +1 -1
- rasa/e2e_test/e2e_test_runner.py +143 -38
- rasa/e2e_test/llm_judge_prompts/answer_relevance_prompt_template.jinja2 +93 -0
- rasa/e2e_test/llm_judge_prompts/groundedness_prompt_template.jinja2 +169 -0
- rasa/e2e_test/stub_custom_action.py +1 -1
- rasa/e2e_test/utils/generative_assertions.py +243 -0
- rasa/e2e_test/utils/io.py +123 -93
- rasa/e2e_test/utils/validation.py +101 -3
- rasa/engine/caching.py +5 -7
- rasa/engine/constants.py +1 -1
- rasa/engine/graph.py +3 -2
- rasa/engine/language.py +182 -0
- rasa/engine/recipes/config_files/default_config.yml +4 -0
- rasa/engine/recipes/default_components.py +13 -15
- rasa/engine/recipes/default_recipe.py +65 -49
- rasa/engine/recipes/graph_recipe.py +10 -7
- rasa/engine/recipes/recipe.py +2 -2
- rasa/engine/runner/dask.py +2 -2
- rasa/engine/runner/interface.py +1 -0
- rasa/engine/storage/local_model_storage.py +6 -4
- rasa/engine/storage/resource.py +2 -1
- rasa/engine/storage/storage.py +8 -3
- rasa/engine/training/components.py +2 -1
- rasa/engine/training/fingerprinting.py +4 -2
- rasa/engine/training/graph_trainer.py +4 -4
- rasa/engine/training/hooks.py +2 -2
- rasa/engine/validation.py +36 -33
- rasa/exceptions.py +3 -2
- rasa/graph_components/converters/nlu_message_converter.py +3 -3
- rasa/graph_components/providers/domain_for_core_training_provider.py +3 -3
- rasa/graph_components/providers/domain_provider.py +3 -2
- rasa/graph_components/providers/flows_provider.py +2 -3
- rasa/graph_components/providers/forms_provider.py +4 -4
- rasa/graph_components/providers/nlu_training_data_provider.py +5 -3
- rasa/graph_components/providers/responses_provider.py +4 -4
- rasa/graph_components/providers/rule_only_provider.py +3 -2
- rasa/graph_components/providers/story_graph_provider.py +8 -8
- rasa/graph_components/providers/training_tracker_provider.py +3 -2
- rasa/graph_components/validators/default_recipe_validator.py +16 -16
- rasa/graph_components/validators/finetuning_validator.py +10 -8
- rasa/hooks.py +19 -14
- rasa/jupyter.py +2 -2
- rasa/llm_fine_tuning/annotation_module.py +4 -4
- rasa/llm_fine_tuning/conversations.py +5 -33
- rasa/llm_fine_tuning/llm_data_preparation_module.py +6 -4
- rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +4 -4
- rasa/llm_fine_tuning/paraphrasing/rephrase_validator.py +18 -13
- rasa/llm_fine_tuning/paraphrasing_module.py +6 -2
- rasa/llm_fine_tuning/storage.py +3 -3
- rasa/llm_fine_tuning/train_test_split_module.py +27 -27
- rasa/llm_fine_tuning/utils.py +7 -0
- rasa/markers/marker.py +2 -3
- rasa/markers/marker_base.py +1 -2
- rasa/markers/upload.py +2 -2
- rasa/markers/validate.py +2 -3
- rasa/model.py +3 -5
- rasa/model_manager/config.py +1 -1
- rasa/model_manager/model_api.py +5 -4
- rasa/model_manager/runner_service.py +13 -10
- rasa/model_manager/socket_bridge.py +15 -9
- rasa/model_manager/studio_jwt_auth.py +1 -0
- rasa/model_manager/trainer_service.py +9 -7
- rasa/model_manager/utils.py +1 -1
- rasa/model_manager/warm_rasa_process.py +14 -9
- rasa/model_service.py +5 -6
- rasa/model_testing.py +13 -15
- rasa/model_training.py +29 -29
- rasa/nlu/classifiers/diet_classifier.py +72 -73
- rasa/nlu/classifiers/fallback_classifier.py +9 -8
- rasa/nlu/classifiers/keyword_intent_classifier.py +7 -6
- rasa/nlu/classifiers/logistic_regression_classifier.py +3 -3
- rasa/nlu/classifiers/mitie_intent_classifier.py +5 -4
- rasa/nlu/classifiers/regex_message_handler.py +3 -2
- rasa/nlu/classifiers/sklearn_intent_classifier.py +2 -2
- rasa/nlu/convert.py +2 -2
- rasa/nlu/emulators/dialogflow.py +3 -3
- rasa/nlu/emulators/luis.py +5 -5
- rasa/nlu/emulators/no_emulator.py +1 -0
- rasa/nlu/emulators/wit.py +4 -4
- rasa/nlu/extractors/crf_entity_extractor.py +11 -11
- rasa/nlu/extractors/duckling_entity_extractor.py +7 -6
- rasa/nlu/extractors/entity_synonyms.py +10 -9
- rasa/nlu/extractors/extractor.py +16 -16
- rasa/nlu/extractors/mitie_entity_extractor.py +10 -9
- rasa/nlu/extractors/regex_entity_extractor.py +11 -10
- rasa/nlu/extractors/spacy_entity_extractor.py +2 -2
- rasa/nlu/featurizers/dense_featurizer/convert_featurizer.py +15 -14
- rasa/nlu/featurizers/dense_featurizer/dense_featurizer.py +2 -1
- rasa/nlu/featurizers/dense_featurizer/lm_featurizer.py +10 -9
- rasa/nlu/featurizers/dense_featurizer/mitie_featurizer.py +9 -7
- rasa/nlu/featurizers/dense_featurizer/spacy_featurizer.py +13 -12
- rasa/nlu/featurizers/featurizer.py +5 -4
- rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +6 -6
- rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +4 -4
- rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +4 -4
- rasa/nlu/featurizers/sparse_featurizer/sparse_featurizer.py +2 -0
- rasa/nlu/model.py +0 -1
- rasa/nlu/selectors/response_selector.py +67 -68
- rasa/nlu/test.py +38 -38
- rasa/nlu/tokenizers/jieba_tokenizer.py +1 -2
- rasa/nlu/tokenizers/mitie_tokenizer.py +2 -2
- rasa/nlu/tokenizers/spacy_tokenizer.py +3 -3
- rasa/nlu/tokenizers/tokenizer.py +6 -7
- rasa/nlu/tokenizers/whitespace_tokenizer.py +1 -1
- rasa/nlu/utils/bilou_utils.py +7 -7
- rasa/nlu/utils/hugging_face/registry.py +22 -22
- rasa/nlu/utils/hugging_face/transformers_pre_post_processors.py +2 -1
- rasa/nlu/utils/mitie_utils.py +2 -1
- rasa/nlu/utils/pattern_utils.py +1 -1
- rasa/nlu/utils/spacy_utils.py +3 -3
- rasa/plugin.py +12 -1
- rasa/server.py +3 -2
- rasa/shared/constants.py +45 -18
- rasa/shared/core/command_payload_reader.py +15 -7
- rasa/shared/core/constants.py +34 -4
- rasa/shared/core/conversation.py +1 -2
- rasa/shared/core/domain.py +19 -20
- rasa/shared/core/events.py +60 -39
- rasa/shared/core/flows/__init__.py +0 -1
- rasa/shared/core/flows/constants.py +11 -0
- rasa/shared/core/flows/flow.py +107 -26
- rasa/shared/core/flows/flow_step.py +4 -3
- rasa/shared/core/flows/flow_step_links.py +1 -2
- rasa/shared/core/flows/flow_step_sequence.py +1 -1
- rasa/shared/core/flows/flows_list.py +3 -3
- rasa/shared/core/flows/flows_yaml_schema.json +69 -3
- rasa/shared/core/flows/nlu_trigger.py +1 -1
- rasa/shared/core/flows/steps/__init__.py +2 -2
- rasa/shared/core/flows/steps/action.py +1 -1
- rasa/shared/core/flows/steps/call.py +1 -1
- rasa/shared/core/flows/steps/collect.py +22 -40
- rasa/shared/core/flows/steps/internal.py +1 -1
- rasa/shared/core/flows/steps/link.py +1 -1
- rasa/shared/core/flows/steps/no_operation.py +2 -2
- rasa/shared/core/flows/steps/set_slots.py +1 -1
- rasa/shared/core/flows/utils.py +44 -4
- rasa/shared/core/flows/validation.py +4 -6
- rasa/shared/core/generator.py +20 -21
- rasa/shared/core/slot_mappings.py +360 -121
- rasa/shared/core/slots.py +163 -6
- rasa/shared/core/trackers.py +108 -33
- rasa/shared/core/training_data/loading.py +1 -1
- rasa/shared/core/training_data/story_reader/story_reader.py +3 -3
- rasa/shared/core/training_data/story_reader/story_step_builder.py +4 -4
- rasa/shared/core/training_data/story_reader/yaml_story_reader.py +29 -31
- rasa/shared/core/training_data/story_writer/yaml_story_writer.py +22 -24
- rasa/shared/core/training_data/structures.py +11 -12
- rasa/shared/core/training_data/visualization.py +10 -10
- rasa/shared/data.py +6 -6
- rasa/shared/engine/caching.py +0 -1
- rasa/shared/exceptions.py +2 -2
- rasa/shared/importers/importer.py +58 -2
- rasa/shared/importers/rasa.py +5 -6
- rasa/shared/importers/utils.py +1 -1
- rasa/shared/nlu/constants.py +9 -0
- rasa/shared/nlu/training_data/entities_parser.py +6 -6
- rasa/shared/nlu/training_data/features.py +3 -3
- rasa/shared/nlu/training_data/formats/__init__.py +1 -1
- rasa/shared/nlu/training_data/formats/dialogflow.py +4 -5
- rasa/shared/nlu/training_data/formats/luis.py +7 -8
- rasa/shared/nlu/training_data/formats/rasa.py +4 -5
- rasa/shared/nlu/training_data/formats/rasa_yaml.py +17 -16
- rasa/shared/nlu/training_data/formats/readerwriter.py +8 -11
- rasa/shared/nlu/training_data/formats/wit.py +3 -4
- rasa/shared/nlu/training_data/loading.py +4 -4
- rasa/shared/nlu/training_data/lookup_tables_parser.py +1 -1
- rasa/shared/nlu/training_data/message.py +13 -14
- rasa/shared/nlu/training_data/schemas/data_schema.py +1 -1
- rasa/shared/nlu/training_data/schemas/responses.yml +19 -11
- rasa/shared/nlu/training_data/synonyms_parser.py +3 -3
- rasa/shared/nlu/training_data/training_data.py +12 -13
- rasa/shared/nlu/training_data/util.py +11 -10
- rasa/shared/providers/_configs/azure_entra_id_config.py +541 -0
- rasa/shared/providers/_configs/azure_openai_client_config.py +150 -15
- rasa/shared/providers/_configs/client_config.py +3 -1
- rasa/shared/providers/_configs/default_litellm_client_config.py +9 -7
- rasa/shared/providers/_configs/huggingface_local_embedding_client_config.py +13 -11
- rasa/shared/providers/_configs/litellm_router_client_config.py +12 -10
- rasa/shared/providers/_configs/model_group_config.py +8 -5
- rasa/shared/providers/_configs/oauth_config.py +33 -0
- rasa/shared/providers/_configs/openai_client_config.py +14 -12
- rasa/shared/providers/_configs/rasa_llm_client_config.py +5 -3
- rasa/shared/providers/_configs/self_hosted_llm_client_config.py +12 -11
- rasa/shared/providers/_configs/utils.py +1 -0
- rasa/shared/providers/_ssl_verification_utils.py +5 -6
- rasa/shared/providers/_utils.py +5 -5
- rasa/shared/providers/constants.py +6 -0
- rasa/shared/providers/embedding/_base_litellm_embedding_client.py +1 -1
- rasa/shared/providers/embedding/azure_openai_embedding_client.py +32 -7
- rasa/shared/providers/embedding/embedding_client.py +1 -1
- rasa/shared/providers/embedding/litellm_router_embedding_client.py +5 -2
- rasa/shared/providers/llm/_base_litellm_client.py +43 -18
- rasa/shared/providers/llm/azure_openai_llm_client.py +90 -34
- rasa/shared/providers/llm/default_litellm_llm_client.py +4 -2
- rasa/shared/providers/llm/litellm_router_llm_client.py +32 -9
- rasa/shared/providers/llm/llm_client.py +24 -8
- rasa/shared/providers/llm/llm_response.py +61 -2
- rasa/shared/providers/llm/openai_llm_client.py +11 -5
- rasa/shared/providers/llm/rasa_llm_client.py +17 -14
- rasa/shared/providers/llm/self_hosted_llm_client.py +35 -15
- rasa/shared/providers/mappings.py +18 -19
- rasa/shared/providers/router/_base_litellm_router_client.py +48 -15
- rasa/shared/providers/router/router_client.py +3 -1
- rasa/shared/utils/cli.py +1 -1
- rasa/shared/utils/common.py +15 -1
- rasa/shared/utils/constants.py +3 -0
- rasa/shared/utils/health_check/embeddings_health_check_mixin.py +1 -1
- rasa/shared/utils/health_check/health_check.py +3 -3
- rasa/shared/utils/health_check/llm_health_check_mixin.py +1 -1
- rasa/shared/utils/io.py +1 -1
- rasa/shared/utils/llm.py +100 -18
- rasa/shared/utils/pykwalify_extensions.py +25 -1
- rasa/shared/utils/schemas/domain.yml +26 -1
- rasa/shared/utils/schemas/events.py +1 -1
- rasa/shared/utils/yaml.py +24 -20
- rasa/studio/auth.py +3 -3
- rasa/studio/config.py +1 -2
- rasa/studio/data_handler.py +3 -3
- rasa/studio/download.py +1 -1
- rasa/studio/results_logger.py +3 -3
- rasa/studio/upload.py +21 -5
- rasa/telemetry.py +127 -48
- rasa/tracing/config.py +5 -3
- rasa/tracing/constants.py +12 -0
- rasa/tracing/instrumentation/attribute_extractors.py +92 -14
- rasa/tracing/instrumentation/instrumentation.py +61 -5
- rasa/tracing/instrumentation/intentless_policy_instrumentation.py +1 -1
- rasa/tracing/instrumentation/metrics.py +52 -11
- rasa/tracing/metric_instrument_provider.py +54 -14
- rasa/utils/common.py +12 -24
- rasa/utils/endpoints.py +1 -1
- rasa/utils/io.py +7 -7
- rasa/utils/licensing.py +3 -4
- rasa/utils/log_utils.py +7 -6
- rasa/utils/ml_utils.py +1 -0
- rasa/utils/plotting.py +3 -3
- rasa/utils/sanic_error_handler.py +1 -1
- rasa/utils/tensorflow/callback.py +2 -2
- rasa/utils/tensorflow/crf.py +2 -2
- rasa/utils/tensorflow/data_generator.py +5 -5
- rasa/utils/tensorflow/environment.py +3 -3
- rasa/utils/tensorflow/feature_array.py +2 -3
- rasa/utils/tensorflow/layers.py +18 -12
- rasa/utils/tensorflow/layers_utils.py +2 -1
- rasa/utils/tensorflow/metrics.py +2 -2
- rasa/utils/tensorflow/model_data.py +7 -7
- rasa/utils/tensorflow/model_data_utils.py +10 -9
- rasa/utils/tensorflow/models.py +31 -32
- rasa/utils/tensorflow/rasa_layers.py +20 -19
- rasa/utils/tensorflow/types.py +2 -1
- rasa/utils/train_utils.py +23 -21
- rasa/utils/url_tools.py +1 -1
- rasa/validator.py +594 -115
- rasa/version.py +1 -1
- {rasa_pro-3.11.5.dist-info → rasa_pro-3.12.0.dist-info}/METADATA +23 -26
- rasa_pro-3.12.0.dist-info/RECORD +829 -0
- rasa/core/channels/inspector/dist/assets/channel-e265ea59.js +0 -1
- rasa/core/channels/inspector/dist/assets/clone-21f8a43d.js +0 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-5c8ce12d.js +0 -1
- rasa_pro-3.11.5.dist-info/RECORD +0 -785
- /rasa/dialogue_understanding/generator/{single_step → prompt_templates}/command_prompt_template.jinja2 +0 -0
- {rasa_pro-3.11.5.dist-info → rasa_pro-3.12.0.dist-info}/NOTICE +0 -0
- {rasa_pro-3.11.5.dist-info → rasa_pro-3.12.0.dist-info}/WHEEL +0 -0
- {rasa_pro-3.11.5.dist-info → rasa_pro-3.12.0.dist-info}/entry_points.txt +0 -0
|
@@ -1,45 +1,150 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import copy
|
|
4
|
+
from enum import Enum
|
|
5
|
+
from typing import (
|
|
6
|
+
TYPE_CHECKING,
|
|
7
|
+
Any,
|
|
8
|
+
Dict,
|
|
9
|
+
List,
|
|
10
|
+
Optional,
|
|
11
|
+
Set,
|
|
12
|
+
Text,
|
|
13
|
+
Tuple,
|
|
14
|
+
Union,
|
|
15
|
+
cast,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
import structlog
|
|
19
|
+
from pydantic import BaseModel, Field
|
|
3
20
|
|
|
4
|
-
from rasa.shared.constants import DOCS_URL_NLU_BASED_SLOTS, IGNORED_INTENTS
|
|
5
21
|
import rasa.shared.utils.io
|
|
22
|
+
from rasa.shared.constants import DOCS_URL_NLU_BASED_SLOTS, IGNORED_INTENTS
|
|
23
|
+
from rasa.shared.core.constants import (
|
|
24
|
+
ACTION_EXTRACT_SLOTS,
|
|
25
|
+
ACTION_VALIDATE_SLOT_MAPPINGS,
|
|
26
|
+
ACTIVE_LOOP,
|
|
27
|
+
KEY_ACTION,
|
|
28
|
+
KEY_COEXISTENCE_SYSTEM,
|
|
29
|
+
KEY_MAPPING_TYPE,
|
|
30
|
+
KEY_RUN_ACTION_EVERY_TURN,
|
|
31
|
+
MAPPING_CONDITIONS,
|
|
32
|
+
REQUESTED_SLOT,
|
|
33
|
+
SlotMappingType,
|
|
34
|
+
)
|
|
35
|
+
from rasa.shared.core.events import BotUttered, Event, SlotSet
|
|
6
36
|
from rasa.shared.core.slots import ListSlot, Slot
|
|
37
|
+
from rasa.shared.exceptions import RasaException
|
|
7
38
|
from rasa.shared.nlu.constants import (
|
|
8
39
|
ENTITIES,
|
|
9
|
-
ENTITY_ATTRIBUTE_TYPE,
|
|
10
|
-
ENTITY_ATTRIBUTE_ROLE,
|
|
11
40
|
ENTITY_ATTRIBUTE_GROUP,
|
|
41
|
+
ENTITY_ATTRIBUTE_ROLE,
|
|
42
|
+
ENTITY_ATTRIBUTE_TYPE,
|
|
12
43
|
ENTITY_ATTRIBUTE_VALUE,
|
|
13
44
|
INTENT,
|
|
14
|
-
NOT_INTENT,
|
|
15
45
|
INTENT_NAME_KEY,
|
|
16
46
|
TEXT,
|
|
17
47
|
)
|
|
18
|
-
from rasa.shared.core.constants import (
|
|
19
|
-
ACTIVE_FLOW,
|
|
20
|
-
ACTIVE_LOOP,
|
|
21
|
-
REQUESTED_SLOT,
|
|
22
|
-
SLOT_MAPPINGS,
|
|
23
|
-
MAPPING_TYPE,
|
|
24
|
-
SlotMappingType,
|
|
25
|
-
MAPPING_CONDITIONS,
|
|
26
|
-
)
|
|
27
48
|
|
|
28
49
|
if TYPE_CHECKING:
|
|
29
|
-
from rasa.
|
|
50
|
+
from rasa.core.channels.channel import OutputChannel
|
|
51
|
+
from rasa.core.nlg import NaturalLanguageGenerator
|
|
30
52
|
from rasa.shared.core.domain import Domain
|
|
53
|
+
from rasa.shared.core.trackers import DialogueStateTracker
|
|
31
54
|
from rasa.shared.nlu.training_data.message import Message
|
|
32
55
|
from rasa.utils.endpoints import EndpointConfig
|
|
33
56
|
|
|
57
|
+
structlogger = structlog.get_logger()
|
|
34
58
|
|
|
35
|
-
logger = logging.getLogger(__name__)
|
|
36
59
|
|
|
60
|
+
class SlotMappingCondition(BaseModel):
|
|
61
|
+
"""Defines a condition for a slot mapping."""
|
|
37
62
|
|
|
38
|
-
|
|
63
|
+
active_loop: Optional[str]
|
|
64
|
+
requested_slot: Optional[str] = None
|
|
65
|
+
active_flow: Optional[str] = None
|
|
66
|
+
|
|
67
|
+
@staticmethod
|
|
68
|
+
def from_dict(data: Dict[str, Any]) -> SlotMappingCondition:
|
|
69
|
+
# we allow None as a valid value for active_loop
|
|
70
|
+
# therefore we need to set a different default value
|
|
71
|
+
active_loop = data.pop(ACTIVE_LOOP, "")
|
|
72
|
+
|
|
73
|
+
return SlotMappingCondition(active_loop=active_loop, **data)
|
|
74
|
+
|
|
75
|
+
def as_dict(self) -> Dict[str, Any]:
|
|
76
|
+
return self.model_dump(exclude_none=True)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class CoexistenceSystemType(Enum):
|
|
80
|
+
NLU = "NLU"
|
|
81
|
+
CALM = "CALM"
|
|
82
|
+
SHARED = "SHARED"
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class SlotMapping(BaseModel):
|
|
39
86
|
"""Defines functionality for the available slot mappings."""
|
|
40
87
|
|
|
88
|
+
type: SlotMappingType
|
|
89
|
+
conditions: List[SlotMappingCondition] = Field(default_factory=list)
|
|
90
|
+
entity: Optional[str] = None
|
|
91
|
+
intent: Optional[Union[str, List[str]]] = None
|
|
92
|
+
role: Optional[str] = None
|
|
93
|
+
group: Optional[str] = None
|
|
94
|
+
not_intent: Optional[Union[str, List[str]]] = None
|
|
95
|
+
value: Optional[Any] = None
|
|
96
|
+
allow_nlu_correction: Optional[bool] = None
|
|
97
|
+
run_action_every_turn: Optional[str] = None
|
|
98
|
+
coexistence_system: Optional[CoexistenceSystemType] = None
|
|
99
|
+
|
|
41
100
|
@staticmethod
|
|
42
|
-
def
|
|
101
|
+
def from_dict(data: Dict[str, Any], slot_name: str) -> SlotMapping:
|
|
102
|
+
data_copy = copy.deepcopy(data)
|
|
103
|
+
mapping_type = SlotMapping.validate_mapping(data_copy, slot_name)
|
|
104
|
+
conditions = [
|
|
105
|
+
SlotMappingCondition.from_dict(condition)
|
|
106
|
+
for condition in data_copy.pop(MAPPING_CONDITIONS, [])
|
|
107
|
+
]
|
|
108
|
+
|
|
109
|
+
deprecated_action = data_copy.pop(KEY_ACTION, None)
|
|
110
|
+
if deprecated_action:
|
|
111
|
+
rasa.shared.utils.io.raise_deprecation_warning(
|
|
112
|
+
f"The `{KEY_ACTION}` key in slot mappings is deprecated and "
|
|
113
|
+
f"will be removed in Rasa Pro 4.0.0. "
|
|
114
|
+
f"Please use the `{KEY_RUN_ACTION_EVERY_TURN}` key instead.",
|
|
115
|
+
)
|
|
116
|
+
data_copy[KEY_RUN_ACTION_EVERY_TURN] = deprecated_action
|
|
117
|
+
|
|
118
|
+
run_action_every_turn = data_copy.pop(KEY_RUN_ACTION_EVERY_TURN, None)
|
|
119
|
+
|
|
120
|
+
coexistence_system = data_copy.pop(KEY_COEXISTENCE_SYSTEM, None)
|
|
121
|
+
coexistence_system_type = (
|
|
122
|
+
CoexistenceSystemType(coexistence_system) if coexistence_system else None
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
return SlotMapping(
|
|
126
|
+
type=mapping_type,
|
|
127
|
+
conditions=conditions,
|
|
128
|
+
run_action_every_turn=run_action_every_turn,
|
|
129
|
+
coexistence_system=coexistence_system_type,
|
|
130
|
+
**data_copy,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
def as_dict(self) -> Dict[str, Any]:
|
|
134
|
+
data = self.model_dump(mode="json", exclude_none=True)
|
|
135
|
+
data[KEY_MAPPING_TYPE] = self.type.value
|
|
136
|
+
|
|
137
|
+
if self.conditions:
|
|
138
|
+
data[MAPPING_CONDITIONS] = [
|
|
139
|
+
condition.as_dict() for condition in self.conditions
|
|
140
|
+
]
|
|
141
|
+
else:
|
|
142
|
+
data.pop(MAPPING_CONDITIONS, None)
|
|
143
|
+
|
|
144
|
+
return data
|
|
145
|
+
|
|
146
|
+
@staticmethod
|
|
147
|
+
def validate_mapping(mapping: Dict[str, Any], slot_name: str) -> SlotMappingType:
|
|
43
148
|
"""Validates a slot mapping.
|
|
44
149
|
|
|
45
150
|
Args:
|
|
@@ -58,12 +163,22 @@ class SlotMapping:
|
|
|
58
163
|
f"{DOCS_URL_NLU_BASED_SLOTS} for more information."
|
|
59
164
|
)
|
|
60
165
|
|
|
166
|
+
mapping_raw = mapping.pop(KEY_MAPPING_TYPE, SlotMappingType.FROM_LLM.value)
|
|
167
|
+
|
|
168
|
+
if mapping_raw == "custom":
|
|
169
|
+
rasa.shared.utils.io.raise_deprecation_warning(
|
|
170
|
+
"The `custom` slot mapping type is deprecated and "
|
|
171
|
+
"will be removed in Rasa Pro 4.0.0. "
|
|
172
|
+
"Please use the `controlled` slot mapping type instead.",
|
|
173
|
+
)
|
|
174
|
+
mapping_raw = "controlled"
|
|
175
|
+
|
|
61
176
|
try:
|
|
62
|
-
mapping_type = SlotMappingType(
|
|
177
|
+
mapping_type = SlotMappingType(mapping_raw)
|
|
63
178
|
except ValueError:
|
|
64
179
|
raise InvalidDomain(
|
|
65
180
|
f"Your domain uses an invalid slot mapping of type "
|
|
66
|
-
f"'{
|
|
181
|
+
f"'{mapping_raw}' for slot '{slot_name}'. Please see "
|
|
67
182
|
f"{DOCS_URL_NLU_BASED_SLOTS} for more information."
|
|
68
183
|
)
|
|
69
184
|
|
|
@@ -72,7 +187,7 @@ class SlotMapping:
|
|
|
72
187
|
SlotMappingType.FROM_INTENT: ["value"],
|
|
73
188
|
SlotMappingType.FROM_TRIGGER_INTENT: ["value"],
|
|
74
189
|
SlotMappingType.FROM_TEXT: [],
|
|
75
|
-
SlotMappingType.
|
|
190
|
+
SlotMappingType.CONTROLLED: [],
|
|
76
191
|
SlotMappingType.FROM_LLM: [],
|
|
77
192
|
}
|
|
78
193
|
|
|
@@ -86,19 +201,18 @@ class SlotMapping:
|
|
|
86
201
|
f"{DOCS_URL_NLU_BASED_SLOTS} for more information."
|
|
87
202
|
)
|
|
88
203
|
|
|
89
|
-
|
|
204
|
+
return mapping_type
|
|
205
|
+
|
|
90
206
|
def _get_active_loop_ignored_intents(
|
|
91
|
-
|
|
207
|
+
self, domain: "Domain", active_loop_name: Text
|
|
92
208
|
) -> List[Text]:
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
mapping_conditions = mapping.get(MAPPING_CONDITIONS)
|
|
209
|
+
mapping_conditions = self.conditions
|
|
96
210
|
active_loop_match = True
|
|
97
211
|
ignored_intents = []
|
|
98
212
|
|
|
99
213
|
if mapping_conditions:
|
|
100
214
|
match_list = [
|
|
101
|
-
condition.
|
|
215
|
+
condition.active_loop == active_loop_name
|
|
102
216
|
for condition in mapping_conditions
|
|
103
217
|
]
|
|
104
218
|
active_loop_match = any(match_list)
|
|
@@ -111,24 +225,21 @@ class SlotMapping:
|
|
|
111
225
|
|
|
112
226
|
return ignored_intents
|
|
113
227
|
|
|
114
|
-
@staticmethod
|
|
115
228
|
def intent_is_desired(
|
|
116
|
-
|
|
229
|
+
self,
|
|
117
230
|
tracker: "DialogueStateTracker",
|
|
118
231
|
domain: "Domain",
|
|
119
232
|
message: Optional["Message"] = None,
|
|
120
233
|
) -> bool:
|
|
121
234
|
"""Checks whether user intent matches slot mapping intent specifications."""
|
|
122
|
-
mapping_intents = SlotMapping.to_list(
|
|
123
|
-
mapping_not_intents = SlotMapping.to_list(
|
|
235
|
+
mapping_intents = SlotMapping.to_list(self.intent)
|
|
236
|
+
mapping_not_intents = SlotMapping.to_list(self.not_intent)
|
|
124
237
|
|
|
125
238
|
active_loop_name = tracker.active_loop_name
|
|
126
239
|
if active_loop_name:
|
|
127
240
|
mapping_not_intents = (
|
|
128
241
|
mapping_not_intents
|
|
129
|
-
+
|
|
130
|
-
mapping, domain, active_loop_name
|
|
131
|
-
)
|
|
242
|
+
+ self._get_active_loop_ignored_intents(domain, active_loop_name)
|
|
132
243
|
)
|
|
133
244
|
|
|
134
245
|
if message is not None:
|
|
@@ -155,16 +266,14 @@ class SlotMapping:
|
|
|
155
266
|
|
|
156
267
|
return x
|
|
157
268
|
|
|
158
|
-
@staticmethod
|
|
159
269
|
def entity_is_desired(
|
|
160
|
-
|
|
270
|
+
self,
|
|
161
271
|
tracker: "DialogueStateTracker",
|
|
162
272
|
message: Optional["Message"] = None,
|
|
163
273
|
) -> List[str]:
|
|
164
274
|
"""Checks whether slot should be filled by an entity in the input or not.
|
|
165
275
|
|
|
166
276
|
Args:
|
|
167
|
-
mapping: Slot mapping.
|
|
168
277
|
tracker: The tracker.
|
|
169
278
|
message: The message being processed.
|
|
170
279
|
|
|
@@ -176,19 +285,16 @@ class SlotMapping:
|
|
|
176
285
|
matching_values = [
|
|
177
286
|
cast(Text, entity[ENTITY_ATTRIBUTE_VALUE])
|
|
178
287
|
for entity in extracted_entities
|
|
179
|
-
if entity.get(ENTITY_ATTRIBUTE_TYPE)
|
|
180
|
-
|
|
181
|
-
and entity.get(
|
|
182
|
-
== mapping.get(ENTITY_ATTRIBUTE_GROUP)
|
|
183
|
-
and entity.get(ENTITY_ATTRIBUTE_ROLE)
|
|
184
|
-
== mapping.get(ENTITY_ATTRIBUTE_ROLE)
|
|
288
|
+
if entity.get(ENTITY_ATTRIBUTE_TYPE) == self.entity
|
|
289
|
+
and entity.get(ENTITY_ATTRIBUTE_GROUP) == self.group
|
|
290
|
+
and entity.get(ENTITY_ATTRIBUTE_ROLE) == self.role
|
|
185
291
|
]
|
|
186
292
|
elif tracker.latest_message and tracker.latest_message.text is not None:
|
|
187
293
|
matching_values = list(
|
|
188
294
|
tracker.get_latest_entity_values(
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
295
|
+
self.entity,
|
|
296
|
+
self.role,
|
|
297
|
+
self.group,
|
|
192
298
|
)
|
|
193
299
|
)
|
|
194
300
|
else:
|
|
@@ -196,45 +302,38 @@ class SlotMapping:
|
|
|
196
302
|
|
|
197
303
|
return matching_values
|
|
198
304
|
|
|
199
|
-
@staticmethod
|
|
200
305
|
def check_mapping_validity(
|
|
306
|
+
self,
|
|
201
307
|
slot_name: Text,
|
|
202
|
-
mapping_type: SlotMappingType,
|
|
203
|
-
mapping: Dict[Text, Any],
|
|
204
308
|
domain: "Domain",
|
|
205
309
|
) -> bool:
|
|
206
310
|
"""Checks the mapping for validity.
|
|
207
311
|
|
|
208
312
|
Args:
|
|
209
313
|
slot_name: The name of the slot to be validated.
|
|
210
|
-
mapping_type: The type of the slot mapping.
|
|
211
|
-
mapping: Slot mapping.
|
|
212
314
|
domain: The domain to check against.
|
|
213
315
|
|
|
214
316
|
Returns:
|
|
215
317
|
True, if intent and entity specified in a mapping exist in domain.
|
|
216
318
|
"""
|
|
217
319
|
if (
|
|
218
|
-
|
|
219
|
-
and
|
|
320
|
+
self.type == SlotMappingType.FROM_ENTITY
|
|
321
|
+
and self.entity not in domain.entities
|
|
220
322
|
):
|
|
221
323
|
rasa.shared.utils.io.raise_warning(
|
|
222
324
|
f"Slot '{slot_name}' uses a 'from_entity' mapping "
|
|
223
|
-
f"for a non-existent entity '{
|
|
325
|
+
f"for a non-existent entity '{self.entity}'. "
|
|
224
326
|
f"Skipping slot extraction because of invalid mapping."
|
|
225
327
|
)
|
|
226
328
|
return False
|
|
227
329
|
|
|
228
|
-
if
|
|
229
|
-
|
|
230
|
-
and mapping.get(INTENT) is not None
|
|
231
|
-
):
|
|
232
|
-
intent_list = SlotMapping.to_list(mapping.get(INTENT))
|
|
330
|
+
if self.type == SlotMappingType.FROM_INTENT and self.intent is not None:
|
|
331
|
+
intent_list = SlotMapping.to_list(self.intent)
|
|
233
332
|
for intent in intent_list:
|
|
234
333
|
if intent and intent not in domain.intents:
|
|
235
334
|
rasa.shared.utils.io.raise_warning(
|
|
236
335
|
f"Slot '{slot_name}' uses a 'from_intent' mapping for "
|
|
237
|
-
f"a non-existent intent '{
|
|
336
|
+
f"a non-existent intent '{intent}'. "
|
|
238
337
|
f"Skipping slot extraction because of invalid mapping."
|
|
239
338
|
)
|
|
240
339
|
return False
|
|
@@ -242,22 +341,6 @@ class SlotMapping:
|
|
|
242
341
|
return True
|
|
243
342
|
|
|
244
343
|
|
|
245
|
-
def validate_slot_mappings(domain_slots: Dict[Text, Any]) -> None:
|
|
246
|
-
"""Raises InvalidDomain exception if slot mappings are invalid."""
|
|
247
|
-
rasa.shared.utils.io.raise_warning(
|
|
248
|
-
f"Slot auto-fill has been removed in 3.0 and replaced with a "
|
|
249
|
-
f"new explicit mechanism to set slots. "
|
|
250
|
-
f"Please refer to {DOCS_URL_NLU_BASED_SLOTS} to learn more.",
|
|
251
|
-
UserWarning,
|
|
252
|
-
)
|
|
253
|
-
|
|
254
|
-
for slot_name, properties in domain_slots.items():
|
|
255
|
-
mappings = properties.get(SLOT_MAPPINGS, [])
|
|
256
|
-
|
|
257
|
-
for slot_mapping in mappings:
|
|
258
|
-
SlotMapping.validate(slot_mapping, slot_name)
|
|
259
|
-
|
|
260
|
-
|
|
261
344
|
class SlotFillingManager:
|
|
262
345
|
"""Manages slot filling based on conversation context."""
|
|
263
346
|
|
|
@@ -272,45 +355,39 @@ class SlotFillingManager:
|
|
|
272
355
|
self.tracker = tracker
|
|
273
356
|
self.message = message
|
|
274
357
|
self._action_endpoint = action_endpoint
|
|
358
|
+
self.executed_custom_actions: Set[str] = set()
|
|
275
359
|
|
|
276
360
|
def is_slot_mapping_valid(
|
|
277
361
|
self,
|
|
278
362
|
slot_name: str,
|
|
279
|
-
|
|
280
|
-
mapping: Dict[str, Any],
|
|
363
|
+
mapping: SlotMapping,
|
|
281
364
|
) -> bool:
|
|
282
365
|
"""Check if a slot mapping is valid."""
|
|
283
|
-
return
|
|
366
|
+
return mapping.check_mapping_validity(
|
|
284
367
|
slot_name=slot_name,
|
|
285
|
-
mapping_type=mapping_type,
|
|
286
|
-
mapping=mapping,
|
|
287
368
|
domain=self.domain,
|
|
288
369
|
)
|
|
289
370
|
|
|
290
|
-
def is_intent_desired(self, mapping:
|
|
371
|
+
def is_intent_desired(self, mapping: SlotMapping) -> bool:
|
|
291
372
|
"""Check if the intent matches the one indicated in the slot mapping."""
|
|
292
|
-
return
|
|
293
|
-
mapping=mapping,
|
|
373
|
+
return mapping.intent_is_desired(
|
|
294
374
|
tracker=self.tracker,
|
|
295
375
|
domain=self.domain,
|
|
296
376
|
message=self.message,
|
|
297
377
|
)
|
|
298
378
|
|
|
299
|
-
def _verify_mapping_conditions(
|
|
300
|
-
|
|
301
|
-
) -> bool:
|
|
302
|
-
if mapping.get(MAPPING_CONDITIONS) and mapping[MAPPING_TYPE] != str(
|
|
379
|
+
def _verify_mapping_conditions(self, mapping: SlotMapping, slot_name: Text) -> bool:
|
|
380
|
+
if mapping.conditions and mapping.type != str(
|
|
303
381
|
SlotMappingType.FROM_TRIGGER_INTENT
|
|
304
382
|
):
|
|
305
|
-
|
|
306
|
-
return False
|
|
383
|
+
return self._matches_mapping_conditions(mapping, slot_name)
|
|
307
384
|
|
|
308
385
|
return True
|
|
309
386
|
|
|
310
387
|
def _matches_mapping_conditions(
|
|
311
|
-
self, mapping:
|
|
388
|
+
self, mapping: SlotMapping, slot_name: Text
|
|
312
389
|
) -> bool:
|
|
313
|
-
slot_mapping_conditions = mapping.
|
|
390
|
+
slot_mapping_conditions = mapping.conditions
|
|
314
391
|
|
|
315
392
|
if not slot_mapping_conditions:
|
|
316
393
|
return True
|
|
@@ -328,20 +405,20 @@ class SlotFillingManager:
|
|
|
328
405
|
@staticmethod
|
|
329
406
|
def _mapping_conditions_match_flow(
|
|
330
407
|
active_flow: str,
|
|
331
|
-
slot_mapping_conditions: List[
|
|
408
|
+
slot_mapping_conditions: List[SlotMappingCondition],
|
|
332
409
|
) -> bool:
|
|
333
410
|
active_flow_conditions = list(
|
|
334
|
-
filter(lambda x: x.
|
|
411
|
+
filter(lambda x: x.active_flow is not None, slot_mapping_conditions)
|
|
335
412
|
)
|
|
336
413
|
return any(
|
|
337
414
|
[
|
|
338
|
-
condition.
|
|
415
|
+
condition.active_flow == active_flow
|
|
339
416
|
for condition in active_flow_conditions
|
|
340
417
|
]
|
|
341
418
|
)
|
|
342
419
|
|
|
343
420
|
def _mapping_conditions_match_form(
|
|
344
|
-
self, slot_name: str, slot_mapping_conditions: List[
|
|
421
|
+
self, slot_name: str, slot_mapping_conditions: List[SlotMappingCondition]
|
|
345
422
|
) -> bool:
|
|
346
423
|
if (
|
|
347
424
|
self.tracker.is_active_loop_rejected
|
|
@@ -351,12 +428,10 @@ class SlotFillingManager:
|
|
|
351
428
|
|
|
352
429
|
# check if found mapping conditions matches form
|
|
353
430
|
for condition in slot_mapping_conditions:
|
|
354
|
-
|
|
355
|
-
# therefore we need to set a different default value
|
|
356
|
-
active_loop = condition.get(ACTIVE_LOOP, "")
|
|
431
|
+
active_loop = condition.active_loop
|
|
357
432
|
|
|
358
433
|
if active_loop and active_loop == self.tracker.active_loop_name:
|
|
359
|
-
condition_requested_slot = condition.
|
|
434
|
+
condition_requested_slot = condition.requested_slot
|
|
360
435
|
if not condition_requested_slot:
|
|
361
436
|
return True
|
|
362
437
|
if condition_requested_slot == self.tracker.get_slot(REQUESTED_SLOT):
|
|
@@ -370,11 +445,11 @@ class SlotFillingManager:
|
|
|
370
445
|
def _fails_unique_entity_mapping_check(
|
|
371
446
|
self,
|
|
372
447
|
slot_name: Text,
|
|
373
|
-
mapping:
|
|
448
|
+
mapping: SlotMapping,
|
|
374
449
|
) -> bool:
|
|
375
450
|
from rasa.core.actions.forms import FormAction
|
|
376
451
|
|
|
377
|
-
if mapping
|
|
452
|
+
if mapping.type != SlotMappingType.FROM_ENTITY:
|
|
378
453
|
return False
|
|
379
454
|
|
|
380
455
|
form_name = self.tracker.active_loop_name
|
|
@@ -395,12 +470,9 @@ class SlotFillingManager:
|
|
|
395
470
|
|
|
396
471
|
return True
|
|
397
472
|
|
|
398
|
-
def _is_trigger_intent_mapping_condition_met(
|
|
399
|
-
self, mapping: Dict[Text, Any]
|
|
400
|
-
) -> bool:
|
|
473
|
+
def _is_trigger_intent_mapping_condition_met(self, mapping: SlotMapping) -> bool:
|
|
401
474
|
active_loops_in_mapping_conditions = [
|
|
402
|
-
condition.
|
|
403
|
-
for condition in mapping.get(MAPPING_CONDITIONS, [])
|
|
475
|
+
condition.active_loop for condition in mapping.conditions
|
|
404
476
|
]
|
|
405
477
|
|
|
406
478
|
trigger_mapping_condition_met = True
|
|
@@ -421,7 +493,7 @@ class SlotFillingManager:
|
|
|
421
493
|
def extract_slot_value_from_predefined_mapping(
|
|
422
494
|
self,
|
|
423
495
|
mapping_type: SlotMappingType,
|
|
424
|
-
mapping:
|
|
496
|
+
mapping: SlotMapping,
|
|
425
497
|
) -> List[Any]:
|
|
426
498
|
"""Extracts slot value if slot has an applicable predefined mapping."""
|
|
427
499
|
if (
|
|
@@ -454,9 +526,9 @@ class SlotFillingManager:
|
|
|
454
526
|
value: List[Any] = []
|
|
455
527
|
|
|
456
528
|
if should_fill_entity_slot:
|
|
457
|
-
value =
|
|
529
|
+
value = mapping.entity_is_desired(self.tracker, self.message)
|
|
458
530
|
elif should_fill_intent_slot or should_fill_trigger_slot:
|
|
459
|
-
value = [mapping.
|
|
531
|
+
value = [mapping.value]
|
|
460
532
|
elif should_fill_text_slot:
|
|
461
533
|
value = [self.message.get(TEXT)] if self.message is not None else []
|
|
462
534
|
if not value:
|
|
@@ -468,11 +540,9 @@ class SlotFillingManager:
|
|
|
468
540
|
|
|
469
541
|
return value
|
|
470
542
|
|
|
471
|
-
def should_fill_slot(
|
|
472
|
-
self, slot_name: str, mapping_type: SlotMappingType, mapping: Dict[Text, Any]
|
|
473
|
-
) -> bool:
|
|
543
|
+
def should_fill_slot(self, slot_name: str, mapping: SlotMapping) -> bool:
|
|
474
544
|
"""Checks if a slot should be filled based on the conversation context."""
|
|
475
|
-
if not self.is_slot_mapping_valid(slot_name,
|
|
545
|
+
if not self.is_slot_mapping_valid(slot_name, mapping):
|
|
476
546
|
return False
|
|
477
547
|
|
|
478
548
|
if not self.is_intent_desired(mapping):
|
|
@@ -486,6 +556,173 @@ class SlotFillingManager:
|
|
|
486
556
|
|
|
487
557
|
return True
|
|
488
558
|
|
|
559
|
+
@staticmethod
|
|
560
|
+
def should_fill_slot_in_coexistence(
|
|
561
|
+
is_calm_system: bool,
|
|
562
|
+
slot: Slot,
|
|
563
|
+
calm_slot_names: Set[str],
|
|
564
|
+
) -> bool:
|
|
565
|
+
"""Check if a slot should be filled in a coexistence assistant."""
|
|
566
|
+
if slot.shared_for_coexistence:
|
|
567
|
+
return True
|
|
568
|
+
|
|
569
|
+
coexistence_systems = [
|
|
570
|
+
mapping.coexistence_system
|
|
571
|
+
for mapping in slot.mappings
|
|
572
|
+
if mapping.type == SlotMappingType.CONTROLLED
|
|
573
|
+
]
|
|
574
|
+
|
|
575
|
+
if not is_calm_system and (
|
|
576
|
+
slot.name in calm_slot_names
|
|
577
|
+
or CoexistenceSystemType.CALM in coexistence_systems
|
|
578
|
+
):
|
|
579
|
+
return False
|
|
580
|
+
|
|
581
|
+
if is_calm_system and (
|
|
582
|
+
slot.name not in calm_slot_names
|
|
583
|
+
or CoexistenceSystemType.NLU in coexistence_systems
|
|
584
|
+
):
|
|
585
|
+
return False
|
|
586
|
+
|
|
587
|
+
return True
|
|
588
|
+
|
|
589
|
+
async def run_action_at_every_turn(
|
|
590
|
+
self,
|
|
591
|
+
slot: Slot,
|
|
592
|
+
output_channel: "OutputChannel",
|
|
593
|
+
nlg: "NaturalLanguageGenerator",
|
|
594
|
+
) -> List[Event]:
|
|
595
|
+
"""Runs a custom action at every turn to fill a slot.
|
|
596
|
+
|
|
597
|
+
This executes only if the slot has a controlled mapping type
|
|
598
|
+
with the `run_action_every_turn` key set.
|
|
599
|
+
"""
|
|
600
|
+
slot_events: List[Event] = []
|
|
601
|
+
for mapping in slot.mappings:
|
|
602
|
+
should_fill_controlled_slot = mapping.type == SlotMappingType.CONTROLLED
|
|
603
|
+
|
|
604
|
+
if not should_fill_controlled_slot:
|
|
605
|
+
continue
|
|
606
|
+
|
|
607
|
+
custom_events = await self._execute_custom_action(
|
|
608
|
+
mapping,
|
|
609
|
+
output_channel,
|
|
610
|
+
nlg,
|
|
611
|
+
)
|
|
612
|
+
slot_events.extend(custom_events)
|
|
613
|
+
|
|
614
|
+
return slot_events
|
|
615
|
+
|
|
616
|
+
async def _execute_custom_action(
|
|
617
|
+
self,
|
|
618
|
+
mapping: "SlotMapping",
|
|
619
|
+
output_channel: "OutputChannel",
|
|
620
|
+
nlg: "NaturalLanguageGenerator",
|
|
621
|
+
) -> List[Event]:
|
|
622
|
+
custom_action = mapping.run_action_every_turn
|
|
623
|
+
|
|
624
|
+
if not custom_action or custom_action in self.executed_custom_actions:
|
|
625
|
+
return []
|
|
626
|
+
|
|
627
|
+
slot_events = await self._run_custom_action(custom_action, output_channel, nlg)
|
|
628
|
+
|
|
629
|
+
self.executed_custom_actions.add(custom_action)
|
|
630
|
+
|
|
631
|
+
return slot_events
|
|
632
|
+
|
|
633
|
+
async def _run_custom_action(
|
|
634
|
+
self,
|
|
635
|
+
custom_action: str,
|
|
636
|
+
output_channel: "OutputChannel",
|
|
637
|
+
nlg: "NaturalLanguageGenerator",
|
|
638
|
+
recreate_tracker: bool = False,
|
|
639
|
+
) -> List[Event]:
|
|
640
|
+
from rasa.core.actions.action import RemoteAction
|
|
641
|
+
from rasa.shared.core.trackers import DialogueStateTracker
|
|
642
|
+
from rasa.utils.endpoints import ClientResponseError
|
|
643
|
+
|
|
644
|
+
slot_events: List[Event] = []
|
|
645
|
+
remote_action = RemoteAction(custom_action, self._action_endpoint)
|
|
646
|
+
disallowed_types = set()
|
|
647
|
+
|
|
648
|
+
tracker = (
|
|
649
|
+
DialogueStateTracker.from_events(
|
|
650
|
+
self.tracker.sender_id,
|
|
651
|
+
self.tracker.events_after_latest_restart() + slot_events,
|
|
652
|
+
slots=self.domain.slots,
|
|
653
|
+
)
|
|
654
|
+
if recreate_tracker
|
|
655
|
+
else self.tracker
|
|
656
|
+
)
|
|
657
|
+
|
|
658
|
+
try:
|
|
659
|
+
custom_events = await remote_action.run(
|
|
660
|
+
output_channel, nlg, tracker, self.domain
|
|
661
|
+
)
|
|
662
|
+
for event in custom_events:
|
|
663
|
+
if isinstance(event, SlotSet):
|
|
664
|
+
slot_events.append(event)
|
|
665
|
+
elif isinstance(event, BotUttered):
|
|
666
|
+
slot_events.append(event)
|
|
667
|
+
else:
|
|
668
|
+
disallowed_types.add(event.type_name)
|
|
669
|
+
except (RasaException, ClientResponseError) as e:
|
|
670
|
+
structlogger.warning(
|
|
671
|
+
"slot_filling_manager.run_custom_action_failed",
|
|
672
|
+
failed_custom_action=custom_action,
|
|
673
|
+
event_info=f"Failed to execute custom action '{custom_action}' "
|
|
674
|
+
f"as a result of error '{e!s}'. The default action "
|
|
675
|
+
f"'{ACTION_EXTRACT_SLOTS}' failed to fill slots with custom "
|
|
676
|
+
f"mappings.",
|
|
677
|
+
)
|
|
678
|
+
|
|
679
|
+
for type_name in disallowed_types:
|
|
680
|
+
structlogger.info(
|
|
681
|
+
"slot_filling_manager.run_custom_action_disallowed_event",
|
|
682
|
+
custom_action_name=custom_action,
|
|
683
|
+
disallowed_evet_type=type_name,
|
|
684
|
+
event_info=f"Running custom action '{custom_action}' has resulted "
|
|
685
|
+
f"in an event of type '{type_name}'. This is "
|
|
686
|
+
f"disallowed and the tracker will not be "
|
|
687
|
+
f"updated with this event.",
|
|
688
|
+
)
|
|
689
|
+
|
|
690
|
+
return slot_events
|
|
691
|
+
|
|
692
|
+
async def execute_validation_action(
|
|
693
|
+
self,
|
|
694
|
+
extraction_events: List[Event],
|
|
695
|
+
output_channel: "OutputChannel",
|
|
696
|
+
nlg: "NaturalLanguageGenerator",
|
|
697
|
+
) -> List[Event]:
|
|
698
|
+
slot_events: List[SlotSet] = [
|
|
699
|
+
event for event in extraction_events if isinstance(event, SlotSet)
|
|
700
|
+
]
|
|
701
|
+
|
|
702
|
+
slot_candidates = "\n".join([e.key for e in slot_events])
|
|
703
|
+
structlogger.debug(
|
|
704
|
+
"slot_filling_manager.execute_validation_action",
|
|
705
|
+
slot_candidates=slot_candidates,
|
|
706
|
+
event_info=f"Validating extracted slots: {slot_candidates}",
|
|
707
|
+
)
|
|
708
|
+
|
|
709
|
+
if ACTION_VALIDATE_SLOT_MAPPINGS not in self.domain.user_actions:
|
|
710
|
+
return cast(List[Event], slot_events)
|
|
711
|
+
|
|
712
|
+
validate_events = await self._run_custom_action(
|
|
713
|
+
ACTION_VALIDATE_SLOT_MAPPINGS, output_channel, nlg, recreate_tracker=True
|
|
714
|
+
)
|
|
715
|
+
validated_slot_names = [
|
|
716
|
+
event.key for event in validate_events if isinstance(event, SlotSet)
|
|
717
|
+
]
|
|
718
|
+
|
|
719
|
+
# If the custom action doesn't return a SlotSet event for an extracted slot
|
|
720
|
+
# candidate we assume that it was valid. The custom action has to return a
|
|
721
|
+
# SlotSet(slot_name, None) event to mark a Slot as invalid.
|
|
722
|
+
return validate_events + [
|
|
723
|
+
event for event in slot_events if event.key not in validated_slot_names
|
|
724
|
+
]
|
|
725
|
+
|
|
489
726
|
|
|
490
727
|
def extract_slot_value(
|
|
491
728
|
slot: Slot, slot_filling_manager: SlotFillingManager
|
|
@@ -494,14 +731,12 @@ def extract_slot_value(
|
|
|
494
731
|
is_extracted = False
|
|
495
732
|
|
|
496
733
|
for mapping in slot.mappings:
|
|
497
|
-
mapping_type =
|
|
498
|
-
mapping.get(MAPPING_TYPE, SlotMappingType.FROM_LLM.value)
|
|
499
|
-
)
|
|
734
|
+
mapping_type = mapping.type
|
|
500
735
|
|
|
501
|
-
if mapping_type in [SlotMappingType.FROM_LLM, SlotMappingType.
|
|
736
|
+
if mapping_type in [SlotMappingType.FROM_LLM, SlotMappingType.CONTROLLED]:
|
|
502
737
|
continue
|
|
503
738
|
|
|
504
|
-
if not slot_filling_manager.should_fill_slot(slot.name,
|
|
739
|
+
if not slot_filling_manager.should_fill_slot(slot.name, mapping):
|
|
505
740
|
continue
|
|
506
741
|
|
|
507
742
|
value: List[Any] = (
|
|
@@ -518,7 +753,11 @@ def extract_slot_value(
|
|
|
518
753
|
value is not None
|
|
519
754
|
or slot_filling_manager.tracker.get_slot(slot.name) is not None
|
|
520
755
|
):
|
|
521
|
-
|
|
756
|
+
structlogger.debug(
|
|
757
|
+
"slot_filling_manager.extract_slot_value",
|
|
758
|
+
slot_name=slot.name,
|
|
759
|
+
event_info=f"Extracted value '{value}' for slot '{slot.name}'.",
|
|
760
|
+
)
|
|
522
761
|
|
|
523
762
|
is_extracted = True
|
|
524
763
|
return value, is_extracted
|