rasa-pro 3.13.0rc3__py3-none-any.whl → 3.13.0rc4__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.

@@ -92,6 +92,29 @@ class AuthRetryTrackerStore(TrackerStore):
92
92
  )
93
93
  return None
94
94
 
95
+ async def retrieve_full_tracker(
96
+ self, sender_id: Text
97
+ ) -> Optional["DialogueStateTracker"]:
98
+ """Retries retrieving the full tracker if it fails."""
99
+ # add + 1 to retries because the retries are additional to the first attempt
100
+ for _ in range(self.retries + 1):
101
+ try:
102
+ return await self._tracker_store.retrieve_full_tracker(sender_id)
103
+ except Exception as e:
104
+ logger.warning(
105
+ f"Failed to retrieve full tracker for {sender_id}. Retrying...",
106
+ exc_info=e,
107
+ )
108
+ self._tracker_store = self.recreate_tracker_store(
109
+ self.domain, self.event_broker
110
+ )
111
+
112
+ logger.error(
113
+ f"Failed to retrieve full tracker for {sender_id} "
114
+ f"after {self.retries} retries."
115
+ )
116
+ return None
117
+
95
118
  async def save(self, tracker: "DialogueStateTracker") -> None:
96
119
  """Retries saving the tracker if it fails."""
97
120
  # add + 1 to retries because the retries are additional to the first attempt
@@ -120,6 +143,44 @@ class AuthRetryTrackerStore(TrackerStore):
120
143
  endpoint_config = EndpointResolver.update_config(self.endpoint_config)
121
144
  return create_tracker_store(endpoint_config, domain, event_broker)
122
145
 
123
- async def delete(self, sender_id: Text) -> None:
124
- """Delete tracker for the given sender_id."""
125
- await self._tracker_store.delete(sender_id)
146
+ async def delete(self, sender_id: str) -> None:
147
+ """Retries deleting the tracker for the given sender_id."""
148
+ # add + 1 to retries because the retries are additional to the first attempt
149
+ for _ in range(self.retries + 1):
150
+ try:
151
+ await self._tracker_store.delete(sender_id)
152
+ break
153
+ except Exception as e:
154
+ logger.warning(
155
+ f"Failed to delete tracker for {sender_id}. Retrying...",
156
+ exc_info=e,
157
+ )
158
+ self._tracker_store = self.recreate_tracker_store(
159
+ self.domain, self.event_broker
160
+ )
161
+ else:
162
+ logger.error(
163
+ f"Failed to delete tracker for {sender_id} "
164
+ f"after {self.retries} retries."
165
+ )
166
+
167
+ async def update(self, tracker: DialogueStateTracker) -> None:
168
+ """Retries replacing the tracker if it fails."""
169
+ # add + 1 to retries because the retries are additional to the first attempt
170
+ for _ in range(self.retries + 1):
171
+ try:
172
+ await self._tracker_store.update(tracker)
173
+ break
174
+ except Exception as e:
175
+ logger.warning(
176
+ f"Failed to replace tracker for {tracker.sender_id}. Retrying...",
177
+ exc_info=e,
178
+ )
179
+ self._tracker_store = self.recreate_tracker_store(
180
+ self.domain, self.event_broker
181
+ )
182
+ else:
183
+ logger.error(
184
+ f"Failed to replace tracker for {tracker.sender_id} "
185
+ f"after {self.retries} retries."
186
+ )
@@ -216,3 +216,13 @@ class DynamoTrackerStore(TrackerStore, SerializedTrackerAsDict):
216
216
  sender_ids.extend([i["sender_id"] for i in response["Items"]])
217
217
 
218
218
  return sender_ids
219
+
220
+ async def update(self, tracker: DialogueStateTracker) -> None:
221
+ """Overwrites the tracker for the given sender_id."""
222
+ serialized = self.serialise_tracker(tracker)
223
+ self.db.put_item(Item=serialized)
224
+
225
+ structlogger.info(
226
+ "dynamo_tracker_store.replace.replaced_tracker",
227
+ sender_id=tracker.sender_id,
228
+ )
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import itertools
4
+ from datetime import datetime
4
5
  from typing import Any, Dict, Iterable, Iterator, List, Optional, Text
