rasa-pro 3.13.0.dev5__py3-none-any.whl → 3.13.0.dev20250612__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 (140) hide show
  1. rasa/api.py +4 -0
  2. rasa/cli/arguments/default_arguments.py +13 -1
  3. rasa/cli/arguments/train.py +2 -0
  4. rasa/cli/evaluate.py +1 -1
  5. rasa/cli/export.py +2 -2
  6. rasa/cli/train.py +1 -0
  7. rasa/constants.py +2 -0
  8. rasa/core/agent.py +2 -2
  9. rasa/core/brokers/kafka.py +4 -0
  10. rasa/core/brokers/pika.py +4 -0
  11. rasa/core/brokers/sql.py +1 -1
  12. rasa/core/channels/inspector/.eslintrc.cjs +12 -6
  13. rasa/core/channels/inspector/.prettierrc +5 -0
  14. rasa/core/channels/inspector/README.md +10 -4
  15. rasa/core/channels/inspector/dist/assets/{arc-9f75cc3b.js → arc-c4b064fc.js} +1 -1
  16. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-7f34db23.js → blockDiagram-38ab4fdb-215b5026.js} +1 -1
  17. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-948bab2c.js → c4Diagram-3d4e48cf-2b54a0a3.js} +1 -1
  18. rasa/core/channels/inspector/dist/assets/channel-3730f5fd.js +1 -0
  19. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-53b0dd0e.js → classDiagram-70f12bd4-daacea5f.js} +1 -1
  20. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-fdf789e7.js → classDiagram-v2-f2320105-930d4dc2.js} +1 -1
  21. rasa/core/channels/inspector/dist/assets/clone-e847561e.js +1 -0
  22. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-87c4ece5.js → createText-2e5e7dd3-83c206ba.js} +1 -1
  23. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-5a8b0749.js → edges-e0da2a9e-b0eb01d0.js} +1 -1
  24. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-66da90e2.js → erDiagram-9861fffd-17586500.js} +1 -1
  25. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-10044f05.js → flowDb-956e92f1-be2a1776.js} +1 -1
  26. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-f338f66a.js → flowDiagram-66a62f08-c2120ebd.js} +1 -1
  27. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-efbbfe00.js +1 -0
  28. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-b13140aa.js → flowchart-elk-definition-4a651766-a6ab5c48.js} +1 -1
  29. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-f2b4a55a.js → ganttDiagram-c361ad54-ef613457.js} +1 -1
  30. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-dedc298d.js → gitGraphDiagram-72cf32ee-d59185b3.js} +1 -1
  31. rasa/core/channels/inspector/dist/assets/{graph-4ede11ff.js → graph-0f155405.js} +1 -1
  32. rasa/core/channels/inspector/dist/assets/{index-3862675e-65549d37.js → index-3862675e-d5f1d1b7.js} +1 -1
  33. rasa/core/channels/inspector/dist/assets/{index-3a23e736.js → index-47737d3a.js} +123 -123
  34. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-65439671.js → infoDiagram-f8f76790-b07d141f.js} +1 -1
  35. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-56d03d98.js → journeyDiagram-49397b02-1936d429.js} +1 -1
  36. rasa/core/channels/inspector/dist/assets/{layout-dd48f7f4.js → layout-dde8d0f3.js} +1 -1
  37. rasa/core/channels/inspector/dist/assets/{line-1569ad2c.js → line-0c2c7ee0.js} +1 -1
  38. rasa/core/channels/inspector/dist/assets/{linear-48bf4935.js → linear-35dd89a4.js} +1 -1
  39. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-688504c1.js → mindmap-definition-fc14e90a-56192851.js} +1 -1
  40. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-78b6d7e6.js → pieDiagram-8a3498a8-fc21ed78.js} +1 -1
  41. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-048b84b3.js → quadrantDiagram-120e2f19-25e98518.js} +1 -1
  42. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-dd67f107.js → requirementDiagram-deff3bca-546ff1f5.js} +1 -1
  43. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-8128436e.js → sankeyDiagram-04a897e0-02d8b82d.js} +1 -1
  44. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-1a0d1461.js → sequenceDiagram-704730f1-3ca5a92e.js} +1 -1
  45. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-46d388ed.js → stateDiagram-587899a1-128ea07c.js} +1 -1
  46. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-ea42951a.js → stateDiagram-v2-d93cdb3a-95f290af.js} +1 -1
  47. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-7427ed0c.js → styles-6aaf32cf-4984898a.js} +1 -1
  48. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-ff5e5a16.js → styles-9a916d00-1bf266ba.js} +1 -1
  49. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-7b3680cf.js → styles-c10674c1-60521c63.js} +1 -1
  50. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-f860f2ad.js → svgDrawCommon-08f97a94-a25b6e12.js} +1 -1
  51. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-2eebf0c8.js → timeline-definition-85554ec2-0fc086bf.js} +1 -1
  52. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-5d7f4e96.js → xychartDiagram-e933f94c-44ee592e.js} +1 -1
  53. rasa/core/channels/inspector/dist/index.html +1 -1
  54. rasa/core/channels/inspector/package.json +3 -1
  55. rasa/core/channels/inspector/src/App.tsx +91 -90
  56. rasa/core/channels/inspector/src/components/Chat.tsx +45 -41
  57. rasa/core/channels/inspector/src/components/DiagramFlow.tsx +40 -40
  58. rasa/core/channels/inspector/src/components/DialogueInformation.tsx +57 -57
  59. rasa/core/channels/inspector/src/components/DialogueStack.tsx +36 -27
  60. rasa/core/channels/inspector/src/components/ExpandIcon.tsx +4 -4
  61. rasa/core/channels/inspector/src/components/FullscreenButton.tsx +7 -7
  62. rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +28 -12
  63. rasa/core/channels/inspector/src/components/NoActiveFlow.tsx +9 -9
  64. rasa/core/channels/inspector/src/components/RasaLogo.tsx +5 -5
  65. rasa/core/channels/inspector/src/components/RecruitmentPanel.tsx +55 -60
  66. rasa/core/channels/inspector/src/components/SaraDiagrams.tsx +5 -5
  67. rasa/core/channels/inspector/src/components/Slots.tsx +22 -22
  68. rasa/core/channels/inspector/src/components/Welcome.tsx +28 -31
  69. rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +245 -0
  70. rasa/core/channels/inspector/src/helpers/audio/microphone-processor.js +12 -0
  71. rasa/core/channels/inspector/src/helpers/audio/playback-processor.js +36 -0
  72. rasa/core/channels/inspector/src/helpers/conversation.ts +7 -7
  73. rasa/core/channels/inspector/src/helpers/formatters.test.ts +181 -181
  74. rasa/core/channels/inspector/src/helpers/formatters.ts +111 -111
  75. rasa/core/channels/inspector/src/helpers/utils.ts +78 -61
  76. rasa/core/channels/inspector/src/main.tsx +8 -8
  77. rasa/core/channels/inspector/src/theme/Button/Button.ts +8 -8
  78. rasa/core/channels/inspector/src/theme/Heading/Heading.ts +7 -7
  79. rasa/core/channels/inspector/src/theme/Input/Input.ts +9 -9
  80. rasa/core/channels/inspector/src/theme/Link/Link.ts +6 -6
  81. rasa/core/channels/inspector/src/theme/Modal/Modal.ts +13 -13
  82. rasa/core/channels/inspector/src/theme/Table/Table.tsx +10 -10
  83. rasa/core/channels/inspector/src/theme/Tooltip/Tooltip.ts +5 -5
  84. rasa/core/channels/inspector/src/theme/base/breakpoints.ts +7 -7
  85. rasa/core/channels/inspector/src/theme/base/colors.ts +64 -64
  86. rasa/core/channels/inspector/src/theme/base/fonts/fontFaces.css +21 -18
  87. rasa/core/channels/inspector/src/theme/base/radii.ts +8 -8
  88. rasa/core/channels/inspector/src/theme/base/shadows.ts +5 -5
  89. rasa/core/channels/inspector/src/theme/base/sizes.ts +5 -5
  90. rasa/core/channels/inspector/src/theme/base/space.ts +12 -12
  91. rasa/core/channels/inspector/src/theme/base/styles.ts +5 -5
  92. rasa/core/channels/inspector/src/theme/base/typography.ts +12 -12
  93. rasa/core/channels/inspector/src/theme/base/zIndices.ts +3 -3
  94. rasa/core/channels/inspector/src/theme/index.ts +38 -38
  95. rasa/core/channels/inspector/src/types.ts +56 -50
  96. rasa/core/channels/inspector/yarn.lock +5 -0
  97. rasa/core/channels/voice_ready/audiocodes.py +34 -17
  98. rasa/core/evaluation/marker_tracker_loader.py +1 -1
  99. rasa/core/exporter.py +1 -1
  100. rasa/core/nlg/summarize.py +1 -1
  101. rasa/core/persistor.py +55 -20
  102. rasa/core/processor.py +2 -2
  103. rasa/core/run.py +7 -2
  104. rasa/core/tracker_stores/__init__.py +0 -0
  105. rasa/core/{auth_retry_tracker_store.py → tracker_stores/auth_retry_tracker_store.py} +5 -1
  106. rasa/core/tracker_stores/dynamo_tracker_store.py +218 -0
  107. rasa/core/tracker_stores/mongo_tracker_store.py +206 -0
  108. rasa/core/tracker_stores/redis_tracker_store.py +219 -0
  109. rasa/core/tracker_stores/sql_tracker_store.py +555 -0
  110. rasa/core/tracker_stores/tracker_store.py +805 -0
  111. rasa/core/utils.py +6 -0
  112. rasa/dialogue_understanding/commands/clarify_command.py +2 -2
  113. rasa/dialogue_understanding/generator/llm_based_command_generator.py +1 -1
  114. rasa/hooks.py +2 -2
  115. rasa/keys +1 -0
  116. rasa/model_manager/config.py +3 -1
  117. rasa/model_manager/model_api.py +1 -2
  118. rasa/model_manager/runner_service.py +8 -4
  119. rasa/model_manager/trainer_service.py +1 -0
  120. rasa/model_training.py +12 -3
  121. rasa/nlu/extractors/crf_entity_extractor.py +66 -16
  122. rasa/plugin.py +1 -1
  123. rasa/server.py +6 -2
  124. rasa/shared/core/events.py +68 -2
  125. rasa/telemetry.py +2 -2
  126. rasa/tracing/config.py +1 -1
  127. rasa/tracing/instrumentation/attribute_extractors.py +1 -1
  128. rasa/tracing/instrumentation/instrumentation.py +1 -1
  129. rasa/utils/licensing.py +1 -2
  130. rasa/version.py +1 -1
  131. {rasa_pro-3.13.0.dev5.dist-info → rasa_pro-3.13.0.dev20250612.dist-info}/METADATA +4 -4
  132. {rasa_pro-3.13.0.dev5.dist-info → rasa_pro-3.13.0.dev20250612.dist-info}/RECORD +135 -126
  133. rasa/core/channels/inspector/dist/assets/channel-dfa68278.js +0 -1
  134. rasa/core/channels/inspector/dist/assets/clone-edb7f119.js +0 -1
  135. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-65e7c670.js +0 -1
  136. rasa/core/channels/inspector/src/helpers/audiostream.ts +0 -191
  137. rasa/core/tracker_store.py +0 -1792
  138. {rasa_pro-3.13.0.dev5.dist-info → rasa_pro-3.13.0.dev20250612.dist-info}/NOTICE +0 -0
  139. {rasa_pro-3.13.0.dev5.dist-info → rasa_pro-3.13.0.dev20250612.dist-info}/WHEEL +0 -0
  140. {rasa_pro-3.13.0.dev5.dist-info → rasa_pro-3.13.0.dev20250612.dist-info}/entry_points.txt +0 -0
