rasa-pro 3.13.0.dev7__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.

Files changed (150) hide show
  1. rasa/__main__.py +0 -3
  2. rasa/api.py +1 -1
  3. rasa/cli/dialogue_understanding_test.py +1 -1
  4. rasa/cli/e2e_test.py +1 -1
  5. rasa/cli/evaluate.py +1 -1
  6. rasa/cli/export.py +1 -1
  7. rasa/cli/llm_fine_tuning.py +12 -11
  8. rasa/cli/project_templates/defaults.py +133 -0
  9. rasa/cli/run.py +1 -1
  10. rasa/cli/studio/link.py +53 -0
  11. rasa/cli/studio/pull.py +78 -0
  12. rasa/cli/studio/push.py +78 -0
  13. rasa/cli/studio/studio.py +12 -0
  14. rasa/cli/studio/upload.py +8 -0
  15. rasa/cli/train.py +1 -1
  16. rasa/cli/utils.py +1 -1
  17. rasa/cli/x.py +1 -1
  18. rasa/constants.py +2 -0
  19. rasa/core/__init__.py +0 -16
  20. rasa/core/actions/action.py +5 -1
  21. rasa/core/actions/action_repeat_bot_messages.py +18 -22
  22. rasa/core/actions/action_run_slot_rejections.py +0 -1
  23. rasa/core/agent.py +16 -1
  24. rasa/core/available_endpoints.py +146 -0
  25. rasa/core/brokers/pika.py +1 -2
  26. rasa/core/channels/botframework.py +2 -2
  27. rasa/core/channels/channel.py +2 -2
  28. rasa/core/channels/hangouts.py +8 -5
  29. rasa/core/channels/mattermost.py +1 -1
  30. rasa/core/channels/rasa_chat.py +2 -4
  31. rasa/core/channels/rest.py +5 -4
  32. rasa/core/channels/studio_chat.py +3 -2
  33. rasa/core/channels/vier_cvg.py +1 -2
  34. rasa/core/channels/voice_ready/audiocodes.py +1 -8
  35. rasa/core/channels/voice_stream/audiocodes.py +7 -4
  36. rasa/core/channels/voice_stream/genesys.py +2 -2
  37. rasa/core/channels/voice_stream/twilio_media_streams.py +10 -5
  38. rasa/core/channels/voice_stream/voice_channel.py +33 -22
  39. rasa/core/http_interpreter.py +3 -7
  40. rasa/core/jobs.py +2 -1
  41. rasa/core/nlg/contextual_response_rephraser.py +34 -9
  42. rasa/core/nlg/generator.py +0 -1
  43. rasa/core/nlg/interpolator.py +2 -3
  44. rasa/core/nlg/summarize.py +39 -5
  45. rasa/core/policies/enterprise_search_policy.py +283 -62
  46. rasa/core/policies/enterprise_search_prompt_with_relevancy_check_and_citation_template.jinja2 +63 -0
  47. rasa/core/policies/flow_policy.py +1 -1
  48. rasa/core/policies/flows/flow_executor.py +96 -17
  49. rasa/core/policies/intentless_policy.py +9 -7
  50. rasa/core/processor.py +104 -51
  51. rasa/core/run.py +33 -11
  52. rasa/core/tracker_stores/tracker_store.py +1 -1
  53. rasa/core/training/interactive.py +1 -1
  54. rasa/core/utils.py +24 -97
  55. rasa/dialogue_understanding/coexistence/intent_based_router.py +2 -1
  56. rasa/dialogue_understanding/commands/can_not_handle_command.py +2 -0
  57. rasa/dialogue_understanding/commands/cancel_flow_command.py +2 -0
  58. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +2 -0
  59. rasa/dialogue_understanding/commands/clarify_command.py +5 -1
  60. rasa/dialogue_understanding/commands/command_syntax_manager.py +1 -0
  61. rasa/dialogue_understanding/commands/human_handoff_command.py +2 -0
  62. rasa/dialogue_understanding/commands/knowledge_answer_command.py +4 -2
  63. rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +2 -0
  64. rasa/dialogue_understanding/commands/set_slot_command.py +11 -1
  65. rasa/dialogue_understanding/commands/skip_question_command.py +2 -0
  66. rasa/dialogue_understanding/commands/start_flow_command.py +4 -0
  67. rasa/dialogue_understanding/commands/utils.py +26 -2
  68. rasa/dialogue_understanding/generator/__init__.py +7 -1
  69. rasa/dialogue_understanding/generator/command_generator.py +4 -2
  70. rasa/dialogue_understanding/generator/command_parser.py +2 -2
  71. rasa/dialogue_understanding/generator/command_parser_validator.py +63 -0
  72. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +12 -33
  73. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +78 -0
  74. rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +26 -461
  75. rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +147 -0
  76. rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +477 -0
  77. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +8 -58
  78. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +37 -25
  79. rasa/dialogue_understanding/patterns/domain_for_patterns.py +190 -0
  80. rasa/dialogue_understanding/processor/command_processor.py +3 -3
  81. rasa/dialogue_understanding/processor/command_processor_component.py +3 -3
  82. rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +17 -4
  83. rasa/dialogue_understanding/utils.py +68 -12
  84. rasa/dialogue_understanding_test/du_test_case.py +1 -1
  85. rasa/dialogue_understanding_test/du_test_runner.py +4 -22
  86. rasa/dialogue_understanding_test/test_case_simulation/test_case_tracker_simulator.py +2 -6
  87. rasa/e2e_test/e2e_test_runner.py +1 -1
  88. rasa/engine/constants.py +1 -1
  89. rasa/engine/recipes/default_recipe.py +26 -2
  90. rasa/engine/validation.py +3 -2
  91. rasa/hooks.py +0 -28
  92. rasa/llm_fine_tuning/annotation_module.py +39 -9
  93. rasa/llm_fine_tuning/conversations.py +3 -0
  94. rasa/llm_fine_tuning/llm_data_preparation_module.py +66 -49
  95. rasa/llm_fine_tuning/paraphrasing/rephrase_validator.py +52 -44
  96. rasa/llm_fine_tuning/paraphrasing_module.py +10 -12
  97. rasa/llm_fine_tuning/storage.py +4 -4
  98. rasa/llm_fine_tuning/utils.py +63 -1
  99. rasa/model_manager/model_api.py +88 -0
  100. rasa/model_manager/trainer_service.py +4 -4
  101. rasa/plugin.py +1 -11
  102. rasa/privacy/__init__.py +0 -0
  103. rasa/privacy/constants.py +83 -0
  104. rasa/privacy/event_broker_utils.py +77 -0
  105. rasa/privacy/privacy_config.py +281 -0
  106. rasa/privacy/privacy_config_schema.json +86 -0
  107. rasa/privacy/privacy_filter.py +340 -0
  108. rasa/privacy/privacy_manager.py +576 -0
  109. rasa/server.py +23 -2
  110. rasa/shared/constants.py +3 -0
  111. rasa/shared/core/constants.py +4 -3
  112. rasa/shared/core/domain.py +7 -0
  113. rasa/shared/core/events.py +37 -7
  114. rasa/shared/core/flows/flow.py +1 -2
  115. rasa/shared/core/flows/flows_yaml_schema.json +3 -0
  116. rasa/shared/core/flows/steps/collect.py +46 -2
  117. rasa/shared/core/slots.py +28 -0
  118. rasa/shared/exceptions.py +4 -0
  119. rasa/shared/utils/llm.py +161 -6
  120. rasa/shared/utils/yaml.py +32 -0
  121. rasa/studio/data_handler.py +3 -3
  122. rasa/studio/download/download.py +37 -60
  123. rasa/studio/download/flows.py +23 -31
  124. rasa/studio/link.py +200 -0
  125. rasa/studio/pull.py +94 -0
  126. rasa/studio/push.py +131 -0
  127. rasa/studio/upload.py +117 -67
  128. rasa/telemetry.py +82 -25
  129. rasa/tracing/config.py +3 -4
  130. rasa/tracing/constants.py +19 -1
  131. rasa/tracing/instrumentation/attribute_extractors.py +10 -2
  132. rasa/tracing/instrumentation/instrumentation.py +53 -2
  133. rasa/tracing/instrumentation/metrics.py +98 -15
  134. rasa/tracing/metric_instrument_provider.py +75 -3
  135. rasa/utils/common.py +1 -27
  136. rasa/utils/log_utils.py +1 -45
  137. rasa/validator.py +2 -8
  138. rasa/version.py +1 -1
  139. {rasa_pro-3.13.0.dev7.dist-info → rasa_pro-3.13.0.dev8.dist-info}/METADATA +5 -6
  140. {rasa_pro-3.13.0.dev7.dist-info → rasa_pro-3.13.0.dev8.dist-info}/RECORD +143 -129
  141. rasa/anonymization/__init__.py +0 -2
  142. rasa/anonymization/anonymisation_rule_yaml_reader.py +0 -91
  143. rasa/anonymization/anonymization_pipeline.py +0 -286
  144. rasa/anonymization/anonymization_rule_executor.py +0 -266
  145. rasa/anonymization/anonymization_rule_orchestrator.py +0 -119
  146. rasa/anonymization/schemas/config.yml +0 -47
  147. rasa/anonymization/utils.py +0 -118
  148. {rasa_pro-3.13.0.dev7.dist-info → rasa_pro-3.13.0.dev8.dist-info}/NOTICE +0 -0
  149. {rasa_pro-3.13.0.dev7.dist-info → rasa_pro-3.13.0.dev8.dist-info}/WHEEL +0 -0
  150. {rasa_pro-3.13.0.dev7.dist-info → rasa_pro-3.13.0.dev8.dist-info}/entry_points.txt +0 -0
