rasa-pro 3.13.0.dev20250613__py3-none-any.whl → 3.13.0rc2__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 (160) 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 +0 -17
  7. rasa/cli/studio/pull.py +3 -2
  8. rasa/cli/studio/push.py +1 -1
  9. rasa/cli/studio/train.py +1 -5
  10. rasa/cli/studio/upload.py +1 -1
  11. rasa/core/agent.py +6 -0
  12. rasa/core/channels/__init__.py +3 -0
  13. rasa/core/channels/development_inspector.py +1 -1
  14. rasa/core/channels/facebook.py +1 -4
  15. rasa/core/channels/inspector/README.md +3 -3
  16. rasa/core/channels/inspector/dist/assets/{arc-c4b064fc.js → arc-371401b1.js} +1 -1
  17. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-215b5026.js → blockDiagram-38ab4fdb-3f126156.js} +1 -1
  18. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-2b54a0a3.js → c4Diagram-3d4e48cf-12f22eb7.js} +1 -1
  19. rasa/core/channels/inspector/dist/assets/channel-f1efda17.js +1 -0
  20. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-daacea5f.js → classDiagram-70f12bd4-03b1d386.js} +1 -1
  21. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-930d4dc2.js → classDiagram-v2-f2320105-84f69d63.js} +1 -1
  22. rasa/core/channels/inspector/dist/assets/clone-fdf164e2.js +1 -0
  23. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-83c206ba.js → createText-2e5e7dd3-ca47fd38.js} +1 -1
  24. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-b0eb01d0.js → edges-e0da2a9e-f837ca8a.js} +1 -1
  25. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-17586500.js → erDiagram-9861fffd-8717ac54.js} +1 -1
  26. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-be2a1776.js → flowDb-956e92f1-94f38b83.js} +1 -1
  27. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-c2120ebd.js → flowDiagram-66a62f08-b616f9fb.js} +1 -1
  28. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-7d7a1629.js +1 -0
  29. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-a6ab5c48.js → flowchart-elk-definition-4a651766-f5d24bb8.js} +1 -1
  30. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-ef613457.js → ganttDiagram-c361ad54-b43ba8d9.js} +1 -1
  31. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-d59185b3.js → gitGraphDiagram-72cf32ee-c3aafaa5.js} +1 -1
  32. rasa/core/channels/inspector/dist/assets/{graph-0f155405.js → graph-0d0a2c10.js} +1 -1
  33. rasa/core/channels/inspector/dist/assets/{index-3862675e-d5f1d1b7.js → index-3862675e-58ea0305.js} +1 -1
  34. rasa/core/channels/inspector/dist/assets/{index-47737d3a.js → index-cce6f8a1.js} +3 -3
  35. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-b07d141f.js → infoDiagram-f8f76790-b8f60461.js} +1 -1
  36. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-1936d429.js → journeyDiagram-49397b02-95be5545.js} +1 -1
  37. rasa/core/channels/inspector/dist/assets/{layout-dde8d0f3.js → layout-da885b9b.js} +1 -1
  38. rasa/core/channels/inspector/dist/assets/{line-0c2c7ee0.js → line-f1c817d3.js} +1 -1
  39. rasa/core/channels/inspector/dist/assets/{linear-35dd89a4.js → linear-d42801e6.js} +1 -1
  40. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-56192851.js → mindmap-definition-fc14e90a-a38923a6.js} +1 -1
  41. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-fc21ed78.js → pieDiagram-8a3498a8-ca6e71e9.js} +1 -1
  42. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-25e98518.js → quadrantDiagram-120e2f19-b290dae9.js} +1 -1
  43. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-546ff1f5.js → requirementDiagram-deff3bca-03f02ceb.js} +1 -1
  44. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-02d8b82d.js → sankeyDiagram-04a897e0-c49eee40.js} +1 -1
  45. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-3ca5a92e.js → sequenceDiagram-704730f1-b2cd6a3d.js} +1 -1
  46. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-128ea07c.js → stateDiagram-587899a1-e53a2028.js} +1 -1
  47. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-95f290af.js → stateDiagram-v2-d93cdb3a-e1982a03.js} +1 -1
  48. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-4984898a.js → styles-6aaf32cf-d0226ca5.js} +1 -1
  49. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-1bf266ba.js → styles-9a916d00-0e21dc00.js} +1 -1
  50. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-60521c63.js → styles-c10674c1-9588494e.js} +1 -1
  51. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-a25b6e12.js → svgDrawCommon-08f97a94-be478d4f.js} +1 -1
  52. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-0fc086bf.js → timeline-definition-85554ec2-74631749.js} +1 -1
  53. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-44ee592e.js → xychartDiagram-e933f94c-a043552f.js} +1 -1
  54. rasa/core/channels/inspector/dist/index.html +1 -1
  55. rasa/core/channels/inspector/src/components/RecruitmentPanel.tsx +1 -1
  56. rasa/core/channels/socketio.py +56 -41
  57. rasa/core/channels/studio_chat.py +311 -8
  58. rasa/core/channels/voice_ready/audiocodes.py +1 -1
  59. rasa/core/channels/voice_ready/jambonz.py +5 -6
  60. rasa/core/channels/voice_ready/twilio_voice.py +13 -12
  61. rasa/core/channels/voice_ready/utils.py +22 -0
  62. rasa/core/channels/voice_stream/asr/azure.py +9 -0
  63. rasa/core/channels/voice_stream/audiocodes.py +5 -11
  64. rasa/core/channels/voice_stream/browser_audio.py +1 -1
  65. rasa/core/channels/voice_stream/genesys.py +35 -16
  66. rasa/core/channels/voice_stream/jambonz.py +232 -0
  67. rasa/core/channels/voice_stream/tts/__init__.py +8 -0
  68. rasa/core/channels/voice_stream/twilio_media_streams.py +12 -7
  69. rasa/core/channels/voice_stream/voice_channel.py +53 -15
  70. rasa/core/exporter.py +36 -0
  71. rasa/core/information_retrieval/faiss.py +18 -11
  72. rasa/core/information_retrieval/ingestion/faq_parser.py +158 -0
  73. rasa/core/nlg/contextual_response_rephraser.py +10 -1
  74. rasa/core/policies/enterprise_search_policy.py +189 -263
  75. rasa/core/policies/enterprise_search_policy_config.py +241 -0
  76. rasa/core/policies/enterprise_search_prompt_with_relevancy_check_and_citation_template.jinja2 +6 -5
  77. rasa/core/policies/intentless_policy.py +47 -10
  78. rasa/core/processor.py +6 -0
  79. rasa/core/utils.py +11 -2
  80. rasa/dialogue_understanding/coexistence/llm_based_router.py +13 -11
  81. rasa/dialogue_understanding/commands/__init__.py +4 -0
  82. rasa/dialogue_understanding/commands/cancel_flow_command.py +4 -2
  83. rasa/dialogue_understanding/commands/clarify_command.py +2 -2
  84. rasa/dialogue_understanding/commands/correct_slots_command.py +5 -6
  85. rasa/dialogue_understanding/commands/error_command.py +1 -1
  86. rasa/dialogue_understanding/commands/human_handoff_command.py +1 -3
  87. rasa/dialogue_understanding/commands/set_slot_command.py +4 -4
  88. rasa/dialogue_understanding/commands/skip_question_command.py +1 -3
  89. rasa/dialogue_understanding/commands/start_flow_command.py +3 -3
  90. rasa/dialogue_understanding/generator/command_generator.py +11 -1
  91. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +3 -2
  92. rasa/dialogue_understanding/generator/nlu_command_adapter.py +2 -2
  93. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_template.jinja2 +0 -2
  94. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +1 -0
  95. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +1 -0
  96. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2 +79 -0
  97. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +1 -0
  98. rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +2 -2
  99. rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +2 -18
  100. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +17 -11
  101. rasa/dialogue_understanding/patterns/cancel.py +1 -2
  102. rasa/dialogue_understanding/patterns/clarify.py +1 -1
  103. rasa/dialogue_understanding/patterns/correction.py +2 -2
  104. rasa/dialogue_understanding/processor/command_processor.py +11 -12
  105. rasa/dialogue_understanding/stack/utils.py +3 -1
  106. rasa/e2e_test/constants.py +1 -1
  107. rasa/e2e_test/e2e_test_coverage_report.py +1 -1
  108. rasa/engine/graph.py +2 -2
  109. rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +2 -6
  110. rasa/model_manager/runner_service.py +20 -4
  111. rasa/model_manager/trainer_service.py +6 -0
  112. rasa/privacy/privacy_manager.py +26 -11
  113. rasa/shared/constants.py +14 -0
  114. rasa/shared/core/command_payload_reader.py +1 -5
  115. rasa/shared/core/events.py +1 -3
  116. rasa/shared/core/flows/constants.py +2 -0
  117. rasa/shared/core/flows/flow.py +126 -12
  118. rasa/shared/core/flows/flows_list.py +18 -1
  119. rasa/shared/core/flows/steps/link.py +7 -2
  120. rasa/shared/core/flows/validation.py +25 -5
  121. rasa/shared/core/training_data/story_reader/yaml_story_reader.py +1 -4
  122. rasa/shared/providers/_configs/azure_openai_client_config.py +2 -2
  123. rasa/shared/providers/_configs/default_litellm_client_config.py +1 -1
  124. rasa/shared/providers/_configs/huggingface_local_embedding_client_config.py +1 -1
  125. rasa/shared/providers/_configs/openai_client_config.py +1 -1
  126. rasa/shared/providers/_configs/rasa_llm_client_config.py +1 -1
  127. rasa/shared/providers/_configs/self_hosted_llm_client_config.py +1 -1
  128. rasa/shared/providers/_configs/utils.py +0 -99
  129. rasa/shared/utils/common.py +1 -1
  130. rasa/shared/utils/configs.py +110 -0
  131. rasa/shared/utils/constants.py +0 -3
  132. rasa/shared/utils/llm.py +123 -8
  133. rasa/shared/utils/pykwalify_extensions.py +0 -9
  134. rasa/studio/constants.py +1 -0
  135. rasa/studio/data_handler.py +30 -9
  136. rasa/studio/download.py +171 -0
  137. rasa/studio/link.py +13 -2
  138. rasa/studio/prompts.py +221 -0
  139. rasa/studio/pull/__init__.py +0 -0
  140. rasa/studio/{download/flows.py → pull/data.py} +2 -131
  141. rasa/studio/{download → pull}/domains.py +1 -1
  142. rasa/studio/pull/pull.py +239 -0
  143. rasa/studio/push.py +7 -0
  144. rasa/studio/train.py +1 -1
  145. rasa/studio/upload.py +61 -5
  146. rasa/studio/utils.py +33 -0
  147. rasa/tracing/instrumentation/attribute_extractors.py +21 -7
  148. rasa/utils/common.py +11 -0
  149. rasa/version.py +1 -1
  150. {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/METADATA +4 -4
  151. {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/RECORD +155 -147
  152. rasa/core/channels/inspector/dist/assets/channel-3730f5fd.js +0 -1
  153. rasa/core/channels/inspector/dist/assets/clone-e847561e.js +0 -1
  154. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-efbbfe00.js +0 -1
  155. rasa/studio/download/download.py +0 -416
  156. rasa/studio/pull.py +0 -94
  157. /rasa/{studio/download → core/information_retrieval/ingestion}/__init__.py +0 -0
  158. {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/NOTICE +0 -0
  159. {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/WHEEL +0 -0
  160. {rasa_pro-3.13.0.dev20250613.dist-info → rasa_pro-3.13.0rc2.dist-info}/entry_points.txt +0 -0
@@ -1,8 +1,10 @@
1
1
  import dataclasses
2
+ import glob
2
3
  import importlib.resources
3
4
  import json
5
+ import os.path
4
6
  import re
5
- from typing import TYPE_CHECKING, Any, Dict, List, Literal, Optional, Text
7
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Text
6
8
 
7
9
  import dotenv
8
10
  import structlog
@@ -12,9 +14,6 @@ from pydantic import ValidationError
12
14
  import rasa.shared.utils.io
13
15
  from rasa.core.available_endpoints import AvailableEndpoints
14
16
  from rasa.core.constants import (
15
- POLICY_MAX_HISTORY,
16
- POLICY_PRIORITY,
17
- SEARCH_POLICY_PRIORITY,
18
17
  UTTER_SOURCE_METADATA_KEY,
19
18
  )
20
19
  from rasa.core.information_retrieval import (
@@ -24,6 +23,14 @@ from rasa.core.information_retrieval import (
24
23
  create_from_endpoint_config,
25
24
  )
26
25
  from rasa.core.information_retrieval.faiss import FAISS_Store
26
+ from rasa.core.policies.enterprise_search_policy_config import (
27
+ DEFAULT_EMBEDDINGS_CONFIG,
28
+ DEFAULT_ENTERPRISE_SEARCH_CONFIG,
29
+ DEFAULT_LLM_CONFIG,
30
+ DEFAULT_VECTOR_STORE_TYPE,
31
+ SOURCE_PROPERTY,
32
+ EnterpriseSearchPolicyConfig,
33
+ )
27
34
  from rasa.core.policies.policy import Policy, PolicyPrediction
28
35
  from rasa.dialogue_understanding.generator.constants import (
29
36
  LLM_CONFIG_KEY,
@@ -47,18 +54,11 @@ from rasa.graph_components.providers.forms_provider import Forms
47
54
  from rasa.graph_components.providers.responses_provider import Responses
48
55
  from rasa.shared.constants import (
49
56
  EMBEDDINGS_CONFIG_KEY,
50
- MAX_COMPLETION_TOKENS_CONFIG_KEY,
51
- MAX_RETRIES_CONFIG_KEY,
52
57
  MODEL_CONFIG_KEY,
53
58
  MODEL_GROUP_ID_CONFIG_KEY,
54
59
  MODEL_NAME_CONFIG_KEY,
55
- OPENAI_PROVIDER,
56
- PROMPT_CONFIG_KEY,
57
- PROMPT_TEMPLATE_CONFIG_KEY,
58
60
  PROVIDER_CONFIG_KEY,
59
61
  RASA_PATTERN_CANNOT_HANDLE_NO_RELEVANT_ANSWER,
60
- TEMPERATURE_CONFIG_KEY,
61
- TIMEOUT_CONFIG_KEY,
62
62
  )
63
63
  from rasa.shared.core.constants import (
64
64
  ACTION_CANCEL_FLOW,
@@ -93,12 +93,9 @@ from rasa.shared.utils.health_check.embeddings_health_check_mixin import (
93
93
  from rasa.shared.utils.health_check.llm_health_check_mixin import LLMHealthCheckMixin
94
94
  from rasa.shared.utils.io import deep_container_fingerprint
95
95
  from rasa.shared.utils.llm import (
96
- DEFAULT_OPENAI_CHAT_MODEL_NAME,
97
- DEFAULT_OPENAI_EMBEDDING_MODEL_NAME,
98
96
  embedder_factory,
99
97
  get_prompt_template,
100
98
  llm_factory,
101
- resolve_model_client_config,
102
99
  sanitize_message_for_prompt,
103
100
  tracker_as_readable_transcript,
104
101
  )
@@ -119,42 +116,6 @@ structlogger = structlog.get_logger()
119
116
 
120
117
  dotenv.load_dotenv("./.env")
121
118
 
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
119
  ENTERPRISE_SEARCH_PROMPT_FILE_NAME = "enterprise_search_policy_prompt.jinja2"
159
120
  ENTERPRISE_SEARCH_CONFIG_FILE_NAME = "config.json"
160
121
 
@@ -176,10 +137,7 @@ DEFAULT_ENTERPRISE_SEARCH_PROMPT_WITH_RELEVANCY_CHECK_AND_CITATION_TEMPLATE = (
176
137
  )
177
138
  )
178
139
 
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
- )
140
+ _ENTERPRISE_SEARCH_ANSWER_NOT_RELEVANT_PATTERN = re.compile(r"\[NO_RAG_ANSWER\]")
183
141
 
184
142
 
185
143
  class VectorStoreConnectionError(RasaException):
@@ -227,10 +185,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
227
185
  @staticmethod
228
186
  def get_default_config() -> Dict[str, Any]:
229
187
  """Returns the default config of the policy."""
230
- return {
231
- POLICY_PRIORITY: SEARCH_POLICY_PRIORITY,
232
- VECTOR_STORE_PROPERTY: DEFAULT_VECTOR_STORE,
233
- }
188
+ return DEFAULT_ENTERPRISE_SEARCH_CONFIG
234
189
 
235
190
  def __init__(
236
191
  self,
@@ -245,131 +200,71 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
245
200
  """Constructs a new Policy object."""
246
201
  super().__init__(config, model_storage, resource, execution_context, featurizer)
247
202
 
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
- )
203
+ parsed_config = EnterpriseSearchPolicyConfig.from_dict(config)
261
204
 
262
205
  # Vector store object and configuration
263
206
  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
- )
207
+ self.vector_store_config = parsed_config.vector_store_config
208
+ self.vector_search_threshold = parsed_config.vector_store_threshold
209
+ self.vector_store_type = parsed_config.vector_store_type
270
210
 
271
- # Embeddings configuration for encoding the search query
272
- self.embeddings_config = (
273
- self.config[EMBEDDINGS_CONFIG_KEY] or DEFAULT_EMBEDDINGS_CONFIG
274
- )
211
+ # Resolved embeddings configuration for encoding the search query
212
+ self.embeddings_config = parsed_config.embeddings_config
275
213
 
276
- # LLM Configuration for response generation
277
- self.llm_config = self.config[LLM_CONFIG_KEY] or DEFAULT_LLM_CONFIG
214
+ # Resolved LLM Configuration for response generation
215
+ self.llm_config = parsed_config.llm_config
278
216
 
279
217
  # Maximum number of turns to include in the prompt
280
- self.max_history = self.config.get(POLICY_MAX_HISTORY)
218
+ self.max_history = parsed_config.max_history
281
219
 
282
220
  # 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)
221
+ self.max_messages_in_query = parsed_config.max_messages_in_query
284
222
 
285
223
  # Boolean to enable/disable tracing of prompt tokens
286
- self.trace_prompt_tokens = self.config.get(TRACE_TOKENS_PROPERTY, False)
224
+ self.trace_prompt_tokens = parsed_config.trace_prompt_tokens
287
225
 
288
226
  # 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)
227
+ self.use_llm = parsed_config.use_generative_llm
290
228
 
291
229
  # Boolean to enable/disable citation generation. This flag enables citation
292
230
  # 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
- )
231
+ self.citation_enabled = parsed_config.enable_citation
296
232
 
297
233
  # Boolean to enable/disable the use of relevancy check alongside answer
298
234
  # generation. This flag enables citation logic, but it only takes effect if
299
235
  # `use_llm` is True.
300
- self.relevancy_check_enabled = self.config.get(
301
- CHECK_RELEVANCY_PROPERTY, DEFAULT_CHECK_RELEVANCY_PROPERTY
302
- )
236
+ self.relevancy_check_enabled = parsed_config.check_relevancy
303
237
 
304
238
  # Resolve the prompt template. The prompt will only be used if the 'use_llm' is
305
239
  # set to True.
306
- self.prompt_template = prompt_template or self._resolve_prompt_template(
307
- self.config, LOG_COMPONENT_SOURCE_METHOD_INIT
240
+ self.prompt_template = prompt_template or get_prompt_template(
241
+ jinja_file_path=parsed_config.prompt_template,
242
+ default_prompt_template=self._select_default_prompt_template_based_on_features(
243
+ parsed_config.check_relevancy, parsed_config.enable_citation
244
+ ),
245
+ log_source_component=EnterpriseSearchPolicy.__name__,
246
+ log_source_method=LOG_COMPONENT_SOURCE_METHOD_INIT,
308
247
  )
309
248
 
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
249
  @classmethod
358
- def _create_plain_embedder(cls, config: Dict[Text, Any]) -> "Embeddings":
250
+ def _create_plain_embedder(cls, embeddings_config: Dict[Text, Any]) -> "Embeddings":
359
251
  """Creates an embedder based on the given configuration.
360
252
 
253
+ Args:
254
+ embeddings_config: A resolved embeddings configuration. Resolved means the
255
+ configuration is either:
256
+ - A reference to a model group that has already been expanded into
257
+ its corresponding configuration using the information from
258
+ `endpoints.yml`, or
259
+ - A full configuration for the embedder defined directly (i.e. not
260
+ relying on model groups or indirections).
261
+
361
262
  Returns:
362
- The embedder.
263
+ The embedder.
363
264
  """
364
265
  # 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
- )
266
+ embeddings_config = embeddings_config.copy()
267
+ client = embedder_factory(embeddings_config, DEFAULT_EMBEDDINGS_CONFIG)
373
268
  # Wrap the embedding client in the adapter
374
269
  return _LangchainEmbeddingClientAdapter(client)
375
270
 
@@ -435,16 +330,16 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
435
330
  can load the policy from the resource.
436
331
  """
437
332
  # 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)
333
+ self._perform_health_checks(
334
+ self.llm_config, self.embeddings_config, "enterprise_search_policy.train"
335
+ )
441
336
 
442
337
  # telemetry call to track training start
443
338
  track_enterprise_search_policy_train_started()
444
339
 
445
340
  # validate embedding configuration
446
341
  try:
447
- embeddings = self._create_plain_embedder(self.config)
342
+ embeddings = self._create_plain_embedder(self.embeddings_config)
448
343
  except (ValidationError, Exception) as e:
449
344
  structlogger.error(
450
345
  "enterprise_search_policy.train.embedder_instantiation_failed",
@@ -456,23 +351,27 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
456
351
  f"required environment variables. Error: {e}"
457
352
  )
458
353
 
459
- if store_type == DEFAULT_VECTOR_STORE_TYPE:
354
+ if self.vector_store_type == DEFAULT_VECTOR_STORE_TYPE:
460
355
  structlogger.info("enterprise_search_policy.train.faiss")
356
+ docs_folder = self.vector_store_config.get(SOURCE_PROPERTY)
357
+ self._validate_documents_folder(docs_folder)
461
358
  with self._model_storage.write_to(self._resource) as path:
462
359
  self.vector_store = FAISS_Store(
463
- docs_folder=self.vector_store_config.get(SOURCE_PROPERTY),
360
+ docs_folder=docs_folder,
464
361
  embeddings=embeddings,
465
362
  index_path=path,
466
363
  create_index=True,
364
+ parse_as_faq_pairs=not self.use_llm,
467
365
  )
468
366
  else:
469
367
  structlogger.info(
470
- "enterprise_search_policy.train.custom", store_type=store_type
368
+ "enterprise_search_policy.train.custom",
369
+ store_type=self.vector_store_type,
471
370
  )
472
371
 
473
372
  # telemetry call to track training completion
474
373
  track_enterprise_search_policy_train_completed(
475
- vector_store_type=store_type,
374
+ vector_store_type=self.vector_store_type,
476
375
  embeddings_type=self.embeddings_config.get(PROVIDER_CONFIG_KEY),
477
376
  embeddings_model=self.embeddings_config.get(MODEL_CONFIG_KEY)
478
377
  or self.embeddings_config.get(MODEL_NAME_CONFIG_KEY),
@@ -495,8 +394,11 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
495
394
  rasa.shared.utils.io.write_text_file(
496
395
  self.prompt_template, path / ENTERPRISE_SEARCH_PROMPT_FILE_NAME
497
396
  )
397
+ config = self.config.copy()
398
+ config[LLM_CONFIG_KEY] = self.llm_config
399
+ config[EMBEDDINGS_CONFIG_KEY] = self.embeddings_config
498
400
  rasa.shared.utils.io.dump_obj_as_json_to_file(
499
- path / ENTERPRISE_SEARCH_CONFIG_FILE_NAME, self.config
401
+ path / ENTERPRISE_SEARCH_CONFIG_FILE_NAME, config
500
402
  )
501
403
 
502
404
  def _prepare_slots_for_template(
@@ -535,8 +437,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
535
437
  endpoints: Endpoints configuration.
536
438
  """
537
439
  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:
440
+ if config is None and self.vector_store_type != DEFAULT_VECTOR_STORE_TYPE:
540
441
  structlogger.error(
541
442
  "enterprise_search_policy._connect_vector_store_or_raise.no_config"
542
443
  )
@@ -697,7 +598,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
697
598
 
698
599
  # telemetry call to track policy prediction
699
600
  track_enterprise_search_policy_predict(
700
- vector_store_type=self.vector_store_config.get(VECTOR_STORE_TYPE_PROPERTY),
601
+ vector_store_type=self.vector_store_type,
701
602
  embeddings_type=self.embeddings_config.get(PROVIDER_CONFIG_KEY),
702
603
  embeddings_model=self.embeddings_config.get(MODEL_CONFIG_KEY)
703
604
  or self.embeddings_config.get(MODEL_NAME_CONFIG_KEY),
@@ -756,7 +657,7 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
756
657
  Returns:
757
658
  An LLMResponse object, or None if the call fails.
758
659
  """
759
- llm = llm_factory(self.config.get(LLM_CONFIG_KEY), DEFAULT_LLM_CONFIG)
660
+ llm = llm_factory(self.llm_config, DEFAULT_LLM_CONFIG)
760
661
  try:
761
662
  response = await llm.acompletion(prompt)
762
663
  return LLMResponse.ensure_llm_response(response)
@@ -876,6 +777,33 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
876
777
  result[domain.index_for_action(action_name)] = score # type: ignore[assignment]
877
778
  return result
878
779
 
780
+ @classmethod
781
+ def _validate_documents_folder(cls, docs_folder: str) -> None:
782
+ if not os.path.exists(docs_folder) or not os.path.isdir(docs_folder):
783
+ error_message = (
784
+ f"Document source directory does not exist or is not a "
785
+ f"directory: '{docs_folder}'. "
786
+ "Please specify a valid path to the documents source directory in the "
787
+ "vector_store configuration."
788
+ )
789
+ structlogger.error(
790
+ "enterprise_search_policy.train.faiss.invalid_source_directory",
791
+ message=error_message,
792
+ )
793
+ print_error_and_exit(error_message)
794
+
795
+ docs = glob.glob(os.path.join(docs_folder, "*.txt"), recursive=True)
796
+ if not docs or len(docs) < 1:
797
+ error_message = (
798
+ f"Document source directory is empty: '{docs_folder}'. "
799
+ "Please add documents to this directory or specify a different one."
800
+ )
801
+ structlogger.error(
802
+ "enterprise_search_policy.train.faiss.source_directory_empty",
803
+ message=error_message,
804
+ )
805
+ print_error_and_exit(error_message)
806
+
879
807
  @classmethod
880
808
  def load(
881
809
  cls,
@@ -886,70 +814,93 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
886
814
  **kwargs: Any,
887
815
  ) -> "EnterpriseSearchPolicy":
888
816
  """Loads a trained policy (see parent class for full docstring)."""
817
+ parsed_config = EnterpriseSearchPolicyConfig.from_dict(config)
818
+
889
819
  # Perform health checks for both LLM and embeddings client configs
890
- cls._perform_health_checks(config, "enterprise_search_policy.load")
820
+ cls._perform_health_checks(
821
+ parsed_config.llm_config,
822
+ parsed_config.embeddings_config,
823
+ "enterprise_search_policy.load",
824
+ )
825
+
826
+ prompt_template = cls._load_prompt_template(model_storage, resource)
827
+ embeddings = cls._create_plain_embedder(parsed_config.embeddings_config)
828
+ vector_store = cls._load_vector_store(
829
+ embeddings,
830
+ parsed_config.vector_store_type,
831
+ parsed_config.use_generative_llm,
832
+ model_storage,
833
+ resource,
834
+ )
835
+
836
+ structlogger.info("enterprise_search_policy.load", config=config)
891
837
 
892
- prompt_template = None
838
+ return cls(
839
+ config,
840
+ model_storage,
841
+ resource,
842
+ execution_context,
843
+ vector_store=vector_store,
844
+ prompt_template=prompt_template,
845
+ )
846
+
847
+ @classmethod
848
+ def _load_prompt_template(
849
+ cls, model_storage: ModelStorage, resource: Resource
850
+ ) -> Optional[str]:
893
851
  try:
894
852
  with model_storage.read_from(resource) as path:
895
- prompt_template = rasa.shared.utils.io.read_file(
853
+ return rasa.shared.utils.io.read_file(
896
854
  path / ENTERPRISE_SEARCH_PROMPT_FILE_NAME
897
855
  )
898
856
  except (FileNotFoundError, FileIOException) as e:
899
857
  structlogger.warning(
900
858
  "enterprise_search_policy.load.failed", error=e, resource=resource.name
901
859
  )
860
+ return None
902
861
 
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)
862
+ @classmethod
863
+ def _load_vector_store(
864
+ cls,
865
+ embeddings: "Embeddings",
866
+ store_type: str,
867
+ use_generative_llm: bool,
868
+ model_storage: ModelStorage,
869
+ resource: Resource,
870
+ ) -> InformationRetrieval:
910
871
  if store_type == DEFAULT_VECTOR_STORE_TYPE:
911
872
  # if a vector store is not specified,
912
873
  # default to using FAISS with the index stored in the model
913
874
  # TODO figure out a way to get path without context manager
914
875
  with model_storage.read_from(resource) as path:
915
- vector_store = FAISS_Store(
876
+ return FAISS_Store(
916
877
  embeddings=embeddings,
917
878
  index_path=path,
918
879
  docs_folder=None,
919
880
  create_index=False,
881
+ parse_as_faq_pairs=not use_generative_llm,
920
882
  )
921
883
  else:
922
- vector_store = create_from_endpoint_config(
884
+ return create_from_endpoint_config(
923
885
  config_type=store_type,
924
886
  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
- )
887
+ )
935
888
 
936
889
  @classmethod
937
- def _get_local_knowledge_data(cls, config: Dict[str, Any]) -> Optional[List[str]]:
890
+ def _get_local_knowledge_data(
891
+ cls, store_type: str, source: Optional[str] = None
892
+ ) -> Optional[List[str]]:
938
893
  """This is required only for local knowledge base types.
939
894
 
940
895
  e.g. FAISS, to ensure that the graph component is retrained when the knowledge
941
896
  base is updated.
942
897
  """
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:
898
+ if (
899
+ store_type != DEFAULT_VECTOR_STORE_TYPE
900
+ or not source
901
+ or not os.path.exists(source)
902
+ or not os.path.isdir(source)
903
+ ):
953
904
  return None
954
905
 
955
906
  docs = FAISS_Store.load_documents(source)
@@ -965,18 +916,28 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
965
916
  @classmethod
966
917
  def fingerprint_addon(cls, config: Dict[str, Any]) -> Optional[str]:
967
918
  """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
- )
919
+ parsed_config = EnterpriseSearchPolicyConfig.from_dict(config)
971
920
 
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__
921
+ # Resolve the prompt template
922
+ default_prompt_template = cls._select_default_prompt_template_based_on_features(
923
+ parsed_config.check_relevancy, parsed_config.enable_citation
976
924
  )
977
- embedding_config = resolve_model_client_config(
978
- config.get(EMBEDDINGS_CONFIG_KEY), EnterpriseSearchPolicy.__name__
925
+ prompt_template = get_prompt_template(
926
+ jinja_file_path=parsed_config.prompt_template,
927
+ default_prompt_template=default_prompt_template,
928
+ log_source_component=EnterpriseSearchPolicy.__name__,
929
+ log_source_method=LOG_COMPONENT_SOURCE_METHOD_FINGERPRINT_ADDON,
979
930
  )
931
+
932
+ # Fetch the local knowledge data in case FAISS is used
933
+ local_knowledge_data = cls._get_local_knowledge_data(
934
+ parsed_config.vector_store_type, parsed_config.vector_store_source
935
+ )
936
+
937
+ # Get the resolved LLM and embeddings configurations
938
+ llm_config = parsed_config.llm_config
939
+ embedding_config = parsed_config.embeddings_config
940
+
980
941
  return deep_container_fingerprint(
981
942
  [prompt_template, local_knowledge_data, llm_config, embedding_config]
982
943
  )
@@ -1074,21 +1035,32 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
1074
1035
 
1075
1036
  @classmethod
1076
1037
  def _perform_health_checks(
1077
- cls, config: Dict[Text, Any], log_source_method: str
1038
+ cls,
1039
+ llm_config: Dict[Text, Any],
1040
+ embeddings_config: Dict[Text, Any],
1041
+ log_source_method: str,
1078
1042
  ) -> None:
1079
- # Perform health check of the LLM client config
1080
- llm_config = resolve_model_client_config(config.get(LLM_CONFIG_KEY, {}))
1043
+ """
1044
+ Perform the health checks using resolved LLM and embeddings configurations.
1045
+ Resolved means the configuration is either:
1046
+ - A reference to a model group that has already been expanded into
1047
+ its corresponding configuration using the information from
1048
+ `endpoints.yml`, or
1049
+ - A full configuration for the embedder defined directly (i.e. not
1050
+ relying on model groups or indirections).
1051
+
1052
+ Args:
1053
+ llm_config: A resolved LLM configuration.
1054
+ embeddings_config: A resolved embeddings configuration.
1055
+ log_source_method: The method health checks has been called from.
1056
+
1057
+ """
1081
1058
  cls.perform_llm_health_check(
1082
1059
  llm_config,
1083
1060
  DEFAULT_LLM_CONFIG,
1084
1061
  log_source_method,
1085
1062
  EnterpriseSearchPolicy.__name__,
1086
1063
  )
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
1064
  cls.perform_embeddings_health_check(
1093
1065
  embeddings_config,
1094
1066
  DEFAULT_EMBEDDINGS_CONFIG,
@@ -1114,62 +1086,16 @@ class EnterpriseSearchPolicy(LLMHealthCheckMixin, EmbeddingsHealthCheckMixin, Po
1114
1086
  Returns:
1115
1087
  The resolved jinja prompt template as a string.
1116
1088
  """
1117
-
1118
1089
  # 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
-
1090
+ parsed_config = EnterpriseSearchPolicyConfig.from_dict(config)
1126
1091
  # Based on the enabled features (citation, relevancy check) fetch the
1127
1092
  # appropriate default prompt
1128
1093
  default_prompt = cls._select_default_prompt_template_based_on_features(
1129
- relevancy_check_enabled, citation_enabled
1094
+ parsed_config.check_relevancy, parsed_config.enable_citation
1130
1095
  )
1131
1096
 
1132
1097
  return default_prompt
1133
1098
 
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
1099
  @classmethod
1174
1100
  def _select_default_prompt_template_based_on_features(
1175
1101
  cls,