rasa-pro 3.13.0.dev20250613__py3-none-any.whl → 3.13.0rc1__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 (146) hide show
  1. rasa/cli/e2e_test.py +0 -7
  2. rasa/cli/export.py +2 -0
  3. rasa/cli/project_templates/tutorial/config.yml +1 -1
  4. rasa/cli/project_templates/tutorial/endpoints.yml +1 -1
  5. rasa/cli/studio/download.py +1 -23
  6. rasa/cli/studio/link.py +1 -2
  7. rasa/cli/studio/pull.py +3 -2
  8. rasa/cli/studio/push.py +1 -1
  9. rasa/cli/studio/train.py +0 -1
  10. rasa/core/channels/__init__.py +2 -0
  11. rasa/core/channels/development_inspector.py +1 -1
  12. rasa/core/channels/facebook.py +1 -4
  13. rasa/core/channels/inspector/README.md +3 -3
  14. rasa/core/channels/inspector/dist/assets/{arc-c4b064fc.js → arc-371401b1.js} +1 -1
  15. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-215b5026.js → blockDiagram-38ab4fdb-3f126156.js} +1 -1
  16. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-2b54a0a3.js → c4Diagram-3d4e48cf-12f22eb7.js} +1 -1
  17. rasa/core/channels/inspector/dist/assets/channel-f1efda17.js +1 -0
  18. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-daacea5f.js → classDiagram-70f12bd4-03b1d386.js} +1 -1
  19. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-930d4dc2.js → classDiagram-v2-f2320105-84f69d63.js} +1 -1
  20. rasa/core/channels/inspector/dist/assets/clone-fdf164e2.js +1 -0
  21. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-83c206ba.js → createText-2e5e7dd3-ca47fd38.js} +1 -1
  22. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-b0eb01d0.js → edges-e0da2a9e-f837ca8a.js} +1 -1
  23. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-17586500.js → erDiagram-9861fffd-8717ac54.js} +1 -1
  24. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-be2a1776.js → flowDb-956e92f1-94f38b83.js} +1 -1
  25. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-c2120ebd.js → flowDiagram-66a62f08-b616f9fb.js} +1 -1
  26. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-7d7a1629.js +1 -0
  27. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-a6ab5c48.js → flowchart-elk-definition-4a651766-f5d24bb8.js} +1 -1
  28. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-ef613457.js → ganttDiagram-c361ad54-b43ba8d9.js} +1 -1
  29. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-d59185b3.js → gitGraphDiagram-72cf32ee-c3aafaa5.js} +1 -1
  30. rasa/core/channels/inspector/dist/assets/{graph-0f155405.js → graph-0d0a2c10.js} +1 -1
  31. rasa/core/channels/inspector/dist/assets/{index-3862675e-d5f1d1b7.js → index-3862675e-58ea0305.js} +1 -1
  32. rasa/core/channels/inspector/dist/assets/{index-47737d3a.js → index-cce6f8a1.js} +3 -3
  33. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-b07d141f.js → infoDiagram-f8f76790-b8f60461.js} +1 -1
  34. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-1936d429.js → journeyDiagram-49397b02-95be5545.js} +1 -1
  35. rasa/core/channels/inspector/dist/assets/{layout-dde8d0f3.js → layout-da885b9b.js} +1 -1
  36. rasa/core/channels/inspector/dist/assets/{line-0c2c7ee0.js → line-f1c817d3.js} +1 -1
  37. rasa/core/channels/inspector/dist/assets/{linear-35dd89a4.js → linear-d42801e6.js} +1 -1
  38. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-56192851.js → mindmap-definition-fc14e90a-a38923a6.js} +1 -1
  39. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-fc21ed78.js → pieDiagram-8a3498a8-ca6e71e9.js} +1 -1
  40. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-25e98518.js → quadrantDiagram-120e2f19-b290dae9.js} +1 -1
  41. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-546ff1f5.js → requirementDiagram-deff3bca-03f02ceb.js} +1 -1
  42. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-02d8b82d.js → sankeyDiagram-04a897e0-c49eee40.js} +1 -1
  43. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-3ca5a92e.js → sequenceDiagram-704730f1-b2cd6a3d.js} +1 -1
  44. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-128ea07c.js → stateDiagram-587899a1-e53a2028.js} +1 -1
  45. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-95f290af.js → stateDiagram-v2-d93cdb3a-e1982a03.js} +1 -1
  46. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-4984898a.js → styles-6aaf32cf-d0226ca5.js} +1 -1
  47. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-1bf266ba.js → styles-9a916d00-0e21dc00.js} +1 -1
  48. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-60521c63.js → styles-c10674c1-9588494e.js} +1 -1
  49. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-a25b6e12.js → svgDrawCommon-08f97a94-be478d4f.js} +1 -1
  50. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-0fc086bf.js → timeline-definition-85554ec2-74631749.js} +1 -1
  51. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-44ee592e.js → xychartDiagram-e933f94c-a043552f.js} +1 -1
  52. rasa/core/channels/inspector/dist/index.html +1 -1
  53. rasa/core/channels/inspector/src/components/RecruitmentPanel.tsx +1 -1
  54. rasa/core/channels/socketio.py +56 -41
  55. rasa/core/channels/studio_chat.py +311 -8
  56. rasa/core/channels/voice_ready/audiocodes.py +1 -1
  57. rasa/core/channels/voice_stream/asr/azure.py +9 -0
  58. rasa/core/channels/voice_stream/audiocodes.py +1 -1
  59. rasa/core/channels/voice_stream/browser_audio.py +1 -1
  60. rasa/core/channels/voice_stream/jambonz.py +166 -0
  61. rasa/core/channels/voice_stream/tts/__init__.py +8 -0
  62. rasa/core/channels/voice_stream/twilio_media_streams.py +7 -0
  63. rasa/core/channels/voice_stream/voice_channel.py +14 -5
  64. rasa/core/exporter.py +36 -0
  65. rasa/core/information_retrieval/faiss.py +18 -11
  66. rasa/core/information_retrieval/ingestion/faq_parser.py +158 -0
  67. rasa/core/nlg/contextual_response_rephraser.py +10 -1
  68. rasa/core/policies/enterprise_search_policy.py +152 -262
  69. rasa/core/policies/enterprise_search_policy_config.py +241 -0
  70. rasa/core/policies/enterprise_search_prompt_with_relevancy_check_and_citation_template.jinja2 +6 -5
  71. rasa/core/policies/intentless_policy.py +47 -10
  72. rasa/core/utils.py +11 -2
  73. rasa/dialogue_understanding/coexistence/llm_based_router.py +9 -18
  74. rasa/dialogue_understanding/commands/__init__.py +4 -0
  75. rasa/dialogue_understanding/commands/cancel_flow_command.py +4 -2
  76. rasa/dialogue_understanding/commands/clarify_command.py +2 -2
  77. rasa/dialogue_understanding/commands/correct_slots_command.py +5 -6
  78. rasa/dialogue_understanding/commands/error_command.py +1 -1
  79. rasa/dialogue_understanding/commands/human_handoff_command.py +1 -3
  80. rasa/dialogue_understanding/commands/set_slot_command.py +4 -4
  81. rasa/dialogue_understanding/commands/skip_question_command.py +1 -3
  82. rasa/dialogue_understanding/commands/start_flow_command.py +3 -3
  83. rasa/dialogue_understanding/generator/command_generator.py +11 -1
  84. rasa/dialogue_understanding/generator/nlu_command_adapter.py +2 -2
  85. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_template.jinja2 +0 -2
  86. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +1 -0
  87. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +1 -0
  88. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2 +79 -0
  89. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +1 -0
  90. rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +2 -2
  91. rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +2 -18
  92. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +8 -11
  93. rasa/dialogue_understanding/patterns/cancel.py +1 -2
  94. rasa/dialogue_understanding/patterns/clarify.py +1 -1
  95. rasa/dialogue_understanding/patterns/correction.py +2 -2
  96. rasa/dialogue_understanding/processor/command_processor.py +8 -9
  97. rasa/dialogue_understanding/stack/utils.py +3 -1
  98. rasa/e2e_test/e2e_test_coverage_report.py +1 -1
  99. rasa/engine/graph.py +2 -2
  100. rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +1 -5
  101. rasa/shared/constants.py +12 -0
  102. rasa/shared/core/command_payload_reader.py +1 -5
  103. rasa/shared/core/events.py +1 -3
  104. rasa/shared/core/flows/constants.py +2 -0
  105. rasa/shared/core/flows/flow.py +126 -12
  106. rasa/shared/core/flows/flows_list.py +18 -1
  107. rasa/shared/core/flows/steps/link.py +7 -2
  108. rasa/shared/core/flows/validation.py +25 -5
  109. rasa/shared/core/training_data/story_reader/yaml_story_reader.py +1 -4
  110. rasa/shared/providers/_configs/azure_openai_client_config.py +2 -2
  111. rasa/shared/providers/_configs/default_litellm_client_config.py +1 -1
  112. rasa/shared/providers/_configs/huggingface_local_embedding_client_config.py +1 -1
  113. rasa/shared/providers/_configs/openai_client_config.py +1 -1
  114. rasa/shared/providers/_configs/rasa_llm_client_config.py +1 -1
  115. rasa/shared/providers/_configs/self_hosted_llm_client_config.py +1 -1
  116. rasa/shared/providers/_configs/utils.py +0 -99
  117. rasa/shared/utils/common.py +1 -1
  118. rasa/shared/utils/configs.py +110 -0
  119. rasa/shared/utils/constants.py +0 -3
  120. rasa/shared/utils/llm.py +37 -6
  121. rasa/shared/utils/pykwalify_extensions.py +0 -9
  122. rasa/studio/constants.py +1 -0
  123. rasa/studio/data_handler.py +8 -1
  124. rasa/studio/download.py +167 -0
  125. rasa/studio/link.py +1 -1
  126. rasa/studio/prompts.py +223 -0
  127. rasa/studio/pull/__init__.py +0 -0
  128. rasa/studio/{download/flows.py → pull/data.py} +2 -131
  129. rasa/studio/{download → pull}/domains.py +1 -1
  130. rasa/studio/pull/pull.py +235 -0
  131. rasa/studio/push.py +5 -0
  132. rasa/studio/train.py +1 -1
  133. rasa/tracing/instrumentation/attribute_extractors.py +20 -6
  134. rasa/utils/common.py +11 -0
  135. rasa/version.py +1 -1
  136. {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc1.dist-info}/METADATA +4 -4
  137. {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc1.dist-info}/RECORD +141 -134
  138. rasa/core/channels/inspector/dist/assets/channel-3730f5fd.js +0 -1
  139. rasa/core/channels/inspector/dist/assets/clone-e847561e.js +0 -1
  140. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-efbbfe00.js +0 -1
  141. rasa/studio/download/download.py +0 -416
  142. rasa/studio/pull.py +0 -94
  143. /rasa/{studio/download → core/information_retrieval/ingestion}/__init__.py +0 -0
  144. {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc1.dist-info}/NOTICE +0 -0
  145. {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc1.dist-info}/WHEEL +0 -0
  146. {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc1.dist-info}/entry_points.txt +0 -0
