rasa-pro 3.13.0.dev8__py3-none-any.whl → 3.13.0.dev10__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 (99) hide show
  1. rasa/cli/export.py +2 -0
  2. rasa/core/channels/development_inspector.py +1 -1
  3. rasa/core/channels/facebook.py +1 -4
  4. rasa/core/channels/inspector/README.md +3 -3
  5. rasa/core/channels/inspector/dist/assets/{arc-c4b064fc.js → arc-02053cc1.js} +1 -1
  6. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-215b5026.js → blockDiagram-38ab4fdb-008b6289.js} +1 -1
  7. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-2b54a0a3.js → c4Diagram-3d4e48cf-fb2597be.js} +1 -1
  8. rasa/core/channels/inspector/dist/assets/channel-078dada8.js +1 -0
  9. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-daacea5f.js → classDiagram-70f12bd4-7f847e00.js} +1 -1
  10. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-930d4dc2.js → classDiagram-v2-f2320105-ba1d689b.js} +1 -1
  11. rasa/core/channels/inspector/dist/assets/clone-5b4516de.js +1 -0
  12. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-83c206ba.js → createText-2e5e7dd3-dd8e67c4.js} +1 -1
  13. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-b0eb01d0.js → edges-e0da2a9e-10784939.js} +1 -1
  14. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-17586500.js → erDiagram-9861fffd-24947ae6.js} +1 -1
  15. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-be2a1776.js → flowDb-956e92f1-a9ced505.js} +1 -1
  16. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-c2120ebd.js → flowDiagram-66a62f08-afda9c7c.js} +1 -1
  17. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-f9613071.js +1 -0
  18. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-a6ab5c48.js → flowchart-elk-definition-4a651766-6ef530b8.js} +1 -1
  19. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-ef613457.js → ganttDiagram-c361ad54-0c7dd39a.js} +1 -1
  20. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-d59185b3.js → gitGraphDiagram-72cf32ee-b57239d6.js} +1 -1
  21. rasa/core/channels/inspector/dist/assets/{graph-0f155405.js → graph-9ed57cec.js} +1 -1
  22. rasa/core/channels/inspector/dist/assets/{index-3862675e-d5f1d1b7.js → index-3862675e-233090de.js} +1 -1
  23. rasa/core/channels/inspector/dist/assets/{index-47737d3a.js → index-72184470.js} +3 -3
  24. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-b07d141f.js → infoDiagram-f8f76790-aa116649.js} +1 -1
  25. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-1936d429.js → journeyDiagram-49397b02-e51877cc.js} +1 -1
  26. rasa/core/channels/inspector/dist/assets/{layout-dde8d0f3.js → layout-3ca3798c.js} +1 -1
  27. rasa/core/channels/inspector/dist/assets/{line-0c2c7ee0.js → line-26ee10d3.js} +1 -1
  28. rasa/core/channels/inspector/dist/assets/{linear-35dd89a4.js → linear-aedded32.js} +1 -1
  29. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-56192851.js → mindmap-definition-fc14e90a-d8957261.js} +1 -1
  30. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-fc21ed78.js → pieDiagram-8a3498a8-d771f885.js} +1 -1
  31. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-25e98518.js → quadrantDiagram-120e2f19-09fdf50c.js} +1 -1
  32. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-546ff1f5.js → requirementDiagram-deff3bca-9f0af02e.js} +1 -1
  33. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-02d8b82d.js → sankeyDiagram-04a897e0-84415b37.js} +1 -1
  34. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-3ca5a92e.js → sequenceDiagram-704730f1-8dec4055.js} +1 -1
  35. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-128ea07c.js → stateDiagram-587899a1-c5431d07.js} +1 -1
  36. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-95f290af.js → stateDiagram-v2-d93cdb3a-274e77d9.js} +1 -1
  37. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-4984898a.js → styles-6aaf32cf-e364a1d7.js} +1 -1
  38. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-1bf266ba.js → styles-9a916d00-0dae36f6.js} +1 -1
  39. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-60521c63.js → styles-c10674c1-c4641675.js} +1 -1
  40. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-a25b6e12.js → svgDrawCommon-08f97a94-831fe9a1.js} +1 -1
  41. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-0fc086bf.js → timeline-definition-85554ec2-c3304b3a.js} +1 -1
  42. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-44ee592e.js → xychartDiagram-e933f94c-da799369.js} +1 -1
  43. rasa/core/channels/inspector/dist/index.html +1 -1
  44. rasa/core/channels/inspector/src/components/RecruitmentPanel.tsx +1 -1
  45. rasa/core/channels/socketio.py +56 -41
  46. rasa/core/channels/studio_chat.py +311 -8
  47. rasa/core/channels/voice_ready/audiocodes.py +1 -1
  48. rasa/core/channels/voice_stream/audiocodes.py +1 -1
  49. rasa/core/channels/voice_stream/browser_audio.py +1 -1
  50. rasa/core/channels/voice_stream/tts/__init__.py +8 -0
  51. rasa/core/channels/voice_stream/voice_channel.py +6 -1
  52. rasa/core/exporter.py +36 -0
  53. rasa/core/information_retrieval/faiss.py +18 -11
  54. rasa/core/information_retrieval/ingestion/__init__.py +0 -0
  55. rasa/core/information_retrieval/ingestion/faq_parser.py +158 -0
  56. rasa/core/nlg/contextual_response_rephraser.py +10 -1
  57. rasa/core/policies/enterprise_search_policy.py +151 -258
  58. rasa/core/policies/enterprise_search_policy_config.py +242 -0
  59. rasa/core/policies/intentless_policy.py +47 -10
  60. rasa/dialogue_understanding/coexistence/llm_based_router.py +9 -6
  61. rasa/dialogue_understanding/commands/cancel_flow_command.py +3 -1
  62. rasa/dialogue_understanding/commands/correct_slots_command.py +1 -3
  63. rasa/dialogue_understanding/generator/nlu_command_adapter.py +2 -2
  64. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2 +78 -0
  65. rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +2 -2
  66. rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +2 -2
  67. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +8 -11
  68. rasa/dialogue_understanding/patterns/cancel.py +1 -2
  69. rasa/dialogue_understanding/patterns/clarify.py +1 -1
  70. rasa/dialogue_understanding/patterns/correction.py +2 -2
  71. rasa/dialogue_understanding/processor/command_processor.py +3 -4
  72. rasa/dialogue_understanding/stack/utils.py +3 -1
  73. rasa/engine/graph.py +2 -2
  74. rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +1 -5
  75. rasa/shared/constants.py +11 -0
  76. rasa/shared/core/command_payload_reader.py +1 -5
  77. rasa/shared/core/events.py +1 -3
  78. rasa/shared/core/flows/validation.py +25 -5
  79. rasa/shared/core/training_data/story_reader/yaml_story_reader.py +1 -4
  80. rasa/shared/providers/_configs/azure_openai_client_config.py +2 -2
  81. rasa/shared/providers/_configs/default_litellm_client_config.py +1 -1
  82. rasa/shared/providers/_configs/huggingface_local_embedding_client_config.py +1 -1
  83. rasa/shared/providers/_configs/openai_client_config.py +1 -1
  84. rasa/shared/providers/_configs/rasa_llm_client_config.py +1 -1
  85. rasa/shared/providers/_configs/self_hosted_llm_client_config.py +1 -1
  86. rasa/shared/providers/_configs/utils.py +0 -99
  87. rasa/shared/utils/common.py +1 -1
  88. rasa/shared/utils/configs.py +110 -0
  89. rasa/shared/utils/llm.py +30 -0
  90. rasa/tracing/instrumentation/attribute_extractors.py +10 -5
  91. rasa/version.py +1 -1
  92. {rasa_pro-3.13.0.dev8.dist-info → rasa_pro-3.13.0.dev10.dist-info}/METADATA +3 -3
  93. {rasa_pro-3.13.0.dev8.dist-info → rasa_pro-3.13.0.dev10.dist-info}/RECORD +96 -91
  94. rasa/core/channels/inspector/dist/assets/channel-3730f5fd.js +0 -1
  95. rasa/core/channels/inspector/dist/assets/clone-e847561e.js +0 -1
  96. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-efbbfe00.js +0 -1
  97. {rasa_pro-3.13.0.dev8.dist-info → rasa_pro-3.13.0.dev10.dist-info}/NOTICE +0 -0
  98. {rasa_pro-3.13.0.dev8.dist-info → rasa_pro-3.13.0.dev10.dist-info}/WHEEL +0 -0
  99. {rasa_pro-3.13.0.dev8.dist-info → rasa_pro-3.13.0.dev10.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
 
@@ -227,10 +186,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
227
186
  @staticmethod
228
187
  def get_default_config() -> Dict[str, Any]:
229
188
  """Returns the default config of the policy."""
230
- return {
231
- POLICY_PRIORITY: SEARCH_POLICY_PRIORITY,
232
- VECTOR_STORE_PROPERTY: DEFAULT_VECTOR_STORE,
233
- }
189
+ return DEFAULT_ENTERPRISE_SEARCH_CONFIG
234
190
 
235
191
  def __init__(
236
192
  self,
@@ -245,131 +201,71 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
245
201
  """Constructs a new Policy object."""
246
202
  super().__init__(config, model_storage, resource, execution_context, featurizer)
247
203
 
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
- )
204
+ parsed_config = EnterpriseSearchPolicyConfig.from_dict(config)
261
205
 
262
206
  # Vector store object and configuration
263
207
  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
- )
208
+ self.vector_store_config = parsed_config.vector_store_config
209
+ self.vector_search_threshold = parsed_config.vector_store_threshold
210
+ self.vector_store_type = parsed_config.vector_store_type
270
211
 