@@ -105,7 +105,6 @@ def run_rejections(
105
105
  structlogger.error(
106
106
  "run.predicate.error",
107
107
  predicate=condition,
108
- document=document,
109
108
  error=str(e),
110
109
  )
111
110
  violation = True
rasa/core/agent.py CHANGED
@@ -13,6 +13,7 @@ from aiohttp import ClientError
13
13
 
14
14
  import rasa.shared.utils.io
15
15
  from rasa.core import jobs
16
+ from rasa.core.available_endpoints import AvailableEndpoints
16
17
  from rasa.core.channels.channel import OutputChannel, UserMessage
17
18
  from rasa.core.constants import DEFAULT_REQUEST_TIMEOUT
18
19
  from rasa.core.exceptions import AgentNotReady
@@ -27,13 +28,14 @@ from rasa.core.tracker_stores.tracker_store import (
27
28
  InMemoryTrackerStore,
28
29
  TrackerStore,
29
30
  )
30
- from rasa.core.utils import AvailableEndpoints
31
31
  from rasa.exceptions import ModelNotFound
32
32
  from rasa.nlu.utils import is_url
33
+ from rasa.privacy.privacy_manager import BackgroundPrivacyManager
33
34
  from rasa.shared.constants import DEFAULT_SENDER_ID
34
35
  from rasa.shared.core.domain import Domain
35
36
  from rasa.shared.core.trackers import DialogueStateTracker, EventVerbosity
36
37
  from rasa.shared.exceptions import RasaException
38
+ from rasa.telemetry import track_privacy_enabled
37
39
  from rasa.utils.common import TempDirectoryPath, get_temp_dir_name
38
40
  from rasa.utils.endpoints import EndpointConfig
39
41
 
@@ -222,6 +224,7 @@ async def load_agent(
222
224
  generator = None
223
225
  action_endpoint = None
224
226
  http_interpreter = None
227
+ privacy_manager = None
225
228
 
226
229
  if endpoints:
227
230
  broker = await EventBroker.create(endpoints.event_broker, loop=loop)
@@ -234,6 +237,12 @@ async def load_agent(
234
237
  model_server = endpoints.model if endpoints.model else model_server
235
238
  if endpoints.nlu:
236
239
  http_interpreter = RasaNLUHttpInterpreter(endpoints.nlu)
240
+ if endpoints.privacy:
241
+ privacy_manager = await BackgroundPrivacyManager.create_instance(
242
+ endpoints=endpoints,
243
+ event_loop=loop,
244
+ )
245
+ track_privacy_enabled(privacy_manager.config, broker)
237
246
 
238
247
  agent = Agent(
239
248
  generator=generator,
@@ -244,6 +253,7 @@ async def load_agent(
244
253
  remote_storage=remote_storage,
245
254
  http_interpreter=http_interpreter,
246
255
  endpoints=endpoints,
256
+ privacy_manager=privacy_manager,
247
257
  )
248
258
 
249
259
  try:
@@ -306,6 +316,7 @@ class Agent:
306
316
  remote_storage: Optional[StorageType] = None,
307
317
  http_interpreter: Optional[RasaNLUHttpInterpreter] = None,
308
318
  endpoints: Optional[AvailableEndpoints] = None,
319
+ privacy_manager: Optional[BackgroundPrivacyManager] = None,
309
320
  ):
310
321
  """Initializes an `Agent`."""
311
322
  self.domain = domain
@@ -321,6 +332,7 @@ class Agent:
321
332
  self._set_fingerprint(fingerprint)
322
333
  self.model_server = model_server
323
334
  self.remote_storage = remote_storage
335
+ self.privacy_manager = privacy_manager
324
336
 
325
337
  @classmethod
326
338
  def load(
@@ -336,6 +348,7 @@ class Agent:
336
348
  remote_storage: Optional[StorageType] = None,
337
349
  http_interpreter: Optional[RasaNLUHttpInterpreter] = None,
338
350
  endpoints: Optional[AvailableEndpoints] = None,
351
+ privacy_manager: Optional[BackgroundPrivacyManager] = None,
339
352
  ) -> Agent:
340
353
  """Constructs a new agent and loads the processor and model."""
341
354
  agent = Agent(
@@ -349,6 +362,7 @@ class Agent:
349
362
  remote_storage=remote_storage,
350
363
  http_interpreter=http_interpreter,
351
364
  endpoints=endpoints,
365
+ privacy_manager=privacy_manager,
352
366
  )
353
367
  agent.load_model(model_path=model_path, fingerprint=fingerprint)
354
368
  return agent
@@ -365,6 +379,7 @@ class Agent:
365
379
  generator=self.nlg,
366
380
  http_interpreter=self.http_interpreter,
367
381
  endpoints=self.endpoints,
382
+ privacy_manager=self.privacy_manager,
368
383
  )
369
384
  self.domain = self.processor.domain
370
385
 
@@ -0,0 +1,146 @@
1
+ from __future__ import annotations
2
+
3
+ import dataclasses
4
+ from typing import Any, Dict, List, Optional, Union
5
+
6
+ from rasa.shared.constants import DEFAULT_ENDPOINTS_PATH
7
+ from rasa.shared.core.constants import (
8
+ GLOBAL_SILENCE_TIMEOUT_DEFAULT_VALUE,
9
+ GLOBAL_SILENCE_TIMEOUT_KEY,
10
+ )
11
+ from rasa.shared.exceptions import RasaException
12
+ from rasa.utils.endpoints import (
13
+ EndpointConfig,
14
+ read_endpoint_config,
15
+ read_property_config_from_endpoints_file,
16
+ )
17
+
18
+
19
+ @dataclasses.dataclass
20
+ class InteractionHandlingConfig:
21
+ """Configuration for interaction handling."""
22
+
23
+ global_silence_timeout: Union[float, int] = GLOBAL_SILENCE_TIMEOUT_DEFAULT_VALUE
24
+
25
+ def __post_init__(self) -> None:
26
+ # Validate the type of `global_silence_timeout`.
27
+ if isinstance(self.global_silence_timeout, str):
28
+ try:
29
+ self.global_silence_timeout = float(self.global_silence_timeout)
30
+ except ValueError:
31
+ raise RasaException(
32
+ f"Type for {GLOBAL_SILENCE_TIMEOUT_KEY} is wrong, expected number. "
33
+ f"Got: '{self.global_silence_timeout}'. "
34
+ )
35
+
36
+ if not isinstance(self.global_silence_timeout, (float, int)):
37
+ raise RasaException(
38
+ f"Type for {GLOBAL_SILENCE_TIMEOUT_KEY} is wrong, expected number. "
39
+ f"Got: '{type(self.global_silence_timeout)}'. "
40
+ )
41
+
42
+ if self.global_silence_timeout <= 0:
43
+ raise RasaException(
44
+ f"Value for {GLOBAL_SILENCE_TIMEOUT_KEY} must be a positive number. "
45
+ f"Got: '{self.global_silence_timeout}'. "
46
+ )
47
+
48
+ @classmethod
49
+ def from_dict(cls, data: Optional[Dict[str, Any]]) -> InteractionHandlingConfig:
50
+ """Create a InteractionHandlingConfig instance from a dictionary."""
51
+ return cls(
52
+ global_silence_timeout=data.get(
53
+ GLOBAL_SILENCE_TIMEOUT_KEY, GLOBAL_SILENCE_TIMEOUT_DEFAULT_VALUE
54
+ )
55
+ if data is not None
56
+ else GLOBAL_SILENCE_TIMEOUT_DEFAULT_VALUE
57
+ )
58
+
59
+
60
+ class AvailableEndpoints:
61
+ """Collection of configured endpoints."""
62
+
63
+ _instance = None
64
+
65
+ @classmethod
66
+ def read_endpoints(cls, endpoint_file: str) -> AvailableEndpoints:
67
+ """Read the different endpoints from a yaml file."""
68
+ nlg = read_endpoint_config(endpoint_file, endpoint_type="nlg")
69
+ nlu = read_endpoint_config(endpoint_file, endpoint_type="nlu")
70
+ action = read_endpoint_config(endpoint_file, endpoint_type="action_endpoint")
71
+ model = read_endpoint_config(endpoint_file, endpoint_type="models")
72
+ tracker_store = read_endpoint_config(
73
+ endpoint_file, endpoint_type="tracker_store"
74
+ )
75
+ lock_store = read_endpoint_config(endpoint_file, endpoint_type="lock_store")
76
+ event_broker = read_endpoint_config(endpoint_file, endpoint_type="event_broker")
77
+ vector_store = read_endpoint_config(endpoint_file, endpoint_type="vector_store")
78
+ model_groups = read_property_config_from_endpoints_file(
79
+ endpoint_file, property_name="model_groups"
80
+ )
81
+ privacy = read_property_config_from_endpoints_file(
82
+ endpoint_file, property_name="privacy"
83
+ )
84
+
85
+ interaction_handling = InteractionHandlingConfig.from_dict(
86
+ read_property_config_from_endpoints_file(
87
+ endpoint_file, property_name="interaction_handling"
88
+ )
89
+ )
90
+
91
+ return cls(
92
+ nlg,
93
+ nlu,
94
+ action,
95
+ model,
96
+ tracker_store,
97
+ lock_store,
98
+ event_broker,
99
+ vector_store,
100
+ model_groups,
101
+ privacy,
102
+ interaction_handling,
103
+ )
104
+
105
+ def __init__(
106
+ self,
107
+ nlg: Optional[EndpointConfig] = None,
108
+ nlu: Optional[EndpointConfig] = None,
109
+ action: Optional[EndpointConfig] = None,
110
+ model: Optional[EndpointConfig] = None,
111
+ tracker_store: Optional[EndpointConfig] = None,
112
+ lock_store: Optional[EndpointConfig] = None,
113
+ event_broker: Optional[EndpointConfig] = None,
114
+ vector_store: Optional[EndpointConfig] = None,
115
+ model_groups: Optional[List[Dict[str, Any]]] = None,
116
+ privacy: Optional[Dict[str, Any]] = None,
117
+ interaction_handling: InteractionHandlingConfig = InteractionHandlingConfig(
118
+ global_silence_timeout=GLOBAL_SILENCE_TIMEOUT_DEFAULT_VALUE
119
+ ),
120
+ ) -> None:
121
+ """Create an `AvailableEndpoints` object."""
122
+ self.model = model
123
+ self.action = action
124
+ self.nlu = nlu
125
+ self.nlg = nlg
126
+ self.tracker_store = tracker_store
127
+ self.lock_store = lock_store
128
+ self.event_broker = event_broker
129
+ self.vector_store = vector_store
130
+ self.model_groups = model_groups
131
+ self.privacy = privacy
132
+ self.interaction_handling = interaction_handling
133
+
134
+ @classmethod
135
+ def get_instance(
136
+ cls, endpoint_file: Optional[str] = DEFAULT_ENDPOINTS_PATH
137
+ ) -> AvailableEndpoints:
138
+ """Get the singleton instance of AvailableEndpoints."""
139
+ # Ensure that the instance is initialized only once.
140
+ if cls._instance is None:
141
+ cls._instance = cls.read_endpoints(endpoint_file)
142
+ return cls._instance
143
+
144
+ @classmethod
145
+ def reset_instance(cls) -> None:
146
+ cls._instance = None
rasa/core/brokers/pika.py CHANGED
@@ -316,9 +316,8 @@ class PikaEventBroker(EventBroker):
316
316
  except Exception as e:
317
317
  structlogger.error(
318
318
  "pika.events.publish.failed",
319
- event_info="Logging a reduced version of the failed Pika event",
319
+ event_info=f"Failed to publish Pika event. Error: {e}",
320
320
  host=self.host,
321
- rasa_event=reduced_event,
322
321
  )
323
322
  if self.should_keep_unpublished_messages:
324
323
  self._unpublished_events.append(event)
@@ -115,8 +115,8 @@ class BotFramework(OutputChannel):
115
115
 
116
116
  if not send_response.ok:
117
117
  logger.error(
118
- "Error trying to send botframework messge. Response: %s",
119
- send_response.text,
118
+ "Error trying to send botframework messge. "
119
+ f"Error: {send_response.reason}"
120
120
  )
121
121
 
122
122
  async def send_text_message(
@@ -103,7 +103,7 @@ class UserMessage:
103
103
 
104
104
 
105
105
  def register(
106
- input_channels: List["InputChannel"], app: Sanic, route: Optional[Text]
106
+ input_channels: List[InputChannel], app: Sanic, route: Optional[Text]
107
107
  ) -> None:
108
108
  """Registers input channel blueprints with Sanic."""
109
109
 
@@ -129,7 +129,7 @@ class InputChannel:
129
129
  return cls.__name__
130
130
 
131
131
  @classmethod
132
- def from_credentials(cls, credentials: Optional[Dict[Text, Any]]) -> "InputChannel":
132
+ def from_credentials(cls, credentials: Optional[Dict[Text, Any]]) -> InputChannel:
133
133
  return cls()
134
134
 
135
135
  def url_prefix(self) -> Text:
@@ -1,4 +1,3 @@
1
- import copy
2
1
  import logging
3
2
  from asyncio import CancelledError
4
3
  from typing import Any, Awaitable, Callable, Dict, Iterable, List, Optional, Text, Union
@@ -314,13 +313,17 @@ class HangoutsInput(InputChannel):
314
313
  metadata={"room": room_name},
315
314
  )
316
315
  )
317
- except CancelledError:
316
+ except CancelledError as e:
318
317
  structlogger.error(
319
- "hangouts.message.blueprint.timeout", text=copy.deepcopy(text)
318
+ "hangouts.message.blueprint.timeout",
319
+ event_info=f"Message processing was cancelled. Error: {e}",
320
320
  )
321
- except Exception:
321
+ except Exception as e:
322
322
  structlogger.exception(
323
- "hangouts.message.blueprint.failure", text=copy.deepcopy(text)
323
+ "hangouts.message.blueprint.failure",
324
+ event_info=(
325
+ f"An error occurred while processing the message. Error: {e}",
326
+ ),
324
327
  )
325
328
 
326
329
  return response.json(collector.messages)
@@ -28,7 +28,7 @@ class MattermostBot(OutputChannel):
28
28
  if r.status_code == 200:
29
29
  return r.headers["Token"]
30
30
  else:
31
- logger.error(f"Failed to login mattermost user {user}. Response: {r}")
31
+ logger.error(f"Failed to login mattermost user. Response: {r}")
32
32
  return None
33
33
 
34
34
  def __init__(
@@ -107,10 +107,8 @@ class RasaChatInput(RestInput):
107
107
  return req.json[CONVERSATION_ID_KEY]
108
108
  else:
109
109
  logger.error(
110
- "User '{}' does not have permissions to send messages to "
111
- "conversation '{}'.".format(
112
- jwt_payload[JWT_USERNAME_KEY], req.json[CONVERSATION_ID_KEY]
113
- )
110
+ "User does not have permissions to send messages to "
111
+ "conversation '{}'.".format(req.json[CONVERSATION_ID_KEY])
114
112
  )
115
113
  raise SanicException(status_code=401)
116
114
 
@@ -1,5 +1,4 @@
1
1
  import asyncio
2
- import copy
3
2
  import inspect
4
3
  import json
5
4
  import logging
@@ -166,11 +165,13 @@ class RestInput(InputChannel):
166
165
  )
167
166
  except CancelledError:
168
167
  structlogger.error(
169
- "rest.message.received.timeout", text=copy.deepcopy(text)
168
+ "rest.message.received.timeout",
169
+ event_info="Message processing was cancelled.",
170
170
  )
171
- except Exception:
171
+ except Exception as e:
172
172
  structlogger.exception(
173
- "rest.message.received.failure", text=copy.deepcopy(text)
173
+ "rest.message.received.failure",
174
+ event_info=f"Message processing failed. Error: {e}",
174
175
  )
175
176
 
176
177
  return response.json(collector.messages)
@@ -83,7 +83,9 @@ class StudioTrackerUpdatePlugin:
83
83
 
84
84
  def handle_tracker_update(self, tracker: "DialogueStateTracker") -> None:
85
85
  """Handles a tracker update when triggered by a hook."""
86
- structlogger.info("studio_chat.after_tracker_update", tracker=tracker)
86
+ structlogger.info(
87
+ "studio_chat.after_tracker_update", sender_id=tracker.sender_id
88
+ )
87
89
  # directly create a dump to avoid the tracker getting modified by another
88
90
  # function before it gets published (since the publishing is scheduled
89
91
  # as an async task)
@@ -185,7 +187,6 @@ class StudioChatInput(SocketIOInput):
185
187
  output_channel = self.get_output_channel()
186
188
 
187
189
  await processor._run_prediction_loop(output_channel, tracker)
188
- await processor.run_anonymization_pipeline(tracker)
189
190
  await self.agent.tracker_store.save(tracker)
190
191
 
191
192
  await self.on_tracker_updated(tracker)
@@ -129,9 +129,8 @@ class CVGOutput(OutputChannel):
129
129
  )