5
6
 
6
7
  import structlog
@@ -204,3 +205,19 @@ class MongoTrackerStore(TrackerStore, SerializedTrackerAsText):
204
205
  async def keys(self) -> Iterable[Text]:
205
206
  """Returns sender_ids of the Mongo Tracker Store."""
206
207
  return [c["sender_id"] for c in self.conversations.find()]
208
+
209
+ async def update(self, tracker: DialogueStateTracker) -> None:
210
+ """Overwrites the tracker for the given sender_id."""
211
+ self.conversations.replace_one(
212
+ {"sender_id": tracker.sender_id},
213
+ tracker.current_state(EventVerbosity.ALL),
214
+ upsert=True,
215
+ )
216
+
217
+ first_event_timestamp = str(datetime.fromtimestamp(tracker.events[0].timestamp))
218
+
219
+ structlogger.info(
220
+ "redis_tracker_store.update.updated_tracker",
221
+ sender_id=tracker.sender_id,
222
+ first_event_timestamp=first_event_timestamp,
223
+ )
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from datetime import datetime
3
4
  from typing import Any, Dict, Iterable, Optional, Text
4
5
 
5
6
  import structlog
@@ -227,3 +228,25 @@ class RedisTrackerStore(TrackerStore, SerializedTrackerAsText):
227
228
  merged.update(new_event)
228
229
 
229
230
  return merged
231
+
232
+ async def update(self, tracker: DialogueStateTracker) -> None:
233
+ """Overwrites the tracker for the given sender_id."""
234
+ serialised_tracker = self.serialise_tracker(tracker)
235
+
236
+ # if the sender_id starts with the key prefix, we remove it
237
+ # this is used to avoid storing the prefix twice
238
+ sender_id = tracker.sender_id
239
+ if sender_id.startswith(self.key_prefix):
240
+ sender_id = sender_id[len(self.key_prefix) :]
241
+
242
+ self.red.set(
243
+ self.key_prefix + sender_id, serialised_tracker, ex=self.record_exp
244
+ )
245
+
246
+ first_event_timestamp = str(datetime.fromtimestamp(tracker.events[0].timestamp))
247
+
248
+ structlogger.info(
249
+ "redis_tracker_store.update.updated_tracker",
250
+ sender_id=tracker.sender_id,
251
+ first_event_timestamp=first_event_timestamp,
252
+ )
@@ -4,6 +4,7 @@ import contextlib
4
4
  import itertools
5
5
  import json
6
6
  import os
7
+ from datetime import datetime
7
8
  from time import sleep