271
- # Embeddings configuration for encoding the search query
272
- self.embeddings_config = (
273
- self.config[EMBEDDINGS_CONFIG_KEY] or DEFAULT_EMBEDDINGS_CONFIG
274
- )
212
+ # Resolved embeddings configuration for encoding the search query
213
+ self.embeddings_config = parsed_config.embeddings_config
275
214
 
276
- # LLM Configuration for response generation
277
- self.llm_config = self.config[LLM_CONFIG_KEY] or DEFAULT_LLM_CONFIG
215
+ # Resolved LLM Configuration for response generation
216
+ self.llm_config = parsed_config.llm_config
278
217
 
279
218
  # Maximum number of turns to include in the prompt
280
- self.max_history = self.config.get(POLICY_MAX_HISTORY)
219
+ self.max_history = parsed_config.max_history
281
220
 
282
221
  # 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)
222
+ self.max_messages_in_query = parsed_config.max_messages_in_query
284
223
 
285
224
  # Boolean to enable/disable tracing of prompt tokens
286
- self.trace_prompt_tokens = self.config.get(TRACE_TOKENS_PROPERTY, False)
225
+ self.trace_prompt_tokens = parsed_config.trace_prompt_tokens
287
226
 
288
227
  # 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)
228
+ self.use_llm = parsed_config.use_generative_llm
290
229
 