130
130
 
131
131
  logger.info(
132
- "Creating incoming UserMessage: {text=%s, output_channel=%s, sender_id=%s, metadata=%s}" # noqa: E501
132
+ "Creating incoming UserMessage: {output_channel=%s, sender_id=%s, metadata=%s}" # noqa: E501
133
133
  % (
134
- user_message.text,
135
134
  user_message.output_channel,
136
135
  user_message.sender_id,
137
136
  user_message.metadata,
@@ -193,16 +193,9 @@ class Conversation:
193
193
  try:
194
194
  await on_new_message(user_msg)
195
195
  except Exception as e: # skipcq: PYL-W0703
196
- if isinstance(user_msg.text, dict):
197
- anonymized_info = json.dumps(user_msg.text)
198
- elif isinstance(user_msg.text, str):
199
- anonymized_info = user_msg.text
200
- else:
201
- anonymized_info = INFO_UNKNOWN
202
-
203
196
  structlogger.exception(
204
197
  "audiocodes.handle.activities.failure",
205
- user_message=copy.deepcopy(anonymized_info),
198
+ sender_id=self.conversation_id,
206
199
  error=e,
207
200
  exc_info=True,
208
201
  )
@@ -108,15 +108,19 @@ class AudiocodesVoiceInputChannel(VoiceInputChannel):
108
108
  server_url: str,
109
109
  asr_config: Dict,
110
110
  tts_config: Dict,
111
- monitor_silence: bool = False,
112
111
  ):
113
112
  mark_as_beta_feature("Audiocodes (audiocodes_stream) Channel")
114
- super().__init__(server_url, asr_config, tts_config, monitor_silence)
113
+ super().__init__(
114
+ server_url=server_url,
115
+ asr_config=asr_config,
116
+ tts_config=tts_config,
117
+ )
115
118
  self.token = token
116
119
 
117
120
  @classmethod
118
121
  def from_credentials(
119
- cls, credentials: Optional[Dict[str, Any]]
122
+ cls,
123
+ credentials: Optional[Dict[str, Any]],
120
124
  ) -> VoiceInputChannel:
121
125
  if not credentials:
122
126
  raise ValueError("No credentials given for Audiocodes voice channel.")
@@ -126,7 +130,6 @@ class AudiocodesVoiceInputChannel(VoiceInputChannel):
126
130
  server_url=credentials["server_url"],
127
131
  asr_config=credentials["asr"],
128
132
  tts_config=credentials["tts"],
129
- monitor_silence=credentials.get("monitor_silence", False),
130
133
  )