rasa/core/utils.py CHANGED
@@ -198,6 +198,9 @@ class AvailableEndpoints:
198
198
  model_groups = read_property_config_from_endpoints_file(
199
199
  endpoint_file, property_name="model_groups"
200
200
  )
201
+ privacy = read_property_config_from_endpoints_file(
202
+ endpoint_file, property_name="privacy"
203
+ )
201
204
 
202
205
  return cls(
203
206
  nlg,
@@ -209,6 +212,7 @@ class AvailableEndpoints:
209
212
  event_broker,
210
213
  vector_store,
211
214
  model_groups,
215
+ privacy,
212
216
  )
213
217
 
214
218
  def __init__(
@@ -222,6 +226,7 @@ class AvailableEndpoints:
222
226
  event_broker: Optional[EndpointConfig] = None,
223
227
  vector_store: Optional[EndpointConfig] = None,
224
228
  model_groups: Optional[List[Dict[str, Any]]] = None,
229
+ privacy: Optional[Dict[Text, Any]] = None,
225
230
  ) -> None:
226
231
  """Create an `AvailableEndpoints` object."""
227
232
  self.model = model
@@ -233,6 +238,7 @@ class AvailableEndpoints:
233
238
  self.event_broker = event_broker
234
239
  self.vector_store = vector_store