291
230
  # Boolean to enable/disable citation generation. This flag enables citation
292
231
  # 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
- )
232
+ self.citation_enabled = parsed_config.enable_citation
296
233
 
297
234
  # Boolean to enable/disable the use of relevancy check alongside answer
298
235
  # generation. This flag enables citation logic, but it only takes effect if
299
236
  # `use_llm` is True.
300
- self.relevancy_check_enabled = self.config.get(
301
- CHECK_RELEVANCY_PROPERTY, DEFAULT_CHECK_RELEVANCY_PROPERTY
302
- )
237
+ self.relevancy_check_enabled = parsed_config.check_relevancy
303
238
 
304
239
  # Resolve the prompt template. The prompt will only be used if the 'use_llm' is
305
240
  # set to True.
306
- self.prompt_template = prompt_template or self._resolve_prompt_template(
307
- self.config, LOG_COMPONENT_SOURCE_METHOD_INIT
241
+ self.prompt_template = prompt_template or get_prompt_template(
242
+ jinja_file_path=parsed_config.prompt_template,
243
+ default_prompt_template=self._select_default_prompt_template_based_on_features(
244
+ parsed_config.check_relevancy, parsed_config.enable_citation
245
+ ),
246
+ log_source_component=EnterpriseSearchPolicy.__name__,
247
+ log_source_method=LOG_COMPONENT_SOURCE_METHOD_INIT,
308
248
  )
309
249
 
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
250
  @classmethod
358
- def _create_plain_embedder(cls, config: Dict[Text, Any]) -> "Embeddings":
251
+ def _create_plain_embedder(cls, embeddings_config: Dict[Text, Any]) -> "Embeddings":
359
252
  """Creates an embedder based on the given configuration.
360
253
 
254
+ Args:
255
+ embeddings_config: A resolved embeddings configuration. Resolved means the
256
+ configuration is either:
257
+ - A reference to a model group that has already been expanded into
258
+ its corresponding configuration using the information from
259
+ `endpoints.yml`, or
260
+ - A full configuration for the embedder defined directly (i.e. not
261
+ relying on model groups or indirections).
262
+
361
263
  Returns:
362
- The embedder.
264
+ The embedder.
363
265
  """
364
266
  # 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
- )
267
+ embeddings_config = embeddings_config.copy()
268
+ client = embedder_factory(embeddings_config, DEFAULT_EMBEDDINGS_CONFIG)
373
269
  # Wrap the embedding client in the adapter