8
9
  from typing import (
9
10
  TYPE_CHECKING,
@@ -553,3 +554,29 @@ class SQLTrackerStore(TrackerStore, SerializedTrackerAsText):
553
554
  return itertools.islice(
554
555
  tracker.events, number_of_events_since_last_session, len(tracker.events)
555
556
  )
557
+
558
+ async def update(self, tracker_to_keep: DialogueStateTracker) -> None:
559
+ """Overwrite the tracker in the SQL tracker store."""
560
+ with self.session_scope() as session:
561
+ # Delete events whose timestamp are older
562
+ # than the first event of the tracker to keep.
563
+ statement = sa.delete(self.SQLEvent).where(
564
+ self.SQLEvent.sender_id == tracker_to_keep.sender_id,
565
+ self.SQLEvent.timestamp < tracker_to_keep.events[0].timestamp
566
+ if tracker_to_keep.events
567
+ else 0,
568
+ )
569
+
570
+ result = session.execute(statement)
571
+ session.commit()
572
+
573
+ first_event_timestamp = str(
574
+ datetime.fromtimestamp(tracker_to_keep.events[0].timestamp)
575
+ )
576
+
577
+ structlogger.info(
578
+ "sql_tracker_store.update.updated_tracker",
579
+ sender_id=tracker_to_keep.sender_id,
580
+ first_event_timestamp=first_event_timestamp,
581
+ event_info=f"{result.rowcount} rows removed from tracker.",
582
+ )
@@ -251,6 +251,14 @@ class TrackerStore:
251
251
  """
252
252
  raise NotImplementedError()
253
253
 
254
+ async def update(self, tracker: DialogueStateTracker) -> None:
255
+ """Replace an existing tracker with a new one.
256
+
257
+ Args:
258
+ tracker: The tracker to update.
259
+ """
260
+ raise NotImplementedError()
261
+
254
262
  async def retrieve_full_tracker(
255
263
  self, conversation_id: Text
256
264
  ) -> Optional[DialogueStateTracker]:
@@ -478,6 +486,14 @@ class InMemoryTrackerStore(TrackerStore, SerializedTrackerAsText):
478
486
 
479
487
  return multiple_tracker_sessions[-1]
480
488
 
489
+ async def update(self, tracker: DialogueStateTracker) -> None:
490
+ """Replace an existing tracker with a new one.
491
+
492
+ Args:
493
+ tracker: The tracker to update.
494
+ """
495
+ await self.save(tracker)
496
+
481
497
 
482
498
  def validate_port(port: Any) -> Optional[int]:
483
499
  """Ensure that port can be converted to integer.
@@ -583,7 +599,19 @@ class FailSafeTrackerStore(TrackerStore):
583
599
 
584
600
  async def delete(self, sender_id: Text) -> None:
585
601
  """Delete tracker for the given sender_id."""
586
- await self._tracker_store.delete(sender_id)
602
+ try:
603
+ await self._tracker_store.delete(sender_id)
604
+ except Exception as e:
605
+ self.on_tracker_store_error(e)
606
+ await self.fallback_tracker_store.delete(sender_id)
607
+
608
+ async def update(self, tracker: DialogueStateTracker) -> None:
609
+ """Replace an existing tracker with a new one."""
610
+ try:
611
+ await self._tracker_store.update(tracker)
612
+ except Exception as e:
613
+ self.on_tracker_store_error(e)
614
+ await self.fallback_tracker_store.update(tracker)
587
615
 
588
616
  async def retrieve_full_tracker(
589
617
  self, sender_id: Text
@@ -793,7 +821,13 @@ class AwaitableTrackerStore(TrackerStore):
793
821
 
794
822
  async def delete(self, sender_id: Text) -> None:
795
823
  """Delete tracker for the given sender_id."""
796
- await self._tracker_store.delete(sender_id)
824
+ result = self._tracker_store.delete(sender_id)
825
+ return await result if isawaitable(result) else result
826
+
827
+ async def update(self, tracker: DialogueStateTracker) -> None:
828
+ """Replace an existing tracker with a new one."""
829
+ result = self._tracker_store.update(tracker)
830
+ return await result if isawaitable(result) else result
797
831
 
798
832
  async def retrieve_full_tracker(
799
833
  self, conversation_id: Text
@@ -249,7 +249,7 @@ flows:
249
249
  next: END
250
250
 
251
251
  pattern_repeat_bot_messages:
252
- description: Voice conversation repair pattern to repeat bot messages
252
+ description: Conversation repair flow for repeating previous messages
253
253
  name: pattern repeat bot messages
254
254
  steps:
255
255
  - action: action_repeat_bot_messages
@@ -12,7 +12,7 @@ import structlog
12
12
  from apscheduler.schedulers.background import BackgroundScheduler
13
13
 
14
14
  import rasa.shared.core.trackers
15
- from rasa.core.tracker_stores.tracker_store import FailSafeTrackerStore, TrackerStore
15
+ from rasa.core.tracker_stores.tracker_store import TrackerStore
16
16
  from rasa.privacy.constants import (
17
17
  TEXT_KEY,
18
18
  USER_CHAT_INACTIVITY_IN_MINUTES_ENV_VAR_NAME,
@@ -25,7 +25,7 @@ from rasa.privacy.privacy_config import (
25
25
  )
26
26
  from rasa.privacy.privacy_filter import PrivacyFilter
27
27
  from rasa.shared.core.events import Event, SlotSet, UserUttered, split_events
28
- from rasa.shared.core.trackers import DialogueStateTracker
28
+ from rasa.shared.core.trackers import DialogueStateTracker, EventVerbosity
29
29
 
30
30
  if TYPE_CHECKING:
31
31
  from asyncio import AbstractEventLoop
@@ -97,7 +97,7 @@ class BackgroundPrivacyManager:
97
97
  else TrackerStore.create(None)
98
98
  )
99
99
 
100
- self.tracker_store = FailSafeTrackerStore(tracker_store)
100
+ self.tracker_store = tracker_store
101
101
 
102
102
  self.event_brokers: List["EventBroker"] = []
103
103
  self.event_loop = event_loop
@@ -264,15 +264,16 @@ class BackgroundPrivacyManager:
264
264
  )
265
265
  return None
266
266
 
267
- latest_message = tracker.latest_message
268
-
269
- if latest_message is None or not latest_message.text:
267
+ latest_user_message = tracker.get_last_event_for(
268
+ UserUttered, event_verbosity=EventVerbosity.ALL
269
+ )
270
+ if latest_user_message is None or not latest_user_message.text:
270
271
  structlogger.debug(
271
272
  "rasa.privacy_manager.no_user_message.skipping_processing",
272
273
  )
273
274
  return None
274
275
 
275
- return latest_message
276
+ return latest_user_message
276
277
 
277
278
  @staticmethod
278
279
  def _has_session_been_anonymized(events: List[Event]) -> bool:
@@ -360,9 +361,13 @@ class BackgroundPrivacyManager:
360
361
  full_tracker
361
362
  )
362
363
 
363
- await self.tracker_store.delete(sender_id=key)
364
-
365
364
  if not events_to_be_retained:
365
+ await self.tracker_store.delete(sender_id=key)
366
+ structlogger.info(
367
+ "rasa.privacy_manager.tracker_session_deleted",
368
+ sender_id=full_tracker.sender_id,
369
+ triggered_by="deletion_cron_job",
370
+ )
366
371
  continue
367
372
 
368
373
  tracker = DialogueStateTracker.from_events(
@@ -370,12 +375,13 @@ class BackgroundPrivacyManager:
370
375
  evts=events_to_be_retained,
371
376
  slots=full_tracker.slots.values(),
372
377
  )
373
- await self.tracker_store.save(tracker)
378
+ await self.tracker_store.update(tracker)
374
379
 
375
380
  structlogger.info(
376
- "rasa.privacy_manager.save_tracker_after_deletion",
381
+ "rasa.privacy_manager.overwritten_tracker",
377
382
  sender_id=key,
378
- event_info="Saved tracker with events not scheduled "
383
+ event_info="Deleted eligible events and saved "
384
+ "tracker with events not scheduled "
379
385
  "for deletion yet.",
380
386
  )
381
387
 
@@ -527,10 +533,7 @@ class BackgroundPrivacyManager:
527
533
  last_event_timestamp=last_event_timestamp,
528
534
  triggered_by="anonymization_cron_job",
529
535
  )
