rasa-pro 3.13.0.dev3__py3-none-any.whl → 3.13.0.dev7__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.
- rasa/__main__.py +3 -1
- rasa/api.py +4 -0
- rasa/cli/arguments/default_arguments.py +13 -1
- rasa/cli/arguments/train.py +2 -0
- rasa/cli/evaluate.py +1 -1
- rasa/cli/export.py +2 -2
- rasa/cli/inspect.py +8 -4
- rasa/cli/project_templates/default/config.yml +5 -32
- rasa/cli/project_templates/{calm → default}/e2e_tests/cancelations/user_cancels_during_a_correction.yml +1 -1
- rasa/cli/project_templates/{calm → default}/e2e_tests/cancelations/user_changes_mind_on_a_whim.yml +1 -1
- rasa/cli/project_templates/{calm → default}/e2e_tests/corrections/user_corrects_contact_handle.yml +1 -1
- rasa/cli/project_templates/{calm → default}/e2e_tests/corrections/user_corrects_contact_name.yml +1 -1
- rasa/cli/project_templates/{calm → default}/e2e_tests/happy_paths/user_adds_contact_to_their_list.yml +1 -1
- rasa/cli/project_templates/{calm → default}/e2e_tests/happy_paths/user_lists_contacts.yml +1 -1
- rasa/cli/project_templates/{calm → default}/e2e_tests/happy_paths/user_removes_contact.yml +1 -1
- rasa/cli/project_templates/{calm → default}/e2e_tests/happy_paths/user_removes_contact_from_list.yml +1 -1
- rasa/cli/project_templates/default/endpoints.yml +18 -2
- rasa/cli/scaffold.py +3 -4
- rasa/cli/studio/download.py +1 -1
- rasa/cli/studio/upload.py +0 -6
- rasa/cli/train.py +1 -0
- rasa/constants.py +2 -0
- rasa/core/agent.py +2 -2
- rasa/core/brokers/kafka.py +4 -0
- rasa/core/brokers/pika.py +4 -0
- rasa/core/brokers/sql.py +1 -1
- rasa/core/channels/channel.py +68 -5
- rasa/core/channels/inspector/.eslintrc.cjs +12 -6
- rasa/core/channels/inspector/.prettierrc +5 -0
- rasa/core/channels/inspector/README.md +10 -4
- rasa/core/channels/inspector/dist/assets/{arc-c7691751.js → arc-c4b064fc.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-ab99dff7.js → blockDiagram-38ab4fdb-215b5026.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-08c35a6b.js → c4Diagram-3d4e48cf-2b54a0a3.js} +1 -1
- rasa/core/channels/inspector/dist/assets/channel-3730f5fd.js +1 -0
- rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-9e9c71c9.js → classDiagram-70f12bd4-daacea5f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-15e7e2bf.js → classDiagram-v2-f2320105-930d4dc2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/clone-e847561e.js +1 -0
- rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-9c105cb1.js → createText-2e5e7dd3-83c206ba.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-77e89e48.js → edges-e0da2a9e-b0eb01d0.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-7a011646.js → erDiagram-9861fffd-17586500.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-b6f105ac.js → flowDb-956e92f1-be2a1776.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-ce4f18c2.js → flowDiagram-66a62f08-c2120ebd.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-efbbfe00.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-cb5f6da4.js → flowchart-elk-definition-4a651766-a6ab5c48.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-e4d19e28.js → ganttDiagram-c361ad54-ef613457.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-727b1c33.js → gitGraphDiagram-72cf32ee-d59185b3.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{graph-6e2ab9a7.js → graph-0f155405.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-3862675e-84ec700f.js → index-3862675e-d5f1d1b7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-098a1a24.js → index-47737d3a.js} +162 -149
- rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-78dda442.js → infoDiagram-f8f76790-b07d141f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-f1cc6dd1.js → journeyDiagram-49397b02-1936d429.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-d98dcd0c.js → layout-dde8d0f3.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-838e3d82.js → line-0c2c7ee0.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-eae72406.js → linear-35dd89a4.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-c96fd84b.js → mindmap-definition-fc14e90a-56192851.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-c936d4e2.js → pieDiagram-8a3498a8-fc21ed78.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-b338eb8f.js → quadrantDiagram-120e2f19-25e98518.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-c6b6c0d5.js → requirementDiagram-deff3bca-546ff1f5.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-b9372e19.js → sankeyDiagram-04a897e0-02d8b82d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-479e0a3f.js → sequenceDiagram-704730f1-3ca5a92e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-fd26eebc.js → stateDiagram-587899a1-128ea07c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-3233e0ae.js → stateDiagram-v2-d93cdb3a-95f290af.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-1fdd392b.js → styles-6aaf32cf-4984898a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9a916d00-6d7bfa1b.js → styles-9a916d00-1bf266ba.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-c10674c1-f86aab11.js → styles-c10674c1-60521c63.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-e3e49d7a.js → svgDrawCommon-08f97a94-a25b6e12.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-6fe08b4d.js → timeline-definition-85554ec2-0fc086bf.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-c2e06fd6.js → xychartDiagram-e933f94c-44ee592e.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +1 -1
- rasa/core/channels/inspector/package.json +3 -1
- rasa/core/channels/inspector/src/App.tsx +92 -90
- rasa/core/channels/inspector/src/components/Chat.tsx +61 -36
- rasa/core/channels/inspector/src/components/DiagramFlow.tsx +40 -43
- rasa/core/channels/inspector/src/components/DialogueInformation.tsx +57 -57
- rasa/core/channels/inspector/src/components/DialogueStack.tsx +36 -27
- rasa/core/channels/inspector/src/components/ExpandIcon.tsx +4 -4
- rasa/core/channels/inspector/src/components/FullscreenButton.tsx +7 -7
- rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +28 -12
- rasa/core/channels/inspector/src/components/NoActiveFlow.tsx +9 -9
- rasa/core/channels/inspector/src/components/RasaLogo.tsx +5 -5
- rasa/core/channels/inspector/src/components/RecruitmentPanel.tsx +55 -60
- rasa/core/channels/inspector/src/components/SaraDiagrams.tsx +5 -5
- rasa/core/channels/inspector/src/components/Slots.tsx +22 -22
- rasa/core/channels/inspector/src/components/Welcome.tsx +28 -31
- rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +245 -0
- rasa/core/channels/inspector/src/helpers/audio/microphone-processor.js +12 -0
- rasa/core/channels/inspector/src/helpers/audio/playback-processor.js +36 -0
- rasa/core/channels/inspector/src/helpers/conversation.ts +16 -0
- rasa/core/channels/inspector/src/helpers/formatters.test.ts +181 -181
- rasa/core/channels/inspector/src/helpers/formatters.ts +111 -111
- rasa/core/channels/inspector/src/helpers/utils.ts +78 -61
- rasa/core/channels/inspector/src/main.tsx +8 -8
- rasa/core/channels/inspector/src/theme/Button/Button.ts +8 -8
- rasa/core/channels/inspector/src/theme/Heading/Heading.ts +7 -7
- rasa/core/channels/inspector/src/theme/Input/Input.ts +9 -9
- rasa/core/channels/inspector/src/theme/Link/Link.ts +6 -6
- rasa/core/channels/inspector/src/theme/Modal/Modal.ts +13 -13
- rasa/core/channels/inspector/src/theme/Table/Table.tsx +10 -10
- rasa/core/channels/inspector/src/theme/Tooltip/Tooltip.ts +5 -5
- rasa/core/channels/inspector/src/theme/base/breakpoints.ts +7 -7
- rasa/core/channels/inspector/src/theme/base/colors.ts +64 -64
- rasa/core/channels/inspector/src/theme/base/fonts/fontFaces.css +21 -18
- rasa/core/channels/inspector/src/theme/base/radii.ts +8 -8
- rasa/core/channels/inspector/src/theme/base/shadows.ts +5 -5
- rasa/core/channels/inspector/src/theme/base/sizes.ts +5 -5
- rasa/core/channels/inspector/src/theme/base/space.ts +12 -12
- rasa/core/channels/inspector/src/theme/base/styles.ts +5 -5
- rasa/core/channels/inspector/src/theme/base/typography.ts +12 -12
- rasa/core/channels/inspector/src/theme/base/zIndices.ts +3 -3
- rasa/core/channels/inspector/src/theme/index.ts +38 -38
- rasa/core/channels/inspector/src/types.ts +56 -50
- rasa/core/channels/inspector/yarn.lock +5 -0
- rasa/core/channels/voice_ready/audiocodes.py +75 -32
- rasa/core/channels/voice_ready/twilio_voice.py +48 -1
- rasa/core/channels/voice_stream/tts/azure.py +11 -2
- rasa/core/channels/voice_stream/twilio_media_streams.py +101 -26
- rasa/core/channels/voice_stream/voice_channel.py +28 -2
- rasa/core/concurrent_lock_store.py +24 -10
- rasa/core/evaluation/marker_tracker_loader.py +1 -1
- rasa/core/exporter.py +1 -1
- rasa/core/lock_store.py +151 -60
- rasa/core/nlg/contextual_response_rephraser.py +4 -2
- rasa/core/nlg/summarize.py +1 -1
- rasa/core/persistor.py +55 -20
- rasa/core/policies/enterprise_search_policy.py +7 -4
- rasa/core/policies/intentless_policy.py +15 -9
- rasa/core/processor.py +2 -2
- rasa/core/run.py +7 -2
- rasa/core/{auth_retry_tracker_store.py → tracker_stores/auth_retry_tracker_store.py} +5 -1
- rasa/core/tracker_stores/dynamo_tracker_store.py +218 -0
- rasa/core/tracker_stores/mongo_tracker_store.py +206 -0
- rasa/core/tracker_stores/redis_tracker_store.py +219 -0
- rasa/core/tracker_stores/sql_tracker_store.py +555 -0
- rasa/core/tracker_stores/tracker_store.py +805 -0
- rasa/core/utils.py +6 -0
- rasa/dialogue_understanding/coexistence/llm_based_router.py +8 -3
- rasa/dialogue_understanding/commands/clarify_command.py +2 -2
- rasa/dialogue_understanding/commands/knowledge_answer_command.py +2 -2
- rasa/dialogue_understanding/generator/constants.py +2 -2
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +1 -1
- rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +33 -12
- rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +2 -2
- rasa/dialogue_understanding_test/du_test_case.py +16 -8
- rasa/hooks.py +2 -2
- rasa/keys +1 -0
- rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +4 -2
- rasa/model_manager/config.py +3 -1
- rasa/model_manager/model_api.py +1 -2
- rasa/model_manager/runner_service.py +8 -4
- rasa/model_manager/trainer_service.py +1 -0
- rasa/model_training.py +12 -3
- rasa/nlu/extractors/crf_entity_extractor.py +66 -16
- rasa/plugin.py +1 -4
- rasa/server.py +6 -2
- rasa/shared/constants.py +4 -0
- rasa/shared/core/domain.py +165 -11
- rasa/shared/core/events.py +68 -2
- rasa/shared/core/flows/flow.py +155 -131
- rasa/shared/core/flows/flow_step.py +19 -3
- rasa/shared/core/flows/flow_step_links.py +15 -0
- rasa/shared/core/flows/flow_step_sequence.py +6 -0
- rasa/shared/core/flows/nlu_trigger.py +13 -0
- rasa/shared/core/flows/steps/action.py +7 -4
- rasa/shared/core/flows/steps/call.py +11 -4
- rasa/shared/core/flows/steps/collect.py +27 -6
- rasa/shared/core/flows/steps/internal.py +6 -1
- rasa/shared/core/flows/steps/link.py +7 -4
- rasa/shared/core/flows/steps/no_operation.py +7 -4
- rasa/shared/core/flows/steps/set_slots.py +8 -4
- rasa/shared/core/flows/yaml_flows_io.py +106 -5
- rasa/shared/importers/importer.py +8 -0
- rasa/shared/providers/_configs/azure_openai_client_config.py +4 -0
- rasa/shared/providers/_configs/openai_client_config.py +4 -0
- rasa/shared/providers/_utils.py +83 -0
- rasa/shared/providers/embedding/_base_litellm_embedding_client.py +3 -0
- rasa/shared/providers/llm/_base_litellm_client.py +11 -5
- rasa/shared/providers/llm/azure_openai_llm_client.py +6 -68
- rasa/shared/providers/router/_base_litellm_router_client.py +53 -1
- rasa/shared/utils/common.py +42 -0
- rasa/studio/download/__init__.py +0 -0
- rasa/studio/download/domains.py +49 -0
- rasa/studio/download/download.py +439 -0
- rasa/studio/download/flows.py +359 -0
- rasa/studio/results_logger.py +6 -1
- rasa/studio/upload.py +69 -5
- rasa/telemetry.py +2 -2
- rasa/tracing/config.py +1 -1
- rasa/tracing/instrumentation/attribute_extractors.py +1 -1
- rasa/tracing/instrumentation/instrumentation.py +1 -1
- rasa/utils/common.py +36 -0
- rasa/utils/endpoints.py +22 -1
- rasa/utils/licensing.py +2 -3
- rasa/validator.py +1 -2
- rasa/version.py +1 -1
- {rasa_pro-3.13.0.dev3.dist-info → rasa_pro-3.13.0.dev7.dist-info}/METADATA +10 -10
- {rasa_pro-3.13.0.dev3.dist-info → rasa_pro-3.13.0.dev7.dist-info}/RECORD +213 -210
- rasa/cli/project_templates/calm/config.yml +0 -10
- rasa/cli/project_templates/calm/credentials.yml +0 -33
- rasa/cli/project_templates/calm/endpoints.yml +0 -58
- rasa/cli/project_templates/default/actions/actions.py +0 -27
- rasa/cli/project_templates/default/data/nlu.yml +0 -91
- rasa/cli/project_templates/default/data/rules.yml +0 -13
- rasa/cli/project_templates/default/data/stories.yml +0 -30
- rasa/cli/project_templates/default/domain.yml +0 -34
- rasa/cli/project_templates/default/tests/test_stories.yml +0 -91
- rasa/core/channels/inspector/dist/assets/channel-11268142.js +0 -1
- rasa/core/channels/inspector/dist/assets/clone-ff7f2ce7.js +0 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-cba7ae20.js +0 -1
- rasa/core/channels/inspector/src/helpers/audiostream.ts +0 -191
- rasa/core/tracker_store.py +0 -1792
- rasa/studio/download.py +0 -489
- /rasa/cli/project_templates/{calm → default}/actions/action_template.py +0 -0
- /rasa/cli/project_templates/{calm → default}/actions/add_contact.py +0 -0
- /rasa/cli/project_templates/{calm → default}/actions/db.py +0 -0
- /rasa/cli/project_templates/{calm → default}/actions/list_contacts.py +0 -0
- /rasa/cli/project_templates/{calm → default}/actions/remove_contact.py +0 -0
- /rasa/cli/project_templates/{calm → default}/data/flows/add_contact.yml +0 -0
- /rasa/cli/project_templates/{calm → default}/data/flows/list_contacts.yml +0 -0
- /rasa/cli/project_templates/{calm → default}/data/flows/remove_contact.yml +0 -0
- /rasa/cli/project_templates/{calm → default}/db/contacts.json +0 -0
- /rasa/cli/project_templates/{calm → default}/domain/add_contact.yml +0 -0
- /rasa/cli/project_templates/{calm → default}/domain/list_contacts.yml +0 -0
- /rasa/cli/project_templates/{calm → default}/domain/remove_contact.yml +0 -0
- /rasa/cli/project_templates/{calm → default}/domain/shared.yml +0 -0
- /rasa/{cli/project_templates/calm/actions → core/tracker_stores}/__init__.py +0 -0
- {rasa_pro-3.13.0.dev3.dist-info → rasa_pro-3.13.0.dev7.dist-info}/NOTICE +0 -0
- {rasa_pro-3.13.0.dev3.dist-info → rasa_pro-3.13.0.dev7.dist-info}/WHEEL +0 -0
- {rasa_pro-3.13.0.dev3.dist-info → rasa_pro-3.13.0.dev7.dist-info}/entry_points.txt +0 -0
rasa/shared/core/domain.py
CHANGED
|
@@ -134,6 +134,22 @@ ALL_DOMAIN_KEYS = [
|
|
|
134
134
|
|
|
135
135
|
PREV_PREFIX = "prev_"
|
|
136
136
|
|
|
137
|
+
MERGE_FUNC_MAPPING: Dict[Text, Callable[..., Any]] = {
|
|
138
|
+
KEY_ACTIONS: rasa.shared.utils.common.merge_lists_of_dicts,
|
|
139
|
+
KEY_RESPONSES: rasa.shared.utils.common.merge_dicts,
|
|
140
|
+
KEY_SLOTS: rasa.shared.utils.common.merge_dicts,
|
|
141
|
+
KEY_INTENTS: rasa.shared.utils.common.merge_lists_of_dicts,
|
|
142
|
+
KEY_ENTITIES: rasa.shared.utils.common.merge_lists_of_dicts,
|
|
143
|
+
KEY_E2E_ACTIONS: rasa.shared.utils.common.merge_lists,
|
|
144
|
+
KEY_FORMS: rasa.shared.utils.common.merge_dicts,
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
DICT_DATA_KEYS = [
|
|
148
|
+
key
|
|
149
|
+
for key, value in MERGE_FUNC_MAPPING.items()
|
|
150
|
+
if value == rasa.shared.utils.common.merge_dicts
|
|
151
|
+
]
|
|
152
|
+
|
|
137
153
|
# State is a dictionary with keys (USER, PREVIOUS_ACTION, SLOTS, ACTIVE_LOOP)
|
|
138
154
|
# representing the origin of a SubState;
|
|
139
155
|
# the values are SubStates, that contain the information needed for featurization
|
|
@@ -466,17 +482,7 @@ class Domain:
|
|
|
466
482
|
|
|
467
483
|
duplicates: Dict[Text, List[Text]] = {}
|
|
468
484
|
|
|
469
|
-
|
|
470
|
-
KEY_INTENTS: rasa.shared.utils.common.merge_lists_of_dicts,
|
|
471
|
-
KEY_ENTITIES: rasa.shared.utils.common.merge_lists_of_dicts,
|
|
472
|
-
KEY_ACTIONS: rasa.shared.utils.common.merge_lists_of_dicts,
|
|
473
|
-
KEY_E2E_ACTIONS: rasa.shared.utils.common.merge_lists,
|
|
474
|
-
KEY_FORMS: rasa.shared.utils.common.merge_dicts,
|
|
475
|
-
KEY_RESPONSES: rasa.shared.utils.common.merge_dicts,
|
|
476
|
-
KEY_SLOTS: rasa.shared.utils.common.merge_dicts,
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
for key, merge_func in merge_func_mappings.items():
|
|
485
|
+
for key, merge_func in MERGE_FUNC_MAPPING.items():
|
|
480
486
|
duplicates[key] = rasa.shared.utils.common.extract_duplicates(
|
|
481
487
|
combined.get(key, []), domain_dict.get(key, [])
|
|
482
488
|
)
|
|
@@ -494,6 +500,74 @@ class Domain:
|
|
|
494
500
|
|
|
495
501
|
return combined
|
|
496
502
|
|
|
503
|
+
def partial_merge(self, other: Domain) -> Domain:
|
|
504
|
+
"""
|
|
505
|
+
Returns a new Domain with intersection-based merging:
|
|
506
|
+
- For each domain section only overwrite items that already exist in self.
|
|
507
|
+
- Brand-new items in `other` are ignored.
|
|
508
|
+
|
|
509
|
+
Args:
|
|
510
|
+
other: The domain to merge with.
|
|
511
|
+
|
|
512
|
+
Returns:
|
|
513
|
+
A new Domain object with the merged content.
|
|
514
|
+
"""
|
|
515
|
+
updated_self = copy.deepcopy(self.as_dict())
|
|
516
|
+
other_dict = other.as_dict()
|
|
517
|
+
|
|
518
|
+
keys_to_merge = MERGE_FUNC_MAPPING.keys()
|
|
519
|
+
for key in keys_to_merge:
|
|
520
|
+
if key in DICT_DATA_KEYS:
|
|
521
|
+
# Merge dictionaries
|
|
522
|
+
self_val = updated_self.get(key, {})
|
|
523
|
+
other_val = other_dict.get(key, {})
|
|
524
|
+
updated_self[key] = rasa.shared.utils.common.partial_merge_dict(
|
|
525
|
+
self_val, other_val
|
|
526
|
+
)
|
|
527
|
+
else:
|
|
528
|
+
# Merge lists
|
|
529
|
+
self_val = updated_self.get(key, [])
|
|
530
|
+
other_val = other_dict.get(key, [])
|
|
531
|
+
is_same_item_fn = SAME_ITEM_FUNCTIONS.get(key, default_is_same_item)
|
|
532
|
+
updated_self[key] = rasa.shared.utils.common.partial_merge_list(
|
|
533
|
+
self_val, other_val, is_same_item_fn
|
|
534
|
+
)
|
|
535
|
+
|
|
536
|
+
return Domain.from_dict(updated_self)
|
|
537
|
+
|
|
538
|
+
def difference(self, other: Domain) -> Domain:
|
|
539
|
+
"""
|
|
540
|
+
Returns a new Domain containing items in `self` that are NOT in `other`,
|
|
541
|
+
using simple equality checks for dict/list items.
|
|
542
|
+
|
|
543
|
+
Args:
|
|
544
|
+
other: The domain to compare with.
|
|
545
|
+
|
|
546
|
+
Returns:
|
|
547
|
+
A new Domain object with the difference content.
|
|
548
|
+
"""
|
|
549
|
+
self_dict = self.as_dict()
|
|
550
|
+
other_dict = other.as_dict()
|
|
551
|
+
|
|
552
|
+
difference_dict = {}
|
|
553
|
+
for key in MERGE_FUNC_MAPPING.keys():
|
|
554
|
+
is_dict = key in DICT_DATA_KEYS
|
|
555
|
+
self_val = self_dict.get(key, {} if is_dict else [])
|
|
556
|
+
other_val = other_dict.get(key, {} if is_dict else [])
|
|
557
|
+
|
|
558
|
+
if is_dict and isinstance(self_val, dict) and isinstance(other_val, dict):
|
|
559
|
+
difference_dict[key] = {
|
|
560
|
+
k: v
|
|
561
|
+
for k, v in self_val.items()
|
|
562
|
+
if k not in other_val or v != other_val[k]
|
|
563
|
+
}
|
|
564
|
+
else:
|
|
565
|
+
difference_dict[key] = [
|
|
566
|
+
item for item in self_val if item not in other_val
|
|
567
|
+
] # type: ignore[assignment]
|
|
568
|
+
|
|
569
|
+
return Domain.from_dict(difference_dict)
|
|
570
|
+
|
|
497
571
|
def _preprocess_domain_dict(
|
|
498
572
|
self,
|
|
499
573
|
data: Dict,
|
|
@@ -2120,6 +2194,11 @@ class Domain:
|
|
|
2120
2194
|
"""Remove all builtin slots from the domain."""
|
|
2121
2195
|
self.slots = [slot for slot in self.slots if not slot.is_builtin]
|
|
2122
2196
|
|
|
2197
|
+
def __eq__(self, other: object) -> bool:
|
|
2198
|
+
if isinstance(other, Domain):
|
|
2199
|
+
return self.as_dict() == other.as_dict()
|
|
2200
|
+
return False
|
|
2201
|
+
|
|
2123
2202
|
|
|
2124
2203
|
def warn_about_duplicates_found_during_domain_merging(
|
|
2125
2204
|
duplicates: Dict[Text, List[Text]],
|
|
@@ -2178,3 +2257,78 @@ def _validate_forms(forms: Union[Dict, List]) -> None:
|
|
|
2178
2257
|
f"the keyword `{REQUIRED_SLOTS_KEY}` is required. "
|
|
2179
2258
|
f"Please see {DOCS_URL_FORMS} for more information."
|
|
2180
2259
|
)
|
|
2260
|
+
|
|
2261
|
+
|
|
2262
|
+
def is_same_entity(e1: Any, e2: Any) -> bool:
|
|
2263
|
+
"""Check if two entities are the 'same' (string or dict).
|
|
2264
|
+
|
|
2265
|
+
Args:
|
|
2266
|
+
e1: First entity to compare.
|
|
2267
|
+
e2: Second entity to compare.
|
|
2268
|
+
|
|
2269
|
+
Returns:
|
|
2270
|
+
True if the entities are the same, False otherwise.
|
|
2271
|
+
"""
|
|
2272
|
+
if isinstance(e1, str) and isinstance(e2, str):
|
|
2273
|
+
return e1 == e2
|
|
2274
|
+
|
|
2275
|
+
if isinstance(e1, dict) and isinstance(e2, dict):
|
|
2276
|
+
return (
|
|
2277
|
+
e1.get(ENTITY_ATTRIBUTE_TYPE) == e2.get(ENTITY_ATTRIBUTE_TYPE)
|
|
2278
|
+
and e1.get(ENTITY_ATTRIBUTE_ROLE) == e2.get(ENTITY_ATTRIBUTE_ROLE)
|
|
2279
|
+
and e1.get(ENTITY_ATTRIBUTE_GROUP) == e2.get(ENTITY_ATTRIBUTE_GROUP)
|
|
2280
|
+
)
|
|
2281
|
+
|
|
2282
|
+
return False
|
|
2283
|
+
|
|
2284
|
+
|
|
2285
|
+
def is_same_intent(i1: Any, i2: Any) -> bool:
|
|
2286
|
+
"""Check if two intents are the 'same' (string or dict).
|
|
2287
|
+
|
|
2288
|
+
Args:
|
|
2289
|
+
i1: First intent to compare.
|
|
2290
|
+
i2: Second intent to compare.
|
|
2291
|
+
|
|
2292
|
+
Returns:
|
|
2293
|
+
True if the intents are the same, False otherwise.
|
|
2294
|
+
"""
|
|
2295
|
+
if isinstance(i1, str) and isinstance(i2, str):
|
|
2296
|
+
return i1 == i2
|
|
2297
|
+
|
|
2298
|
+
if isinstance(i1, dict) and isinstance(i2, dict):
|
|
2299
|
+
key1, key2 = next(iter(i1.keys())), next(iter((i2.keys())))
|
|
2300
|
+
return key1 == key2
|
|
2301
|
+
|
|
2302
|
+
return False
|
|
2303
|
+
|
|
2304
|
+
|
|
2305
|
+
def is_same_action(a1: Any, a2: Any) -> bool:
|
|
2306
|
+
"""Check if two actions are the 'same' (string or dict).
|
|
2307
|
+
|
|
2308
|
+
Args:
|
|
2309
|
+
a1: First action to compare.
|
|
2310
|
+
a2: Second action to compare.
|
|
2311
|
+
|
|
2312
|
+
Returns:
|
|
2313
|
+
True if the actions are the same, False otherwise.
|
|
2314
|
+
"""
|
|
2315
|
+
if isinstance(a1, str) and isinstance(a2, str):
|
|
2316
|
+
return a1 == a2
|
|
2317
|
+
|
|
2318
|
+
if isinstance(a1, dict) and isinstance(a2, dict):
|
|
2319
|
+
key1, key2 = next(iter((a1.keys()))), next(iter((a2.keys())))
|
|
2320
|
+
return key1 == key2
|
|
2321
|
+
|
|
2322
|
+
return False
|
|
2323
|
+
|
|
2324
|
+
|
|
2325
|
+
def default_is_same_item(a: Any, b: Any) -> bool:
|
|
2326
|
+
"""Fallback exact equality check if a key doesn't need special handling."""
|
|
2327
|
+
return a == b
|
|
2328
|
+
|
|
2329
|
+
|
|
2330
|
+
SAME_ITEM_FUNCTIONS: Dict[Text, Callable[[Any, Any], bool]] = {
|
|
2331
|
+
KEY_ENTITIES: is_same_entity,
|
|
2332
|
+
KEY_INTENTS: is_same_intent,
|
|
2333
|
+
KEY_ACTIONS: is_same_action,
|
|
2334
|
+
}
|
rasa/shared/core/events.py
CHANGED
|
@@ -107,6 +107,8 @@ if TYPE_CHECKING:
|
|
|
107
107
|
logger = logging.getLogger(__name__)
|
|
108
108
|
structlogger = structlog.get_logger()
|
|
109
109
|
|
|
110
|
+
INVALID_DATETIME_ERROR_MESSAGE = "`anonymized_at` must be a datetime object."
|
|
111
|
+
|
|
110
112
|
|
|
111
113
|
def deserialise_events(serialized_events: List[Dict[Text, Any]]) -> List["Event"]:
|
|
112
114
|
"""Convert a list of dictionaries to a list of corresponding events.
|
|
@@ -498,6 +500,23 @@ class UserUttered(Event):
|
|
|
498
500
|
if parse_data:
|
|
499
501
|
self.parse_data.update(**parse_data)
|
|
500
502
|
|
|
503
|
+
self._anonymized_at: Optional[datetime] = None
|
|
504
|
+
|
|
505
|
+
@property
|
|
506
|
+
def anonymized_at(self) -> Optional[datetime]:
|
|
507
|
+
"""Returns the time when the event was anonymized in the tracker store.
|
|
508
|
+
|
|
509
|
+
If the event was not anonymized, it returns None.
|
|
510
|
+
"""
|
|
511
|
+
return self._anonymized_at
|
|
512
|
+
|
|
513
|
+
@anonymized_at.setter
|
|
514
|
+
def anonymized_at(self, value: Optional[datetime]) -> None:
|
|
515
|
+
"""Sets the time when the event was anonymized in the tracker store."""
|
|
516
|
+
if value is not None and not isinstance(value, datetime):
|
|
517
|
+
raise ValueError(INVALID_DATETIME_ERROR_MESSAGE)
|
|
518
|
+
self._anonymized_at = value
|
|
519
|
+
|
|
501
520
|
@staticmethod
|
|
502
521
|
def _from_parse_data(
|
|
503
522
|
text: Text,
|
|
@@ -614,6 +633,7 @@ class UserUttered(Event):
|
|
|
614
633
|
"input_channel": getattr(self, "input_channel", None),
|
|
615
634
|
"message_id": getattr(self, "message_id", None),
|
|
616
635
|
"metadata": self.metadata,
|
|
636
|
+
"anonymized_at": self.anonymized_at,
|
|
617
637
|
}
|
|
618
638
|
)
|
|
619
639
|
return _dict
|
|
@@ -911,8 +931,24 @@ class BotUttered(SkipEventInMDStoryMixin):
|
|
|
911
931
|
"""
|
|
912
932
|
self.text = text
|
|
913
933
|
self.data = data or {}
|
|
934
|
+
self._anonymized_at: Optional[datetime] = None
|
|
914
935
|
super().__init__(timestamp, metadata)
|
|
915
936
|
|
|
937
|
+
@property
|
|
938
|
+
def anonymized_at(self) -> Optional[datetime]:
|
|
939
|
+
"""Returns the time when the event was anonymized in the tracker store.
|
|
940
|
+
|
|
941
|
+
If the event was not anonymized, it returns None.
|
|
942
|
+
"""
|
|
943
|
+
return self._anonymized_at
|
|
944
|
+
|
|
945
|
+
@anonymized_at.setter
|
|
946
|
+
def anonymized_at(self, value: Optional[datetime]) -> None:
|
|
947
|
+
"""Sets the time when the event was anonymized in the tracker store."""
|
|
948
|
+
if value is not None and not isinstance(value, datetime):
|
|
949
|
+
raise ValueError(INVALID_DATETIME_ERROR_MESSAGE)
|
|
950
|
+
self._anonymized_at = value
|
|
951
|
+
|
|
916
952
|
def __members(self) -> Tuple[Optional[Text], Text, Text]:
|
|
917
953
|
data_no_nones = {k: v for k, v in self.data.items() if v is not None}
|
|
918
954
|
meta_no_nones = {k: v for k, v in self.metadata.items() if v is not None}
|
|
@@ -999,7 +1035,14 @@ class BotUttered(SkipEventInMDStoryMixin):
|
|
|
999
1035
|
def as_dict(self) -> Dict[Text, Any]:
|
|
1000
1036
|
"""Returns serialized event."""
|
|
1001
1037
|
d = super().as_dict()
|
|
1002
|
-
d.update(
|
|
1038
|
+
d.update(
|
|
1039
|
+
{
|
|
1040
|
+
"text": self.text,
|
|
1041
|
+
"data": self.data,
|
|
1042
|
+
"metadata": self.metadata,
|
|
1043
|
+
"anonymized_at": self.anonymized_at,
|
|
1044
|
+
}
|
|
1045
|
+
)
|
|
1003
1046
|
return d
|
|
1004
1047
|
|
|
1005
1048
|
@classmethod
|
|
@@ -1046,8 +1089,24 @@ class SlotSet(Event):
|
|
|
1046
1089
|
self.key = key
|
|
1047
1090
|
self.value = value
|
|
1048
1091
|
self._filled_by = filled_by
|
|
1092
|
+
self._anonymized_at: Optional[datetime] = None
|
|
1049
1093
|
super().__init__(timestamp, metadata)
|
|
1050
1094
|
|
|
1095
|
+
@property
|
|
1096
|
+
def anonymized_at(self) -> Optional[datetime]:
|
|
1097
|
+
"""Returns the time when the event was anonymized in the tracker store.
|
|
1098
|
+
|
|
1099
|
+
If the event was not anonymized, it returns None.
|
|
1100
|
+
"""
|
|
1101
|
+
return self._anonymized_at
|
|
1102
|
+
|
|
1103
|
+
@anonymized_at.setter
|
|
1104
|
+
def anonymized_at(self, value: Optional[datetime]) -> None:
|
|
1105
|
+
"""Sets the time when the event was anonymized in the tracker store."""
|
|
1106
|
+
if value is not None and not isinstance(value, datetime):
|
|
1107
|
+
raise ValueError(INVALID_DATETIME_ERROR_MESSAGE)
|
|
1108
|
+
self._anonymized_at = value
|
|
1109
|
+
|
|
1051
1110
|
def __repr__(self) -> Text:
|
|
1052
1111
|
"""Returns text representation of event."""
|
|
1053
1112
|
return f"SlotSet(key: {self.key}, value: {self.value})"
|
|
@@ -1092,7 +1151,14 @@ class SlotSet(Event):
|
|
|
1092
1151
|
def as_dict(self) -> Dict[Text, Any]:
|
|
1093
1152
|
"""Returns serialized event."""
|
|
1094
1153
|
d = super().as_dict()
|
|
1095
|
-
d.update(
|
|
1154
|
+
d.update(
|
|
1155
|
+
{
|
|
1156
|
+
"name": self.key,
|
|
1157
|
+
"value": self.value,
|
|
1158
|
+
"filled_by": self.filled_by,
|
|
1159
|
+
"anonymized_at": self.anonymized_at,
|
|
1160
|
+
}
|
|
1161
|
+
)
|
|
1096
1162
|
return d
|
|
1097
1163
|
|
|
1098
1164
|
@classmethod
|