374
270
  return _LangchainEmbeddingClientAdapter(client)
375
271
 
@@ -435,16 +331,16 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
435
331
  can load the policy from the resource.
436
332
  """
437
333
  # 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)
334
+ self._perform_health_checks(
335
+ self.llm_config, self.embeddings_config, "enterprise_search_policy.train"
336
+ )
441
337
 
442
338
  # telemetry call to track training start
443
339
  track_enterprise_search_policy_train_started()
444
340
 
445
341
  # validate embedding configuration
446
342
  try:
447
- embeddings = self._create_plain_embedder(self.config)
343
+ embeddings = self._create_plain_embedder(self.embeddings_config)
448
344
  except (ValidationError, Exception) as e:
449
345
  structlogger.error(
450
346
  "enterprise_search_policy.train.embedder_instantiation_failed",
@@ -456,7 +352,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
456
352
  f"required environment variables. Error: {e}"
457
353
  )
458
354
 
459
- if store_type == DEFAULT_VECTOR_STORE_TYPE:
355
+ if self.vector_store_type == DEFAULT_VECTOR_STORE_TYPE:
460
356
  structlogger.info("enterprise_search_policy.train.faiss")
461
357
  with self._model_storage.write_to(self._resource) as path:
462
358
  self.vector_store = FAISS_Store(
@@ -464,15 +360,17 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
464
360
  embeddings=embeddings,
465
361
  index_path=path,
466
362
  create_index=True,
363
+ parse_as_faq_pairs=not self.use_llm,
467
364
  )
468
365
  else:
469
366
  structlogger.info(
470
- "enterprise_search_policy.train.custom", store_type=store_type
367
+ "enterprise_search_policy.train.custom",
368
+ store_type=self.vector_store_type,
471
369
  )
472
370
 
473
371
  # telemetry call to track training completion
474
372
  track_enterprise_search_policy_train_completed(
475
- vector_store_type=store_type,
373
+ vector_store_type=self.vector_store_type,
476
374
  embeddings_type=self.embeddings_config.get(PROVIDER_CONFIG_KEY),
477
375
  embeddings_model=self.embeddings_config.get(MODEL_CONFIG_KEY)
478
376
  or self.embeddings_config.get(MODEL_NAME_CONFIG_KEY),
@@ -495,8 +393,11 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
495
393
  rasa.shared.utils.io.write_text_file(
496
394
  self.prompt_template, path / ENTERPRISE_SEARCH_PROMPT_FILE_NAME
497
395
  )
396
+ config = self.config.copy()
397
+ config[LLM_CONFIG_KEY] = self.llm_config
398
+ config[EMBEDDINGS_CONFIG_KEY] = self.embeddings_config
498
399
  rasa.shared.utils.io.dump_obj_as_json_to_file(
499
- path / ENTERPRISE_SEARCH_CONFIG_FILE_NAME, self.config
400
+ path / ENTERPRISE_SEARCH_CONFIG_FILE_NAME, config
500
401
  )
501
402
 
502
403
  def _prepare_slots_for_template(
@@ -535,8 +436,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
535
436
  endpoints: Endpoints configuration.
536
437
  """
537
438
  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:
439
+ if config is None and self.vector_store_type != DEFAULT_VECTOR_STORE_TYPE:
540
440
  structlogger.error(
541
441
  "enterprise_search_policy._connect_vector_store_or_raise.no_config"
542
442
  )
@@ -697,7 +597,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
697
597
 
698
598
  # telemetry call to track policy prediction