131
134
 
132
135
  def channel_bytes_to_rasa_audio_bytes(self, input_bytes: bytes) -> RasaAudioBytes:
@@ -99,7 +99,8 @@ class GenesysInputChannel(VoiceInputChannel):
99
99
 
100
100
  @classmethod
101
101
  def from_credentials(
102
- cls, credentials: Optional[Dict[str, Any]]
102
+ cls,
103
+ credentials: Optional[Dict[str, Any]],
103
104
  ) -> VoiceInputChannel:
104
105
  if not credentials:
105
106
  raise ValueError("No credentials given for Genesys voice channel.")
@@ -113,7 +114,6 @@ class GenesysInputChannel(VoiceInputChannel):
113
114
  server_url=credentials["server_url"],
114
115
  asr_config=credentials["asr"],
115
116
  tts_config=credentials["tts"],
116
- monitor_silence=credentials.get("monitor_silence", False),
117
117
  )
118
118
 
119
119
  def _ensure_channel_data_initialized(self) -> None:
@@ -14,7 +14,7 @@ from sanic import ( # type: ignore[attr-defined]
14
14
  response,
15
15
  )
16
16
 
17
- from rasa.core.channels import InputChannel, UserMessage
17
+ from rasa.core.channels import UserMessage
18
18
  from rasa.core.channels.channel import (
19
19
  create_auth_requested_response_provider,
20
20
  requires_basic_auth,
@@ -102,16 +102,22 @@ class TwilioMediaStreamsInputChannel(VoiceInputChannel):
102
102
  server_url: str,
103
103
  asr_config: Dict,
104
104
  tts_config: Dict,
105
- monitor_silence: bool = False,
106
105
  username: Optional[Text] = None,
107
106
  password: Optional[Text] = None,
108
107
  ):