235
240
  self.model_groups = model_groups
241
+ self.privacy = privacy
236
242
 
237
243
  @classmethod
238
244
  def get_instance(
@@ -117,9 +117,9 @@ class ClarifyCommand(Command):
117
117
  @staticmethod
118
118
  def regex_pattern() -> str:
119
119
  mapper = {
120
- CommandSyntaxVersion.v1: r"Clarify\(([\"\'a-zA-Z0-9_, ]*)\)",
120
+ CommandSyntaxVersion.v1: r"Clarify\(([\"\'a-zA-Z0-9_, -]*)\)",
121
121
  CommandSyntaxVersion.v2: (
122
- r"""^[\s\W\d]*disambiguate flows (["'a-zA-Z0-9_, ]*)['"`]*$"""
122
+ r"""^[\s\W\d]*disambiguate flows (["'a-zA-Z0-9_, -]*)['"`]*$"""
123
123
  ),
124
124
  }
125
125
  return mapper.get(
@@ -527,7 +527,7 @@ class LLMBasedCommandGenerator(
527
527
  either contain a StartFlowCommand or a SetSlot command
528
528
  for the current collect step.
529
529
  """
530
- return self.config.get(KEY_MINIMIZE_NUM_CALLS, False) and (
530
+ return self.config.get(KEY_MINIMIZE_NUM_CALLS, True) and (
531
531
  self._prior_commands_contain_start_flow(prior_commands)
532
532
  or self._prior_commands_contain_set_slot_for_active_collect_step(
533
533
  prior_commands, flows, tracker
rasa/hooks.py CHANGED
@@ -12,7 +12,7 @@ if TYPE_CHECKING:
12
12
  from rasa.anonymization.anonymization_pipeline import AnonymizationPipeline
13
13
  from rasa.cli import SubParsersAction
14
14
  from rasa.core.brokers.broker import EventBroker
15
- from rasa.core.tracker_store import TrackerStore
15
+ from rasa.core.tracker_stores.tracker_store import TrackerStore
16
16
  from rasa.shared.core.domain import Domain
17
17
  from rasa.utils.endpoints import EndpointConfig
18
18
 
@@ -80,7 +80,7 @@ def create_tracker_store(
80
80
  domain: "Domain",
81
81
  event_broker: Optional["EventBroker"],
82
82
  ) -> "TrackerStore":
83
- from rasa.core.auth_retry_tracker_store import AuthRetryTrackerStore
83
+ from rasa.core.tracker_stores.auth_retry_tracker_store import AuthRetryTrackerStore
84
84
  from rasa.utils.endpoints import EndpointConfig
85
85
 
86
86
  if isinstance(endpoint_config, EndpointConfig):
rasa/keys ADDED
@@ -0,0 +1 @@
1
+ {"segment": "CcvVD1I68Nkkxrv93cIqv1twIwrwG8nz", "sentry": "a283f1fde04347b099c8d729109dd450@o251570"}
@@ -1,6 +1,8 @@
1
1
  import os
2
2
  import sys
3
3
 
4
+ from rasa.constants import RASA_REMOTE_STORAGE_ENV_VAR_NAME
5
+
4
6
  DEFAULT_SERVER_BASE_WORKING_DIRECTORY = "working-data"
5
7
 
6
8
  SERVER_BASE_WORKING_DIRECTORY = os.environ.get(
@@ -12,7 +14,7 @@ SERVER_PORT = os.environ.get("RASA_MODEL_SERVER_PORT", 8000)
12
14
  SERVER_BASE_URL = os.environ.get("RASA_MODEL_SERVER_BASE_URL", None)
13
15
 
14
16
  # defaults to storing on the local hard drive
15
- SERVER_MODEL_REMOTE_STORAGE = os.environ.get("RASA_REMOTE_STORAGE", None)
17
+ SERVER_MODEL_REMOTE_STORAGE = os.environ.get(RASA_REMOTE_STORAGE_ENV_VAR_NAME, None)
16
18
 
17
19
  # The path to the python executable that is running this script
18
20
  # we will use the same python to run training / bots
@@ -532,8 +532,7 @@ def size_of_model(model_name: str) -> Optional[int]:
532
532
  model_name=model_file_name,
533
533
  )
534
534
  return fetch_size_of_remote_model(
535
- model_file_name,
536
- config.SERVER_MODEL_REMOTE_STORAGE,
535
+ model_file_name, config.SERVER_MODEL_REMOTE_STORAGE, model_path
537
536
  )
538
537
  raise ModelNotFound("Model not found.")
539
538
 
@@ -166,13 +166,13 @@ def fetch_remote_model_to_dir(
166
166
  ) -> str:
167
167
  """Fetch the model from remote storage.
168
168
 
169
- Returns the path to the model diretory.
169
+ Returns the path to the model directory.
170
170
  """
171
171
  from rasa.core.persistor import get_persistor
172
172
 
173
173
  persistor = get_persistor(storage_type)
174
174
 
175
- # we now there must be a persistor, because the config is set
175
+ # we know there must be a persistor, because the config is set
176
176
  # this is here to please the type checker for the call below
177
177
  assert persistor is not None
178
178
 
@@ -182,7 +182,9 @@ def fetch_remote_model_to_dir(
182
182
  raise ModelNotFound() from e
183
183
 
184
184
 
185
- def fetch_size_of_remote_model(model_name: str, storage_type: str) -> int:
185
+ def fetch_size_of_remote_model(
186
+ model_name: str, storage_type: str, model_path: str
187
+ ) -> int:
186
188
  """Fetch the size of the model from remote storage."""
187
189
  from rasa.core.persistor import get_persistor
188
190
 
@@ -192,7 +194,9 @@ def fetch_size_of_remote_model(model_name: str, storage_type: str) -> int:
192
194
  # this is here to please the type checker for the call below
193
195
  assert persistor is not None
194
196
 
195
- return persistor.size_of_persisted_model(model_name=model_name)
197
+ return persistor.size_of_persisted_model(
198
+ model_name=model_name, target_path=model_path
199
+ )
196
200
 
197
201
 
198
202
  def start_bot_process(
@@ -278,6 +278,7 @@ def start_training_process(
278
278
  "--keep-local-model-copy",
279
279
  "--remote-storage",
280
280
  config.SERVER_MODEL_REMOTE_STORAGE,
281
+ "--remote-root-only",
281
282
  ]
282
283
  )
283
284
 
rasa/model_training.py CHANGED
@@ -160,6 +160,7 @@ async def train(
160
160
  remote_storage: Optional[StorageType] = None,
161
161
  file_importer: Optional[TrainingDataImporter] = None,
162
162
  keep_local_model_copy: bool = False,
163
+ remote_root_only: bool = False,
163
164
  ) -> TrainingResult:
164
165
  """Trains a Rasa model (Core and NLU).
165
166
 
@@ -187,6 +188,8 @@ async def train(
187
188
  If it is not provided, a new instance will be created.
188
189
  keep_local_model_copy: If `True` the model will be stored locally even if
189
190
  remote storage is configured.
191
+ remote_root_only: If `True`, the model will be stored in the root of the
192
+ remote model storage.
190
193
 
191
194
  Returns:
192
195
  An instance of `TrainingResult`.
@@ -269,6 +272,7 @@ async def train(
269
272
  dry_run=dry_run,
270
273
  remote_storage=remote_storage,
271
274
  keep_local_model_copy=keep_local_model_copy,
275
+ remote_root_only=remote_root_only,
272
276
  **(core_additional_arguments or {}),
273
277
  **(nlu_additional_arguments or {}),
274
278
  )
@@ -284,6 +288,7 @@ async def _train_graph(
284
288
  dry_run: bool = False,
285
289
  remote_storage: Optional[StorageType] = None,
286
290
  keep_local_model_copy: bool = False,
291
+ remote_root_only: bool = False,
287
292
  **kwargs: Any,
288
293
  ) -> TrainingResult:
289
294
  if model_to_finetune:
@@ -363,7 +368,9 @@ async def _train_graph(
363
368
  is_finetuning=is_finetuning,
364
369
  )
365
370
  if remote_storage:
366
- push_model_to_remote_storage(full_model_path, remote_storage)
371
+ push_model_to_remote_storage(
372
+ full_model_path, remote_storage, remote_root_only
373
+ )
367
374
  if not keep_local_model_copy:
368
375
  full_model_path.unlink()
369
376
  structlogger.info(
@@ -581,14 +588,16 @@ async def train_nlu(
581
588
  ).model
582
589
 
583
590
 
584
- def push_model_to_remote_storage(model_path: Path, remote_storage: StorageType) -> None:
591
+ def push_model_to_remote_storage(
592
+ model_path: Path, remote_storage: StorageType, remote_root_only: bool = False
593
+ ) -> None:
585
594
  """Push model to remote storage."""
586
595
  from rasa.core.persistor import get_persistor
587
596
 
588
597
  persistor = get_persistor(remote_storage)
589
598
 
590
599
  if persistor is not None:
591
- persistor.persist(str(model_path))
600
+ persistor.persist(str(model_path), remote_root_only)
592
601
 
593
602
  else:
594
603
  raise RasaException(
@@ -1,9 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging
4
+ import shutil
4
5
  import typing
5
6
  from collections import OrderedDict
6
7
  from enum import Enum
8
+ from pathlib import Path
7
9
  from typing import Any, Callable, Dict, List, Optional, Text, Tuple, Type
8
10
 
9
11
  import numpy as np
@@ -43,6 +45,10 @@ if typing.TYPE_CHECKING:
43
45
 
44
46
  CONFIG_FEATURES = "features"
45
47
 
48
+ TAGGERS_DIR = "taggers"
49
+ CRFSUITE_MODEL_FILE_NAME = "model.crfsuite"
50
+ PLAIN_CRF_MODEL_FILE_NAME = "model.txt"
51
+
46
52
 
47
53
  class CRFToken:
48
54
  def __init__(
@@ -419,19 +425,11 @@ class CRFEntityExtractor(GraphComponent, EntityExtractorMixin):
419
425
  """Loads trained component (see parent class for full docstring)."""
420
426
  try:
421
427
  with model_storage.read_from(resource) as model_dir:
422
- dataset = rasa.shared.utils.io.read_json_file(
423
- model_dir / "crf_dataset.json"
424
- )
425
428
  crf_order = rasa.shared.utils.io.read_json_file(
426
429
  model_dir / "crf_order.json"
427
430
  )
428
431
 
429
- dataset = [
430
- [CRFToken.create_from_dict(token_data) for token_data in sub_list]
431
- for sub_list in dataset
432
- ]
433
-
434
- entity_taggers = cls.train_model(dataset, config, crf_order)
432
+ entity_taggers = cls._load_taggers(model_dir, config)
435
433
 
436
434
  entity_extractor = cls(config, model_storage, resource, entity_taggers)
437
435
  entity_extractor.crf_order = crf_order
@@ -443,19 +441,71 @@ class CRFEntityExtractor(GraphComponent, EntityExtractorMixin):
443
441
  )
444
442
  return cls(config, model_storage, resource)
445
443
 
444
+ @classmethod
445
+ def _load_taggers(
446
+ cls, model_dir: Path, config: Dict[Text, Any]
447
+ ) -> Dict[str, "CRF"]:
448
+ """
449
+ Load taggers from model directory that persists trained binary
450
+ `model.crfsuite` files.
451
+ """
452
+
453
+ import pycrfsuite
454
+ import sklearn_crfsuite
455
+
456
+ # Get tagger directories
457
+ taggers_base = model_dir / TAGGERS_DIR
458
+ if not taggers_base.exists():
459
+ return {}
460
+
461
+ taggers_dirs = [
462
+ directory for directory in taggers_base.iterdir() if directory.is_dir()
463
+ ]
464
+
465
+ entity_taggers: Dict[str, "CRF"] = {}
466
+
467
+ for tagger_dir in taggers_dirs:
468
+ # Instantiate sklearns CRF wrapper for the pycrfsuite's Tagger
469
+ entity_tagger = sklearn_crfsuite.CRF(
470
+ algorithm="lbfgs",
471
+ # coefficient for L1 penalty
472
+ c1=config["L1_c"],
473
+ # coefficient for L2 penalty
474
+ c2=config["L2_c"],
475
+ # stop earlier
476
+ max_iterations=config["max_iterations"],
477
+ # include transitions that are possible, but not observed
478
+ all_possible_transitions=True,
479
+ )
480
+
481
+ # Load pycrfsuite tagger from the persisted binary model.crfsuite file
482
+ entity_tagger._tagger = pycrfsuite.Tagger()
483
+ entity_tagger._tagger.open(str(tagger_dir / CRFSUITE_MODEL_FILE_NAME))
484
+
485
+ entity_taggers[tagger_dir.name] = entity_tagger
486
+
487
+ return entity_taggers
488
+
446
489
  def persist(self, dataset: List[List[CRFToken]]) -> None:
447
490
  """Persist this model into the passed directory."""
448
491
  with self._model_storage.write_to(self._resource) as model_dir:
449
- data_to_store = [
450
- [token.to_dict() for token in sub_list] for sub_list in dataset
451
- ]
452
-
453
- rasa.shared.utils.io.dump_obj_as_json_to_file(
454
- model_dir / "crf_dataset.json", data_to_store
455
- )
456
492
  rasa.shared.utils.io.dump_obj_as_json_to_file(
457
493
  model_dir / "crf_order.json", self.crf_order
458
494
  )
495
+ if self.entity_taggers is not None:
496
+ for tag_name, entity_tagger in self.entity_taggers.items():
497
+ # Create the directories for storing the CRF model
498
+ tagger_dir = model_dir / TAGGERS_DIR / tag_name
499
+ tagger_dir.mkdir(parents=True, exist_ok=True)
500
+ # Create a plain text version of the CRF model
501
+ entity_tagger.tagger_.dump(
502
+ str(tagger_dir / PLAIN_CRF_MODEL_FILE_NAME)
503
+ )
504
+ # Persist binary version of the model.crfsuite
505
+ shutil.copy2(
506
+ src=entity_tagger.modelfile.name,
507
+ dst=tagger_dir / CRFSUITE_MODEL_FILE_NAME,
508
+ )
459
509
 
460
510
  @classmethod
461
511
  def _crf_tokens_to_features(
rasa/plugin.py CHANGED
@@ -11,7 +11,7 @@ from rasa.cli import SubParsersAction
11
11
 
12
12
  if TYPE_CHECKING:
13
13
  from rasa.core.brokers.broker import EventBroker
14
- from rasa.core.tracker_store import TrackerStore
14
+ from rasa.core.tracker_stores.tracker_store import TrackerStore
15
15
  from rasa.shared.core.domain import Domain
16
16
  from rasa.shared.core.trackers import DialogueStateTracker
17
17
  from rasa.utils.endpoints import EndpointConfig
rasa/server.py CHANGED
@@ -522,12 +522,15 @@ def configure_cors(
522
522
  )
523
523
 
524
524
 
525
- def add_root_route(app: Sanic) -> None:
525
+ def add_root_route(app: Sanic, is_inspector_enabled: bool = False) -> None:
526
526
  """Add '/' route to return hello."""
527
527
 
528
528
  @app.get("/")
529
529
  async def hello(request: Request) -> HTTPResponse:
530
530
  """Check if the server is running and responds with the version."""
531
+ if not is_inspector_enabled:
532
+ return response.text("Hello from Rasa: " + rasa.__version__)
533
+
531
534
  html_content = f"""
532
535
  <html>
533
536
  <body>
@@ -688,6 +691,7 @@ def create_app(
688
691
  jwt_private_key: Optional[Text] = None,
689
692
  jwt_method: Text = "HS256",
690
693
  endpoints: Optional[AvailableEndpoints] = None,
694
+ is_inspector_enabled: bool = False,
691
695
  ) -> Sanic:
692
696
  """Class representing a Rasa HTTP server."""
693
697
  app = Sanic("rasa_server")
@@ -733,7 +737,7 @@ def create_app(
733
737
  ) -> HTTPResponse:
734
738
  return response.json(exception.error_info, status=exception.status)
735
739
 
736
- add_root_route(app)
740
+ add_root_route(app, is_inspector_enabled)
737
741
 
738
742
  @app.get("/version")
739
743
  async def version(request: Request) -> HTTPResponse:
@@ -107,6 +107,8 @@ if TYPE_CHECKING:
107
107
  logger = logging.getLogger(__name__)
108
108
  structlogger = structlog.get_logger()
109
109
 
110
+ INVALID_DATETIME_ERROR_MESSAGE = "`anonymized_at` must be a datetime object."
111
+
110
112
 
111
113
  def deserialise_events(serialized_events: List[Dict[Text, Any]]) -> List["Event"]:
112
114
  """Convert a list of dictionaries to a list of corresponding events.
@@ -498,6 +500,23 @@ class UserUttered(Event):
498
500
  if parse_data:
499
501
  self.parse_data.update(**parse_data)
500
502
 
503
+ self._anonymized_at: Optional[datetime] = None
504
+
505
+ @property
506
+ def anonymized_at(self) -> Optional[datetime]:
507
+ """Returns the time when the event was anonymized in the tracker store.
508
+
509
+ If the event was not anonymized, it returns None.
510
+ """
511
+ return self._anonymized_at
512
+
513
+ @anonymized_at.setter
514
+ def anonymized_at(self, value: Optional[datetime]) -> None:
515
+ """Sets the time when the event was anonymized in the tracker store."""
516
+ if value is not None and not isinstance(value, datetime):
517
+ raise ValueError(INVALID_DATETIME_ERROR_MESSAGE)
518
+ self._anonymized_at = value
519
+
501
520
  @staticmethod
502
521
  def _from_parse_data(
503
522
  text: Text,
@@ -614,6 +633,7 @@ class UserUttered(Event):
614
633
  "input_channel": getattr(self, "input_channel", None),
615
634
  "message_id": getattr(self, "message_id", None),
616
635
  "metadata": self.metadata,
636
+ "anonymized_at": self.anonymized_at,
617
637
  }
618
638
  )
619
639
  return _dict
@@ -911,8 +931,24 @@ class BotUttered(SkipEventInMDStoryMixin):
911
931
  """
912
932
  self.text = text
913
933
  self.data = data or {}
934
+ self._anonymized_at: Optional[datetime] = None
914
935
  super().__init__(timestamp, metadata)
915
936
 
937
+ @property
938
+ def anonymized_at(self) -> Optional[datetime]:
939
+ """Returns the time when the event was anonymized in the tracker store.
940
+
941
+ If the event was not anonymized, it returns None.
942
+ """
943
+ return self._anonymized_at
944
+
945
+ @anonymized_at.setter
946
+ def anonymized_at(self, value: Optional[datetime]) -> None:
947
+ """Sets the time when the event was anonymized in the tracker store."""
948
+ if value is not None and not isinstance(value, datetime):
949
+ raise ValueError(INVALID_DATETIME_ERROR_MESSAGE)
950
+ self._anonymized_at = value
951
+
916
952
  def __members(self) -> Tuple[Optional[Text], Text, Text]:
917
953
  data_no_nones = {k: v for k, v in self.data.items() if v is not None}
918
954
  meta_no_nones = {k: v for k, v in self.metadata.items() if v is not None}
@@ -999,7 +1035,14 @@ class BotUttered(SkipEventInMDStoryMixin):
999
1035
  def as_dict(self) -> Dict[Text, Any]:
1000
1036
  """Returns serialized event."""
1001
1037
  d = super().as_dict()
1002
- d.update({"text": self.text, "data": self.data, "metadata": self.metadata})
1038
+ d.update(
1039
+ {
1040
+ "text": self.text,
1041
+ "data": self.data,
1042
+ "metadata": self.metadata,
1043
+ "anonymized_at": self.anonymized_at,
1044
+ }
1045
+ )
1003
1046
  return d
1004
1047
 
1005
1048
  @classmethod
@@ -1046,8 +1089,24 @@ class SlotSet(Event):
1046
1089
  self.key = key
1047
1090
  self.value = value
1048
1091
  self._filled_by = filled_by
1092
+ self._anonymized_at: Optional[datetime] = None
1049
1093
  super().__init__(timestamp, metadata)
1050
1094
 
1095
+ @property
1096
+ def anonymized_at(self) -> Optional[datetime]:
1097
+ """Returns the time when the event was anonymized in the tracker store.
1098
+
1099
+ If the event was not anonymized, it returns None.
1100
+ """
1101
+ return self._anonymized_at
1102
+
1103
+ @anonymized_at.setter
1104
+ def anonymized_at(self, value: Optional[datetime]) -> None:
1105
+ """Sets the time when the event was anonymized in the tracker store."""
1106
+ if value is not None and not isinstance(value, datetime):
1107
+ raise ValueError(INVALID_DATETIME_ERROR_MESSAGE)
1108
+ self._anonymized_at = value
1109
+
1051
1110
  def __repr__(self) -> Text:
1052
1111
  """Returns text representation of event."""
1053
1112
  return f"SlotSet(key: {self.key}, value: {self.value})"
@@ -1092,7 +1151,14 @@ class SlotSet(Event):
1092
1151
  def as_dict(self) -> Dict[Text, Any]:
1093
1152
  """Returns serialized event."""
1094
1153
  d = super().as_dict()
1095
- d.update({"name": self.key, "value": self.value, "filled_by": self.filled_by})
1154
+ d.update(
1155
+ {
1156
+ "name": self.key,
1157
+ "value": self.value,
1158
+ "filled_by": self.filled_by,
1159
+ "anonymized_at": self.anonymized_at,
1160
+ }
1161
+ )
1096
1162
  return d
1097
1163
 
1098
1164
  @classmethod
rasa/telemetry.py CHANGED
@@ -64,7 +64,7 @@ if typing.TYPE_CHECKING:
64
64
  from rasa.core.agent import Agent
65
65
  from rasa.core.brokers.broker import EventBroker
66
66
  from rasa.core.channels.channel import InputChannel
67
- from rasa.core.tracker_store import TrackerStore
67
+ from rasa.core.tracker_stores.tracker_store import TrackerStore
68
68
  from rasa.core.utils import AvailableEndpoints
69
69
  from rasa.e2e_test.e2e_test_case import Fixture, Metadata, TestCase
70
70
  from rasa.shared.importers.importer import TrainingDataImporter
@@ -915,7 +915,7 @@ def initialize_error_reporting() -> None:
915
915
  OSError,
916
916
  ],
917
917
  in_app_include=["rasa"], # only submit errors in this package
918
- with_locals=False, # don't submit local variables
918
+ include_local_variables=False, # don't submit local variables
919
919
  release=f"rasa-{rasa.__version__}",
920
920
  default_integrations=False,
921
921
  environment="development" if in_continuous_integration() else "production",
rasa/tracing/config.py CHANGED
@@ -23,7 +23,7 @@ from rasa.core.actions.custom_action_executor import (
23
23
  from rasa.core.actions.grpc_custom_action_executor import GRPCCustomActionExecutor
24
24
  from rasa.core.agent import Agent
25
25
  from rasa.core.processor import MessageProcessor
26
- from rasa.core.tracker_store import TrackerStore
26
+ from rasa.core.tracker_stores.tracker_store import TrackerStore
27
27
  from rasa.dialogue_understanding.commands import (
28
28
  Command,
29
29
  FreeFormAnswerCommand,
@@ -16,7 +16,7 @@ from rasa.core.channels import UserMessage
16
16
  from rasa.core.lock_store import LOCK_LIFETIME, LockStore
17
17
  from rasa.core.nlg.contextual_response_rephraser import ContextualResponseRephraser
18
18
  from rasa.core.processor import MessageProcessor
19
- from rasa.core.tracker_store import TrackerStore
19
+ from rasa.core.tracker_stores.tracker_store import TrackerStore
20
20
  from rasa.dialogue_understanding.commands import Command
21
21
  from rasa.dialogue_understanding.generator import LLMBasedCommandGenerator
22
22
  from rasa.dialogue_understanding.generator.constants import FLOW_RETRIEVAL_KEY
@@ -38,7 +38,7 @@ from rasa.core.nlg import NaturalLanguageGenerator
38
38
  from rasa.core.policies.flows.flow_step_result import FlowActionPrediction
39
39
  from rasa.core.policies.policy import Policy, PolicyPrediction
40
40
  from rasa.core.processor import MessageProcessor
41
- from rasa.core.tracker_store import TrackerStore
41
+ from rasa.core.tracker_stores.tracker_store import TrackerStore
42
42
  from rasa.dialogue_understanding.commands import Command
43
43
  from rasa.dialogue_understanding.generator import (
44
44
  CompactLLMCommandGenerator,
rasa/utils/licensing.py CHANGED
@@ -18,8 +18,7 @@ from rasa import telemetry
18
18
  from rasa.shared.utils.cli import print_error_and_exit
19
19
 
20
20
  if typing.TYPE_CHECKING:
21
- from rasa.core.tracker_store import TrackerStore
22
-
21
+ from rasa.core.tracker_stores.tracker_store import TrackerStore
23
22
 
24
23
  LICENSE_ENV_VAR = "RASA_PRO_LICENSE"
25
24
  ALGORITHM = "RS256"
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.0.dev5"
3
+ __version__ = "3.13.0.dev20250612"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rasa-pro
3
- Version: 3.13.0.dev5
3
+ Version: 3.13.0.dev20250612
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.69.0,<1.70.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)
@@ -115,7 +115,7 @@ Requires-Dist: sanic-routing (>=22.8.0,<23.0.0)
115
115
  Requires-Dist: scikit-learn (>=1.5.1,<1.6.0)
116
116
  Requires-Dist: scipy (>=1.13.1,<1.14.0)
117
117
  Requires-Dist: sentencepiece[sentencepiece] (>=0.1.99,<0.2.0) ; extra == "transformers" or extra == "full"
118
- Requires-Dist: sentry-sdk (>=1.14.0,<1.15.0)
118
+ Requires-Dist: sentry-sdk (>=2.8.0,<3)
119
119
  Requires-Dist: setuptools (>=70.0.0,<70.1.0)
120
120
  Requires-Dist: sklearn-crfsuite (>=0.3.6,<0.4.0)
121
121
  Requires-Dist: skops (>=0.10.0,<0.11.0)