530
- tracker = DialogueStateTracker.from_events(
531
- session.sender_id, session.events
532
- )
533
- events = self.process_events(tracker, process_all=True)
536
+ events = self.process_events(session, process_all=True)
534
537
  processed_events.extend(events)
535
538
  else:
536
539
  # If the session is not valid for anonymization,
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.13.0rc3"
3
+ __version__ = "3.13.0rc4"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rasa-pro
3
- Version: 3.13.0rc3
3
+ Version: 3.13.0rc4
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
@@ -347,12 +347,12 @@ rasa/core/secrets_manager/secret_manager.py,sha256=oYihfIMIMUKA8U_ZRA3blcErFlCoz
347
347
  rasa/core/secrets_manager/vault.py,sha256=02wlsrN3QoHSZkqygHaM_CWDtkpkJ25iD-ksEu3ejBw,20481
348
348
  rasa/core/test.py,sha256=VGlGvmrXRqHaPMaetvvN1fa65oZMryN5ot9L3otNH5E,49282
349
349
  rasa/core/tracker_stores/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
350
- rasa/core/tracker_stores/auth_retry_tracker_store.py,sha256=eFW-uCRImTxouhHux4HVppQhbWNOaPzusbvaJ-U0N4Y,4826
351
- rasa/core/tracker_stores/dynamo_tracker_store.py,sha256=opTSmFfNYKe3pKY5PL2JAKCc9uIur3pc5f_8SVW6g98,7906
352
- rasa/core/tracker_stores/mongo_tracker_store.py,sha256=nuj-XkIC02dGv0l7Ie8801fHGrSN9SWlepenz3DZs78,7024
353
- rasa/core/tracker_stores/redis_tracker_store.py,sha256=cODH4DlUNij-GnKz6ns3nU2E-z_pXtsNA7LojmARZWg,7974
354
- rasa/core/tracker_stores/sql_tracker_store.py,sha256=WZuo5c4TcBwOc6GwWlyNCv3LHNetgWTih0zEdMEvgYY,19879
355
- rasa/core/tracker_stores/tracker_store.py,sha256=BrQFZXQGMncl-Ig3DDUrqpJfxshuy-pOmoVTVa1IMbw,28223
350
+ rasa/core/tracker_stores/auth_retry_tracker_store.py,sha256=eOwsLuQZhWu5Q4RZHJYffL3FhpKOglzJ0MNGffv2E60,7270
351
+ rasa/core/tracker_stores/dynamo_tracker_store.py,sha256=-C0M03H4dlIyX7yOYtL6VJOtnDkNjnCMTdbRIYedN6g,8271
352
+ rasa/core/tracker_stores/mongo_tracker_store.py,sha256=v2ktPXxp7PWfoHPqOJKLkMzML_5E_Of0Ihna2Vcqfbg,7644
353
+ rasa/core/tracker_stores/redis_tracker_store.py,sha256=q38nCZoXW4G7xdZ6nOcOpanIB5XrzEM4rMdFnUHR3pE,8864
354
+ rasa/core/tracker_stores/sql_tracker_store.py,sha256=oJgAqDysP3KXJkPRCZ1s8HhlxOn-y9Apmo6OVO3lQmc,20960
355
+ rasa/core/tracker_stores/tracker_store.py,sha256=bJMsxzuhw90vGY2uGbbCogikoy4HucPy6SvYfcyFQJw,29472
356
356
  rasa/core/train.py,sha256=ESBhZ9vZySziZIG8fvshHO4AYApD0hywRFCmA9h1wFI,3521