109
- super().__init__(server_url, asr_config, tts_config, monitor_silence)
108
+ super().__init__(
109
+ server_url=server_url,
110
+ asr_config=asr_config,
111
+ tts_config=tts_config,
112
+ )
110
113
  self.username = username
111
114
  self.password = password
112
115
 
113
116
  @classmethod
114
- def from_credentials(cls, credentials: Optional[Dict[str, Any]]) -> InputChannel:
117
+ def from_credentials(
118
+ cls,
119
+ credentials: Optional[Dict[str, Any]],
120
+ ) -> VoiceInputChannel:
115
121
  credentials = credentials or {}
116
122
 
117
123
  username = credentials.get("username")
@@ -126,7 +132,6 @@ class TwilioMediaStreamsInputChannel(VoiceInputChannel):
126
132
  credentials["server_url"],
127
133
  credentials["asr"],
128
134
  credentials["tts"],
129
- credentials.get("monitor_silence", False),
130
135
  username=username,
131
136
  password=password,
132
137
  )
@@ -31,8 +31,10 @@ from rasa.core.channels.voice_stream.tts.azure import AzureTTS
31
31
  from rasa.core.channels.voice_stream.tts.cartesia import CartesiaTTS
32
32
  from rasa.core.channels.voice_stream.tts.tts_cache import TTSCache
