rasa-pro 3.13.0rc3__py3-none-any.whl → 3.13.1a2__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 (67) hide show
  1. rasa/builder/README.md +120 -0
  2. rasa/builder/__init__.py +0 -0
  3. rasa/builder/config.py +69 -0
  4. rasa/builder/create_openai_vector_store.py +228 -0
  5. rasa/builder/exceptions.py +49 -0
  6. rasa/builder/llm-helper-schema.json +69 -0
  7. rasa/builder/llm_context.py +81 -0
  8. rasa/builder/llm_helper_prompt.jinja2 +245 -0
  9. rasa/builder/llm_service.py +327 -0
  10. rasa/builder/logging_utils.py +51 -0
  11. rasa/builder/main.py +61 -0
  12. rasa/builder/models.py +174 -0
  13. rasa/builder/project_generator.py +264 -0
  14. rasa/builder/scrape_rasa_docs.py +97 -0
  15. rasa/builder/service.py +447 -0
  16. rasa/builder/skill_to_bot_prompt.jinja2 +164 -0
  17. rasa/builder/training_service.py +123 -0
  18. rasa/builder/validation_service.py +79 -0
  19. rasa/cli/project_templates/finance/config.yml +17 -0
  20. rasa/cli/project_templates/finance/credentials.yml +33 -0
  21. rasa/cli/project_templates/finance/data/flows/transfer_money.yml +5 -0
  22. rasa/cli/project_templates/finance/data/patterns/pattern_session_start.yml +7 -0
  23. rasa/cli/project_templates/finance/domain.yml +7 -0
  24. rasa/cli/project_templates/finance/endpoints.yml +58 -0
  25. rasa/cli/project_templates/plain/config.yml +17 -0
  26. rasa/cli/project_templates/plain/credentials.yml +33 -0
  27. rasa/cli/project_templates/plain/data/patterns/pattern_session_start.yml +7 -0
  28. rasa/cli/project_templates/plain/domain.yml +5 -0
  29. rasa/cli/project_templates/plain/endpoints.yml +58 -0
  30. rasa/cli/project_templates/telecom/config.yml +17 -0
  31. rasa/cli/project_templates/telecom/credentials.yml +33 -0
  32. rasa/cli/project_templates/telecom/data/flows/upgrade_contract.yml +5 -0
  33. rasa/cli/project_templates/telecom/data/patterns/pattern_session_start.yml +7 -0
  34. rasa/cli/project_templates/telecom/domain.yml +7 -0
  35. rasa/cli/project_templates/telecom/endpoints.yml +58 -0
  36. rasa/cli/scaffold.py +19 -3
  37. rasa/core/actions/action.py +5 -3
  38. rasa/core/channels/studio_chat.py +29 -8
  39. rasa/core/policies/flows/flow_executor.py +8 -1
  40. rasa/core/tracker_stores/auth_retry_tracker_store.py +64 -3
  41. rasa/core/tracker_stores/dynamo_tracker_store.py +10 -0
  42. rasa/core/tracker_stores/mongo_tracker_store.py +17 -0
  43. rasa/core/tracker_stores/redis_tracker_store.py +23 -0
  44. rasa/core/tracker_stores/sql_tracker_store.py +27 -0
  45. rasa/core/tracker_stores/tracker_store.py +36 -2
  46. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +1 -1
  47. rasa/model_manager/model_api.py +2 -2
  48. rasa/model_manager/runner_service.py +1 -1
  49. rasa/model_manager/trainer_service.py +12 -9
  50. rasa/model_manager/utils.py +1 -29
  51. rasa/privacy/privacy_manager.py +19 -16
  52. rasa/shared/core/domain.py +62 -15
  53. rasa/shared/core/flows/flow_step.py +7 -1
  54. rasa/shared/core/flows/yaml_flows_io.py +16 -8
  55. rasa/shared/core/slots.py +4 -0
  56. rasa/shared/importers/importer.py +6 -0
  57. rasa/shared/importers/static.py +63 -0
  58. rasa/telemetry.py +2 -1
  59. rasa/utils/io.py +27 -9
  60. rasa/utils/log_utils.py +5 -1
  61. rasa/validator.py +7 -3
  62. rasa/version.py +1 -1
  63. {rasa_pro-3.13.0rc3.dist-info → rasa_pro-3.13.1a2.dist-info}/METADATA +3 -3
  64. {rasa_pro-3.13.0rc3.dist-info → rasa_pro-3.13.1a2.dist-info}/RECORD +67 -31
  65. {rasa_pro-3.13.0rc3.dist-info → rasa_pro-3.13.1a2.dist-info}/NOTICE +0 -0
  66. {rasa_pro-3.13.0rc3.dist-info → rasa_pro-3.13.1a2.dist-info}/WHEEL +0 -0
  67. {rasa_pro-3.13.0rc3.dist-info → rasa_pro-3.13.1a2.dist-info}/entry_points.txt +0 -0