357
357
  rasa/core/training/__init__.py,sha256=23DaZynwsxIaGYvZBSwQRxanaMWa-ihfON7f-NetK_g,3213
358
358
  rasa/core/training/converters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -431,7 +431,7 @@ rasa/dialogue_understanding/patterns/collect_information.py,sha256=8YWvhFTt8CJML
431
431
  rasa/dialogue_understanding/patterns/completed.py,sha256=7qkyUj2d__2R3mpwWVmQpfwCCbJruBrjRZbmbDr3Zbo,1278
432
432
  rasa/dialogue_understanding/patterns/continue_interrupted.py,sha256=OSTbe5l0B0ECNIYWpYB0pdzIeaqM3m3UZskNNjL5vrw,1682
433
433
  rasa/dialogue_understanding/patterns/correction.py,sha256=7fQ02-JU1CGZiTjTi9YqmD1F4o-9Tv5WCAXnFgZlvtY,11380
434
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml,sha256=8zQQ1o9KQsT_wmNBUx4_iHZzYbzPHVLjFDorT60yvCs,11030
434
+ rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml,sha256=NwNXqrodwOTgDPYtu6L5n6epBLzXjnnRCzH_oBPLMnc,11030
435
435
  rasa/dialogue_understanding/patterns/domain_for_patterns.py,sha256=Zv_lCJn4nbkxeNYOPGsR0V8tmYAUsM_Ho_9to8hku-o,6493
436
436
  rasa/dialogue_understanding/patterns/human_handoff.py,sha256=1hkSdL6kui42rZc7zERZ9R7nLyvRHi_tHgNU7FyrhAQ,1132
