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
rasa/e2e_test/utils/io.py
CHANGED
|
@@ -6,7 +6,7 @@ import sys
|
|
|
6
6
|
from functools import lru_cache
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from textwrap import dedent
|
|
9
|
-
from typing import Any, Dict, Generator, List, Optional,
|
|
9
|
+
from typing import TYPE_CHECKING, Any, Dict, Generator, List, Optional, Tuple, Union
|
|
10
10
|
|
|
11
11
|
import matplotlib.pyplot as plt
|
|
12
12
|
import pandas as pd
|
|
@@ -27,7 +27,11 @@ from rasa.e2e_test.constants import (
|
|
|
27
27
|
STATUS_PASSED,
|
|
28
28
|
STUB_CUSTOM_ACTION_NAME_SEPARATOR,
|
|
29
29
|
)
|
|
30
|
-
from rasa.e2e_test.e2e_test_case import Fixture, Metadata,
|
|
30
|
+
from rasa.e2e_test.e2e_test_case import Fixture, Metadata, TestCase, TestSuite
|
|
31
|
+
from rasa.e2e_test.stub_custom_action import (
|
|
32
|
+
StubCustomAction,
|
|
33
|
+
get_stub_custom_action_key,
|
|
34
|
+
)
|
|
31
35
|
from rasa.e2e_test.utils.validation import (
|
|
32
36
|
read_e2e_test_schema,
|
|
33
37
|
validate_path_to_test_cases,
|
|
@@ -41,11 +45,10 @@ from rasa.shared.utils.yaml import (
|
|
|
41
45
|
from rasa.utils.beta import BetaNotEnabledException, ensure_beta_feature_is_enabled
|
|
42
46
|
|
|
43
47
|
if TYPE_CHECKING:
|
|
44
|
-
from rasa.e2e_test.e2e_test_result import TestResult
|
|
45
48
|
from rasa.e2e_test.aggregate_test_stats_calculator import AccuracyCalculation
|
|
49
|
+
from rasa.e2e_test.e2e_test_result import TestResult
|
|
46
50
|
|
|
47
51
|
|
|
48
|
-
RASA_PRO_BETA_E2E_ASSERTIONS_ENV_VAR_NAME = "RASA_PRO_BETA_E2E_ASSERTIONS"
|
|
49
52
|
RASA_PRO_BETA_STUB_CUSTOM_ACTION_ENV_VAR_NAME = "RASA_PRO_BETA_STUB_CUSTOM_ACTION"
|
|
50
53
|
|
|
51
54
|
structlogger = structlog.get_logger()
|
|
@@ -274,16 +277,6 @@ def split_into_passed_failed(
|
|
|
274
277
|
return passed_cases, failed_cases
|
|
275
278
|
|
|
276
279
|
|
|
277
|
-
def has_test_case_with_assertions(test_cases: List["TestCase"]) -> bool:
|
|
278
|
-
"""Check if the test cases contain assertions."""
|
|
279
|
-
try:
|
|
280
|
-
next(test_case for test_case in test_cases if test_case.uses_assertions())
|
|
281
|
-
except StopIteration:
|
|
282
|
-
return False
|
|
283
|
-
|
|
284
|
-
return True
|
|
285
|
-
|
|
286
|
-
|
|
287
280
|
@lru_cache(maxsize=1)
|
|
288
281
|
def extract_test_case_from_path(path: str) -> Tuple[str, str]:
|
|
289
282
|
"""Extract test case from path if specified.
|
|
@@ -318,6 +311,104 @@ def is_test_case_file(file_path: Union[str, Path]) -> bool:
|
|
|
318
311
|
)
|
|
319
312
|
|
|
320
313
|
|
|
314
|
+
def extract_test_cases(
|
|
315
|
+
test_file_content: dict,
|
|
316
|
+
test_case_name: str,
|
|
317
|
+
test_file: str,
|
|
318
|
+
) -> List[TestCase]:
|
|
319
|
+
"""Extract test cases from the test file content.
|
|
320
|
+
|
|
321
|
+
Args:
|
|
322
|
+
test_file_content: Content of the test file.
|
|
323
|
+
test_case_name: Name of the test case to extract.
|
|
324
|
+
test_file: Path to the test file.
|
|
325
|
+
|
|
326
|
+
Returns:
|
|
327
|
+
List of test cases.
|
|
328
|
+
"""
|
|
329
|
+
test_cases_content = test_file_content.get(KEY_TEST_CASES) or []
|
|
330
|
+
if test_case_name:
|
|
331
|
+
return [
|
|
332
|
+
TestCase.from_dict(test_case_dict, file=test_file)
|
|
333
|
+
for test_case_dict in test_cases_content
|
|
334
|
+
if test_case_name == test_case_dict.get(KEY_TEST_CASE)
|
|
335
|
+
]
|
|
336
|
+
return [
|
|
337
|
+
TestCase.from_dict(test_case_dict, file=test_file)
|
|
338
|
+
for test_case_dict in test_cases_content
|
|
339
|
+
]
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
def extract_fixtures(
|
|
343
|
+
test_file_content: dict, existing_fixtures: Dict[str, Fixture]
|
|
344
|
+
) -> Dict[str, Fixture]:
|
|
345
|
+
"""Extract fixtures from the test file content.
|
|
346
|
+
|
|
347
|
+
Args:
|
|
348
|
+
test_file_content: Content of the test file.
|
|
349
|
+
existing_fixtures: Existing fixtures.
|
|
350
|
+
|
|
351
|
+
Returns:
|
|
352
|
+
Dict of fixtures.
|
|
353
|
+
"""
|
|
354
|
+
fixtures_content = test_file_content.get(KEY_FIXTURES) or []
|
|
355
|
+
_fixtures = {}
|
|
356
|
+
for fixture in fixtures_content:
|
|
357
|
+
fixture_obj = Fixture.from_dict(fixture_dict=fixture)
|
|
358
|
+
if existing_fixtures.get(fixture_obj.name) is None:
|
|
359
|
+
_fixtures[fixture_obj.name] = fixture_obj
|
|
360
|
+
return _fixtures
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
def extract_metadata(
|
|
364
|
+
test_file_content: dict, existing_metadata: Dict[str, Metadata]
|
|
365
|
+
) -> Dict[str, Metadata]:
|
|
366
|
+
"""Extract metadata from the test file content.
|
|
367
|
+
|
|
368
|
+
Args:
|
|
369
|
+
test_file_content: Content of the test file.
|
|
370
|
+
existing_metadata: Existing metadata.
|
|
371
|
+
|
|
372
|
+
Returns:
|
|
373
|
+
Dict of metadata.
|
|
374
|
+
"""
|
|
375
|
+
metadata_contents = test_file_content.get(KEY_METADATA) or []
|
|
376
|
+
_metadata = {}
|
|
377
|
+
for metadata_content in metadata_contents:
|
|
378
|
+
metadata_obj = Metadata.from_dict(metadata_dict=metadata_content)
|
|
379
|
+
if existing_metadata.get(metadata_obj.name) is None:
|
|
380
|
+
_metadata[metadata_obj.name] = metadata_obj
|
|
381
|
+
return _metadata
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
def extract_stub_custom_actions(
|
|
385
|
+
test_file_content: dict, test_file: str
|
|
386
|
+
) -> Dict[str, StubCustomAction]:
|
|
387
|
+
"""Extract stub custom actions from the test file content.
|
|
388
|
+
|
|
389
|
+
Args:
|
|
390
|
+
test_file_content: Content of the test file.
|
|
391
|
+
test_file: Path to the test file.
|
|
392
|
+
|
|
393
|
+
Returns:
|
|
394
|
+
Dict of stub custom actions.
|
|
395
|
+
"""
|
|
396
|
+
stub_custom_actions_contents = test_file_content.get(KEY_STUB_CUSTOM_ACTIONS) or {}
|
|
397
|
+
_stub_custom_actions = {}
|
|
398
|
+
for action_name, stub_data in stub_custom_actions_contents.items():
|
|
399
|
+
if STUB_CUSTOM_ACTION_NAME_SEPARATOR in action_name:
|
|
400
|
+
stub_custom_action_key = action_name
|
|
401
|
+
else:
|
|
402
|
+
test_file_name = Path(test_file).name
|
|
403
|
+
stub_custom_action_key = get_stub_custom_action_key(
|
|
404
|
+
test_file_name, action_name
|
|
405
|
+
)
|
|
406
|
+
_stub_custom_actions[stub_custom_action_key] = StubCustomAction.from_dict(
|
|
407
|
+
action_name=action_name, stub_data=stub_data
|
|
408
|
+
)
|
|
409
|
+
return _stub_custom_actions
|
|
410
|
+
|
|
411
|
+
|
|
321
412
|
def read_test_cases(path: str) -> TestSuite:
|
|
322
413
|
"""Read test cases from the given path.
|
|
323
414
|
|
|
@@ -327,92 +418,41 @@ def read_test_cases(path: str) -> TestSuite:
|
|
|
327
418
|
Returns:
|
|
328
419
|
TestSuite.
|
|
329
420
|
"""
|
|
330
|
-
|
|
331
|
-
StubCustomAction,
|
|
332
|
-
get_stub_custom_action_key,
|
|
333
|
-
)
|
|
334
|
-
|
|
421
|
+
# Extract test case path and name
|
|
335
422
|
path, test_case_name = extract_test_case_from_path(path)
|
|
336
423
|
validate_path_to_test_cases(path)
|
|
337
424
|
|
|
425
|
+
# Load test files and schema
|
|
338
426
|
test_files = rasa.shared.data.get_data_files([path], is_test_case_file)
|
|
339
427
|
e2e_test_schema = read_e2e_test_schema()
|
|
340
428
|
|
|
429
|
+
# Initialize containers
|
|
341
430
|
input_test_cases = []
|
|
342
431
|
fixtures: Dict[str, Fixture] = {}
|
|
343
432
|
metadata: Dict[str, Metadata] = {}
|
|
344
433
|
stub_custom_actions: Dict[str, StubCustomAction] = {}
|
|
345
434
|
|
|
346
|
-
|
|
347
|
-
|
|
435
|
+
# Process each test file
|
|
348
436
|
for test_file in test_files:
|
|
349
437
|
test_file_content = parse_raw_yaml(Path(test_file).read_text(encoding="utf-8"))
|
|
350
438
|
|
|
439
|
+
# Validate YAML content using the provided function
|
|
351
440
|
validate_yaml_data_using_schema_with_assertions(
|
|
352
441
|
yaml_data=test_file_content, schema_content=e2e_test_schema
|
|
353
442
|
)
|
|
354
443
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
if test_case_name == test_case_dict.get(KEY_TEST_CASE)
|
|
362
|
-
]
|
|
363
|
-
else:
|
|
364
|
-
test_cases = [
|
|
365
|
-
TestCase.from_dict(test_case_dict, file=test_file)
|
|
366
|
-
for test_case_dict in test_cases_content
|
|
367
|
-
]
|
|
368
|
-
|
|
369
|
-
beta_flag_verified = verify_beta_feature_flag_for_assertions(
|
|
370
|
-
test_cases, beta_flag_verified
|
|
444
|
+
# Parse test cases, fixtures, metadata, and stub custom actions
|
|
445
|
+
test_cases = extract_test_cases(test_file_content, test_case_name, test_file)
|
|
446
|
+
fixtures.update(extract_fixtures(test_file_content, fixtures))
|
|
447
|
+
metadata.update(extract_metadata(test_file_content, metadata))
|
|
448
|
+
stub_custom_actions.update(
|
|
449
|
+
extract_stub_custom_actions(test_file_content, test_file)
|
|
371
450
|
)
|
|
372
|
-
|
|
373
451
|
input_test_cases.extend(test_cases)
|
|
374
|
-
fixtures_content = test_file_content.get(KEY_FIXTURES) or []
|
|
375
|
-
for fixture in fixtures_content:
|
|
376
|
-
fixture_obj = Fixture.from_dict(fixture_dict=fixture)
|
|
377
452
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
metadata_contents = test_file_content.get(KEY_METADATA) or []
|
|
383
|
-
for metadata_content in metadata_contents:
|
|
384
|
-
metadata_obj = Metadata.from_dict(metadata_dict=metadata_content)
|
|
385
|
-
|
|
386
|
-
# avoid adding duplicates from across multiple files
|
|
387
|
-
if metadata.get(metadata_obj.name) is None:
|
|
388
|
-
metadata[metadata_obj.name] = metadata_obj
|
|
389
|
-
|
|
390
|
-
stub_custom_actions_contents = (
|
|
391
|
-
test_file_content.get(KEY_STUB_CUSTOM_ACTIONS) or {}
|
|
392
|
-
)
|
|
393
|
-
|
|
394
|
-
for action_name, stub_data in stub_custom_actions_contents.items():
|
|
395
|
-
if STUB_CUSTOM_ACTION_NAME_SEPARATOR in action_name:
|
|
396
|
-
stub_custom_action_key = action_name
|
|
397
|
-
else:
|
|
398
|
-
test_file_name = Path(test_file).name
|
|
399
|
-
stub_custom_action_key = get_stub_custom_action_key(
|
|
400
|
-
test_file_name, action_name
|
|
401
|
-
)
|
|
402
|
-
stub_custom_actions[stub_custom_action_key] = StubCustomAction.from_dict(
|
|
403
|
-
action_name=action_name,
|
|
404
|
-
stub_data=stub_data,
|
|
405
|
-
)
|
|
406
|
-
|
|
407
|
-
validate_test_case(test_case_name, input_test_cases)
|
|
408
|
-
try:
|
|
409
|
-
if stub_custom_actions:
|
|
410
|
-
ensure_beta_feature_is_enabled(
|
|
411
|
-
"enabling stubs for custom actions",
|
|
412
|
-
RASA_PRO_BETA_STUB_CUSTOM_ACTION_ENV_VAR_NAME,
|
|
413
|
-
)
|
|
414
|
-
except BetaNotEnabledException as exc:
|
|
415
|
-
rasa.shared.utils.cli.print_error_and_exit(str(exc))
|
|
453
|
+
validate_test_case(test_case_name, input_test_cases, fixtures, metadata)
|
|
454
|
+
if stub_custom_actions:
|
|
455
|
+
check_beta_feature_flag_for_custom_actions_stubs()
|
|
416
456
|
|
|
417
457
|
return TestSuite(
|
|
418
458
|
input_test_cases,
|
|
@@ -422,26 +462,16 @@ def read_test_cases(path: str) -> TestSuite:
|
|
|
422
462
|
)
|
|
423
463
|
|
|
424
464
|
|
|
425
|
-
def
|
|
426
|
-
|
|
427
|
-
) -> bool:
|
|
428
|
-
"""Verify the beta feature flag for assertions."""
|
|
429
|
-
if beta_flag_verified:
|
|
430
|
-
return True
|
|
431
|
-
|
|
432
|
-
if not has_test_case_with_assertions(test_cases):
|
|
433
|
-
return beta_flag_verified
|
|
434
|
-
|
|
465
|
+
def check_beta_feature_flag_for_custom_actions_stubs() -> None:
|
|
466
|
+
"""Check the beta feature flag for custom actions stub and exit if not enabled."""
|
|
435
467
|
try:
|
|
436
468
|
ensure_beta_feature_is_enabled(
|
|
437
|
-
"
|
|
438
|
-
|
|
469
|
+
"enabling stubs for custom actions",
|
|
470
|
+
RASA_PRO_BETA_STUB_CUSTOM_ACTION_ENV_VAR_NAME,
|
|
439
471
|
)
|
|
440
472
|
except BetaNotEnabledException as exc:
|
|
441
473
|
rasa.shared.utils.cli.print_error_and_exit(str(exc))
|
|
442
474
|
|
|
443
|
-
return True
|
|
444
|
-
|
|
445
475
|
|
|
446
476
|
def _save_coverage_report(
|
|
447
477
|
report: Optional[pd.DataFrame], test_status: str, output_dir: str
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import sys
|
|
2
2
|
from pathlib import Path
|
|
3
|
-
from typing import Any, Dict, List, Optional,
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
|
|
4
4
|
|
|
5
5
|
import structlog
|
|
6
6
|
|
|
7
7
|
import rasa.shared.utils.io
|
|
8
8
|
from rasa.e2e_test.constants import SCHEMA_FILE_PATH
|
|
9
|
+
from rasa.e2e_test.e2e_test_case import Fixture, Metadata
|
|
9
10
|
from rasa.shared.utils.yaml import read_schema_file
|
|
10
11
|
|
|
11
12
|
if TYPE_CHECKING:
|
|
@@ -27,8 +28,24 @@ def validate_path_to_test_cases(path: str) -> None:
|
|
|
27
28
|
sys.exit(1)
|
|
28
29
|
|
|
29
30
|
|
|
30
|
-
def validate_test_case(
|
|
31
|
-
|
|
31
|
+
def validate_test_case(
|
|
32
|
+
test_case_name: str,
|
|
33
|
+
input_test_cases: List["TestCase"],
|
|
34
|
+
fixtures: Dict[str, Fixture],
|
|
35
|
+
metadata: Dict[str, Metadata],
|
|
36
|
+
) -> None:
|
|
37
|
+
"""
|
|
38
|
+
Validate the test case, its fixtures, and metadata.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
test_case_name (str): The name of the test case to validate.
|
|
42
|
+
input_test_cases (List["TestCase"]): A list of test cases to validate.
|
|
43
|
+
fixtures (Dict[str, Fixture]): A dictionary of defined fixtures.
|
|
44
|
+
metadata (Dict[str, Metadata]): A dictionary of defined metadata.
|
|
45
|
+
|
|
46
|
+
Raises:
|
|
47
|
+
SystemExit: If the test case, fixtures, or metadata are not defined.
|
|
48
|
+
"""
|
|
32
49
|
if test_case_name and not input_test_cases:
|
|
33
50
|
rasa.shared.utils.io.raise_warning(
|
|
34
51
|
f"Test case does not exist: {test_case_name}. "
|
|
@@ -38,6 +55,87 @@ def validate_test_case(test_case_name: str, input_test_cases: List["TestCase"])
|
|
|
38
55
|
)
|
|
39
56
|
sys.exit(1)
|
|
40
57
|
|
|
58
|
+
all_good = True
|
|
59
|
+
for test_case in input_test_cases:
|
|
60
|
+
all_good_fixtures = validate_test_case_fixtures(test_case, fixtures)
|
|
61
|
+
all_good_metadata = validate_test_case_metadata(test_case, metadata)
|
|
62
|
+
all_good = all_good and all_good_fixtures and all_good_metadata
|
|
63
|
+
|
|
64
|
+
if not all_good:
|
|
65
|
+
sys.exit(1)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def validate_test_case_fixtures(
|
|
69
|
+
test_case: "TestCase", fixtures: Dict[str, Fixture]
|
|
70
|
+
) -> bool:
|
|
71
|
+
"""Validates that the fixtures used in the test case are defined.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
test_case (TestCase): The test case to validate.
|
|
75
|
+
fixtures (Dict[str, Fixture]): A dictionary of defined fixtures.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
True if all fixtures used in the test case are defined, False otherwise.
|
|
79
|
+
|
|
80
|
+
Raises:
|
|
81
|
+
Logs an error if a fixture used in the test case is not defined.
|
|
82
|
+
"""
|
|
83
|
+
all_good = True
|
|
84
|
+
if not test_case.fixture_names:
|
|
85
|
+
return all_good
|
|
86
|
+
|
|
87
|
+
for fixture_name in test_case.fixture_names:
|
|
88
|
+
if fixture_name not in fixtures:
|
|
89
|
+
structlogger.error(
|
|
90
|
+
"validation.validate_test_case_fixtures",
|
|
91
|
+
event_info=(
|
|
92
|
+
f"Fixture '{fixture_name}' referenced in the "
|
|
93
|
+
f"test case '{test_case.name}' is not defined."
|
|
94
|
+
),
|
|
95
|
+
)
|
|
96
|
+
all_good = False
|
|
97
|
+
return all_good
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def validate_test_case_metadata(
|
|
101
|
+
test_case: "TestCase", metadata: Dict[str, Metadata]
|
|
102
|
+
) -> bool:
|
|
103
|
+
"""
|
|
104
|
+
Validates that the metadata used in the test case and its steps are defined.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
test_case (TestCase): The test case to validate.
|
|
108
|
+
metadata (Dict[str, Metadata]): A dictionary of defined metadata.
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
True if all fixtures used in the test case are defined, False otherwise.
|
|
112
|
+
|
|
113
|
+
Raises:
|
|
114
|
+
Logs an error if metadata used in the test case or its steps is not defined.
|
|
115
|
+
"""
|
|
116
|
+
all_good = True
|
|
117
|
+
if test_case.metadata_name and test_case.metadata_name not in metadata:
|
|
118
|
+
structlogger.error(
|
|
119
|
+
"validation.validate_test_case_metadata.test_case_metadata",
|
|
120
|
+
event_info=(
|
|
121
|
+
f"Metadata '{test_case.metadata_name}' referenced in "
|
|
122
|
+
f"the test case '{test_case.name}' is not defined."
|
|
123
|
+
),
|
|
124
|
+
)
|
|
125
|
+
all_good = False
|
|
126
|
+
|
|
127
|
+
for step in test_case.steps:
|
|
128
|
+
if step.metadata_name and step.metadata_name not in metadata:
|
|
129
|
+
structlogger.error(
|
|
130
|
+
"validation.validate_test_case_metadata.step_metadata",
|
|
131
|
+
event_info=(
|
|
132
|
+
f"Metadata '{step.metadata_name}' referenced in the "
|
|
133
|
+
f"step of the test case '{test_case.name}' is not defined."
|
|
134
|
+
),
|
|
135
|
+
)
|
|
136
|
+
all_good = False
|
|
137
|
+
return all_good
|
|
138
|
+
|
|
41
139
|
|
|
42
140
|
def validate_model_path(model_path: Optional[str], parameter: str, default: str) -> str:
|
|
43
141
|
"""Validate the model path.
|
rasa/engine/caching.py
CHANGED
|
@@ -5,27 +5,25 @@ import logging
|
|
|
5
5
|
import shutil
|
|
6
6
|
from datetime import datetime
|
|
7
7
|
from pathlib import Path
|
|
8
|
-
from typing import
|
|
8
|
+
from typing import Any, List, Optional, Text, Tuple
|
|
9
9
|
|
|
10
|
+
import sqlalchemy as sa
|
|
11
|
+
import sqlalchemy.orm
|
|
10
12
|
from packaging import version
|
|
11
13
|
from sqlalchemy.engine import URL
|
|
12
|
-
|
|
13
14
|
from sqlalchemy.exc import OperationalError
|
|
14
15
|
from typing_extensions import Protocol, runtime_checkable
|
|
15
16
|
|
|
16
17
|
import rasa
|
|
17
18
|
import rasa.model
|
|
18
|
-
import rasa.utils.common
|
|
19
19
|
import rasa.shared.utils.common
|
|
20
|
+
import rasa.utils.common
|
|
20
21
|
from rasa.constants import MINIMUM_COMPATIBLE_VERSION
|
|
21
|
-
import sqlalchemy as sa
|
|
22
|
-
import sqlalchemy.orm
|
|
23
|
-
|
|
24
22
|
from rasa.engine.storage.storage import ModelStorage
|
|
25
23
|
from rasa.shared.engine.caching import (
|
|
24
|
+
get_cache_database_name,
|
|
26
25
|
get_local_cache_location,
|
|
27
26
|
get_max_cache_size,
|
|
28
|
-
get_cache_database_name,
|
|
29
27
|
)
|
|
30
28
|
|
|
31
29
|
logger = logging.getLogger(__name__)
|
rasa/engine/constants.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from typing import List, Optional
|
|
2
2
|
|
|
3
3
|
from rasa.core.channels import UserMessage
|
|
4
|
+
from rasa.core.utils import AvailableEndpoints
|
|
4
5
|
from rasa.shared.core.trackers import DialogueStateTracker
|
|
5
6
|
from rasa.shared.importers.importer import TrainingDataImporter
|
|
6
|
-
from rasa.core.utils import AvailableEndpoints
|
|
7
7
|
|
|
8
8
|
PLACEHOLDER_IMPORTER = "__importer__"
|
|
9
9
|
PLACEHOLDER_MESSAGE = "__message__"
|
rasa/engine/graph.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import asyncio
|
|
3
4
|
import dataclasses
|
|
4
5
|
from abc import ABC, abstractmethod
|
|
5
6
|
from dataclasses import dataclass, field
|
|
6
|
-
from typing import Any, Callable, Dict, List, Optional, Text,
|
|
7
|
+
from typing import Any, Callable, Dict, List, Optional, Text, Tuple, Type, Union
|
|
7
8
|
|
|
8
9
|
import structlog
|
|
9
|
-
import asyncio
|
|
10
10
|
|
|
11
11
|
import rasa.shared.utils.common
|
|
12
12
|
import rasa.utils.common
|
|
@@ -640,3 +640,4 @@ class GraphModelConfiguration:
|
|
|
640
640
|
language: Optional[Text]
|
|
641
641
|
core_target: Optional[Text]
|
|
642
642
|
nlu_target: Optional[Text]
|
|
643
|
+
additional_languages: Optional[List[Text]]
|
rasa/engine/language.py
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Any, Dict, Text
|
|
3
|
+
|
|
4
|
+
from langcodes import Language as LangcodesLanguage
|
|
5
|
+
from langcodes import standardize_tag
|
|
6
|
+
from langcodes.tag_parser import LanguageTagError
|
|
7
|
+
|
|
8
|
+
from rasa.shared.exceptions import RasaException
|
|
9
|
+
|
|
10
|
+
CUSTOM_LANGUAGE_CODE_PREFIX = "x-"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class Language:
|
|
15
|
+
code: str
|
|
16
|
+
label: str
|
|
17
|
+
is_default: bool
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def from_language_code(
|
|
21
|
+
cls, language_code: str, is_default: bool = False
|
|
22
|
+
) -> "Language":
|
|
23
|
+
"""Creates a Language object from a language code.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
language_code: The language code.
|
|
27
|
+
is_default: Whether the language is the default language.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
A Language object.
|
|
31
|
+
|
|
32
|
+
Raises:
|
|
33
|
+
RasaException: If the language code or custom language code is invalid.
|
|
34
|
+
"""
|
|
35
|
+
if cls.is_custom_language_code(language_code):
|
|
36
|
+
cls.validate_custom_language_code(language_code)
|
|
37
|
+
elif not cls.is_language_code_bcp_47_standard(language_code):
|
|
38
|
+
raise RasaException(
|
|
39
|
+
f"Language '{language_code}' is not a BCP 47 standard language code."
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
language = LangcodesLanguage.get(language_code)
|
|
43
|
+
return cls(
|
|
44
|
+
code=language_code,
|
|
45
|
+
label=cls.get_language_label(language),
|
|
46
|
+
is_default=is_default,
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
@staticmethod
|
|
50
|
+
def is_language_code_bcp_47_standard(language_code: str) -> bool:
|
|
51
|
+
"""Checks if a language code is a BCP 47 standard language code.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
language_code: The language code to check.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
`True` if the language code is a BCP 47 standard, `False` otherwise.
|
|
58
|
+
"""
|
|
59
|
+
try:
|
|
60
|
+
standardized_language_code = standardize_tag(language_code)
|
|
61
|
+
return (
|
|
62
|
+
standardized_language_code == language_code
|
|
63
|
+
and LangcodesLanguage.get(language_code).is_valid()
|
|
64
|
+
)
|
|
65
|
+
except LanguageTagError:
|
|
66
|
+
return False
|
|
67
|
+
|
|
68
|
+
@staticmethod
|
|
69
|
+
def is_custom_language_code(language_code: str) -> bool:
|
|
70
|
+
"""Checks if a language code is a custom language code.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
language_code: The language code to check.
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
`True` if the language code is a custom language code, `False` otherwise.
|
|
77
|
+
"""
|
|
78
|
+
return language_code.startswith(CUSTOM_LANGUAGE_CODE_PREFIX)
|
|
79
|
+
|
|
80
|
+
@classmethod
|
|
81
|
+
def get_language_label(cls, language: LangcodesLanguage) -> str:
|
|
82
|
+
"""Gets the display name of a language.
|
|
83
|
+
|
|
84
|
+
For custom languages (in the format "x-<base_lang>-<custom_label>"),
|
|
85
|
+
the label is derived from the base language code.
|
|
86
|
+
This method considers that the language code has previously been validated.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
language: The language code.
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
The display name of the language.
|
|
93
|
+
"""
|
|
94
|
+
language_code = str(language)
|
|
95
|
+
|
|
96
|
+
if cls.is_custom_language_code(language_code):
|
|
97
|
+
# If it's a custom language, derive the label from the base language code.
|
|
98
|
+
without_prefix = language_code[len(CUSTOM_LANGUAGE_CODE_PREFIX) :]
|
|
99
|
+
base_language_code, _ = without_prefix.rsplit("-", 1)
|
|
100
|
+
base_language = LangcodesLanguage.get(base_language_code)
|
|
101
|
+
return base_language.display_name()
|
|
102
|
+
else:
|
|
103
|
+
return language.display_name()
|
|
104
|
+
|
|
105
|
+
@classmethod
|
|
106
|
+
def validate_language(cls, language: LangcodesLanguage) -> None:
|
|
107
|
+
"""Validates a language code.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
language: The language object to validate.
|
|
111
|
+
|
|
112
|
+
Raises:
|
|
113
|
+
RasaException: If the language validation fails.
|
|
114
|
+
"""
|
|
115
|
+
if not language.is_valid():
|
|
116
|
+
raise RasaException(f"Language '{language}' is not a valid language code.")
|
|
117
|
+
|
|
118
|
+
language_code = str(language)
|
|
119
|
+
if language_code.startswith(CUSTOM_LANGUAGE_CODE_PREFIX):
|
|
120
|
+
cls.validate_custom_language_code(language_code)
|
|
121
|
+
|
|
122
|
+
@classmethod
|
|
123
|
+
def validate_custom_language_code(cls, custom_language_code: str) -> None:
|
|
124
|
+
"""Validates a custom language code.
|
|
125
|
+
|
|
126
|
+
A valid custom language code should adhere to the format:
|
|
127
|
+
"x-<existing_language_code>-<custom_label>"
|
|
128
|
+
Example: x-en-formal or x-en-US-formal.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
custom_language_code: The custom language code to validate.
|
|
132
|
+
|
|
133
|
+
Raises:
|
|
134
|
+
RasaException: If the custom language code validation fails.
|
|
135
|
+
"""
|
|
136
|
+
# Ensure the custom language code starts with the custom prefix.
|
|
137
|
+
if not custom_language_code.startswith(CUSTOM_LANGUAGE_CODE_PREFIX):
|
|
138
|
+
raise RasaException(
|
|
139
|
+
f"Custom language '{custom_language_code}' must "
|
|
140
|
+
f"start with '{CUSTOM_LANGUAGE_CODE_PREFIX}'."
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
# Remove the custom prefix.
|
|
144
|
+
without_prefix = custom_language_code[len(CUSTOM_LANGUAGE_CODE_PREFIX) :]
|
|
145
|
+
if "-" not in without_prefix:
|
|
146
|
+
raise RasaException(
|
|
147
|
+
f"Custom language '{custom_language_code}' must be in the format "
|
|
148
|
+
f"'{CUSTOM_LANGUAGE_CODE_PREFIX}<language_code>-<custom_label>'."
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
base_language_code, custom_label = without_prefix.rsplit("-", 1)
|
|
152
|
+
if not base_language_code:
|
|
153
|
+
raise RasaException(
|
|
154
|
+
f"Base language in '{custom_language_code}' cannot be empty. "
|
|
155
|
+
f"Expected custom language code format is "
|
|
156
|
+
f"'{CUSTOM_LANGUAGE_CODE_PREFIX}<language_code>-<custom_label>'."
|
|
157
|
+
)
|
|
158
|
+
if not custom_label:
|
|
159
|
+
raise RasaException(
|
|
160
|
+
f"Custom label in '{custom_language_code}' cannot be empty."
|
|
161
|
+
f"Expected custom language code format is "
|
|
162
|
+
f"'{CUSTOM_LANGUAGE_CODE_PREFIX}<language_code>-<custom_label>'."
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
# Validate the base language code using langcodes.
|
|
166
|
+
if not cls.is_language_code_bcp_47_standard(base_language_code):
|
|
167
|
+
raise RasaException(
|
|
168
|
+
f"Base language '{base_language_code}' in custom language "
|
|
169
|
+
f"'{custom_language_code}' is not a valid language code."
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
def as_dict(self) -> Dict[Text, Any]:
|
|
173
|
+
"""Converts the Language dataclass instance into a dictionary.
|
|
174
|
+
|
|
175
|
+
Returns:
|
|
176
|
+
A dictionary representing the Language object.
|
|
177
|
+
"""
|
|
178
|
+
return {
|
|
179
|
+
"code": self.code,
|
|
180
|
+
"label": self.label,
|
|
181
|
+
"is_default": self.is_default,
|
|
182
|
+
}
|
|
@@ -9,6 +9,10 @@ assistant_id: placeholder_default
|
|
|
9
9
|
# Configuration for the Rasa NLU components.
|
|
10
10
|
# https://rasa.com/docs/rasa-pro/nlu-based-assistants/components
|
|
11
11
|
language: en
|
|
12
|
+
additional_languages:
|
|
13
|
+
- it
|
|
14
|
+
- de
|
|
15
|
+
- es
|
|
12
16
|
|
|
13
17
|
pipeline:
|
|
14
18
|
- name: WhitespaceTokenizer
|