rasa-pro 3.12.8__py3-none-any.whl → 3.12.10__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.

@@ -898,7 +898,7 @@ class RemoteAction(Action):
898
898
  draft["buttons"].extend(buttons)
899
899
 
900
900
  # Avoid overwriting `draft` values with empty values
901
- response = {k: v for k, v in response.items() if v}
901
+ response = {k: v for k, v in response.items() if v is not None}
902
902
  draft.update(response)
903
903
  bot_messages.append(create_bot_utterance(draft))
904
904
 
@@ -16,6 +16,7 @@ import structlog
16
16
  from sanic import Sanic
17
17
 
18
18
  from rasa.core.channels.socketio import SocketBlueprint, SocketIOInput
19
+ from rasa.core.exceptions import AgentNotReady
19
20
  from rasa.hooks import hookimpl
20
21
  from rasa.plugin import plugin_manager
21
22
  from rasa.shared.core.constants import ACTION_LISTEN_NAME
@@ -149,8 +150,15 @@ class StudioChatInput(SocketIOInput):
149
150
  """
150
151
  await on_new_message(message)
151
152
 
152
- if not self.agent:
153
+ if not self.agent or not self.agent.is_ready():
153
154
  structlogger.error("studio_chat.on_message_proxy.agent_not_initialized")
155
+ await self.emit_error(
156
+ "The Rasa Pro model could not be loaded. "
157
+ "Please check the training and deployment logs "
158
+ "for more information.",
159
+ message.sender_id,
160
+ AgentNotReady("The Rasa Pro model could not be loaded."),
161
+ )
154
162
  return
155
163
 
156
164
  tracker = await self.agent.tracker_store.retrieve(message.sender_id)
@@ -160,6 +168,17 @@ class StudioChatInput(SocketIOInput):
160
168
 
161
169
  await self.on_tracker_updated(tracker)
162
170
 
171
+ async def emit_error(self, message: str, room: str, e: Exception) -> None:
172
+ await self.emit(
173
+ "error",
174
+ {
175
+ "message": message,
176
+ "error": str(e),
177
+ "exception": str(type(e).__name__),
178
+ },
179
+ room=room,
180
+ )
181
+
163
182
  async def handle_tracker_update(self, sid: str, data: Dict) -> None:
164
183
  from rasa.shared.core.trackers import DialogueStateTracker
165
184
 
@@ -200,15 +219,12 @@ class StudioChatInput(SocketIOInput):
200
219
  error=e,
201
220
  sender_id=data["sender_id"],
202
221
  )
203
- await self.emit(
204
- "error",
205
- {
206
- "message": "An error occurred while updating the conversation.",
207
- "error": str(e),
208
- "exception": str(type(e).__name__),
209
- },
210
- room=sid,
222
+ await self.emit_error(
223
+ "An error occurred while updating the conversation.",
224
+ data["sender_id"],
225
+ e,
211
226
  )
227
+
212
228
  if not tracker:
213
229
  # in case the tracker couldn't be updated, we retrieve the prior
214
230
  # version and use that to populate the update
@@ -6,7 +6,18 @@ import uuid
6
6
  from collections import defaultdict
7
7
  from dataclasses import asdict
8
8
  from datetime import datetime, timedelta, timezone
9
- from typing import Any, Awaitable, Callable, Dict, List, Optional, Set, Text, Union
9
+ from typing import (
10
+ Any,
11
+ Awaitable,
12
+ Callable,
13
+ Dict,
14
+ List,
15
+ Optional,
16
+ Set,
17
+ Text,
18
+ Tuple,
19
+ Union,
20
+ )
10
21
 
11
22
  import structlog
12
23
  from jsonschema import ValidationError, validate
@@ -76,35 +87,45 @@ class Conversation:
76
87
 
77
88
  @staticmethod
78
89
  def get_metadata(activity: Dict[Text, Any]) -> Optional[Dict[Text, Any]]:
79
- """Get metadata from the activity."""
80
- return asdict(map_call_params(activity["parameters"]))
90
+ """Get metadata from the activity.
91
+
92
+ ONLY used for activities NOT for events (see _handle_event)."""
93
+ return activity.get("parameters")
81
94
 
82
95
  @staticmethod
83
- def _handle_event(event: Dict[Text, Any]) -> Text:
84
- """Handle start and DTMF event and return the corresponding text."""
96
+ def _handle_event(event: Dict[Text, Any]) -> Tuple[Text, Dict[Text, Any]]:
97
+ """Handle events and return a tuple of text and metadata.
98
+
99
+ Args:
100
+ event: The event to handle.
101
+
102
+ Returns:
103
+ Tuple of text and metadata.
104
+ text is either /session_start or /vaig_event_<event_name>
105
+ metadata is a dictionary with the event parameters.
106
+ """
85
107
  structlogger.debug("audiocodes.handle.event", event_payload=event)
86
108
  if "name" not in event:
87
109
  structlogger.warning(
88
110
  "audiocodes.handle.event.no_name_key", event_payload=event
89
111
  )
90
- return ""
112
+ return "", {}
91
113
 
92
114
  if event["name"] == EVENT_START:
93
115
  text = f"{INTENT_MESSAGE_PREFIX}{USER_INTENT_SESSION_START}"
116
+ metadata = asdict(map_call_params(event.get("parameters", {})))
94
117
  elif event["name"] == EVENT_DTMF:
95
118
  text = f"{INTENT_MESSAGE_PREFIX}vaig_event_DTMF"
96
- event_params = {"value": event["value"]}
97
- text += json.dumps(event_params)
119
+ metadata = {"value": event["value"]}
98
120
  else:
99
121
  # handle other events described by Audiocodes
100
122
  # https://techdocs.audiocodes.com/voice-ai-connect/#VAIG_Combined/inactivity-detection.htm?TocPath=Bot%2520integration%257CReceiving%2520notifications%257C_____3
101
123
  text = f"{INTENT_MESSAGE_PREFIX}vaig_event_{event['name']}"
102
- event_params = {**event.get("parameters", {})}
124
+ metadata = {**event.get("parameters", {})}
103
125
  if "value" in event:
104
- event_params["value"] = event["value"]
105
- text += json.dumps(event_params)
126
+ metadata["value"] = event["value"]
106
127
 
107
- return text
128
+ return text, metadata
108
129
 
109
130
  def is_active_conversation(self, now: datetime, delta: timedelta) -> bool:
110
131
  """Check if the conversation is active."""
@@ -139,21 +160,29 @@ class Conversation:
139
160
  structlogger.warning(
140
161
  "audiocodes.handle.activities.duplicate_activity",
141
162
  activity_id=activity[ACTIVITY_ID_KEY],
163
+ event_info=(
164
+ "Audiocodes might send duplicate activities if the bot has not "
165
+ "responded to the previous one or responded too late. Please "
166
+ "consider enabling the `use_websocket` option to use"
167
+ " Audiocodes Asynchronous API."
168
+ ),
142
169
  )
143
170
  continue
144
171
  self.activity_ids.append(activity[ACTIVITY_ID_KEY])
145
172
  if activity["type"] == ACTIVITY_MESSAGE:
146
173
  text = activity["text"]
174
+ metadata = self.get_metadata(activity)
147
175
  elif activity["type"] == ACTIVITY_EVENT:
148
- text = self._handle_event(activity)
176
+ text, metadata = self._handle_event(activity)
149
177
  else:
150
178
  structlogger.warning(
151
179
  "audiocodes.handle.activities.unknown_activity_type",
152
180
  activity=activity,
153
181
  )
182
+ continue
183
+
154
184
  if not text:
155
185
  continue
156
- metadata = self.get_metadata(activity)
157
186
  user_msg = UserMessage(
158
187
  text=text,
159
188
  input_channel=input_channel_name,
@@ -392,30 +421,41 @@ class AudiocodesInput(InputChannel):
392
421
  "audiocodes.on_activities.no_conversation", request=request.json
393
422
  )
394
423
  return response.json({})
395
- elif conversation.ws:
424
+
425
+ if self.use_websocket:
426
+ # send an empty response for this request
427
+ # activities are processed in the background
428
+ # chat response is sent via the websocket
396
429
  ac_output: Union[WebsocketOutput, AudiocodesOutput] = WebsocketOutput(
397
430
  conversation.ws, conversation_id
398
431
  )
399
- response_json = {}
400
- else:
401
- # handle non websocket case where messages get returned in json
402
- ac_output = AudiocodesOutput()
403
- response_json = {
432
+ self._create_task(
433
+ conversation_id,
434
+ conversation.handle_activities(
435
+ request.json,
436
+ input_channel_name=self.name(),
437
+ output_channel=ac_output,
438
+ on_new_message=on_new_message,
439
+ ),
440
+ )
441
+ return response.json({})
442
+
443
+ # without websockets, this becomes a blocking call
444
+ # and the response is sent back to the Audiocodes server
445
+ # after the activities are processed
446
+ ac_output = AudiocodesOutput()
447
+ await conversation.handle_activities(
448
+ request.json,
449
+ input_channel_name=self.name(),
450
+ output_channel=ac_output,
451
+ on_new_message=on_new_message,
452
+ )
453
+ return response.json(
454
+ {
404
455
  "conversation": conversation_id,
405
456
  "activities": ac_output.messages,
406
457
  }
407
-
408
- # start a background task to handle activities
409
- self._create_task(
410
- conversation_id,
411
- conversation.handle_activities(
412
- request.json,
413
- input_channel_name=self.name(),
414
- output_channel=ac_output,
415
- on_new_message=on_new_message,
416
- ),
417
458
  )
418
- return response.json(response_json)
419
459
 
420
460
  @ac_webhook.route(
421
461
  "/conversation/<conversation_id>/disconnect", methods=["POST"]
@@ -38,6 +38,7 @@ from rasa.shared.core.flows.flow_step_sequence import FlowStepSequence
38
38
  from rasa.shared.core.flows.nlu_trigger import NLUTriggers
39
39
  from rasa.shared.core.flows.steps import (
40
40
  ActionFlowStep,
41
+ CallFlowStep,
41
42
  CollectInformationFlowStep,
42
43
  EndFlowStep,
43
44
  StartFlowStep,
@@ -466,161 +467,156 @@ class Flow:
466
467
  and a set of visited step IDs to prevent revisiting steps.
467
468
  It calls `go_over_steps` to recursively explore and fill the paths list.
468
469
  """