437
437
  rasa/dialogue_understanding/patterns/internal_error.py,sha256=APCKVv16M6mSQ4upu4UwG0yIaaKTyr7uB2yV8ZtpMzo,1609
@@ -637,7 +637,7 @@ rasa/privacy/event_broker_utils.py,sha256=K0ej9vRED5sJiG8YJq3_pynMRJEenCyKSjt6xO
637
637
  rasa/privacy/privacy_config.py,sha256=mctRStSliSUbbjHAl5ISTczJ2TgU7T5yjSfZvLmUtlI,9339
638
638
  rasa/privacy/privacy_config_schema.json,sha256=kQVJCrlKljJMkOCL3WDzquVS8V1-KE6_XMEyVSuUkJw,1835
639
639
  rasa/privacy/privacy_filter.py,sha256=s1LxnOeIoGh16vzTzxoM5vSDelk1P55Ay3bm0XRuINs,14988
640
- rasa/privacy/privacy_manager.py,sha256=6tK1cLfJDfk_XbFZZNq1a9ImhtDh1_l8RC2GWHWRMfw,22386
640
+ rasa/privacy/privacy_manager.py,sha256=IWbWIpJeX7EgHXPjYXPmq-5RaoJEnCFa5xKE7M2roTE,22593
641
641
  rasa/server.py,sha256=prH4FVO5kd7VKgSJnP_dt7PhXlW0vf8KWf62ccK8mlw,60505
642
642
  rasa/shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
643
643
  rasa/shared/constants.py,sha256=pYMlsFE9kao5BUOXd-8cHWLV9jMfUop7Mfm57mBPcxc,12856
@@ -846,9 +846,9 @@ rasa/utils/train_utils.py,sha256=ClJx-6x3-h3Vt6mskacgkcCUJTMXjFPe3zAcy_DfmaU,212
846
846
  rasa/utils/url_tools.py,sha256=dZ1HGkVdWTJB7zYEdwoDIrEuyX9HE5WsxKKFVsXBLE0,1218
847
847
  rasa/utils/yaml.py,sha256=KjbZq5C94ZP7Jdsw8bYYF7HASI6K4-C_kdHfrnPLpSI,2000
848
848
  rasa/validator.py,sha256=JXi8bz3SsTB2c1tbDRY3r3TkcfSbhxacoxs-rVx6a9s,82937
849
- rasa/version.py,sha256=-KPJ9E-IAgMogu8pKWMj7VxcA8dbmX0UKuG-U9k-adc,120
850
- rasa_pro-3.13.0rc3.dist-info/METADATA,sha256=5yPX5oyvTOwfwvysDX16kfh7toEmYoM6KUZSJqJjckY,10556
851
- rasa_pro-3.13.0rc3.dist-info/NOTICE,sha256=7HlBoMHJY9CL2GlYSfTQ-PZsVmLmVkYmMiPlTjhuCqA,218
852
- rasa_pro-3.13.0rc3.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
853
- rasa_pro-3.13.0rc3.dist-info/entry_points.txt,sha256=ckJ2SfEyTPgBqj_I6vm_tqY9dZF_LAPJZA335Xp0Q9U,43
854
- rasa_pro-3.13.0rc3.dist-info/RECORD,,
849
+ rasa/version.py,sha256=CR4TIGitcXn4TjFFR4dvuB7MwIBGoxfQBLSyXmoOigk,120
850
+ rasa_pro-3.13.0rc4.dist-info/METADATA,sha256=kyiTLbOAtGtqCKm9hjUNlkTdUSTMCuZIUNB76NXTDu8,10556
851
+ rasa_pro-3.13.0rc4.dist-info/NOTICE,sha256=7HlBoMHJY9CL2GlYSfTQ-PZsVmLmVkYmMiPlTjhuCqA,218
852
+ rasa_pro-3.13.0rc4.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
853
+ rasa_pro-3.13.0rc4.dist-info/entry_points.txt,sha256=ckJ2SfEyTPgBqj_I6vm_tqY9dZF_LAPJZA335Xp0Q9U,43
854
+ rasa_pro-3.13.0rc4.dist-info/RECORD,,