@@ -2,7 +2,7 @@ import dataclasses
2
2
  import importlib.resources
3
3
  import json
4
4
  import re
5
- from typing import TYPE_CHECKING, Any, Dict, List, Literal, Optional, Text
5
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Text
6
6
 
7
7
  import dotenv
8
8
  import structlog
@@ -12,9 +12,6 @@ from pydantic import ValidationError
12
12
  import rasa.shared.utils.io
13
13
  from rasa.core.available_endpoints import AvailableEndpoints
14
14
  from rasa.core.constants import (
15
- POLICY_MAX_HISTORY,
16
- POLICY_PRIORITY,
17
- SEARCH_POLICY_PRIORITY,
18
15
  UTTER_SOURCE_METADATA_KEY,
19
16
  )
20
17
  from rasa.core.information_retrieval import (
@@ -24,6 +21,14 @@ from rasa.core.information_retrieval import (
24
21
  create_from_endpoint_config,
25
22
  )
26
23
  from rasa.core.information_retrieval.faiss import FAISS_Store
24
+ from rasa.core.policies.enterprise_search_policy_config import (
25
+ DEFAULT_EMBEDDINGS_CONFIG,
26
+ DEFAULT_ENTERPRISE_SEARCH_CONFIG,
27
+ DEFAULT_LLM_CONFIG,
28
+ DEFAULT_VECTOR_STORE_TYPE,
29
+ SOURCE_PROPERTY,
30
+ EnterpriseSearchPolicyConfig,
31
+ )
27
32
  from rasa.core.policies.policy import Policy, PolicyPrediction
28
33
  from rasa.dialogue_understanding.generator.constants import (
29
34
  LLM_CONFIG_KEY,
@@ -47,18 +52,11 @@ from rasa.graph_components.providers.forms_provider import Forms
47
52
  from rasa.graph_components.providers.responses_provider import Responses
48
53
  from rasa.shared.constants import (
49
54
  EMBEDDINGS_CONFIG_KEY,
50
- MAX_COMPLETION_TOKENS_CONFIG_KEY,
51
- MAX_RETRIES_CONFIG_KEY,
52
55
  MODEL_CONFIG_KEY,
53
56
  MODEL_GROUP_ID_CONFIG_KEY,
54
57
  MODEL_NAME_CONFIG_KEY,
55
- OPENAI_PROVIDER,
56
- PROMPT_CONFIG_KEY,
57
- PROMPT_TEMPLATE_CONFIG_KEY,
58
58
  PROVIDER_CONFIG_KEY,
59
59
  RASA_PATTERN_CANNOT_HANDLE_NO_RELEVANT_ANSWER,
60
- TEMPERATURE_CONFIG_KEY,
61
- TIMEOUT_CONFIG_KEY,
62
60
  )
63
61
  from rasa.shared.core.constants import (
64
62
  ACTION_CANCEL_FLOW,
@@ -93,12 +91,9 @@ from rasa.shared.utils.health_check.embeddings_health_check_mixin import (
93
91
  from rasa.shared.utils.health_check.llm_health_check_mixin import LLMHealthCheckMixin
94
92
  from rasa.shared.utils.io import deep_container_fingerprint
95
93
  from rasa.shared.utils.llm import (
96
- DEFAULT_OPENAI_CHAT_MODEL_NAME,
97
- DEFAULT_OPENAI_EMBEDDING_MODEL_NAME,
98
94
  embedder_factory,
99
95
  get_prompt_template,
100
96
  llm_factory,
101
- resolve_model_client_config,
102
97
  sanitize_message_for_prompt,
103
98
  tracker_as_readable_transcript,
104
99
  )
@@ -119,42 +114,6 @@ structlogger = structlog.get_logger()
119
114
 
120
115
  dotenv.load_dotenv("./.env")
121
116
 
122
- SOURCE_PROPERTY = "source"
123
- VECTOR_STORE_TYPE_PROPERTY = "type"
124
- VECTOR_STORE_PROPERTY = "vector_store"
125
- VECTOR_STORE_THRESHOLD_PROPERTY = "threshold"
126
- TRACE_TOKENS_PROPERTY = "trace_prompt_tokens"
127
- CITATION_ENABLED_PROPERTY = "citation_enabled"
128
- USE_LLM_PROPERTY = "use_generative_llm"
129
- CHECK_RELEVANCY_PROPERTY = "check_relevancy"
130
- MAX_MESSAGES_IN_QUERY_KEY = "max_messages_in_query"
131
-
132
- DEFAULT_VECTOR_STORE_TYPE = "faiss"
133
- DEFAULT_VECTOR_STORE_THRESHOLD = 0.0
134
- DEFAULT_VECTOR_STORE = {
135
- VECTOR_STORE_TYPE_PROPERTY: DEFAULT_VECTOR_STORE_TYPE,
136
- SOURCE_PROPERTY: "./docs",
137
- VECTOR_STORE_THRESHOLD_PROPERTY: DEFAULT_VECTOR_STORE_THRESHOLD,
138
- }
139
-
140
- DEFAULT_CHECK_RELEVANCY_PROPERTY = False
141
- DEFAULT_USE_LLM_PROPERTY = True
142
- DEFAULT_CITATION_ENABLED_PROPERTY = False
143
-
144
- DEFAULT_LLM_CONFIG = {
145
- PROVIDER_CONFIG_KEY: OPENAI_PROVIDER,
146
- MODEL_CONFIG_KEY: DEFAULT_OPENAI_CHAT_MODEL_NAME,
147
- TIMEOUT_CONFIG_KEY: 10,
148
- TEMPERATURE_CONFIG_KEY: 0.0,
149
- MAX_COMPLETION_TOKENS_CONFIG_KEY: 256,
150
- MAX_RETRIES_CONFIG_KEY: 1,
151
- }
152
-
153
- DEFAULT_EMBEDDINGS_CONFIG = {
154
- PROVIDER_CONFIG_KEY: OPENAI_PROVIDER,
155
- MODEL_CONFIG_KEY: DEFAULT_OPENAI_EMBEDDING_MODEL_NAME,
156
- }
157
-
158
117
  ENTERPRISE_SEARCH_PROMPT_FILE_NAME = "enterprise_search_policy_prompt.jinja2"
159
118
  ENTERPRISE_SEARCH_CONFIG_FILE_NAME = "config.json"
160
119
 
@@ -176,10 +135,7 @@ DEFAULT_ENTERPRISE_SEARCH_PROMPT_WITH_RELEVANCY_CHECK_AND_CITATION_TEMPLATE = (
176
135
  )
177
136
  )
178
137
 
179
- # TODO: Update this pattern once the experiments are done
180
- _ENTERPRISE_SEARCH_ANSWER_NOT_RELEVANT_PATTERN = re.compile(
181
- r"\[NO_RELEVANT_ANSWER_FOUND\]"
182
- )
138
+ _ENTERPRISE_SEARCH_ANSWER_NOT_RELEVANT_PATTERN = re.compile(r"\[NO_RAG_ANSWER\]")
183
139
 
184
140
 
185
141
  class VectorStoreConnectionError(RasaException):
@@ -227,10 +183,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
227
183
  @staticmethod
228
184
  def get_default_config() -> Dict[str, Any]:
229
185
  """Returns the default config of the policy."""
230
- return {
231
- POLICY_PRIORITY: SEARCH_POLICY_PRIORITY,
232
- VECTOR_STORE_PROPERTY: DEFAULT_VECTOR_STORE,
233
- }
186
+ return DEFAULT_ENTERPRISE_SEARCH_CONFIG
234
187
 
235
188
  def __init__(
236
189
  self,
@@ -245,131 +198,71 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
245
198
  """Constructs a new Policy object."""
246
199
  super().__init__(config, model_storage, resource, execution_context, featurizer)
247
200
 
248
- # Check for deprecated keys and issue a warning if those are used
249
- self._check_config_keys_and_warn_if_deprecated()
250
- # Check for mutual exclusivity of extractive and generative search
251
- self._check_and_warn_mutual_exclusivity_of_extractive_and_generative_search()
252
-
253
- # Resolve LLM config
254
- self.config[LLM_CONFIG_KEY] = resolve_model_client_config(
255
- self.config.get(LLM_CONFIG_KEY), EnterpriseSearchPolicy.__name__
256
- )
257
- # Resolve embeddings config
258
- self.config[EMBEDDINGS_CONFIG_KEY] = resolve_model_client_config(
259
- self.config.get(EMBEDDINGS_CONFIG_KEY), EnterpriseSearchPolicy.__name__
260
- )
201
+ parsed_config = EnterpriseSearchPolicyConfig.from_dict(config)
261
202
 
262
203
  # Vector store object and configuration
263
204
  self.vector_store = vector_store
264
- self.vector_store_config = self.config.get(
265
- VECTOR_STORE_PROPERTY, DEFAULT_VECTOR_STORE
266
- )
267
- self.vector_search_threshold = self.vector_store_config.get(
268
- VECTOR_STORE_THRESHOLD_PROPERTY, DEFAULT_VECTOR_STORE_THRESHOLD
269
- )
205
+ self.vector_store_config = parsed_config.vector_store_config
206
+ self.vector_search_threshold = parsed_config.vector_store_threshold
207
+ self.vector_store_type = parsed_config.vector_store_type
270
208
 
271
- # Embeddings configuration for encoding the search query
272
- self.embeddings_config = (
273
- self.config[EMBEDDINGS_CONFIG_KEY] or DEFAULT_EMBEDDINGS_CONFIG
274
- )
209
+ # Resolved embeddings configuration for encoding the search query
210
+ self.embeddings_config = parsed_config.embeddings_config
275
211
 
276
- # LLM Configuration for response generation
277
- self.llm_config = self.config[LLM_CONFIG_KEY] or DEFAULT_LLM_CONFIG
212
+ # Resolved LLM Configuration for response generation
213
+ self.llm_config = parsed_config.llm_config
278
214
 
279
215
  # Maximum number of turns to include in the prompt
280
- self.max_history = self.config.get(POLICY_MAX_HISTORY)
216
+ self.max_history = parsed_config.max_history
281
217
 
282
218
  # Maximum number of messages to include in the search query
283
- self.max_messages_in_query = self.config.get(MAX_MESSAGES_IN_QUERY_KEY, 2)
219
+ self.max_messages_in_query = parsed_config.max_messages_in_query
284
220
 
285
221
  # Boolean to enable/disable tracing of prompt tokens
286
- self.trace_prompt_tokens = self.config.get(TRACE_TOKENS_PROPERTY, False)
222
+ self.trace_prompt_tokens = parsed_config.trace_prompt_tokens
287
223
 
288
224
  # Boolean to enable/disable the use of LLM for response generation
289
- self.use_llm = self.config.get(USE_LLM_PROPERTY, DEFAULT_USE_LLM_PROPERTY)
225
+ self.use_llm = parsed_config.use_generative_llm
290
226
 
291
227
  # Boolean to enable/disable citation generation. This flag enables citation
292
228
  # logic, but it only takes effect if `use_llm` is True.
293
- self.citation_enabled = self.config.get(
294
- CITATION_ENABLED_PROPERTY, DEFAULT_CITATION_ENABLED_PROPERTY
295
- )
229
+ self.citation_enabled = parsed_config.enable_citation
296
230
 
297
231
  # Boolean to enable/disable the use of relevancy check alongside answer
298
232
  # generation. This flag enables citation logic, but it only takes effect if
299
233
  # `use_llm` is True.
300
- self.relevancy_check_enabled = self.config.get(
301
- CHECK_RELEVANCY_PROPERTY, DEFAULT_CHECK_RELEVANCY_PROPERTY
302
- )
234
+ self.relevancy_check_enabled = parsed_config.check_relevancy
303
235
 
304
236
  # Resolve the prompt template. The prompt will only be used if the 'use_llm' is
305
237
  # set to True.
306
- self.prompt_template = prompt_template or self._resolve_prompt_template(
307
- self.config, LOG_COMPONENT_SOURCE_METHOD_INIT
238
+ self.prompt_template = prompt_template or get_prompt_template(
239
+ jinja_file_path=parsed_config.prompt_template,
240
+ default_prompt_template=self._select_default_prompt_template_based_on_features(
241
+ parsed_config.check_relevancy, parsed_config.enable_citation
242
+ ),
243
+ log_source_component=EnterpriseSearchPolicy.__name__,
244
+ log_source_method=LOG_COMPONENT_SOURCE_METHOD_INIT,
308
245
  )
309
246
 
310
- def _check_config_keys_and_warn_if_deprecated(self) -> None:
311
- """Checks and warns about deprecated config parameters."""
312
- if (
313
- PROMPT_CONFIG_KEY in self.config
314
- and PROMPT_TEMPLATE_CONFIG_KEY in self.config
315
- ):
316
- structlogger.warning(
317
- "enterprise_search_policy.init"
318
- ".both_deprecated_and_non_deprecated_config_keys_used_at_the_same_time",
319
- event_info=(
320
- f"Both '{PROMPT_CONFIG_KEY}' and '{PROMPT_TEMPLATE_CONFIG_KEY}' "
321
- f"are present in the config. '{PROMPT_CONFIG_KEY}' will be ignored "
322
- f"in favor of {PROMPT_TEMPLATE_CONFIG_KEY}."
323
- ),
324
- )
325
-
326
- # 'prompt' config key is deprecated in favor of 'prompt_template'
327
- if PROMPT_CONFIG_KEY in self.config:
328
- structlogger.warning(
329
- "enterprise_search_policy.init.deprecated_config_key",
330
- event_info=(
331
- f"The config parameter '{PROMPT_CONFIG_KEY}' is deprecated "
332
- "and will be removed in Rasa 4.0.0. "
333
- f"Please use the config parameter '{PROMPT_TEMPLATE_CONFIG_KEY}'"
334
- f"instead. "
335
- ),
336
- )
337
-
338
- def _check_and_warn_mutual_exclusivity_of_extractive_and_generative_search(
339
- self,
340
- ) -> None:
341
- if self.config.get(
342
- CHECK_RELEVANCY_PROPERTY, DEFAULT_CHECK_RELEVANCY_PROPERTY
343
- ) and not self.config.get(USE_LLM_PROPERTY, DEFAULT_USE_LLM_PROPERTY):
344
- structlogger.warning(
345
- "enterprise_search_policy.init"
346
- ".relevancy_check_enabled_with_disabled_generative_search",
347
- event_info=(
348
- f"The config parameter '{CHECK_RELEVANCY_PROPERTY}' is set to"
349
- f"'True', but the generative search is disabled (config"
350
- f"parameter '{USE_LLM_PROPERTY}' is set to 'False'). As a result, "
351
- "the relevancy check for the generative search will be disabled. "
352
- f"To use this check, set the config parameter '{USE_LLM_PROPERTY}' "
353
- f"to `True`."
354
- ),
355
- )
356
-
357
247
  @classmethod
358
- def _create_plain_embedder(cls, config: Dict[Text, Any]) -> "Embeddings":
248
+ def _create_plain_embedder(cls, embeddings_config: Dict[Text, Any]) -> "Embeddings":
359
249
  """Creates an embedder based on the given configuration.
360
250
 
251
+ Args:
252
+ embeddings_config: A resolved embeddings configuration. Resolved means the
253
+ configuration is either:
254
+ - A reference to a model group that has already been expanded into
255
+ its corresponding configuration using the information from
256
+ `endpoints.yml`, or
257
+ - A full configuration for the embedder defined directly (i.e. not
258
+ relying on model groups or indirections).
259
+
361
260
  Returns:
362
- The embedder.
261
+ The embedder.
363
262
  """
364
263
  # Copy the config so original config is not modified
365
- config = config.copy()
366
- # Resolve config and instantiate the embedding client
367
- config[EMBEDDINGS_CONFIG_KEY] = resolve_model_client_config(
368
- config.get(EMBEDDINGS_CONFIG_KEY), EnterpriseSearchPolicy.__name__
369
- )
370
- client = embedder_factory(
371
- config.get(EMBEDDINGS_CONFIG_KEY), DEFAULT_EMBEDDINGS_CONFIG
372
- )
264
+ embeddings_config = embeddings_config.copy()
265
+ client = embedder_factory(embeddings_config, DEFAULT_EMBEDDINGS_CONFIG)
373
266
  # Wrap the embedding client in the adapter
374
267
  return _LangchainEmbeddingClientAdapter(client)
375
268
 
@@ -435,16 +328,16 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
435
328
  can load the policy from the resource.
436
329
  """
437
330
  # Perform health checks for both LLM and embeddings client configs
438
- self._perform_health_checks(self.config, "enterprise_search_policy.train")
439
-
440
- store_type = self.vector_store_config.get(VECTOR_STORE_TYPE_PROPERTY)
331
+ self._perform_health_checks(
332
+ self.llm_config, self.embeddings_config, "enterprise_search_policy.train"
333
+ )
441
334
 
442
335
  # telemetry call to track training start
443
336
  track_enterprise_search_policy_train_started()
444
337
 
445
338
  # validate embedding configuration
446
339
  try:
447
- embeddings = self._create_plain_embedder(self.config)
340
+ embeddings = self._create_plain_embedder(self.embeddings_config)
448
341
  except (ValidationError, Exception) as e:
449
342
  structlogger.error(
450
343
  "enterprise_search_policy.train.embedder_instantiation_failed",
@@ -456,7 +349,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
456
349
  f"required environment variables. Error: {e}"
457
350
  )
458
351
 
459
- if store_type == DEFAULT_VECTOR_STORE_TYPE:
352
+ if self.vector_store_type == DEFAULT_VECTOR_STORE_TYPE:
460
353
  structlogger.info("enterprise_search_policy.train.faiss")
461
354
  with self._model_storage.write_to(self._resource) as path:
462
355
  self.vector_store = FAISS_Store(
@@ -464,15 +357,17 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
464
357
  embeddings=embeddings,
465
358
  index_path=path,
466
359
  create_index=True,
360
+ parse_as_faq_pairs=not self.use_llm,
467
361
  )
468
362
  else:
469
363
  structlogger.info(
470
- "enterprise_search_policy.train.custom", store_type=store_type
364
+ "enterprise_search_policy.train.custom",
365
+ store_type=self.vector_store_type,
471
366
  )
472
367
 
473
368
  # telemetry call to track training completion
474
369
  track_enterprise_search_policy_train_completed(
475
- vector_store_type=store_type,
370
+ vector_store_type=self.vector_store_type,
476
371
  embeddings_type=self.embeddings_config.get(PROVIDER_CONFIG_KEY),
477
372
  embeddings_model=self.embeddings_config.get(MODEL_CONFIG_KEY)
478
373
  or self.embeddings_config.get(MODEL_NAME_CONFIG_KEY),
@@ -495,8 +390,11 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
495
390
  rasa.shared.utils.io.write_text_file(
496
391
  self.prompt_template, path / ENTERPRISE_SEARCH_PROMPT_FILE_NAME
497
392
  )
393
+ config = self.config.copy()
394
+ config[LLM_CONFIG_KEY] = self.llm_config
395
+ config[EMBEDDINGS_CONFIG_KEY] = self.embeddings_config
498
396
  rasa.shared.utils.io.dump_obj_as_json_to_file(
499
- path / ENTERPRISE_SEARCH_CONFIG_FILE_NAME, self.config
397
+ path / ENTERPRISE_SEARCH_CONFIG_FILE_NAME, config
500
398
  )
501
399
 
502
400
  def _prepare_slots_for_template(
@@ -535,8 +433,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
535
433
  endpoints: Endpoints configuration.
536
434
  """
537
435
  config = endpoints.vector_store if endpoints else None
538
- store_type = self.vector_store_config.get(VECTOR_STORE_TYPE_PROPERTY)
539
- if config is None and store_type != DEFAULT_VECTOR_STORE_TYPE:
436
+ if config is None and self.vector_store_type != DEFAULT_VECTOR_STORE_TYPE:
540
437
  structlogger.error(
541
438
  "enterprise_search_policy._connect_vector_store_or_raise.no_config"
542
439
  )
@@ -697,7 +594,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
697
594
 
698
595
  # telemetry call to track policy prediction
699
596
  track_enterprise_search_policy_predict(
700
- vector_store_type=self.vector_store_config.get(VECTOR_STORE_TYPE_PROPERTY),
597
+ vector_store_type=self.vector_store_type,
701
598
  embeddings_type=self.embeddings_config.get(PROVIDER_CONFIG_KEY),
702
599
  embeddings_model=self.embeddings_config.get(MODEL_CONFIG_KEY)
703
600
  or self.embeddings_config.get(MODEL_NAME_CONFIG_KEY),
@@ -756,7 +653,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
756
653
  Returns:
757
654
  An LLMResponse object, or None if the call fails.
758
655
  """
759
- llm = llm_factory(self.config.get(LLM_CONFIG_KEY), DEFAULT_LLM_CONFIG)
656
+ llm = llm_factory(self.llm_config, DEFAULT_LLM_CONFIG)
760
657
  try:
761
658
  response = await llm.acompletion(prompt)
762
659
  return LLMResponse.ensure_llm_response(response)
@@ -886,70 +783,88 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
886
783
  **kwargs: Any,
887
784
  ) -> "EnterpriseSearchPolicy":
888
785
  """Loads a trained policy (see parent class for full docstring)."""
786
+ parsed_config = EnterpriseSearchPolicyConfig.from_dict(config)
787
+
889
788
  # Perform health checks for both LLM and embeddings client configs
890
- cls._perform_health_checks(config, "enterprise_search_policy.load")
789
+ cls._perform_health_checks(
790
+ parsed_config.llm_config,
791
+ parsed_config.embeddings_config,
792
+ "enterprise_search_policy.load",
793
+ )
891
794
 
892
- prompt_template = None
795
+ prompt_template = cls._load_prompt_template(model_storage, resource)
796
+ embeddings = cls._create_plain_embedder(parsed_config.embeddings_config)
797
+ vector_store = cls._load_vector_store(
798
+ embeddings,
799
+ parsed_config.vector_store_type,
800
+ parsed_config.use_generative_llm,
801
+ model_storage,
802
+ resource,
803
+ )
804
+
805
+ structlogger.info("enterprise_search_policy.load", config=config)
806
+
807
+ return cls(
808
+ config,
809
+ model_storage,
810
+ resource,
811
+ execution_context,
812
+ vector_store=vector_store,
813
+ prompt_template=prompt_template,
814
+ )
815
+
816
+ @classmethod
817
+ def _load_prompt_template(
818
+ cls, model_storage: ModelStorage, resource: Resource
819
+ ) -> Optional[str]:
893
820
  try:
894
821
  with model_storage.read_from(resource) as path:
895
- prompt_template = rasa.shared.utils.io.read_file(
822
+ return rasa.shared.utils.io.read_file(
896
823
  path / ENTERPRISE_SEARCH_PROMPT_FILE_NAME
897
824
  )
898
825
  except (FileNotFoundError, FileIOException) as e:
899
826
  structlogger.warning(
900
827
  "enterprise_search_policy.load.failed", error=e, resource=resource.name
901
828
  )
829
+ return None
902
830
 
903
- store_type = config.get(VECTOR_STORE_PROPERTY, {}).get(
904
- VECTOR_STORE_TYPE_PROPERTY
905
- )
906
-
907
- embeddings = cls._create_plain_embedder(config)
908
-
909
- structlogger.info("enterprise_search_policy.load", config=config)
831
+ @classmethod
832
+ def _load_vector_store(
833
+ cls,
834
+ embeddings: "Embeddings",
835
+ store_type: str,
836
+ use_generative_llm: bool,
837
+ model_storage: ModelStorage,
838
+ resource: Resource,
839
+ ) -> InformationRetrieval:
910
840
  if store_type == DEFAULT_VECTOR_STORE_TYPE:
911
841
  # if a vector store is not specified,
912
842
  # default to using FAISS with the index stored in the model
913
843
  # TODO figure out a way to get path without context manager
914
844
  with model_storage.read_from(resource) as path:
915
- vector_store = FAISS_Store(
845
+ return FAISS_Store(
916
846
  embeddings=embeddings,
917
847
  index_path=path,
918
848
  docs_folder=None,
919
849
  create_index=False,
850
+ parse_as_faq_pairs=not use_generative_llm,
920
851
  )
921
852
  else:
922
- vector_store = create_from_endpoint_config(
853
+ return create_from_endpoint_config(
923
854
  config_type=store_type,
924
855
  embeddings=embeddings,
925
- ) # type: ignore
926
-
927
- return cls(
928
- config,
929
- model_storage,
930
- resource,
931
- execution_context,
932
- vector_store=vector_store,
933
- prompt_template=prompt_template,
934
- )
856
+ )
935
857
 
936
858
  @classmethod
937
- def _get_local_knowledge_data(cls, config: Dict[str, Any]) -> Optional[List[str]]:
859
+ def _get_local_knowledge_data(
860
+ cls, store_type: str, source: Optional[str] = None
861
+ ) -> Optional[List[str]]:
938
862
  """This is required only for local knowledge base types.
939
863
 
940
864
  e.g. FAISS, to ensure that the graph component is retrained when the knowledge
941
865
  base is updated.
942
866
  """
943
- merged_config = {**cls.get_default_config(), **config}
944
-
945
- store_type = merged_config.get(VECTOR_STORE_PROPERTY, {}).get(
946
- VECTOR_STORE_TYPE_PROPERTY
947
- )
948
- if store_type != DEFAULT_VECTOR_STORE_TYPE:
949
- return None
950
-
951
- source = merged_config.get(VECTOR_STORE_PROPERTY, {}).get(SOURCE_PROPERTY)
952
- if not source:
867
+ if store_type != DEFAULT_VECTOR_STORE_TYPE or not source:
953
868
  return None
954
869
 
955
870
  docs = FAISS_Store.load_documents(source)
@@ -965,18 +880,28 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
965
880
  @classmethod
966
881
  def fingerprint_addon(cls, config: Dict[str, Any]) -> Optional[str]:
967
882
  """Add a fingerprint of enterprise search policy for the graph."""
968
- prompt_template = cls._resolve_prompt_template(
969
- config, LOG_COMPONENT_SOURCE_METHOD_FINGERPRINT_ADDON
970
- )
971
-
972
- local_knowledge_data = cls._get_local_knowledge_data(config)
883
+ parsed_config = EnterpriseSearchPolicyConfig.from_dict(config)
973
884
 
974
- llm_config = resolve_model_client_config(
975
- config.get(LLM_CONFIG_KEY), EnterpriseSearchPolicy.__name__
885
+ # Resolve the prompt template
886
+ default_prompt_template = cls._select_default_prompt_template_based_on_features(
887
+ parsed_config.check_relevancy, parsed_config.enable_citation
976
888
  )
977
- embedding_config = resolve_model_client_config(
978
- config.get(EMBEDDINGS_CONFIG_KEY), EnterpriseSearchPolicy.__name__
889
+ prompt_template = get_prompt_template(
890
+ jinja_file_path=parsed_config.prompt_template,
891
+ default_prompt_template=default_prompt_template,
892
+ log_source_component=EnterpriseSearchPolicy.__name__,
893
+ log_source_method=LOG_COMPONENT_SOURCE_METHOD_FINGERPRINT_ADDON,
979
894
  )
895
+
896
+ # Fetch the local knowledge data in case FAISS is used
897
+ local_knowledge_data = cls._get_local_knowledge_data(
898
+ parsed_config.vector_store_type, parsed_config.vector_store_source
899
+ )
900
+
901
+ # Get the resolved LLM and embeddings configurations
902
+ llm_config = parsed_config.llm_config
903
+ embedding_config = parsed_config.embeddings_config
904
+
980
905
  return deep_container_fingerprint(
981
906
  [prompt_template, local_knowledge_data, llm_config, embedding_config]
982
907
  )
@@ -1074,21 +999,32 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
1074
999
 
1075
1000
  @classmethod
1076
1001
  def _perform_health_checks(
1077
- cls, config: Dict[Text, Any], log_source_method: str
1002
+ cls,
1003
+ llm_config: Dict[Text, Any],
1004
+ embeddings_config: Dict[Text, Any],
1005
+ log_source_method: str,
1078
1006
  ) -> None:
1079
- # Perform health check of the LLM client config
1080
- llm_config = resolve_model_client_config(config.get(LLM_CONFIG_KEY, {}))
1007
+ """
1008
+ Perform the health checks using resolved LLM and embeddings configurations.
1009
+ Resolved means the configuration is either:
1010
+ - A reference to a model group that has already been expanded into
1011
+ its corresponding configuration using the information from
1012
+ `endpoints.yml`, or
1013
+ - A full configuration for the embedder defined directly (i.e. not
1014
+ relying on model groups or indirections).
1015
+
1016
+ Args:
1017
+ llm_config: A resolved LLM configuration.
1018
+ embeddings_config: A resolved embeddings configuration.
1019
+ log_source_method: The method health checks has been called from.
1020
+
1021
+ """
1081
1022
  cls.perform_llm_health_check(
1082
1023
  llm_config,
1083
1024
  DEFAULT_LLM_CONFIG,
1084
1025
  log_source_method,
1085
1026
  EnterpriseSearchPolicy.__name__,
1086
1027
  )
1087
-
1088
- # Perform health check of the embeddings client config
1089
- embeddings_config = resolve_model_client_config(
1090
- config.get(EMBEDDINGS_CONFIG_KEY, {})
1091
- )
1092
1028
  cls.perform_embeddings_health_check(
1093
1029
  embeddings_config,
1094
1030
  DEFAULT_EMBEDDINGS_CONFIG,
@@ -1114,62 +1050,16 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
1114
1050
  Returns:
1115
1051
  The resolved jinja prompt template as a string.
1116
1052
  """
1117
-
1118
1053
  # Get the feature flags
1119
- citation_enabled = config.get(
1120
- CITATION_ENABLED_PROPERTY, DEFAULT_CITATION_ENABLED_PROPERTY
1121
- )
1122
- relevancy_check_enabled = config.get(
1123
- CHECK_RELEVANCY_PROPERTY, DEFAULT_CHECK_RELEVANCY_PROPERTY
1124
- )
1125
-
1054
+ parsed_config = EnterpriseSearchPolicyConfig.from_dict(config)
1126
1055
  # Based on the enabled features (citation, relevancy check) fetch the
1127
1056
  # appropriate default prompt
1128
1057
  default_prompt = cls._select_default_prompt_template_based_on_features(
1129
- relevancy_check_enabled, citation_enabled
1058
+ parsed_config.check_relevancy, parsed_config.enable_citation
1130
1059
  )
1131
1060
 
1132
1061
  return default_prompt
1133
1062
 
1134
- @classmethod
1135
- def _resolve_prompt_template(
1136
- cls,
1137
- config: dict,
1138
- log_source_method: Literal["init", "fingerprint"],
1139
- ) -> str:
1140
- """
1141
- Resolves the prompt template to use for the Enterprise Search Policy's
1142
- generative search.
1143
-
1144
- Checks if a custom template is provided via component's configuration. If not,
1145
- it selects the appropriate default template based on the enabled features
1146
- (citation and relevancy check).
1147
-
1148
- Args:
1149
- config: The component's configuration.
1150
- log_source_method: The name of the method or function emitting the log for
1151
- better traceability.
1152
- Returns:
1153
- The resolved jinja prompt template as a string.
1154
- """
1155
-
1156
- # Read the template path from the configuration if available.
1157
- # The deprecated 'prompt' has a lower priority compared to 'prompt_template'
1158
- config_defined_prompt = (
1159
- config.get(PROMPT_TEMPLATE_CONFIG_KEY)
1160
- or config.get(PROMPT_CONFIG_KEY)
1161
- or None
1162
- )
1163
- # Select the default prompt based on the features set in the config.
1164
- default_prompt = cls.get_system_default_prompt_based_on_config(config)
1165
-
1166
- return get_prompt_template(
1167
- config_defined_prompt,
1168
- default_prompt,
1169
- log_source_component=EnterpriseSearchPolicy.__name__,
1170
- log_source_method=log_source_method,
1171
- )
1172
-
1173
1063
  @classmethod
1174
1064
  def _select_default_prompt_template_based_on_features(
1175
1065
  cls,