469
- flow_paths_list = FlowPathsList(self.id, paths=[])
470
- steps: List[FlowStep] = self.steps
470
+ all_paths = FlowPathsList(self.id, paths=[])
471
+ start_step: FlowStep = self.first_step_in_flow()
471
472
  current_path: FlowPath = FlowPath(flow=self.id, nodes=[])
472
- step_ids_visited: Set[str] = set()
473
+ visited_step_ids: Set[str] = set()
473
474
 
474
- self._go_over_steps(steps, current_path, flow_paths_list, step_ids_visited)
475
-
476
- if not flow_paths_list.is_path_part_of_list(current_path):
477
- flow_paths_list.paths.append(copy.deepcopy(current_path))
475
+ self._go_over_steps(start_step, current_path, all_paths, visited_step_ids)
478
476
 
479
477
  structlogger.debug(
480
478
  "shared.core.flows.flow.extract_all_paths",
481
479
  comment="Extraction complete",
482
- number_of_paths=len(flow_paths_list.paths),
480
+ number_of_paths=len(all_paths.paths),
483
481
  flow_name=self.name,
484
482
  )
485
- return flow_paths_list
483
+ return all_paths
486
484
 
487
485
  def _go_over_steps(
488
486
  self,
489
- steps_to_go: Union[str, List[FlowStep]],
487
+ current_step: FlowStep,
490
488
  current_path: FlowPath,
491
- completed_paths: FlowPathsList,
492
- step_ids_visited: Set[str],
489
+ all_paths: FlowPathsList,
490
+ visited_step_ids: Set[str],
493
491
  ) -> None:
494
492
  """Processes the flow steps recursively.
495
493
 
496
- Either following direct step IDs or handling conditions, and adds complete
497
- paths to the collected_paths.
498
-
499
494
  Args:
500
- steps_to_go: Either a direct step ID or a list of steps to process.
495
+ current_step: The current step being processed.
501
496
  current_path: The current path being constructed.
502
- completed_paths: The list where completed paths are added.
503
- step_ids_visited: A set of step IDs that have been visited to avoid cycles.
497
+ all_paths: The list where completed paths are added.
498
+ visited_step_ids: A set of steps that have been visited to avoid cycles.
504
499
 
505
500
  Returns:
506
- None: This function modifies collected_paths in place by appending new paths
501
+ None: This function modifies all_paths in place by appending new paths
507
502
  as they are found.
508
503
  """
509
- # Case 1: If the steps_to_go is a custom_id string
510
- # This happens when a "next" of, for example, a IfFlowStepLink is targeting
511
- # a specific step by id
512
- if isinstance(steps_to_go, str):
513
- for i, step in enumerate(self.steps):
514
- # We don't need to check for 'id' as a link can only happen to a
515
- # custom id.
516
- if step.custom_id == steps_to_go:
517
- self._go_over_steps(
518
- self.steps[i:], current_path, completed_paths, step_ids_visited
519
- )
520
-
521
- # Case 2: If steps_to_go is a list of steps
522
- else:
523
- for i, step in enumerate(steps_to_go):
524
- # 1. Check if the step is relevant for testable_paths extraction.
525
- # We only create new path nodes for ActionFlowStep and
526
- # CollectInformationFlowStep because these are externally visible
527
- # changes in the assistant's behaviour (trackable in the e2e tests).
528
- # For other flow steps, we only follow their links.
529
- # We decided to ignore calls to other flows in our coverage analysis.
530
- if not isinstance(step, (CollectInformationFlowStep, ActionFlowStep)):
531
- self._handle_links(
532
- step.next.links,
533
- current_path,
534
- completed_paths,
535
- step_ids_visited,
536
- )
537
- continue
538
-
539
- # 2. Check if already visited this custom step id
540
- # in order to keep track of loops
541
- if step.custom_id is not None and step.custom_id in step_ids_visited:
542
- if not completed_paths.is_path_part_of_list(current_path):
543
- completed_paths.paths.append(copy.deepcopy(current_path))
544
- return # Stop traversing this path if we've revisited a step
545
- elif step.custom_id is not None:
546
- step_ids_visited.add(step.custom_id)
547
-
548
- # 3. Append step info to the path
549
- current_path.nodes.append(
550
- PathNode(
551
- flow=current_path.flow,
552
- step_id=step.id,
553
- lines=step.metadata["line_numbers"],
554
- )
504
+ # Check if the step is relevant for testable_paths extraction.
505
+ # We only create new path nodes for ActionFlowStep, CallFlowStep and
506
+ # CollectInformationFlowStep because these are externally visible
507
+ # changes in the assistant's behaviour (trackable in the e2e tests).
508
+ # For other flow steps, we only follow their links.
509
+ # We decided to ignore calls to other flows in our coverage analysis.
510
+ should_add_node = isinstance(
511
+ current_step, (CollectInformationFlowStep, ActionFlowStep, CallFlowStep)
512
+ )
513
+ if should_add_node:
514
+ # Add current step to the current path that is being constructed.
515
+ current_path.nodes.append(
516
+ PathNode(
517
+ flow=current_path.flow,
518
+ step_id=current_step.id,
519
+ lines=current_step.metadata["line_numbers"],
555
520
  )
521
+ )
556
522
 
557
- # 4. Check if 'END' branch
558
- if (
559
- len(step.next.links) == 1
560
- and isinstance(step.next.links[0], StaticFlowStepLink)
561
- and step.next.links[0].target == END_STEP
562
- ):
563
- if not completed_paths.is_path_part_of_list(current_path):
564
- completed_paths.paths.append(copy.deepcopy(current_path))
565
- return
566
- else:
567
- self._handle_links(
568
- step.next.links,
569
- current_path,
570
- completed_paths,
571
- step_ids_visited,
572
- )
523
+ if current_step.id in visited_step_ids or self.is_end_of_path(current_step):
524
+ # Found a cycle, or reached an end step, do not proceed further.
525
+ all_paths.paths.append(copy.deepcopy(current_path))
526
+ # Remove the last node from the path if it was added.
527
+ if should_add_node:
528
+ current_path.nodes.pop()
529
+ return
530
+
531
+ # Mark current step as visited in this path.
532
+ visited_step_ids.add(current_step.id)
533
+
534
+ # Iterate over all links of the current step.
535
+ for link in current_step.next.links:
536
+ self._handle_link(
537
+ current_path,
538
+ all_paths,
539
+ visited_step_ids,
540
+ link,
541
+ )
542
+
543
+ # Backtrack the current step and remove it from the path.
544
+ visited_step_ids.remove(current_step.id)
573
545
 
574
- def _handle_links(
546
+ # Remove the last node from the path if it was added.
547
+ if should_add_node:
548
+ current_path.nodes.pop()
549
+
550
+ def _handle_link(
575
551
  self,
576
- links: List[FlowStepLink],
577
- path: FlowPath,
578
- collected_paths: FlowPathsList,
579
- step_ids_visited: set,
552
+ current_path: FlowPath,
553
+ all_paths: FlowPathsList,
554
+ visited_step_ids: Set[str],
555
+ link: FlowStepLink,
580
556
  ) -> None:
581
- """Processes the next step in a flow.
582
-
583
- Potentially recursively calling itself to handle conditional paths and
584
- branching.
557
+ """Handles the next step in a flow.
585
558
 
586
559
  Args:
587
- links: Links listed in the "next" attribute.
588
- path: The current path taken in the flow.
589
- collected_paths: A list of paths collected so far.
590
- step_ids_visited: A set of step IDs that have already been visited
591
- to avoid loops.
560
+ current_path: The current path being constructed.
561
+ all_paths: The list where completed paths are added.
562
+ visited_step_ids: A set of steps that have been visited to avoid cycles.
563
+ link: The link to be followed.
592
564
 
593
565
  Returns:
594
- None: Modifies collected_paths in place by appending new paths
595
- as they are completed.
566
+ None: This function modifies all_paths in place by appending new paths
567
+ as they are found.
596
568
  """
597
- steps = self.steps
598
-
599
- for link in links:
600
- # Direct step id reference
601
- if isinstance(link, StaticFlowStepLink):
602
- # Find this id in the flow steps and restart from there
603
- for i, step in enumerate(steps):
604
- if step.id == link.target_step_id:
605
- self._go_over_steps(
606
- steps[i:],
607
- copy.deepcopy(path),
608
- collected_paths,
609
- copy.deepcopy(step_ids_visited),
610
- )
611
-
612
- # If conditions
613
- elif isinstance(link, (IfFlowStepLink, ElseFlowStepLink)):
614
- # Handling conditional paths
615
- target_steps: Union[str, List[FlowStep]]
616
- if isinstance(link.target_reference, FlowStepSequence):
617
- target_steps = link.target_reference.child_steps
618
- else:
619
- target_steps = link.target_reference
620
-
569
+ # StaticFlowStepLink is a direct link to the next step.
570
+ if isinstance(link, StaticFlowStepLink):
571
+ # Find the step by its id and continue the path.
572
+ if step := self._get_step_by_step_id(link.target_step_id):
621
573
  self._go_over_steps(
622
- target_steps,
623
- copy.deepcopy(path),
624
- collected_paths,
625
- copy.deepcopy(step_ids_visited),
574
+ step,
575
+ current_path,
576
+ all_paths,
577
+ visited_step_ids,
626
578
  )
579
+ return
580
+ # IfFlowStepLink and ElseFlowStepLink are conditional links.
581
+ elif isinstance(link, (IfFlowStepLink, ElseFlowStepLink)):
582
+ if isinstance(link.target_reference, FlowStepSequence):
583
+ # If the target is a FlowStepSequence, we need to go over all
584
+ # child steps of the sequence.
585
+ for child_step in link.target_reference.child_steps:
586
+ self._go_over_steps(
587
+ child_step,
588
+ current_path,
589
+ all_paths,
590
+ visited_step_ids,
591
+ )
592
+ return
593
+ else:
594
+ # Find the step by its id and continue the path.
595
+ if step := self._get_step_by_step_id(link.target_reference):
596
+ self._go_over_steps(
597
+ step,
598
+ current_path,
599
+ all_paths,
600
+ visited_step_ids,
601
+ )
602
+ return
603
+
604
+ def is_end_of_path(self, step: FlowStep) -> bool:
605
+ """Check if there is no path available from the current step."""
606
+ if (
607
+ len(step.next.links) == 1
608
+ and isinstance(step.next.links[0], StaticFlowStepLink)
609
+ and step.next.links[0].target == END_STEP
610
+ ):
611
+ return True
612
+ return False
613
+
614
+ def _get_step_by_step_id(
615
+ self,
616
+ step_id: Optional[str],
617
+ ) -> Optional[FlowStep]:
618
+ """Get a step by its id from a list of steps."""
619
+ for step in self.steps:
620
+ if step.id == step_id:
621
+ return step
622
+ return None
rasa/version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  # this file will automatically be changed,
2
2
  # do not add anything but the version number here!
3
- __version__ = "3.12.8"
3
+ __version__ = "3.12.10"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rasa-pro
3
- Version: 3.12.8
3
+ Version: 3.12.10
4
4
  Summary: State-of-the-art open-core Conversational AI framework for Enterprises that natively leverages generative AI for effortless assistant development.
5
5
  Keywords: nlp,machine-learning,machine-learning-library,bot,bots,botkit,rasa conversational-agents,conversational-ai,chatbot,chatbot-framework,bot-framework
6
6
  Author: Rasa Technologies GmbH
@@ -63,12 +63,12 @@ Requires-Dist: keras (==2.14.0)
63
63
  Requires-Dist: langchain (>=0.2.17,<0.3.0)
64
64
  Requires-Dist: langchain-community (>=0.2.19,<0.3.0)
65
65
  Requires-Dist: langcodes (>=3.5.0,<4.0.0)
66
- Requires-Dist: litellm (==1.52.6)
66
+ Requires-Dist: litellm (>=1.68.0,<1.69.0)
67
67
  Requires-Dist: matplotlib (>=3.7,<3.8)
68
68
  Requires-Dist: mattermostwrapper (>=2.2,<2.3)
69
69
  Requires-Dist: networkx (>=3.1,<3.2)
70
70
  Requires-Dist: numpy (>=1.26.4,<1.27.0)
71
- Requires-Dist: openai (>=1.55.3,<1.56.0)
71
+ Requires-Dist: openai (>=1.68.2,<1.69.0)
72
72
  Requires-Dist: openpyxl (>=3.1.5,<4.0.0)
73
73
  Requires-Dist: opentelemetry-api (>=1.16.0,<1.17.0)
74
74
  Requires-Dist: opentelemetry-exporter-jaeger (>=1.16.0,<1.17.0)
@@ -92,7 +92,7 @@ rasa/cli/x.py,sha256=C7dLtYXAkD-uj7hNj7Pz5YbOupp2yRcMjQbsEVqXUJ8,6825
92
92
  rasa/constants.py,sha256=m6If7alC5obaHU-JQWXEBo4mooVwIMzNRTjyTzzZSVg,1306
93
93
  rasa/core/__init__.py,sha256=wTSmsFlgK0Ylvuyq20q9APwpT5xyVJYZfzhs4rrkciM,456
94
94
  rasa/core/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
95
- rasa/core/actions/action.py,sha256=2mDvSi1pSWipDWhprEFjDXf-X9yoID9DQEvmf0rQcJM,42664
95
+ rasa/core/actions/action.py,sha256=_QfY3ngSF2sf2Y3QDPJo7Nd6F_FA6_zDWgw1OQSLkEk,42676
96
96
  rasa/core/actions/action_clean_stack.py,sha256=xUP-2ipPsPAnAiwP17c-ezmHPSrV4JSUZr-eSgPQwIs,2279
97
97
  rasa/core/actions/action_exceptions.py,sha256=hghzXYN6VeHC-O_O7WiPesCNV86ZTkHgG90ZnQcbai8,724
98
98
  rasa/core/actions/action_hangup.py,sha256=o5iklHG-F9IcRgWis5C6AumVXznxzAV3o9zdduhozEM,994
@@ -263,12 +263,12 @@ rasa/core/channels/rest.py,sha256=ShKGmooXphhcDnHyV8TiQhDhj2r7hxTKNQ57FwFfyUA,72
263
263
  rasa/core/channels/rocketchat.py,sha256=hajaH6549CjEYFM5jSapw1DQKBPKTXbn7cVSuZzknmI,5999
264
264
  rasa/core/channels/slack.py,sha256=jVsTTUu9wUjukPoIsAhbee9o0QFUMCNlQHbR8LTcMBc,24406
265
265
  rasa/core/channels/socketio.py,sha256=Q7Gts30Ulwj90pQQxaUk4NykzagXErXgbHYwOjTmDig,10842
266
- rasa/core/channels/studio_chat.py,sha256=R5lOgOjgf-loXHvH8crN9zI_MSM_y_GV-rs7yoAqnYw,8661
266
+ rasa/core/channels/studio_chat.py,sha256=KUhR0Irst8pJ7zGMoeZuKquAUOYVB45i75wlVsbDqPU,9218
267
267
  rasa/core/channels/telegram.py,sha256=TKVknsk3U9tYeY1a8bzlhqkltWmZfGSOvrcmwa9qozc,12499
268
268
  rasa/core/channels/twilio.py,sha256=2BTQpyx0b0yPpc0A2BHYfxLPgodrLGLs8nq6i3lVGAM,5906
269
269
  rasa/core/channels/vier_cvg.py,sha256=GkrWKu7NRMFtLMyYp-kQ2taWAc_keAwhYrkVPW56iaU,13544
270
270
  rasa/core/channels/voice_ready/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
271
- rasa/core/channels/voice_ready/audiocodes.py,sha256=luO0e-azKlkwnWZ9bQWBF2DlkNHvEAkIQTb8HuouqGQ,21130
271
+ rasa/core/channels/voice_ready/audiocodes.py,sha256=eUUL9awt4P49LA5WC2hbsMZsi_qYHd-S3HL1Kpyj2ew,22353
272
272
  rasa/core/channels/voice_ready/jambonz.py,sha256=bU2yrO6Gw_JcmFXeFVc8f1DK3ZDDYLQVjBB8SM2JjWc,4783
273
273
  rasa/core/channels/voice_ready/jambonz_protocol.py,sha256=E9iwvitSDpVkL7BxbckczF4b0a8lWZt-3zR4Innflow,13116
274
274
  rasa/core/channels/voice_ready/twilio_voice.py,sha256=z2pdausxQnXQP9htGh8AL2q9AvcMIx70Y5tErWpssV4,16224
@@ -633,7 +633,7 @@ rasa/shared/core/domain.py,sha256=piJu4Kr2exC9ehC3e2oNaxPxXkeIhOYoQJQQOuzMw18,81
633
633
  rasa/shared/core/events.py,sha256=kTUWSpDepj3kpjjXveYXz3h2XcIQV3Sq8h7MTbx5fMw,86489
634
634
  rasa/shared/core/flows/__init__.py,sha256=Z4pBY0qcEbHeOwgmKsyg2Nz4dX9CF67fFCwj2KXSMpg,180
635
635
  rasa/shared/core/flows/constants.py,sha256=0HN3k-apOb_fi8E2AJtUxMxro8jwFVyXQpil-tHEzbM,340
636
- rasa/shared/core/flows/flow.py,sha256=6RQvDdXNq1FTPKCjZc7wAWZ__eYiJYpvIH2-vQyukG0,23817
636
+ rasa/shared/core/flows/flow.py,sha256=nW7EvfWBS9eK24GIodDUwwKY8nTaJtY6bp5Xz_IHZAc,23107
637
637
  rasa/shared/core/flows/flow_path.py,sha256=xstwahZBU5cfMY46mREA4NoOGlKLBRAqeP_mJ3UZqOI,2283
638
638
  rasa/shared/core/flows/flow_step.py,sha256=ZvjXz1Fs5FR1_BlGBitOEYRnLhzk-bBYv1CC2Oi6iWQ,4537
639
639
  rasa/shared/core/flows/flow_step_links.py,sha256=U9c4MFASieJGp_-XMhR0hrxFQISCJAF4TQ0wEy4IjB0,10530
@@ -821,9 +821,9 @@ rasa/utils/train_utils.py,sha256=ClJx-6x3-h3Vt6mskacgkcCUJTMXjFPe3zAcy_DfmaU,212
821
821
  rasa/utils/url_tools.py,sha256=dZ1HGkVdWTJB7zYEdwoDIrEuyX9HE5WsxKKFVsXBLE0,1218
822
822
  rasa/utils/yaml.py,sha256=KjbZq5C94ZP7Jdsw8bYYF7HASI6K4-C_kdHfrnPLpSI,2000
823
823
  rasa/validator.py,sha256=524VlFTYK0B3iXYveVD6BDC3K0j1QfpzJ9O-TAWczmc,83166
824
- rasa/version.py,sha256=4_StAMhYosjvoGJPgxlRzBM43d8EqzHR-GKhgvaRhfs,117
825
- rasa_pro-3.12.8.dist-info/METADATA,sha256=ENGQIeta0oCP7JdIAJFaQbGm76dbJ0w1I5zdifONzUo,10607
826
- rasa_pro-3.12.8.dist-info/NOTICE,sha256=7HlBoMHJY9CL2GlYSfTQ-PZsVmLmVkYmMiPlTjhuCqA,218
827
- rasa_pro-3.12.8.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
828
- rasa_pro-3.12.8.dist-info/entry_points.txt,sha256=ckJ2SfEyTPgBqj_I6vm_tqY9dZF_LAPJZA335Xp0Q9U,43
829
- rasa_pro-3.12.8.dist-info/RECORD,,
824
+ rasa/version.py,sha256=F6TWQP94ECROLtXqlCrwu9xSrvxZDs3JVTp6gPLbxfE,118
825
+ rasa_pro-3.12.10.dist-info/METADATA,sha256=3wU4IxYsMJruxuysovjfW1wt7IOsh0YELYX4uvwhDhY,10616
826
+ rasa_pro-3.12.10.dist-info/NOTICE,sha256=7HlBoMHJY9CL2GlYSfTQ-PZsVmLmVkYmMiPlTjhuCqA,218
827
+ rasa_pro-3.12.10.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
828
+ rasa_pro-3.12.10.dist-info/entry_points.txt,sha256=ckJ2SfEyTPgBqj_I6vm_tqY9dZF_LAPJZA335Xp0Q9U,43
829
+ rasa_pro-3.12.10.dist-info/RECORD,,