33
33
  from rasa.core.channels.voice_stream.tts.tts_engine import TTSEngine, TTSError
34
- from rasa.core.channels.voice_stream.util import generate_silence
35
- from rasa.shared.core.constants import SLOT_SILENCE_TIMEOUT
34
+ from rasa.core.channels.voice_stream.util import (
35
+ generate_silence,
36
+ )
37
+ from rasa.shared.core.constants import SILENCE_TIMEOUT_SLOT
36
38
  from rasa.shared.utils.cli import print_error_and_exit
37
39
  from rasa.shared.utils.common import (
38
40
  class_from_module_path,
@@ -171,8 +173,12 @@ class VoiceOutputChannel(OutputChannel):
171
173
  def update_silence_timeout(self) -> None:
172
174
  """Updates the silence timeout for the session."""
173
175
  if self.tracker_state:
174
- call_state.silence_timeout = ( # type: ignore[attr-defined]
175
- self.tracker_state["slots"][SLOT_SILENCE_TIMEOUT]
176
+ call_state.silence_timeout = self.tracker_state["slots"][ # type: ignore[attr-defined]
177
+ SILENCE_TIMEOUT_SLOT
178
+ ]
179
+ logger.debug(
180
+ "voice_channel.silence_timeout_updated",
181
+ silence_timeout=call_state.silence_timeout,
176
182
  )
177
183
 
178
184
  async def send_text_with_buttons(
@@ -285,21 +291,24 @@ class VoiceInputChannel(InputChannel):
285
291
  server_url: str,
286
292
  asr_config: Dict,
287
293
  tts_config: Dict,
288
- monitor_silence: bool = False,
289
294
  ):
290
295
  validate_voice_license_scope()
291
296
  self.server_url = server_url
292
297
  self.asr_config = asr_config
293
298
  self.tts_config = tts_config
294
- self.monitor_silence = monitor_silence
295
299
  self.tts_cache = TTSCache(tts_config.get("cache_size", 1000))
296
300
 
301
+ logger.info(
302
+ "voice_channel.initialized",
303
+ server_url=self.server_url,
304
+ asr_config=self.asr_config,
305
+ tts_config=self.tts_config,
306
+ )
307
+
297
308
  async def monitor_silence_timeout(self, asr_event_queue: asyncio.Queue) -> None:
298
309
  timeout = call_state.silence_timeout
299
310
  if not timeout:
300
311
  return
301
- if not self.monitor_silence:
302
- return
303
312
  logger.debug("voice_channel.silence_timeout_watch_started", timeout=timeout)
304
313
  await asyncio.sleep(timeout)
305
314
  await asr_event_queue.put(UserSilence())
@@ -314,13 +323,15 @@ class VoiceInputChannel(InputChannel):
314
323
  call_state.silence_timeout_watcher = None # type: ignore[attr-defined]
315
324
 
316
325
  @classmethod
317
- def from_credentials(cls, credentials: Optional[Dict[str, Any]]) -> InputChannel:
326
+ def from_credentials(
327
+ cls,
328
+ credentials: Optional[Dict[str, Any]],
329
+ ) -> InputChannel:
318
330
  credentials = credentials or {}
319
331
  return cls(
320
332
  credentials["server_url"],
321
333
  credentials["asr"],
322
334
  credentials["tts"],
323
- credentials.get("monitor_silence", False),
324
335
  )
325
336
 
326
337
  def channel_bytes_to_rasa_audio_bytes(self, input_bytes: bytes) -> RasaAudioBytes:
@@ -340,9 +351,9 @@ class VoiceInputChannel(InputChannel):
340
351
  ) -> None:
341
352
  output_channel = self.create_output_channel(channel_websocket, tts_engine)
342
353
  message = UserMessage(
343
- USER_CONVERSATION_SESSION_START,
344
- output_channel,
345
- call_parameters.stream_id,
354
+ text=USER_CONVERSATION_SESSION_START,
355
+ output_channel=output_channel,
356
+ sender_id=call_parameters.stream_id,
346
357
  input_channel=self.name(),
347
358
  metadata=asdict(call_parameters),
348
359
  )
@@ -377,17 +388,17 @@ class VoiceInputChannel(InputChannel):
377
388
 
378
389
  async def consume_audio_bytes() -> None:
379
390
  async for message in channel_websocket:
380
- is_bot_speaking_before = call_state.is_bot_speaking
391
+ was_bot_speaking_before = call_state.is_bot_speaking
381
392
  channel_action = self.map_input_message(message, channel_websocket)
382
393
  is_bot_speaking_after = call_state.is_bot_speaking
383
394
 
384
- if not is_bot_speaking_before and is_bot_speaking_after:
395
+ if not was_bot_speaking_before and is_bot_speaking_after:
385
396
  logger.debug("voice_channel.bot_started_speaking")
386
397
  # relevant when the bot speaks multiple messages in one turn
387
398
  self._cancel_silence_timeout_watcher()
388
399
 
389
400
  # we just stopped speaking, starting a watcher for silence timeout
390
- if is_bot_speaking_before and not is_bot_speaking_after:
401
+ if was_bot_speaking_before and not is_bot_speaking_after:
391
402
  logger.debug("voice_channel.bot_stopped_speaking")
392
403
  self._cancel_silence_timeout_watcher()
393
404
  call_state.silence_timeout_watcher = ( # type: ignore[attr-defined]
@@ -458,9 +469,9 @@ class VoiceInputChannel(InputChannel):
458
469
  call_state.is_user_speaking = False # type: ignore[attr-defined]
459
470
  output_channel = self.create_output_channel(voice_websocket, tts_engine)
460
471
  message = UserMessage(
461
- e.text,
462
- output_channel,
463
- call_parameters.stream_id,
472
+ text=e.text,
473
+ output_channel=output_channel,
474
+ sender_id=call_parameters.stream_id,
464
475
  input_channel=self.name(),
465
476
  metadata=asdict(call_parameters),
466
477
  )
@@ -471,9 +482,9 @@ class VoiceInputChannel(InputChannel):
471
482
  elif isinstance(e, UserSilence):
472
483
  output_channel = self.create_output_channel(voice_websocket, tts_engine)
473
484
  message = UserMessage(
474
- USER_CONVERSATION_SILENCE_TIMEOUT,
475
- output_channel,
476
- call_parameters.stream_id,
485
+ text=USER_CONVERSATION_SILENCE_TIMEOUT,
486
+ output_channel=output_channel,
487
+ sender_id=call_parameters.stream_id,
477
488
  input_channel=self.name(),
478
489
  metadata=asdict(call_parameters),
479
490
  )