rasa-pro 3.13.0.dev5__py3-none-any.whl → 3.13.0.dev8__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 +0 -3
- rasa/api.py +5 -1
- rasa/cli/arguments/default_arguments.py +13 -1
- rasa/cli/arguments/train.py +2 -0
- rasa/cli/dialogue_understanding_test.py +1 -1
- rasa/cli/e2e_test.py +1 -1
- rasa/cli/evaluate.py +2 -2
- rasa/cli/export.py +3 -3
- rasa/cli/llm_fine_tuning.py +12 -11
- rasa/cli/project_templates/defaults.py +133 -0
- rasa/cli/run.py +1 -1
- rasa/cli/studio/link.py +53 -0
- rasa/cli/studio/pull.py +78 -0
- rasa/cli/studio/push.py +78 -0
- rasa/cli/studio/studio.py +12 -0
- rasa/cli/studio/upload.py +8 -0
- rasa/cli/train.py +2 -1
- rasa/cli/utils.py +1 -1
- rasa/cli/x.py +1 -1
- rasa/constants.py +4 -0
- rasa/core/__init__.py +0 -16
- rasa/core/actions/action.py +5 -1
- rasa/core/actions/action_repeat_bot_messages.py +18 -22
- rasa/core/actions/action_run_slot_rejections.py +0 -1
- rasa/core/agent.py +18 -3
- rasa/core/available_endpoints.py +146 -0
- rasa/core/brokers/kafka.py +4 -0
- rasa/core/brokers/pika.py +5 -2
- rasa/core/brokers/sql.py +1 -1
- rasa/core/channels/botframework.py +2 -2
- rasa/core/channels/channel.py +2 -2
- rasa/core/channels/hangouts.py +8 -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-9f75cc3b.js → arc-c4b064fc.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-7f34db23.js → blockDiagram-38ab4fdb-215b5026.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-948bab2c.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-53b0dd0e.js → classDiagram-70f12bd4-daacea5f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-fdf789e7.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-87c4ece5.js → createText-2e5e7dd3-83c206ba.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-5a8b0749.js → edges-e0da2a9e-b0eb01d0.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-66da90e2.js → erDiagram-9861fffd-17586500.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-10044f05.js → flowDb-956e92f1-be2a1776.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-f338f66a.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-b13140aa.js → flowchart-elk-definition-4a651766-a6ab5c48.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-f2b4a55a.js → ganttDiagram-c361ad54-ef613457.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-dedc298d.js → gitGraphDiagram-72cf32ee-d59185b3.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{graph-4ede11ff.js → graph-0f155405.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-3862675e-65549d37.js → index-3862675e-d5f1d1b7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-3a23e736.js → index-47737d3a.js} +123 -123
- rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-65439671.js → infoDiagram-f8f76790-b07d141f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-56d03d98.js → journeyDiagram-49397b02-1936d429.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-dd48f7f4.js → layout-dde8d0f3.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-1569ad2c.js → line-0c2c7ee0.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-48bf4935.js → linear-35dd89a4.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-688504c1.js → mindmap-definition-fc14e90a-56192851.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-78b6d7e6.js → pieDiagram-8a3498a8-fc21ed78.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-048b84b3.js → quadrantDiagram-120e2f19-25e98518.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-dd67f107.js → requirementDiagram-deff3bca-546ff1f5.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-8128436e.js → sankeyDiagram-04a897e0-02d8b82d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-1a0d1461.js → sequenceDiagram-704730f1-3ca5a92e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-46d388ed.js → stateDiagram-587899a1-128ea07c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-ea42951a.js → stateDiagram-v2-d93cdb3a-95f290af.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-7427ed0c.js → styles-6aaf32cf-4984898a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9a916d00-ff5e5a16.js → styles-9a916d00-1bf266ba.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-c10674c1-7b3680cf.js → styles-c10674c1-60521c63.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-f860f2ad.js → svgDrawCommon-08f97a94-a25b6e12.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-2eebf0c8.js → timeline-definition-85554ec2-0fc086bf.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-5d7f4e96.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 +91 -90
- rasa/core/channels/inspector/src/components/Chat.tsx +45 -41
- rasa/core/channels/inspector/src/components/DiagramFlow.tsx +40 -40
- 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 +7 -7
- 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/mattermost.py +1 -1
- rasa/core/channels/rasa_chat.py +2 -4
- rasa/core/channels/rest.py +5 -4
- rasa/core/channels/studio_chat.py +3 -2
- rasa/core/channels/vier_cvg.py +1 -2
- rasa/core/channels/voice_ready/audiocodes.py +35 -25
- rasa/core/channels/voice_stream/audiocodes.py +7 -4
- rasa/core/channels/voice_stream/genesys.py +2 -2
- rasa/core/channels/voice_stream/twilio_media_streams.py +10 -5
- rasa/core/channels/voice_stream/voice_channel.py +33 -22
- rasa/core/evaluation/marker_tracker_loader.py +1 -1
- rasa/core/exporter.py +1 -1
- rasa/core/http_interpreter.py +3 -7
- rasa/core/jobs.py +2 -1
- rasa/core/nlg/contextual_response_rephraser.py +38 -11
- rasa/core/nlg/generator.py +0 -1
- rasa/core/nlg/interpolator.py +2 -3
- rasa/core/nlg/summarize.py +40 -6
- rasa/core/persistor.py +55 -20
- rasa/core/policies/enterprise_search_policy.py +290 -66
- rasa/core/policies/enterprise_search_prompt_with_relevancy_check_and_citation_template.jinja2 +63 -0
- rasa/core/policies/flow_policy.py +1 -1
- rasa/core/policies/flows/flow_executor.py +96 -17
- rasa/core/policies/intentless_policy.py +24 -16
- rasa/core/processor.py +106 -53
- rasa/core/run.py +40 -13
- rasa/core/tracker_stores/__init__.py +0 -0
- 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/training/interactive.py +1 -1
- rasa/core/utils.py +24 -91
- rasa/dialogue_understanding/coexistence/intent_based_router.py +2 -1
- rasa/dialogue_understanding/coexistence/llm_based_router.py +8 -3
- rasa/dialogue_understanding/commands/can_not_handle_command.py +2 -0
- rasa/dialogue_understanding/commands/cancel_flow_command.py +2 -0
- rasa/dialogue_understanding/commands/chit_chat_answer_command.py +2 -0
- rasa/dialogue_understanding/commands/clarify_command.py +6 -2
- rasa/dialogue_understanding/commands/command_syntax_manager.py +1 -0
- rasa/dialogue_understanding/commands/human_handoff_command.py +2 -0
- rasa/dialogue_understanding/commands/knowledge_answer_command.py +2 -0
- rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +2 -0
- rasa/dialogue_understanding/commands/set_slot_command.py +11 -1
- rasa/dialogue_understanding/commands/skip_question_command.py +2 -0
- rasa/dialogue_understanding/commands/start_flow_command.py +4 -0
- rasa/dialogue_understanding/commands/utils.py +26 -2
- rasa/dialogue_understanding/generator/__init__.py +7 -1
- rasa/dialogue_understanding/generator/command_generator.py +4 -2
- rasa/dialogue_understanding/generator/command_parser.py +2 -2
- rasa/dialogue_understanding/generator/command_parser_validator.py +63 -0
- 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_v3_gpt_4o_2024_11_20_template.jinja2 +78 -0
- rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +28 -463
- rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +147 -0
- rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +477 -0
- rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +8 -58
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +37 -25
- rasa/dialogue_understanding/patterns/domain_for_patterns.py +190 -0
- rasa/dialogue_understanding/processor/command_processor.py +3 -3
- rasa/dialogue_understanding/processor/command_processor_component.py +3 -3
- rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +17 -4
- rasa/dialogue_understanding/utils.py +68 -12
- rasa/dialogue_understanding_test/du_test_case.py +1 -1
- rasa/dialogue_understanding_test/du_test_runner.py +4 -22
- rasa/dialogue_understanding_test/test_case_simulation/test_case_tracker_simulator.py +2 -6
- rasa/e2e_test/e2e_test_runner.py +1 -1
- rasa/engine/constants.py +1 -1
- rasa/engine/recipes/default_recipe.py +26 -2
- rasa/engine/validation.py +3 -2
- rasa/hooks.py +2 -30
- rasa/keys +1 -0
- rasa/llm_fine_tuning/annotation_module.py +39 -9
- rasa/llm_fine_tuning/conversations.py +3 -0
- rasa/llm_fine_tuning/llm_data_preparation_module.py +66 -49
- rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +4 -2
- rasa/llm_fine_tuning/paraphrasing/rephrase_validator.py +52 -44
- rasa/llm_fine_tuning/paraphrasing_module.py +10 -12
- rasa/llm_fine_tuning/storage.py +4 -4
- rasa/llm_fine_tuning/utils.py +63 -1
- rasa/model_manager/config.py +3 -1
- rasa/model_manager/model_api.py +89 -2
- rasa/model_manager/runner_service.py +8 -4
- rasa/model_manager/trainer_service.py +5 -4
- rasa/model_training.py +12 -3
- rasa/nlu/extractors/crf_entity_extractor.py +66 -16
- rasa/plugin.py +2 -12
- rasa/privacy/__init__.py +0 -0
- rasa/privacy/constants.py +83 -0
- rasa/privacy/event_broker_utils.py +77 -0
- rasa/privacy/privacy_config.py +281 -0
- rasa/privacy/privacy_config_schema.json +86 -0
- rasa/privacy/privacy_filter.py +340 -0
- rasa/privacy/privacy_manager.py +576 -0
- rasa/server.py +29 -4
- rasa/shared/constants.py +6 -0
- rasa/shared/core/constants.py +4 -3
- rasa/shared/core/domain.py +7 -0
- rasa/shared/core/events.py +99 -3
- rasa/shared/core/flows/flow.py +1 -2
- rasa/shared/core/flows/flows_yaml_schema.json +3 -0
- rasa/shared/core/flows/steps/collect.py +46 -2
- rasa/shared/core/slots.py +28 -0
- rasa/shared/exceptions.py +4 -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/embedding/_base_litellm_embedding_client.py +3 -0
- rasa/shared/providers/llm/_base_litellm_client.py +5 -2
- rasa/shared/utils/llm.py +161 -6
- rasa/shared/utils/yaml.py +32 -0
- rasa/studio/data_handler.py +3 -3
- rasa/studio/download/download.py +37 -60
- rasa/studio/download/flows.py +23 -31
- rasa/studio/link.py +200 -0
- rasa/studio/pull.py +94 -0
- rasa/studio/push.py +131 -0
- rasa/studio/upload.py +117 -67
- rasa/telemetry.py +84 -27
- rasa/tracing/config.py +4 -5
- rasa/tracing/constants.py +19 -1
- rasa/tracing/instrumentation/attribute_extractors.py +11 -3
- rasa/tracing/instrumentation/instrumentation.py +54 -3
- rasa/tracing/instrumentation/metrics.py +98 -15
- rasa/tracing/metric_instrument_provider.py +75 -3
- rasa/utils/common.py +1 -27
- rasa/utils/licensing.py +1 -2
- rasa/utils/log_utils.py +1 -45
- rasa/validator.py +2 -8
- rasa/version.py +1 -1
- {rasa_pro-3.13.0.dev5.dist-info → rasa_pro-3.13.0.dev8.dist-info}/METADATA +8 -9
- {rasa_pro-3.13.0.dev5.dist-info → rasa_pro-3.13.0.dev8.dist-info}/RECORD +254 -231
- rasa/anonymization/__init__.py +0 -2
- rasa/anonymization/anonymisation_rule_yaml_reader.py +0 -91
- rasa/anonymization/anonymization_pipeline.py +0 -286
- rasa/anonymization/anonymization_rule_executor.py +0 -266
- rasa/anonymization/anonymization_rule_orchestrator.py +0 -119
- rasa/anonymization/schemas/config.yml +0 -47
- rasa/anonymization/utils.py +0 -118
- rasa/core/channels/inspector/dist/assets/channel-dfa68278.js +0 -1
- rasa/core/channels/inspector/dist/assets/clone-edb7f119.js +0 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-65e7c670.js +0 -1
- rasa/core/channels/inspector/src/helpers/audiostream.ts +0 -191
- rasa/core/tracker_store.py +0 -1792
- {rasa_pro-3.13.0.dev5.dist-info → rasa_pro-3.13.0.dev8.dist-info}/NOTICE +0 -0
- {rasa_pro-3.13.0.dev5.dist-info → rasa_pro-3.13.0.dev8.dist-info}/WHEEL +0 -0
- {rasa_pro-3.13.0.dev5.dist-info → rasa_pro-3.13.0.dev8.dist-info}/entry_points.txt +0 -0
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import copy
|
|
2
|
-
import json
|
|
3
|
-
import logging
|
|
4
|
-
from typing import Any, Dict, List, Optional, Text
|
|
5
|
-
|
|
6
|
-
from rasa.anonymization.anonymization_rule_executor import (
|
|
7
|
-
AnonymizationRuleExecutor,
|
|
8
|
-
AnonymizationRuleList,
|
|
9
|
-
)
|
|
10
|
-
from rasa.core.brokers.broker import EventBroker
|
|
11
|
-
from rasa.core.brokers.kafka import KafkaEventBroker
|
|
12
|
-
|
|
13
|
-
logger = logging.getLogger(__name__)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class AnonymizationRuleOrchestrator:
|
|
17
|
-
"""Orchestrates the execution of anonymization rules."""
|
|
18
|
-
|
|
19
|
-
def __init__(
|
|
20
|
-
self,
|
|
21
|
-
event_broker: Optional[EventBroker],
|
|
22
|
-
anonymization_rule_list: AnonymizationRuleList,
|
|
23
|
-
):
|
|
24
|
-
"""Initializes the orchestrator."""
|
|
25
|
-
self.event_broker = (
|
|
26
|
-
event_broker if isinstance(event_broker, KafkaEventBroker) else None
|
|
27
|
-
)
|
|
28
|
-
self.anonymization_rule_executor = AnonymizationRuleExecutor(
|
|
29
|
-
anonymization_rule_list
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
def anonymize_event(self, event: Dict[Text, Any]) -> Dict[Text, Any]:
|
|
33
|
-
"""Anonymizes one of the supported event types.
|
|
34
|
-
|
|
35
|
-
The supported event types: user, bot, slot, entities.
|
|
36
|
-
"""
|
|
37
|
-
event_copy = copy.deepcopy(event)
|
|
38
|
-
event_type = event["event"]
|
|
39
|
-
|
|
40
|
-
if event_type == "user" or event_type == "bot":
|
|
41
|
-
if event["text"] is None:
|
|
42
|
-
return event_copy
|
|
43
|
-
|
|
44
|
-
anonymized_text = self.anonymization_rule_executor.run(event["text"])
|
|
45
|
-
event_copy["text"] = anonymized_text
|
|
46
|
-
|
|
47
|
-
if "parse_data" in event_copy:
|
|
48
|
-
event_copy["parse_data"]["text"] = anonymized_text
|
|
49
|
-
|
|
50
|
-
entities = event_copy["parse_data"]["entities"]
|
|
51
|
-
|
|
52
|
-
if entities:
|
|
53
|
-
anonymized_entities = self._anonymize_entities(entities)
|
|
54
|
-
event_copy["parse_data"]["entities"] = anonymized_entities
|
|
55
|
-
|
|
56
|
-
elif event_type == "slot":
|
|
57
|
-
slot_value = event["value"]
|
|
58
|
-
|
|
59
|
-
if slot_value is None:
|
|
60
|
-
return event_copy
|
|
61
|
-
elif not isinstance(slot_value, str):
|
|
62
|
-
slot_value = json.dumps(slot_value)
|
|
63
|
-
|
|
64
|
-
anonymized_value = self.anonymization_rule_executor.run(slot_value)
|
|
65
|
-
event_copy["value"] = anonymized_value
|
|
66
|
-
|
|
67
|
-
elif event_type == "entities":
|
|
68
|
-
entities = event_copy["entities"]
|
|
69
|
-
anonymized_entities = self._anonymize_entities(entities)
|
|
70
|
-
|
|
71
|
-
event_copy["entities"] = anonymized_entities
|
|
72
|
-
else:
|
|
73
|
-
logger.debug(f"Unsupported event type for anonymization: {event_type}.")
|
|
74
|
-
|
|
75
|
-
return event_copy
|
|
76
|
-
|
|
77
|
-
def publish_event(
|
|
78
|
-
self, anonymized_event: Dict[Text, Any], is_anonymized: bool
|
|
79
|
-
) -> None:
|
|
80
|
-
"""Publishes the anonymized event to the event broker."""
|
|
81
|
-
if self.event_broker is None:
|
|
82
|
-
return None
|
|
83
|
-
|
|
84
|
-
# this assumes that the event broker's topic attribute
|
|
85
|
-
# is set to the correct anonymization topic
|
|
86
|
-
if is_anonymized:
|
|
87
|
-
event_type = anonymized_event["event"]
|
|
88
|
-
sender_id = anonymized_event["sender_id"]
|
|
89
|
-
logger.debug(
|
|
90
|
-
f"Publishing event of type '{event_type}' from "
|
|
91
|
-
f"sender ID '{sender_id}' to "
|
|
92
|
-
f"Kafka topic '{self.event_broker.topic}'. "
|
|
93
|
-
f"The anonymization pipeline used rule named "
|
|
94
|
-
f"'{self.anonymization_rule_executor.anonymization_rule_list.id}'."
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
self.event_broker.publish(anonymized_event)
|
|
98
|
-
|
|
99
|
-
def _anonymize_entities(
|
|
100
|
-
self, entities: List[Dict[Text, Any]]
|
|
101
|
-
) -> List[Dict[Text, Any]]:
|
|
102
|
-
"""Anonymizes entities."""
|
|
103
|
-
anonymized_entities = []
|
|
104
|
-
|
|
105
|
-
for entity in entities:
|
|
106
|
-
entity_value = entity.get("value")
|
|
107
|
-
|
|
108
|
-
if entity_value is not None:
|
|
109
|
-
value = self.anonymization_rule_executor.run(str(entity_value))
|
|
110
|
-
entity["value"] = value
|
|
111
|
-
anonymized_entities.append(entity)
|
|
112
|
-
|
|
113
|
-
return anonymized_entities
|
|
114
|
-
|
|
115
|
-
def anonymize_log_message(self, message: Text) -> Any:
|
|
116
|
-
"""Anonymizes log messages."""
|
|
117
|
-
if self.event_broker:
|
|
118
|
-
return None
|
|
119
|
-
return self.anonymization_rule_executor.run(message)
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
allowempty: True
|
|
2
|
-
mapping:
|
|
3
|
-
anonymization:
|
|
4
|
-
type: "map"
|
|
5
|
-
mapping:
|
|
6
|
-
rule_lists:
|
|
7
|
-
type: "seq"
|
|
8
|
-
matching: "any"
|
|
9
|
-
required: True
|
|
10
|
-
sequence:
|
|
11
|
-
- type: "map"
|
|
12
|
-
mapping:
|
|
13
|
-
id:
|
|
14
|
-
type: "str"
|
|
15
|
-
required: True
|
|
16
|
-
rules:
|
|
17
|
-
type: "seq"
|
|
18
|
-
required: True
|
|
19
|
-
matching: "any"
|
|
20
|
-
sequence:
|
|
21
|
-
- type: "map"
|
|
22
|
-
mapping:
|
|
23
|
-
entity:
|
|
24
|
-
type: "str"
|
|
25
|
-
required: True
|
|
26
|
-
substitution:
|
|
27
|
-
type: "str"
|
|
28
|
-
enum: ["text", "mask", "faker"]
|
|
29
|
-
required: False
|
|
30
|
-
value:
|
|
31
|
-
type: "str"
|
|
32
|
-
required: False
|
|
33
|
-
|
|
34
|
-
metadata:
|
|
35
|
-
type: "map"
|
|
36
|
-
required: True
|
|
37
|
-
mapping:
|
|
38
|
-
language:
|
|
39
|
-
type: "str"
|
|
40
|
-
required: True
|
|
41
|
-
model_name:
|
|
42
|
-
type: "any"
|
|
43
|
-
required: True
|
|
44
|
-
model_provider:
|
|
45
|
-
type: "str"
|
|
46
|
-
required: True
|
|
47
|
-
enum: ["spacy", "stanza", "transformers"]
|
rasa/anonymization/utils.py
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
import os
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
from typing import Any, Dict, Optional, Text
|
|
5
|
-
|
|
6
|
-
from rasa.shared.exceptions import RasaException, YamlException
|
|
7
|
-
from rasa.shared.utils.yaml import (
|
|
8
|
-
read_config_file,
|
|
9
|
-
read_yaml_file,
|
|
10
|
-
validate_yaml_content_using_schema,
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
logger = logging.getLogger(__name__)
|
|
14
|
-
SCHEMA_FILE = Path(__file__).parent / "schemas" / "config.yml"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def read_endpoint_config(
|
|
18
|
-
filename: Optional[Text], endpoint_type: Text
|
|
19
|
-
) -> Optional[Dict[Text, Any]]:
|
|
20
|
-
"""Reads a configuration file from disk and extract one config."""
|
|
21
|
-
if not filename:
|
|
22
|
-
return None
|
|
23
|
-
|
|
24
|
-
try:
|
|
25
|
-
content = read_config_file(filename, reader_type=["safe", "rt"])
|
|
26
|
-
|
|
27
|
-
if content.get(endpoint_type) is None:
|
|
28
|
-
return None
|
|
29
|
-
|
|
30
|
-
return content
|
|
31
|
-
except FileNotFoundError:
|
|
32
|
-
logger.error(
|
|
33
|
-
"Failed to read configuration from {}. No such file.".format(
|
|
34
|
-
os.path.abspath(filename)
|
|
35
|
-
),
|
|
36
|
-
)
|
|
37
|
-
return None
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
def extract_anonymization_traits(
|
|
41
|
-
anonymization_config: Optional[Dict[Text, Any]], endpoint_type: Text
|
|
42
|
-
) -> Dict[Text, Any]:
|
|
43
|
-
"""Extract anonymization traits from the anonymization config.
|
|
44
|
-
|
|
45
|
-
Args:
|
|
46
|
-
anonymization_config: The anonymization config.
|
|
47
|
-
endpoint_type: The endpoint type.
|
|
48
|
-
|
|
49
|
-
Returns:
|
|
50
|
-
A dictionary containing the anonymization traits.
|
|
51
|
-
"""
|
|
52
|
-
if not anonymization_config:
|
|
53
|
-
return {"enabled": False}
|
|
54
|
-
|
|
55
|
-
anonymization_value = anonymization_config.get(endpoint_type)
|
|
56
|
-
if not anonymization_value:
|
|
57
|
-
logger.debug("Anonymization config found but nothing is defined.")
|
|
58
|
-
return {"enabled": False}
|
|
59
|
-
|
|
60
|
-
try:
|
|
61
|
-
validate_anonymization_yaml(anonymization_config)
|
|
62
|
-
except RasaException as exception:
|
|
63
|
-
logger.debug(exception)
|
|
64
|
-
return {"enabled": False}
|
|
65
|
-
|
|
66
|
-
rule_lists = anonymization_value.get("rule_lists", [])
|
|
67
|
-
|
|
68
|
-
traits = {
|
|
69
|
-
"enabled": True,
|
|
70
|
-
"metadata": anonymization_value.get("metadata", {}),
|
|
71
|
-
"number_of_rule_lists": len(rule_lists),
|
|
72
|
-
"number_of_rules": 0,
|
|
73
|
-
"substitutions": {
|
|
74
|
-
"mask": 0,
|
|
75
|
-
"faker": 0,
|
|
76
|
-
"text": 0,
|
|
77
|
-
"not_defined": 0,
|
|
78
|
-
},
|
|
79
|
-
"entities": set(),
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
for rule_list in rule_lists:
|
|
83
|
-
traits["number_of_rules"] += len(rule_list.get("rules", []))
|
|
84
|
-
for rule in rule_list.get("rules", []):
|
|
85
|
-
traits["substitutions"][rule.get("substitution", "not_defined")] += 1
|
|
86
|
-
traits["entities"].add(rule.get("entity"))
|
|
87
|
-
|
|
88
|
-
entities = list(traits["entities"])
|
|
89
|
-
entities.sort()
|
|
90
|
-
traits["entities"] = entities
|
|
91
|
-
|
|
92
|
-
return traits
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
def validate_anonymization_yaml(yaml_content: Dict[Text, Any]) -> None:
|
|
96
|
-
"""Checks if the yaml_content adheres to the anonymization rule schema.
|
|
97
|
-
|
|
98
|
-
If the yaml_content is not in the right format, an exception will be raised.
|
|
99
|
-
"""
|
|
100
|
-
schema = read_yaml_file(SCHEMA_FILE, reader_type=("safe", "rt"))
|
|
101
|
-
try:
|
|
102
|
-
validate_yaml_content_using_schema(yaml_content, schema)
|
|
103
|
-
except YamlException as exception:
|
|
104
|
-
raise RasaException(
|
|
105
|
-
f"Invalid configuration for `anonymization_rules` : {exception}"
|
|
106
|
-
) from exception
|
|
107
|
-
|
|
108
|
-
rule_lists = yaml_content.get("anonymization", {}).get("rule_lists", [])
|
|
109
|
-
|
|
110
|
-
rule_set = set()
|
|
111
|
-
for rule_list in rule_lists:
|
|
112
|
-
rule_id = rule_list.get("id")
|
|
113
|
-
if rule_id in rule_set:
|
|
114
|
-
raise RasaException(
|
|
115
|
-
f"Invalid configuration for `anonymization_rules` :"
|
|
116
|
-
f"Duplicate rule id: '{rule_id}' encountered in rule_lists"
|
|
117
|
-
)
|
|
118
|
-
rule_set.add(rule_id)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{aI as o,aJ as r}from"./index-3a23e736.js";const s=(a,n)=>o.lang.round(r.parse(a)[n]),e=s;export{e as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{c as r}from"./graph-4ede11ff.js";var e=4;function a(o){return r(o,e)}export{a as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{p as e,f as o}from"./flowDb-956e92f1-10044f05.js";import{f as t,g as a}from"./styles-c10674c1-7b3680cf.js";import{u as i}from"./index-3a23e736.js";import"./graph-4ede11ff.js";import"./layout-dd48f7f4.js";import"./index-3862675e-65549d37.js";import"./clone-edb7f119.js";import"./edges-e0da2a9e-5a8b0749.js";import"./createText-2e5e7dd3-87c4ece5.js";import"./line-1569ad2c.js";import"./array-9f3ba611.js";import"./path-53f90ab3.js";import"./channel-dfa68278.js";const M={parser:e,db:o,renderer:t,styles:a,init:r=>{r.flowchart||(r.flowchart={}),r.flowchart.arrowMarkerAbsolute=r.arrowMarkerAbsolute,i({flowchart:{arrowMarkerAbsolute:r.arrowMarkerAbsolute}}),t.setConf(r.flowchart),o.clear(),o.setGen("gen-2")}};export{M as diagram};
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
const bufferSize = 4096
|
|
2
|
-
const sampleRate = 8000
|
|
3
|
-
const audioOptions = {
|
|
4
|
-
audio: {
|
|
5
|
-
echoCancellation: true,
|
|
6
|
-
noiseSuppression: true,
|
|
7
|
-
autoGainControl: true
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const arrayBufferToBase64 = ( buffer: ArrayBuffer ): string => {
|
|
12
|
-
let binary = '';
|
|
13
|
-
const bytes = new Uint8Array( buffer );
|
|
14
|
-
const len = bytes.byteLength;
|
|
15
|
-
for (let i = 0; i < len; i++) {
|
|
16
|
-
binary += String.fromCharCode( bytes[ i ] );
|
|
17
|
-
}
|
|
18
|
-
return window.btoa( binary );
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const base64ToArrayBuffer = ( s: string ): ArrayBuffer => {
|
|
22
|
-
const binary_string = window.atob(s);
|
|
23
|
-
const len = binary_string.length;
|
|
24
|
-
const bytes = new Uint8Array( len );
|
|
25
|
-
for (let i = 0; i < len; i++) {
|
|
26
|
-
bytes[i] = binary_string.charCodeAt(i);
|
|
27
|
-
}
|
|
28
|
-
return bytes.buffer;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const floatToIntArray = (arr: Float32Array): Int32Array => {
|
|
32
|
-
// Convert Float Array [-1, 1] to full range int array
|
|
33
|
-
return Int32Array.from(arr, x => x * 0x7fffffff)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const intToFloatArray = (arr: Int32Array): Float32Array => {
|
|
37
|
-
return Float32Array.from(arr, x => (x / 0x7fffffff))
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
interface Mark {
|
|
41
|
-
id: string
|
|
42
|
-
bytesToGo: number
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
interface AudioQueue {
|
|
46
|
-
buffer: Float32Array;
|
|
47
|
-
marks: Array<Mark>
|
|
48
|
-
socket: WebSocket,
|
|
49
|
-
write: (newAudio: Float32Array) => void;
|
|
50
|
-
read: (nSamples: number) => Float32Array;
|
|
51
|
-
length: () => number;
|
|
52
|
-
addMarker: (id: string) => void;
|
|
53
|
-
reduceMarkers: (bytesRead: number) => void;
|
|
54
|
-
popMarkers: () => void;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const createAudioQueue = (socket: WebSocket) : AudioQueue => {
|
|
59
|
-
return {
|
|
60
|
-
buffer: new Float32Array(0),
|
|
61
|
-
marks: new Array<Mark>(),
|
|
62
|
-
socket,
|
|
63
|
-
|
|
64
|
-
write: function(newAudio: Float32Array) {
|
|
65
|
-
const currentQLength = this.buffer.length;
|
|
66
|
-
const newBuffer = new Float32Array(currentQLength + newAudio.length);
|
|
67
|
-
newBuffer.set(this.buffer, 0);
|
|
68
|
-
newBuffer.set(newAudio, currentQLength);
|
|
69
|
-
this.buffer = newBuffer;
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
read: function(nSamples: number) {
|
|
73
|
-
const samplesToPlay = this.buffer.subarray(0, nSamples);
|
|
74
|
-
this.buffer = this.buffer.subarray(nSamples, this.buffer.length);
|
|
75
|
-
this.reduceMarkers(samplesToPlay.length)
|
|
76
|
-
this.popMarkers()
|
|
77
|
-
return samplesToPlay;
|
|
78
|
-
},
|
|
79
|
-
|
|
80
|
-
length: function() {
|
|
81
|
-
return this.buffer.length;
|
|
82
|
-
},
|
|
83
|
-
|
|
84
|
-
addMarker: function(id: string) {
|
|
85
|
-
this.marks.push({id, bytesToGo: this.length()})
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
reduceMarkers: function(bytesRead: number) {
|
|
89
|
-
this.marks = this.marks.map((m) => {
|
|
90
|
-
return {id: m.id, bytesToGo: m.bytesToGo - bytesRead}
|
|
91
|
-
})
|
|
92
|
-
},
|
|
93
|
-
|
|
94
|
-
popMarkers: function() {
|
|
95
|
-
// marks are ordered
|
|
96
|
-
let popUpTo = 0;
|
|
97
|
-
while (popUpTo < this.marks.length) {
|
|
98
|
-
if (this.marks[popUpTo].bytesToGo <= 0) {
|
|
99
|
-
popUpTo += 1
|
|
100
|
-
} else {
|
|
101
|
-
break
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
const marksToPop = this.marks.slice(0, popUpTo)
|
|
105
|
-
this.marks = this.marks.slice(popUpTo, this.marks.length)
|
|
106
|
-
marksToPop.forEach((m) => {
|
|
107
|
-
this.socket.send(JSON.stringify({marker: m.id}))
|
|
108
|
-
})
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const streamMicrophoneToServer = async (socket: WebSocket) => {
|
|
115
|
-
let audioStream = null;
|
|
116
|
-
const audioContext = new AudioContext({sampleRate});
|
|
117
|
-
|
|
118
|
-
try {
|
|
119
|
-
audioStream = await navigator.mediaDevices.getUserMedia(audioOptions);
|
|
120
|
-
const audioInput = audioContext.createMediaStreamSource(audioStream)
|
|
121
|
-
const sender = audioContext.createScriptProcessor(bufferSize, 1, 1)
|
|
122
|
-
sender.onaudioprocess = function(event) {
|
|
123
|
-
const message = JSON.stringify({
|
|
124
|
-
"audio": arrayBufferToBase64(floatToIntArray(event.inputBuffer.getChannelData(0)).buffer)
|
|
125
|
-
})
|
|
126
|
-
socket.send(message)
|
|
127
|
-
}
|
|
128
|
-
audioInput.connect(sender)
|
|
129
|
-
sender.connect(audioContext.destination)
|
|
130
|
-
} catch (err) {
|
|
131
|
-
console.error(err);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const setupAudioPlayback = (socket: WebSocket): AudioQueue => {
|
|
136
|
-
const audioQueue = createAudioQueue(socket)
|
|
137
|
-
const silence = new Float32Array(bufferSize)
|
|
138
|
-
const audioOutputContext = new AudioContext({sampleRate})
|
|
139
|
-
const scriptNode = audioOutputContext.createScriptProcessor(bufferSize, 1, 1);
|
|
140
|
-
scriptNode.onaudioprocess = function(e) {
|
|
141
|
-
const audioData = audioQueue.length() ? audioQueue.read(bufferSize) : silence
|
|
142
|
-
e.outputBuffer.getChannelData(0).set(audioData);
|
|
143
|
-
}
|
|
144
|
-
scriptNode.connect(audioOutputContext.destination)
|
|
145
|
-
return audioQueue
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const addDataToAudioQueue = (audioQueue: AudioQueue) => (message: MessageEvent<any>) => {
|
|
149
|
-
const data = JSON.parse(message.data.toString())
|
|
150
|
-
if (data["audio"]) {
|
|
151
|
-
const audioBytes = base64ToArrayBuffer(data["audio"])
|
|
152
|
-
const audioData = intToFloatArray(new Int32Array(audioBytes))
|
|
153
|
-
audioQueue.write(audioData);
|
|
154
|
-
} else if (data["marker"]) {
|
|
155
|
-
audioQueue.addMarker(data["marker"])
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Constructs a WebSocket URL for browser audio from a base HTTP/HTTPS URL
|
|
161
|
-
*
|
|
162
|
-
* @param baseUrl - The base URL (e.g., "https://example.com" or "http://localhost:5005")
|
|
163
|
-
* @returns WebSocket URL for browser audio endpoint
|
|
164
|
-
*
|
|
165
|
-
* @example
|
|
166
|
-
* getWebSocketUrl("https://example.com")
|
|
167
|
-
* // Returns: "wss://example.com/webhooks/browser_audio/websocket"
|
|
168
|
-
*
|
|
169
|
-
* getWebSocketUrl("http://localhost:5005")
|
|
170
|
-
* // Returns: "ws://localhost:5005/webhooks/browser_audio/websocket"
|
|
171
|
-
*
|
|
172
|
-
* @throws {TypeError} If baseUrl is not a valid URL
|
|
173
|
-
*/
|
|
174
|
-
export function getWebSocketUrl(baseUrl: string) {
|
|
175
|
-
const url = new URL(baseUrl);
|
|
176
|
-
const wsProtocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
177
|
-
return `${wsProtocol}//${url.host}/webhooks/browser_audio/websocket`;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Creates a WebSocket connection for browser audio and streams microphone input to the server
|
|
182
|
-
*
|
|
183
|
-
* @param baseUrl - The base URL (e.g., "https://example.com" or "http://localhost:5005")
|
|
184
|
-
*/
|
|
185
|
-
export async function createAudioConnection(baseUrl: string) {
|
|
186
|
-
const websocketURL = getWebSocketUrl(baseUrl)
|
|
187
|
-
const socket = new WebSocket(websocketURL)
|
|
188
|
-
socket.onopen = async () => { await streamMicrophoneToServer(socket)}
|
|
189
|
-
const audioQueue = setupAudioPlayback(socket)
|
|
190
|
-
socket.onmessage = addDataToAudioQueue(audioQueue)
|
|
191
|
-
}
|