699
599
  track_enterprise_search_policy_predict(
700
- vector_store_type=self.vector_store_config.get(VECTOR_STORE_TYPE_PROPERTY),
600
+ vector_store_type=self.vector_store_type,
701
601
  embeddings_type=self.embeddings_config.get(PROVIDER_CONFIG_KEY),
702
602
  embeddings_model=self.embeddings_config.get(MODEL_CONFIG_KEY)
703
603
  or self.embeddings_config.get(MODEL_NAME_CONFIG_KEY),
@@ -756,7 +656,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
756
656
  Returns:
757
657
  An LLMResponse object, or None if the call fails.
758
658
  """
759
- llm = llm_factory(self.config.get(LLM_CONFIG_KEY), DEFAULT_LLM_CONFIG)
659
+ llm = llm_factory(self.llm_config, DEFAULT_LLM_CONFIG)
760
660
  try:
761
661
  response = await llm.acompletion(prompt)
762
662
  return LLMResponse.ensure_llm_response(response)
@@ -886,70 +786,88 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
886
786
  **kwargs: Any,
887
787
  ) -> "EnterpriseSearchPolicy":
888
788
  """Loads a trained policy (see parent class for full docstring)."""
789
+ parsed_config = EnterpriseSearchPolicyConfig.from_dict(config)
790
+
889
791
  # Perform health checks for both LLM and embeddings client configs
890
- cls._perform_health_checks(config, "enterprise_search_policy.load")
792
+ cls._perform_health_checks(
793
+ parsed_config.llm_config,
794
+ parsed_config.embeddings_config,
795
+ "enterprise_search_policy.load",
796
+ )
797
+
798
+ prompt_template = cls._load_prompt_template(model_storage, resource)
799
+ embeddings = cls._create_plain_embedder(parsed_config.embeddings_config)
800
+ vector_store = cls._load_vector_store(
801
+ embeddings,
802
+ parsed_config.vector_store_type,
803
+ parsed_config.use_generative_llm,
804
+ model_storage,
805
+ resource,
806
+ )
891
807
 
892
- prompt_template = None
808
+ structlogger.info("enterprise_search_policy.load", config=config)
809
+
810
+ return cls(
811
+ config,
812
+ model_storage,
813
+ resource,
814
+ execution_context,
815
+ vector_store=vector_store,
816
+ prompt_template=prompt_template,
817
+ )
818
+
819
+ @classmethod
820
+ def _load_prompt_template(
821
+ cls, model_storage: ModelStorage, resource: Resource
822
+ ) -> Optional[str]:
893
823
  try:
894
824
  with model_storage.read_from(resource) as path:
895
- prompt_template = rasa.shared.utils.io.read_file(
825
+ return rasa.shared.utils.io.read_file(
896
826
  path / ENTERPRISE_SEARCH_PROMPT_FILE_NAME
897
827
  )
898
828
  except (FileNotFoundError, FileIOException) as e:
899
829
  structlogger.warning(
900
830
  "enterprise_search_policy.load.failed", error=e, resource=resource.name
901
831
  )
832
+ return None
902
833
 
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)
834
+ @classmethod
835
+ def _load_vector_store(
836
+ cls,
837
+ embeddings: "Embeddings",
838
+ store_type: str,
839
+ use_generative_llm: bool,
840
+ model_storage: ModelStorage,
841
+ resource: Resource,
842
+ ) -> InformationRetrieval:
910
843
  if store_type == DEFAULT_VECTOR_STORE_TYPE:
911
844
  # if a vector store is not specified,
912
845
  # default to using FAISS with the index stored in the model
913
846
  # TODO figure out a way to get path without context manager
914
847
  with model_storage.read_from(resource) as path:
915
- vector_store = FAISS_Store(
848
+ return FAISS_Store(
916
849
  embeddings=embeddings,
917
850
  index_path=path,
918
851
  docs_folder=None,
919
852
  create_index=False,
853
+ parse_as_faq_pairs=not use_generative_llm,
920
854
  )
921
855
  else:
922
- vector_store = create_from_endpoint_config(
856
+ return create_from_endpoint_config(
923
857
  config_type=store_type,
924
858
  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
- )
859
+ )
935
860
 
936
861
  @classmethod
937
- def _get_local_knowledge_data(cls, config: Dict[str, Any]) -> Optional[List[str]]:
862
+ def _get_local_knowledge_data(
863
+ cls, store_type: str, source: Optional[str] = None
864
+ ) -> Optional[List[str]]:
938
865
  """This is required only for local knowledge base types.
939
866
 
940
867
  e.g. FAISS, to ensure that the graph component is retrained when the knowledge
941
868
  base is updated.
942
869
  """
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:
870
+ if store_type != DEFAULT_VECTOR_STORE_TYPE or not source:
953
871
  return None
954
872
 
955
873
  docs = FAISS_Store.load_documents(source)
@@ -965,18 +883,28 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
965
883
  @classmethod
966
884
  def fingerprint_addon(cls, config: Dict[str, Any]) -> Optional[str]:
967
885
  """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
- )
886
+ parsed_config = EnterpriseSearchPolicyConfig.from_dict(config)
971
887
 