@@ -98,6 +98,8 @@ IS_RETRIEVAL_INTENT_KEY = "is_retrieval_intent"
98
98
  ENTITY_ROLES_KEY = "roles"
99
99
  ENTITY_GROUPS_KEY = "groups"
100
100
  ENTITY_FEATURIZATION_KEY = "influence_conversation"
101
+ STORE_ENTITIES_AS_SLOTS_KEY = "store_entities_as_slots"
102
+ DOMAIN_CONFIG_KEY = "config"
101
103
 
102
104
  KEY_SLOTS = "slots"
103
105
  KEY_INTENTS = "intents"
@@ -146,6 +148,8 @@ MERGE_FUNC_MAPPING: Dict[Text, Callable[..., Any]] = {
146
148
  KEY_FORMS: rasa.shared.utils.common.merge_dicts,
147
149
  }
148
150
 
151
+ DEFAULT_STORE_ENTITIES_AS_SLOTS = True
152
+
149
153
  DICT_DATA_KEYS = [
150
154
  key
151
155
  for key, value in MERGE_FUNC_MAPPING.items()
@@ -318,7 +322,7 @@ class Domain:
318
322
  actions = cls._collect_action_names(domain_actions)
319
323
 
320
324
  additional_arguments = {
321
- **data.get("config", {}),
325
+ **data.get(DOMAIN_CONFIG_KEY, {}),
322
326
  "actions_which_explicitly_need_domain": (
323
327
  cls._collect_actions_which_explicitly_need_domain(domain_actions)
324
328
  ),
@@ -468,9 +472,9 @@ class Domain:
468
472
  return domain_dict
469
473
 
470
474
  if override:
471
- config = domain_dict.get("config", {})
475
+ config = domain_dict.get(DOMAIN_CONFIG_KEY, {})
472
476
  for key, val in config.items():
473
- combined["config"][key] = val
477
+ combined[DOMAIN_CONFIG_KEY][key] = val
474
478
 
475
479
  if (
476
480
  override
@@ -508,10 +512,10 @@ class Domain:
508
512
  return combined
509
513
 
510
514
  def partial_merge(self, other: Domain) -> Domain:
511
- """
512
- Returns a new Domain with intersection-based merging:
513
- - For each domain section only overwrite items that already exist in self.
514
- - Brand-new items in `other` are ignored.
515
+ """Returns a new Domain with intersection-based merging.
516
+
517
+ For each domain section only overwrite items that already exist in self.
518
+ Brand-new items in `other` are ignored.
515
519
 
516
520
  Args:
517
521
  other: The domain to merge with.
@@ -543,9 +547,9 @@ class Domain:
543
547
  return Domain.from_dict(updated_self)
544
548
 
545
549
  def difference(self, other: Domain) -> Domain:
546
- """
547
- Returns a new Domain containing items in `self` that are NOT in `other`,
548
- using simple equality checks for dict/list items.
550
+ """Returns a new Domain containing items in `self` that are NOT in `other`.
551
+
552
+ Uses simple equality checks for dict/list items.
549
553
 
550
554
  Args:
551
555
  other: The domain to compare with.
@@ -598,9 +602,16 @@ class Domain:
598
602
  ) -> Dict:
599
603
  # add the config, session_config and training data version defaults
600
604
  # if not included in the original domain dict
601
- if "config" not in data and not store_entities_as_slots:
605
+ if (
606
+ DOMAIN_CONFIG_KEY not in data
607
+ and store_entities_as_slots != DEFAULT_STORE_ENTITIES_AS_SLOTS
608
+ ):
602
609
  data.update(
603
- {"config": {"store_entities_as_slots": store_entities_as_slots}}
610
+ {
611
+ DOMAIN_CONFIG_KEY: {
612
+ STORE_ENTITIES_AS_SLOTS_KEY: store_entities_as_slots
613
+ }
614
+ }
604
615
  )
605
616
 
606
617
  if SESSION_CONFIG_KEY not in data:
@@ -937,7 +948,7 @@ class Domain:
937
948
  forms: Union[Dict[Text, Any], List[Text]],
938
949
  data: Dict,
939
950
  action_texts: Optional[List[Text]] = None,
940
- store_entities_as_slots: bool = True,
951
+ store_entities_as_slots: bool = DEFAULT_STORE_ENTITIES_AS_SLOTS,
941
952
  session_config: SessionConfig = SessionConfig.default(),
942
953
  **kwargs: Any,
943
954
  ) -> None:
@@ -1711,9 +1722,45 @@ class Domain:
1711
1722
  else:
1712
1723
  return True
1713
1724
 
1714
- def as_dict(self) -> Dict[Text, Any]:
1725
+ def _uses_custom_session_config(self) -> bool:
1726
+ """Check if the domain uses a custom session config."""
1727
+ return self._data.get(SESSION_CONFIG_KEY) != SessionConfig.default().as_dict()
1728
+
1729
+ def _uses_custom_domain_config(self) -> bool:
1730
+ """Check if the domain uses a custom domain config."""
1731
+ return self._data.get(DOMAIN_CONFIG_KEY) != {
1732
+ STORE_ENTITIES_AS_SLOTS_KEY: DEFAULT_STORE_ENTITIES_AS_SLOTS
1733
+ }
1734
+
1735
+ def _cleaned_json_data(self) -> Dict[Text, Any]:
1736
+ """Remove default values from the domain data.
1737
+
1738
+ Only retains data that was customized by the user.
1739
+
1740
+ Returns:
1741
+ A cleaned dictionary version of the domain.
1742
+ """
1743
+ cleaned_data = copy.deepcopy(self._data)
1744
+
1745
+ # Remove default config if it only contains store_entities_as_slots: False
1746
+ if DOMAIN_CONFIG_KEY in cleaned_data and not self._uses_custom_domain_config():
1747
+ del cleaned_data[DOMAIN_CONFIG_KEY]
1748
+
1749
+ # Remove default session config if it matches the default values
1750
+ if (
1751
+ SESSION_CONFIG_KEY in cleaned_data
1752
+ and not self._uses_custom_session_config()
1753
+ ):
1754
+ del cleaned_data[SESSION_CONFIG_KEY]
1755
+
1756
+ return cleaned_data
1757
+
1758
+ def as_dict(self, should_clean_json: bool = False) -> Dict[Text, Any]:
1715
1759
  """Return serialized `Domain`."""
1716
- return self._data
1760
+ if should_clean_json:
1761
+ return self._cleaned_json_data()
1762
+ else:
1763
+ return self._data
1717
1764
 
1718
1765
  @staticmethod
1719
1766
  def get_responses_with_multilines(
@@ -52,7 +52,13 @@ def step_from_json(flow_id: Text, data: Dict[Text, Any]) -> FlowStep:
52
52
  return SetSlotsFlowStep.from_json(flow_id, data)
53
53
  if "noop" in data:
54
54
  return NoOperationFlowStep.from_json(flow_id, data)
55
- raise RasaException(f"Failed to parse step from json. Unknown type for {data}.")
55
+
56
+ required_properties = ["action", "collect", "link", "call", "set_slots", "noop"]
57
+ raise RasaException(
58
+ f"Failed to parse step from json. Unknown type for {data}. "
59
+ f"At lest one of the following properties is required: "
60
+ f"{', '.join(required_properties)}"
61
+ )
56
62
 
57
63
 
58
64
  @dataclass
@@ -262,12 +262,9 @@ class YamlFlowsWriter:
262
262
  Returns:
263
263
  The dumped YAML.
264
264
  """
265
- dump = {}
266
- for flow in flows:
267
- dumped_flow = get_flow_as_json(flow, should_clean_json)
268
- del dumped_flow["id"]
269
- dump[flow.id] = dumped_flow
270
- return dump_obj_as_yaml_to_string({KEY_FLOWS: dump})
265
+ return dump_obj_as_yaml_to_string(
266
+ {KEY_FLOWS: get_flows_as_json(flows, should_clean_json)}
267
+ )
271
268
 
272
269
  @staticmethod
273
270
  def dump(
@@ -424,9 +421,20 @@ def process_yaml_content(yaml_content: Dict[str, Any]) -> Dict[str, Any]:
424
421
  return yaml_content
425
422
 
426
423
 
424
+ def get_flows_as_json(
425
+ flows: FlowsList, should_clean_json: bool = False
426
+ ) -> Dict[str, Any]:
427
+ """Get the flows as a JSON dictionary."""
428
+ dump = {}
429
+ for flow in flows:
430
+ dumped_flow = get_flow_as_json(flow, should_clean_json)
431
+ del dumped_flow["id"]
432
+ dump[flow.id] = dumped_flow
433
+ return dump
434
+
435
+
427
436
  def get_flow_as_json(flow: Flow, should_clean_json: bool = False) -> Dict[str, Any]:
428
- """
429
- Clean the Flow JSON by removing default values and empty fields.
437
+ """Clean the Flow JSON by removing default values and empty fields.
430
438
 
431
439
  Args:
432
440
  flow: The Flow object to clean.
rasa/shared/core/slots.py CHANGED
@@ -273,10 +273,14 @@ class Slot(ABC):
273
273
  try:
274
274
  return rasa.shared.utils.common.class_from_module_path(type_name)
275
275
  except (ImportError, AttributeError):
276
+ known_types = [
277
+ cls.type_name for cls in rasa.shared.utils.common.all_subclasses(Slot)
278
+ ]
276
279
  raise InvalidSlotTypeException(
277
280
  f"Failed to find slot type, '{type_name}' is neither a known type nor "
278
281
  f"user-defined. If you are creating your own slot type, make "
279
282
  f"sure its module path is correct. "
283
+ f"Known types: {', '.join(known_types)} "
280
284
  f"You can find all build in types at {DOCS_URL_SLOTS}"
281
285
  )
282
286
 
@@ -207,6 +207,12 @@ class TrainingDataImporter(ABC):
207
207
  )
208
208
  ]
209
209
 
210
+ return TrainingDataImporter.wrap_in_builtins(importers)
211
+
212
+ @staticmethod
213
+ def wrap_in_builtins(
214
+ importers: List["TrainingDataImporter"],
215
+ ) -> "TrainingDataImporter":
210
216
  return LanguageImporter(
211
217
  E2EImporter(
212
218
  FlowSyncImporter(ResponsesSyncImporter(CombinedDataImporter(importers)))
@@ -0,0 +1,63 @@
1
+ import logging
2
+ from typing import Dict, Optional, Text
3
+
4
+ from rasa.shared.core.domain import Domain
5
+ from rasa.shared.core.flows import FlowsList
6
+ from rasa.shared.core.training_data.structures import StoryGraph
7
+ from rasa.shared.importers.importer import TrainingDataImporter
8
+ from rasa.shared.nlu.training_data.training_data import TrainingData
9
+ from rasa.shared.utils.common import cached_method
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class StaticTrainingDataImporter(TrainingDataImporter):
15
+ """Static `TrainingFileImporter` implementation."""
16
+
17
+ def __init__(
18
+ self,
19
+ domain: Domain,
20
+ stories: Optional[StoryGraph] = None,
21
+ flows: Optional[FlowsList] = None,
22
+ nlu_data: Optional[TrainingData] = None,
23
+ config: Optional[Dict] = None,
24
+ ):
25
+ self.domain = domain
26
+ self.stories = stories or StoryGraph([])
27
+ self.flows = flows or FlowsList(underlying_flows=[])
28
+ self.nlu_data = nlu_data or TrainingData()
29
+ self.config = config or {}
30
+
31
+ @cached_method
32
+ def get_config(self) -> Dict:
33
+ """Retrieves model config (see parent class for full docstring)."""
34
+ return self.config
35
+
36
+ def get_config_file_for_auto_config(self) -> Optional[Text]:
37
+ """Returns config file path for auto-config only if there is a single one."""
38
+ return None
39
+
40
+ @cached_method
41
+ def get_stories(self, exclusion_percentage: Optional[int] = None) -> StoryGraph:
42
+ """Retrieves training stories / rules (see parent class for full docstring)."""
43
+ return self.stories
44
+
45
+ @cached_method
46
+ def get_flows(self) -> FlowsList:
47
+ """Retrieves training stories / rules (see parent class for full docstring)."""
48
+ return self.flows
49
+
50
+ @cached_method
51
+ def get_conversation_tests(self) -> StoryGraph:
52
+ """Retrieves conversation test stories (see parent class for full docstring)."""
53
+ return StoryGraph([])
54
+
55
+ @cached_method
56
+ def get_nlu_data(self, language: Optional[Text] = "en") -> TrainingData:
57
+ """Retrieves NLU training data (see parent class for full docstring)."""
58
+ return self.nlu_data
59
+
60
+ @cached_method
61
+ def get_domain(self) -> Domain:
62
+ """Retrieves model domain (see parent class for full docstring)."""
63
+ return self.domain
rasa/telemetry.py CHANGED
@@ -1426,6 +1426,7 @@ def track_shell_started(model_type: Text, assistant_id: Text) -> None:
1426
1426
 
1427
1427
  Args:
1428
1428
  model_type: Type of the model, core / nlu or rasa.
1429
+ assistant_id: ID of the assistant being inspected.
1429
1430
  """
1430
1431
  _track(
1431
1432
  TELEMETRY_SHELL_STARTED_EVENT,
@@ -1997,7 +1998,7 @@ def _extract_stream_pii(event_broker: Optional["EventBroker"]) -> bool:
1997
1998
  def track_privacy_enabled(
1998
1999
  privacy_config: "PrivacyConfig", event_broker: Optional["EventBroker"]
1999
2000
  ) -> None:
2000
- """Track when PII management capability is enabled"""
2001
+ """Track when PII management capability is enabled."""
2001
2002
  stream_pii = _extract_stream_pii(event_broker)
2002
2003
  privacy_properties = _extract_privacy_enabled_event_properties(
2003
2004
  privacy_config, stream_pii
rasa/utils/io.py CHANGED
@@ -26,6 +26,7 @@ from typing_extensions import Protocol
26
26
 
27
27
  import rasa.shared.constants
28
28
  import rasa.shared.utils.io
29
+ from rasa.shared.exceptions import RasaException
29
30
 
30
31
  if TYPE_CHECKING:
31
32
  from prompt_toolkit.validation import Validator
@@ -124,9 +125,7 @@ def create_path(file_path: Text) -> None:
124
125
  def file_type_validator(
125
126
  valid_file_types: List[Text], error_message: Text
126
127
  ) -> Type["Validator"]:
127
- """Creates a `Validator` class which can be used with `questionary` to validate
128
- file paths.
129
- """
128
+ """Creates a file type validator class for the questionary package."""
130
129
 
131
130
  def is_valid(path: Text) -> bool:
132
131
  return path is not None and any(
@@ -137,9 +136,7 @@ def file_type_validator(
137
136
 
138
137
 
139
138
  def not_empty_validator(error_message: Text) -> Type["Validator"]:
140
- """Creates a `Validator` class which can be used with `questionary` to validate
141
- that the user entered something other than whitespace.
142
- """
139
+ """Creates a not empty validator class for the questionary package."""
143
140
 
144
141
  def is_valid(input: Text) -> bool:
145
142
  return input is not None and input.strip() != ""
@@ -150,9 +147,7 @@ def not_empty_validator(error_message: Text) -> Type["Validator"]:
150
147
  def create_validator(
151
148
  function: Callable[[Text], bool], error_message: Text
152
149
  ) -> Type["Validator"]:
153
- """Helper method to create `Validator` classes from callable functions. Should be
154
- removed when questionary supports `Validator` objects.
155
- """
150
+ """Helper method to create a validator class from a callable function."""
156
151
  from prompt_toolkit.document import Document
157
152
  from prompt_toolkit.validation import ValidationError, Validator
158
153
 
@@ -250,3 +245,26 @@ def write_yaml(
250
245
 
251
246
  with Path(target).open("w", encoding="utf-8") as outfile:
252
247
  dumper.dump(data, outfile, transform=transform)
248
+
249
+
250
+ class InvalidPathException(RasaException):
251
+ """Raised if a path is invalid - e.g. path traversal is detected."""
252
+
253
+
254
+ def subpath(parent: str, child: str) -> str:
255
+ """Return the path to the child directory of the parent directory.
256
+
257
+ Ensures, that child doesn't navigate to parent directories. Prevents
258
+ path traversal. Raises an InvalidPathException if the path is invalid.
259
+
260
+ Based on Snyk's directory traversal mitigation:
261
+ https://learn.snyk.io/lesson/directory-traversal/
262
+ """
263
+ safe_path = os.path.abspath(os.path.join(parent, child))
264
+ parent = os.path.abspath(parent)
265
+
266
+ common_base = os.path.commonpath([parent, safe_path])
267
+ if common_base != parent:
268
+ raise InvalidPathException(f"Invalid path: {safe_path}")
269
+
270
+ return safe_path
rasa/utils/log_utils.py CHANGED
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import logging
4
4
  import os
5
5
  import sys
6
- from typing import Any, Optional
6
+ from typing import Any, List, Optional
7
7
 
8
8
  import structlog
9
9
  from structlog.dev import ConsoleRenderer
@@ -37,6 +37,7 @@ class HumanConsoleRenderer(ConsoleRenderer):
37
37
  def configure_structlog(
38
38
  log_level: Optional[int] = None,
39
39
  include_time: bool = False,
40
+ additional_processors: Optional[List[structlog.processors.Processor]] = None,
40
41
  ) -> None:
41
42
  """Configure logging of the server."""
42
43
  if log_level is None: # Log level NOTSET is 0 so we use `is None` here
@@ -75,6 +76,9 @@ def configure_structlog(
75
76
  if include_time:
76
77
  shared_processors.append(structlog.processors.TimeStamper(fmt="iso"))
77
78
 
79
+ if additional_processors:
80
+ shared_processors.extend(additional_processors)
81
+
78
82
  if not FORCE_JSON_LOGGING and sys.stderr.isatty():
79
83
  # Pretty printing when we run in a terminal session.
80
84
  # Automatically prints pretty tracebacks when "rich" is installed
rasa/validator.py CHANGED
@@ -630,11 +630,14 @@ class Validator:
630
630
  flow_id: str,
631
631
  ) -> bool:
632
632
  """Validates that a collect step can have either an action or an utterance.
633
+
633
634
  Also logs an error if neither an action nor an utterance is defined.
634
635
 
635
636
  Args:
636
637
  collect: the name of the slot to collect
637
638
  all_good: boolean value indicating the validation status
639
+ domain_slots: the slots of the domain
640
+ flow_id: the id of the flow
638
641
 
639
642
  Returns:
640
643
  False, if validation failed, true, otherwise
@@ -683,9 +686,10 @@ class Validator:
683
686
  has_action_defined=has_action_defined,
684
687
  flow=flow_id,
685
688
  event_info=(
686
- f"The collect step '{collect.collect}' has neither an utterance "
687
- f"nor an action defined, or an initial value defined in the domain."
688
- f"You need to define either an utterance or an action."
689
+ f"The collect step '{collect.collect}' has neither a response "
690
+ f"nor an action defined, nor an initial value defined in the "
691
+ f"domain. You can fix this by adding a response named "
692
+ f"'{collect.utter}' used in the collect step."
689
693
  ),
690
694
  )
691
695
  all_good = False
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.1a2"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rasa-pro
3
- Version: 3.13.0rc3
3
+ Version: 3.13.1a2
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
@@ -81,7 +81,7 @@ Requires-Dist: pep440-version-utils (>=1.1.0,<1.2.0)
81
81
  Requires-Dist: pluggy (>=1.2.0,<2.0.0)
82
82
  Requires-Dist: portalocker (>=2.7.0,<3.0.0)
83
83
  Requires-Dist: prompt-toolkit (>=3.0.28,<3.0.29)
84
- Requires-Dist: protobuf (>=4.23.3,<4.25.4)
84
+ Requires-Dist: protobuf (>=4.25.8,<4.26.0)
85
85
  Requires-Dist: psutil (>=5.9.5,<6.0.0)
86
86
  Requires-Dist: psycopg2-binary (>=2.9.10,<2.10.0)
87
87
  Requires-Dist: pydot (>=1.4,<1.5)
@@ -115,7 +115,7 @@ Requires-Dist: scikit-learn (>=1.5.1,<1.6.0)
115
115
  Requires-Dist: scipy (>=1.13.1,<1.14.0)
116
116
  Requires-Dist: sentencepiece[sentencepiece] (>=0.1.99,<0.2.0) ; extra == "transformers" or extra == "full"
117
117
  Requires-Dist: sentry-sdk (>=2.8.0,<3)
118
- Requires-Dist: setuptools (>=70.0.0,<70.1.0)
118
+ Requires-Dist: setuptools (>=78.1.1,<78.2.0)
119
119
  Requires-Dist: sklearn-crfsuite (>=0.3.6,<0.4.0)
120
120
  Requires-Dist: skops (>=0.10.0,<0.11.0)
121
121
  Requires-Dist: slack-sdk (>=3.27.1,<3.28.0)