972
- local_knowledge_data = cls._get_local_knowledge_data(config)
973
-
974
- llm_config = resolve_model_client_config(
975
- config.get(LLM_CONFIG_KEY), EnterpriseSearchPolicy.__name__
888
+ # Resolve the prompt template
889
+ default_prompt_template = cls._select_default_prompt_template_based_on_features(
890
+ parsed_config.check_relevancy, parsed_config.enable_citation
976
891
  )
977
- embedding_config = resolve_model_client_config(
978
- config.get(EMBEDDINGS_CONFIG_KEY), EnterpriseSearchPolicy.__name__
892
+ prompt_template = get_prompt_template(
893
+ jinja_file_path=parsed_config.prompt_template,
894
+ default_prompt_template=default_prompt_template,
895
+ log_source_component=EnterpriseSearchPolicy.__name__,
896
+ log_source_method=LOG_COMPONENT_SOURCE_METHOD_FINGERPRINT_ADDON,
979
897
  )
898
+
899
+ # Fetch the local knowledge data in case FAISS is used
900
+ local_knowledge_data = cls._get_local_knowledge_data(
901
+ parsed_config.vector_store_type, parsed_config.vector_store_source
902
+ )
903
+
904
+ # Get the resolved LLM and embeddings configurations
905
+ llm_config = parsed_config.llm_config
906
+ embedding_config = parsed_config.embeddings_config
907
+
980
908
  return deep_container_fingerprint(
981
909
  [prompt_template, local_knowledge_data, llm_config, embedding_config]
982
910
  )
@@ -1074,21 +1002,32 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
1074
1002
 
1075
1003
  @classmethod
1076
1004
  def _perform_health_checks(
1077
- cls, config: Dict[Text, Any], log_source_method: str
1005
+ cls,
1006
+ llm_config: Dict[Text, Any],
1007
+ embeddings_config: Dict[Text, Any],
1008
+ log_source_method: str,
1078
1009
  ) -> None:
1079
- # Perform health check of the LLM client config
1080
- llm_config = resolve_model_client_config(config.get(LLM_CONFIG_KEY, {}))
1010
+ """
1011
+ Perform the health checks using resolved LLM and embeddings configurations.
1012
+ Resolved means the configuration is either:
1013
+ - A reference to a model group that has already been expanded into
1014
+ its corresponding configuration using the information from
1015
+ `endpoints.yml`, or
1016
+ - A full configuration for the embedder defined directly (i.e. not
1017
+ relying on model groups or indirections).
1018
+
1019
+ Args:
1020
+ llm_config: A resolved LLM configuration.
1021
+ embeddings_config: A resolved embeddings configuration.
1022
+ log_source_method: The method health checks has been called from.
1023
+
1024
+ """
1081
1025
  cls.perform_llm_health_check(
1082
1026
  llm_config,
1083
1027
  DEFAULT_LLM_CONFIG,
1084
1028
  log_source_method,
1085
1029
  EnterpriseSearchPolicy.__name__,
1086
1030
  )
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
1031
  cls.perform_embeddings_health_check(
1093
1032
  embeddings_config,
1094
1033
  DEFAULT_EMBEDDINGS_CONFIG,
@@ -1114,62 +1053,16 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
1114
1053
  Returns:
1115
1054
  The resolved jinja prompt template as a string.
1116
1055
  """
1117
-
1118
1056
  # 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
-
1057
+ parsed_config = EnterpriseSearchPolicyConfig.from_dict(config)
1126
1058
  # Based on the enabled features (citation, relevancy check) fetch the
1127
1059
  # appropriate default prompt
1128
1060
  default_prompt = cls._select_default_prompt_template_based_on_features(
1129
- relevancy_check_enabled, citation_enabled
1061
+ parsed_config.check_relevancy, parsed_config.enable_citation
1130
1062
  )
1131
1063
 
1132
1064
  return default_prompt
1133
1065
 
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
1066
  @classmethod
1174
1067
  def _select_default_prompt_template_based_on_features(
1175
1068
  cls,