rasa-pro 3.13.0.dev3__py3-none-any.whl → 3.13.0.dev7__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 (228) hide show
  1. rasa/__main__.py +3 -1
  2. rasa/api.py +4 -0
  3. rasa/cli/arguments/default_arguments.py +13 -1
  4. rasa/cli/arguments/train.py +2 -0
  5. rasa/cli/evaluate.py +1 -1
  6. rasa/cli/export.py +2 -2
  7. rasa/cli/inspect.py +8 -4
  8. rasa/cli/project_templates/default/config.yml +5 -32
  9. rasa/cli/project_templates/{calm → default}/e2e_tests/cancelations/user_cancels_during_a_correction.yml +1 -1
  10. rasa/cli/project_templates/{calm → default}/e2e_tests/cancelations/user_changes_mind_on_a_whim.yml +1 -1
  11. rasa/cli/project_templates/{calm → default}/e2e_tests/corrections/user_corrects_contact_handle.yml +1 -1
  12. rasa/cli/project_templates/{calm → default}/e2e_tests/corrections/user_corrects_contact_name.yml +1 -1
  13. rasa/cli/project_templates/{calm → default}/e2e_tests/happy_paths/user_adds_contact_to_their_list.yml +1 -1
  14. rasa/cli/project_templates/{calm → default}/e2e_tests/happy_paths/user_lists_contacts.yml +1 -1
  15. rasa/cli/project_templates/{calm → default}/e2e_tests/happy_paths/user_removes_contact.yml +1 -1
  16. rasa/cli/project_templates/{calm → default}/e2e_tests/happy_paths/user_removes_contact_from_list.yml +1 -1
  17. rasa/cli/project_templates/default/endpoints.yml +18 -2
  18. rasa/cli/scaffold.py +3 -4
  19. rasa/cli/studio/download.py +1 -1
  20. rasa/cli/studio/upload.py +0 -6
  21. rasa/cli/train.py +1 -0
  22. rasa/constants.py +2 -0
  23. rasa/core/agent.py +2 -2
  24. rasa/core/brokers/kafka.py +4 -0
  25. rasa/core/brokers/pika.py +4 -0
  26. rasa/core/brokers/sql.py +1 -1
  27. rasa/core/channels/channel.py +68 -5
  28. rasa/core/channels/inspector/.eslintrc.cjs +12 -6
  29. rasa/core/channels/inspector/.prettierrc +5 -0
  30. rasa/core/channels/inspector/README.md +10 -4
  31. rasa/core/channels/inspector/dist/assets/{arc-c7691751.js → arc-c4b064fc.js} +1 -1
  32. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-ab99dff7.js → blockDiagram-38ab4fdb-215b5026.js} +1 -1
  33. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-08c35a6b.js → c4Diagram-3d4e48cf-2b54a0a3.js} +1 -1
  34. rasa/core/channels/inspector/dist/assets/channel-3730f5fd.js +1 -0
  35. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-9e9c71c9.js → classDiagram-70f12bd4-daacea5f.js} +1 -1
  36. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-15e7e2bf.js → classDiagram-v2-f2320105-930d4dc2.js} +1 -1
  37. rasa/core/channels/inspector/dist/assets/clone-e847561e.js +1 -0
  38. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-9c105cb1.js → createText-2e5e7dd3-83c206ba.js} +1 -1
  39. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-77e89e48.js → edges-e0da2a9e-b0eb01d0.js} +1 -1
  40. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-7a011646.js → erDiagram-9861fffd-17586500.js} +1 -1
  41. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-b6f105ac.js → flowDb-956e92f1-be2a1776.js} +1 -1
  42. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-ce4f18c2.js → flowDiagram-66a62f08-c2120ebd.js} +1 -1
  43. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-efbbfe00.js +1 -0
  44. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-cb5f6da4.js → flowchart-elk-definition-4a651766-a6ab5c48.js} +1 -1
  45. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-e4d19e28.js → ganttDiagram-c361ad54-ef613457.js} +1 -1
  46. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-727b1c33.js → gitGraphDiagram-72cf32ee-d59185b3.js} +1 -1
  47. rasa/core/channels/inspector/dist/assets/{graph-6e2ab9a7.js → graph-0f155405.js} +1 -1
  48. rasa/core/channels/inspector/dist/assets/{index-3862675e-84ec700f.js → index-3862675e-d5f1d1b7.js} +1 -1
  49. rasa/core/channels/inspector/dist/assets/{index-098a1a24.js → index-47737d3a.js} +162 -149
  50. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-78dda442.js → infoDiagram-f8f76790-b07d141f.js} +1 -1
  51. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-f1cc6dd1.js → journeyDiagram-49397b02-1936d429.js} +1 -1
  52. rasa/core/channels/inspector/dist/assets/{layout-d98dcd0c.js → layout-dde8d0f3.js} +1 -1
  53. rasa/core/channels/inspector/dist/assets/{line-838e3d82.js → line-0c2c7ee0.js} +1 -1
  54. rasa/core/channels/inspector/dist/assets/{linear-eae72406.js → linear-35dd89a4.js} +1 -1
  55. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-c96fd84b.js → mindmap-definition-fc14e90a-56192851.js} +1 -1
  56. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-c936d4e2.js → pieDiagram-8a3498a8-fc21ed78.js} +1 -1
  57. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-b338eb8f.js → quadrantDiagram-120e2f19-25e98518.js} +1 -1
  58. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-c6b6c0d5.js → requirementDiagram-deff3bca-546ff1f5.js} +1 -1
  59. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-b9372e19.js → sankeyDiagram-04a897e0-02d8b82d.js} +1 -1
  60. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-479e0a3f.js → sequenceDiagram-704730f1-3ca5a92e.js} +1 -1
  61. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-fd26eebc.js → stateDiagram-587899a1-128ea07c.js} +1 -1
  62. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-3233e0ae.js → stateDiagram-v2-d93cdb3a-95f290af.js} +1 -1
  63. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-1fdd392b.js → styles-6aaf32cf-4984898a.js} +1 -1
  64. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-6d7bfa1b.js → styles-9a916d00-1bf266ba.js} +1 -1
  65. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-f86aab11.js → styles-c10674c1-60521c63.js} +1 -1
  66. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-e3e49d7a.js → svgDrawCommon-08f97a94-a25b6e12.js} +1 -1
  67. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-6fe08b4d.js → timeline-definition-85554ec2-0fc086bf.js} +1 -1
  68. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-c2e06fd6.js → xychartDiagram-e933f94c-44ee592e.js} +1 -1
  69. rasa/core/channels/inspector/dist/index.html +1 -1
  70. rasa/core/channels/inspector/package.json +3 -1
  71. rasa/core/channels/inspector/src/App.tsx +92 -90
  72. rasa/core/channels/inspector/src/components/Chat.tsx +61 -36
  73. rasa/core/channels/inspector/src/components/DiagramFlow.tsx +40 -43
  74. rasa/core/channels/inspector/src/components/DialogueInformation.tsx +57 -57
  75. rasa/core/channels/inspector/src/components/DialogueStack.tsx +36 -27
  76. rasa/core/channels/inspector/src/components/ExpandIcon.tsx +4 -4
  77. rasa/core/channels/inspector/src/components/FullscreenButton.tsx +7 -7
  78. rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +28 -12
  79. rasa/core/channels/inspector/src/components/NoActiveFlow.tsx +9 -9
  80. rasa/core/channels/inspector/src/components/RasaLogo.tsx +5 -5
  81. rasa/core/channels/inspector/src/components/RecruitmentPanel.tsx +55 -60
  82. rasa/core/channels/inspector/src/components/SaraDiagrams.tsx +5 -5
  83. rasa/core/channels/inspector/src/components/Slots.tsx +22 -22
  84. rasa/core/channels/inspector/src/components/Welcome.tsx +28 -31
  85. rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +245 -0
  86. rasa/core/channels/inspector/src/helpers/audio/microphone-processor.js +12 -0
  87. rasa/core/channels/inspector/src/helpers/audio/playback-processor.js +36 -0
  88. rasa/core/channels/inspector/src/helpers/conversation.ts +16 -0
  89. rasa/core/channels/inspector/src/helpers/formatters.test.ts +181 -181
  90. rasa/core/channels/inspector/src/helpers/formatters.ts +111 -111
  91. rasa/core/channels/inspector/src/helpers/utils.ts +78 -61
  92. rasa/core/channels/inspector/src/main.tsx +8 -8
  93. rasa/core/channels/inspector/src/theme/Button/Button.ts +8 -8
  94. rasa/core/channels/inspector/src/theme/Heading/Heading.ts +7 -7
  95. rasa/core/channels/inspector/src/theme/Input/Input.ts +9 -9
  96. rasa/core/channels/inspector/src/theme/Link/Link.ts +6 -6
  97. rasa/core/channels/inspector/src/theme/Modal/Modal.ts +13 -13
  98. rasa/core/channels/inspector/src/theme/Table/Table.tsx +10 -10
  99. rasa/core/channels/inspector/src/theme/Tooltip/Tooltip.ts +5 -5
  100. rasa/core/channels/inspector/src/theme/base/breakpoints.ts +7 -7
  101. rasa/core/channels/inspector/src/theme/base/colors.ts +64 -64
  102. rasa/core/channels/inspector/src/theme/base/fonts/fontFaces.css +21 -18
  103. rasa/core/channels/inspector/src/theme/base/radii.ts +8 -8
  104. rasa/core/channels/inspector/src/theme/base/shadows.ts +5 -5
  105. rasa/core/channels/inspector/src/theme/base/sizes.ts +5 -5
  106. rasa/core/channels/inspector/src/theme/base/space.ts +12 -12
  107. rasa/core/channels/inspector/src/theme/base/styles.ts +5 -5
  108. rasa/core/channels/inspector/src/theme/base/typography.ts +12 -12
  109. rasa/core/channels/inspector/src/theme/base/zIndices.ts +3 -3
  110. rasa/core/channels/inspector/src/theme/index.ts +38 -38
  111. rasa/core/channels/inspector/src/types.ts +56 -50
  112. rasa/core/channels/inspector/yarn.lock +5 -0
  113. rasa/core/channels/voice_ready/audiocodes.py +75 -32
  114. rasa/core/channels/voice_ready/twilio_voice.py +48 -1
  115. rasa/core/channels/voice_stream/tts/azure.py +11 -2
  116. rasa/core/channels/voice_stream/twilio_media_streams.py +101 -26
  117. rasa/core/channels/voice_stream/voice_channel.py +28 -2
  118. rasa/core/concurrent_lock_store.py +24 -10
  119. rasa/core/evaluation/marker_tracker_loader.py +1 -1
  120. rasa/core/exporter.py +1 -1
  121. rasa/core/lock_store.py +151 -60
  122. rasa/core/nlg/contextual_response_rephraser.py +4 -2
  123. rasa/core/nlg/summarize.py +1 -1
  124. rasa/core/persistor.py +55 -20
  125. rasa/core/policies/enterprise_search_policy.py +7 -4
  126. rasa/core/policies/intentless_policy.py +15 -9
  127. rasa/core/processor.py +2 -2
  128. rasa/core/run.py +7 -2
  129. rasa/core/{auth_retry_tracker_store.py → tracker_stores/auth_retry_tracker_store.py} +5 -1
  130. rasa/core/tracker_stores/dynamo_tracker_store.py +218 -0
  131. rasa/core/tracker_stores/mongo_tracker_store.py +206 -0
  132. rasa/core/tracker_stores/redis_tracker_store.py +219 -0
  133. rasa/core/tracker_stores/sql_tracker_store.py +555 -0
  134. rasa/core/tracker_stores/tracker_store.py +805 -0
  135. rasa/core/utils.py +6 -0
  136. rasa/dialogue_understanding/coexistence/llm_based_router.py +8 -3
  137. rasa/dialogue_understanding/commands/clarify_command.py +2 -2
  138. rasa/dialogue_understanding/commands/knowledge_answer_command.py +2 -2
  139. rasa/dialogue_understanding/generator/constants.py +2 -2
  140. rasa/dialogue_understanding/generator/llm_based_command_generator.py +1 -1
  141. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +33 -12
  142. rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +2 -2
  143. rasa/dialogue_understanding_test/du_test_case.py +16 -8
  144. rasa/hooks.py +2 -2
  145. rasa/keys +1 -0
  146. rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +4 -2
  147. rasa/model_manager/config.py +3 -1
  148. rasa/model_manager/model_api.py +1 -2
  149. rasa/model_manager/runner_service.py +8 -4
  150. rasa/model_manager/trainer_service.py +1 -0
  151. rasa/model_training.py +12 -3
  152. rasa/nlu/extractors/crf_entity_extractor.py +66 -16
  153. rasa/plugin.py +1 -4
  154. rasa/server.py +6 -2
  155. rasa/shared/constants.py +4 -0
  156. rasa/shared/core/domain.py +165 -11
  157. rasa/shared/core/events.py +68 -2
  158. rasa/shared/core/flows/flow.py +155 -131
  159. rasa/shared/core/flows/flow_step.py +19 -3
  160. rasa/shared/core/flows/flow_step_links.py +15 -0
  161. rasa/shared/core/flows/flow_step_sequence.py +6 -0
  162. rasa/shared/core/flows/nlu_trigger.py +13 -0
  163. rasa/shared/core/flows/steps/action.py +7 -4
  164. rasa/shared/core/flows/steps/call.py +11 -4
  165. rasa/shared/core/flows/steps/collect.py +27 -6
  166. rasa/shared/core/flows/steps/internal.py +6 -1
  167. rasa/shared/core/flows/steps/link.py +7 -4
  168. rasa/shared/core/flows/steps/no_operation.py +7 -4
  169. rasa/shared/core/flows/steps/set_slots.py +8 -4
  170. rasa/shared/core/flows/yaml_flows_io.py +106 -5
  171. rasa/shared/importers/importer.py +8 -0
  172. rasa/shared/providers/_configs/azure_openai_client_config.py +4 -0
  173. rasa/shared/providers/_configs/openai_client_config.py +4 -0
  174. rasa/shared/providers/_utils.py +83 -0
  175. rasa/shared/providers/embedding/_base_litellm_embedding_client.py +3 -0
  176. rasa/shared/providers/llm/_base_litellm_client.py +11 -5
  177. rasa/shared/providers/llm/azure_openai_llm_client.py +6 -68
  178. rasa/shared/providers/router/_base_litellm_router_client.py +53 -1
  179. rasa/shared/utils/common.py +42 -0
  180. rasa/studio/download/__init__.py +0 -0
  181. rasa/studio/download/domains.py +49 -0
  182. rasa/studio/download/download.py +439 -0
  183. rasa/studio/download/flows.py +359 -0
  184. rasa/studio/results_logger.py +6 -1
  185. rasa/studio/upload.py +69 -5
  186. rasa/telemetry.py +2 -2
  187. rasa/tracing/config.py +1 -1
  188. rasa/tracing/instrumentation/attribute_extractors.py +1 -1
  189. rasa/tracing/instrumentation/instrumentation.py +1 -1
  190. rasa/utils/common.py +36 -0
  191. rasa/utils/endpoints.py +22 -1
  192. rasa/utils/licensing.py +2 -3
  193. rasa/validator.py +1 -2
  194. rasa/version.py +1 -1
  195. {rasa_pro-3.13.0.dev3.dist-info → rasa_pro-3.13.0.dev7.dist-info}/METADATA +10 -10
  196. {rasa_pro-3.13.0.dev3.dist-info → rasa_pro-3.13.0.dev7.dist-info}/RECORD +213 -210
  197. rasa/cli/project_templates/calm/config.yml +0 -10
  198. rasa/cli/project_templates/calm/credentials.yml +0 -33
  199. rasa/cli/project_templates/calm/endpoints.yml +0 -58
  200. rasa/cli/project_templates/default/actions/actions.py +0 -27
  201. rasa/cli/project_templates/default/data/nlu.yml +0 -91
  202. rasa/cli/project_templates/default/data/rules.yml +0 -13
  203. rasa/cli/project_templates/default/data/stories.yml +0 -30
  204. rasa/cli/project_templates/default/domain.yml +0 -34
  205. rasa/cli/project_templates/default/tests/test_stories.yml +0 -91
  206. rasa/core/channels/inspector/dist/assets/channel-11268142.js +0 -1
  207. rasa/core/channels/inspector/dist/assets/clone-ff7f2ce7.js +0 -1
  208. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-cba7ae20.js +0 -1
  209. rasa/core/channels/inspector/src/helpers/audiostream.ts +0 -191
  210. rasa/core/tracker_store.py +0 -1792
  211. rasa/studio/download.py +0 -489
  212. /rasa/cli/project_templates/{calm → default}/actions/action_template.py +0 -0
  213. /rasa/cli/project_templates/{calm → default}/actions/add_contact.py +0 -0
  214. /rasa/cli/project_templates/{calm → default}/actions/db.py +0 -0
  215. /rasa/cli/project_templates/{calm → default}/actions/list_contacts.py +0 -0
  216. /rasa/cli/project_templates/{calm → default}/actions/remove_contact.py +0 -0
  217. /rasa/cli/project_templates/{calm → default}/data/flows/add_contact.yml +0 -0
  218. /rasa/cli/project_templates/{calm → default}/data/flows/list_contacts.yml +0 -0
  219. /rasa/cli/project_templates/{calm → default}/data/flows/remove_contact.yml +0 -0
  220. /rasa/cli/project_templates/{calm → default}/db/contacts.json +0 -0
  221. /rasa/cli/project_templates/{calm → default}/domain/add_contact.yml +0 -0
  222. /rasa/cli/project_templates/{calm → default}/domain/list_contacts.yml +0 -0
  223. /rasa/cli/project_templates/{calm → default}/domain/remove_contact.yml +0 -0
  224. /rasa/cli/project_templates/{calm → default}/domain/shared.yml +0 -0
  225. /rasa/{cli/project_templates/calm/actions → core/tracker_stores}/__init__.py +0 -0
  226. {rasa_pro-3.13.0.dev3.dist-info → rasa_pro-3.13.0.dev7.dist-info}/NOTICE +0 -0
  227. {rasa_pro-3.13.0.dev3.dist-info → rasa_pro-3.13.0.dev7.dist-info}/WHEEL +0 -0
  228. {rasa_pro-3.13.0.dev3.dist-info → rasa_pro-3.13.0.dev7.dist-info}/entry_points.txt +0 -0
@@ -1,7 +1,9 @@
1
+ from __future__ import annotations
2
+
1
3
  import base64
2
4
  import json
3
5
  import uuid
4
- from typing import Any, Awaitable, Callable, Dict, Optional, Text, Tuple
6
+ from typing import TYPE_CHECKING, Any, Awaitable, Callable, Dict, Optional, Text, Tuple
5
7
 
6
8
  import structlog
7
9
  from sanic import ( # type: ignore[attr-defined]
@@ -12,7 +14,11 @@ from sanic import ( # type: ignore[attr-defined]
12
14
  response,
13
15
  )
14
16
 
15
- from rasa.core.channels import UserMessage
17
+ from rasa.core.channels import InputChannel, UserMessage
18
+ from rasa.core.channels.channel import (
19
+ create_auth_requested_response_provider,
20
+ requires_basic_auth,
21
+ )
16
22
  from rasa.core.channels.voice_ready.utils import CallParameters
17
23
  from rasa.core.channels.voice_stream.audio_bytes import RasaAudioBytes
18
24
  from rasa.core.channels.voice_stream.call_state import call_state
@@ -25,10 +31,24 @@ from rasa.core.channels.voice_stream.voice_channel import (
25
31
  VoiceInputChannel,
26
32
  VoiceOutputChannel,
27
33
  )
34
+ from rasa.shared.exceptions import RasaException
35
+
36
+ if TYPE_CHECKING:
37
+ from twilio.twiml.voice_response import VoiceResponse
28
38
 
29
39
  logger = structlog.get_logger(__name__)
30
40
 
31
41
 
42
+ TWILIO_MEDIA_STREAMS_WEBHOOK_PATH = "webhooks/twilio_media_streams/webhook"
43
+ TWILIO_MEDIA_STREAMS_WEBSOCKET_PATH = "webhooks/twilio_media_streams/websocket"
44
+
45
+
46
+ CALL_SID_REQUEST_KEY = "CallSid"
47
+ FROM_NUMBER_REQUEST_KEY = "From"
48
+ TO_NUMBER_REQUEST_KEY = "To"
49
+ DIRECTION_REQUEST_KEY = "Direction"
50
+
51
+
32
52
  def map_call_params(data: Dict[Text, Any]) -> CallParameters:
33
53
  """Map the twilio stream parameters to the CallParameters dataclass."""
34
54
  stream_sid = data["streamSid"]
@@ -77,6 +97,40 @@ class TwilioMediaStreamsOutputChannel(VoiceOutputChannel):
77
97
 
78
98
 
79
99
  class TwilioMediaStreamsInputChannel(VoiceInputChannel):
100
+ def __init__(
101
+ self,
102
+ server_url: str,
103
+ asr_config: Dict,
104
+ tts_config: Dict,
105
+ monitor_silence: bool = False,
106
+ username: Optional[Text] = None,
107
+ password: Optional[Text] = None,
108
+ ):
109
+ super().__init__(server_url, asr_config, tts_config, monitor_silence)
110
+ self.username = username
111
+ self.password = password
112
+
113
+ @classmethod
114
+ def from_credentials(cls, credentials: Optional[Dict[str, Any]]) -> InputChannel:
115
+ credentials = credentials or {}
116
+
117
+ username = credentials.get("username")
118
+ password = credentials.get("password")
119
+ if (username is None) != (password is None):
120
+ raise RasaException(
121
+ "In TwilioMediaStreams channel, either both username and password "
122
+ "or neither should be provided. "
123
+ )
124
+
125
+ return cls(
126
+ credentials["server_url"],
127
+ credentials["asr"],
128
+ credentials["tts"],
129
+ credentials.get("monitor_silence", False),
130
+ username=username,
131
+ password=password,
132
+ )
133
+
80
134
  @classmethod
81
135
  def name(cls) -> str:
82
136
  return "twilio_media_streams"
@@ -130,16 +184,6 @@ class TwilioMediaStreamsInputChannel(VoiceInputChannel):
130
184
  self.tts_cache,
131
185
  )
132
186
 
133
- def websocket_stream_url(self) -> str:
134
- """Returns the websocket stream URL."""
135
- # depending on the config value, the url might contain http as a
136
- # protocol or not - we'll make sure both work
137
- if self.server_url.startswith("http"):
138
- base_url = self.server_url.replace("http", "ws")
139
- else:
140
- base_url = f"wss://{self.server_url}"
141
- return f"{base_url}/webhooks/twilio_media_streams/websocket"
142
-
143
187
  def blueprint(
144
188
  self, on_new_message: Callable[[UserMessage], Awaitable[Any]]
145
189
  ) -> Blueprint:
@@ -151,22 +195,20 @@ class TwilioMediaStreamsInputChannel(VoiceInputChannel):
151
195
  return response.json({"status": "ok"})
152
196
 
153
197
  @blueprint.route("/webhook", methods=["POST"])
198
+ @requires_basic_auth(
199
+ username=self.username,
200
+ password=self.password,
201
+ auth_request_provider=create_auth_requested_response_provider(
202
+ realm=TWILIO_MEDIA_STREAMS_WEBHOOK_PATH
203
+ ),
204
+ )
154
205
  async def receive(request: Request) -> HTTPResponse:
155
- from twilio.twiml.voice_response import Connect, VoiceResponse
156
-
157
- voice_response = VoiceResponse()
158
- start = Connect()
159
- stream = start.stream(url=self.websocket_stream_url())
160
- # pass information about the call to the webhook - so we can
161
- # store it in the input channel
162
- stream.parameter(name="call_id", value=request.form.get("CallSid", None))
163
- stream.parameter(name="user_phone", value=request.form.get("From", None))
164
- stream.parameter(name="bot_phone", value=request.form.get("To", None))
165
- stream.parameter(
166
- name="direction", value=request.form.get("Direction", None)
167
- )
206
+ voice_response = self._build_twilio_response(request)
168
207
 
169
- voice_response.append(start)
208
+ logger.debug(
209
+ "twilio_media_streams.webhook.twilio_response",
210
+ twilio_response=str(voice_response),
211
+ )
170
212
 
171
213
  return response.text(str(voice_response), content_type="text/xml")
172
214
 
@@ -175,3 +217,36 @@ class TwilioMediaStreamsInputChannel(VoiceInputChannel):
175
217
  await self.run_audio_streaming(on_new_message, ws)
176
218
 
177
219
  return blueprint
220
+
221
+ def _websocket_stream_url(self) -> str:
222
+ """Returns the websocket stream URL."""
223
+ # depending on the config value, the url might contain http as a
224
+ # protocol or not - we'll make sure both work
225
+ if self.server_url.startswith("http"):
226
+ base_url = self.server_url.replace("http", "ws")
227
+ else:
228
+ base_url = f"wss://{self.server_url}"
229
+ return f"{base_url}/{TWILIO_MEDIA_STREAMS_WEBSOCKET_PATH}"
230
+
231
+ def _build_twilio_response(self, request: Request) -> VoiceResponse:
232
+ from twilio.twiml.voice_response import Connect, VoiceResponse
233
+
234
+ voice_response = VoiceResponse()
235
+ start = Connect()
236
+ stream = start.stream(url=self._websocket_stream_url())
237
+ # pass information about the call to the webhook - so we can
238
+ # store it in the input channel
239
+ stream.parameter(
240
+ name="call_id", value=request.form.get(CALL_SID_REQUEST_KEY, None)
241
+ )
242
+ stream.parameter(
243
+ name="user_phone", value=request.form.get(FROM_NUMBER_REQUEST_KEY, None)
244
+ )
245
+ stream.parameter(
246
+ name="bot_phone", value=request.form.get(TO_NUMBER_REQUEST_KEY, None)
247
+ )
248
+ stream.parameter(
249
+ name="direction", value=request.form.get(DIRECTION_REQUEST_KEY, None)
250
+ )
251
+ voice_response.append(start)
252
+ return voice_response
@@ -42,6 +42,11 @@ from rasa.utils.io import remove_emojis
42
42
 
43
43
  logger = structlog.get_logger(__name__)
44
44
 
45
+ # define constants for the voice channel
46
+ USER_CONVERSATION_SESSION_END = "/session_end"
47
+ USER_CONVERSATION_SESSION_START = "/session_start"
48
+ USER_CONVERSATION_SILENCE_TIMEOUT = "/silence_timeout"
49
+
45
50
 
46
51
  @dataclass
47
52
  class VoiceChannelAction:
@@ -189,6 +194,7 @@ class VoiceOutputChannel(OutputChannel):
189
194
  collected_audio_bytes = RasaAudioBytes(b"")
190
195
  seconds_marker = -1
191
196
  last_sent_offset = 0
197
+ logger.debug("voice_channel.sending_audio", text=text)
192
198
 
193
199
  # Send start marker before first chunk
194
200
  try:
@@ -334,7 +340,7 @@ class VoiceInputChannel(InputChannel):
334
340
  ) -> None:
335
341
  output_channel = self.create_output_channel(channel_websocket, tts_engine)
336
342
  message = UserMessage(
337
- "/session_start",
343
+ USER_CONVERSATION_SESSION_START,
338
344
  output_channel,
339
345
  call_parameters.stream_id,
340
346
  input_channel=self.name(),
@@ -393,6 +399,9 @@ class VoiceInputChannel(InputChannel):
393
399
  await asr_engine.send_audio_chunks(channel_action.audio_bytes)
394
400
  elif isinstance(channel_action, EndConversationAction):
395
401
  # end stream event came from the other side
402
+ await self.handle_disconnect(
403
+ channel_websocket, on_new_message, tts_engine, call_parameters
404
+ )
396
405
  break
397
406
 
398
407
  async def receive_asr_events() -> None:
@@ -462,10 +471,27 @@ class VoiceInputChannel(InputChannel):
462
471
  elif isinstance(e, UserSilence):
463
472
  output_channel = self.create_output_channel(voice_websocket, tts_engine)
464
473
  message = UserMessage(
465
- "/silence_timeout",
474
+ USER_CONVERSATION_SILENCE_TIMEOUT,
466
475
  output_channel,
467
476
  call_parameters.stream_id,
468
477
  input_channel=self.name(),
469
478
  metadata=asdict(call_parameters),
470
479
  )
471
480
  await on_new_message(message)
481
+
482
+ async def handle_disconnect(
483
+ self,
484
+ channel_websocket: Websocket,
485
+ on_new_message: Callable[[UserMessage], Awaitable[Any]],
486
+ tts_engine: TTSEngine,
487
+ call_parameters: CallParameters,
488
+ ) -> None:
489
+ """Handle disconnection from the channel."""
490
+ output_channel = self.create_output_channel(channel_websocket, tts_engine)
491
+ message = UserMessage(
492
+ text=USER_CONVERSATION_SESSION_END,
493
+ output_channel=output_channel,
494
+ sender_id=call_parameters.stream_id,
495
+ input_channel=self.name(),
496
+ )
497
+ await on_new_message(message)
@@ -1,9 +1,10 @@
1
1
  import json
2
- import logging
3
2
  import time
4
3
  from collections import deque
5
4
  from typing import Deque, Optional, Text
6
5
 
6
+ import structlog
7
+
7
8
  from rasa.core.lock import Ticket, TicketLock
8
9
  from rasa.core.lock_store import (
9
10
  DEFAULT_SOCKET_TIMEOUT_IN_SECONDS,
@@ -19,7 +20,7 @@ DEFAULT_PORT = 6379
19
20
 
20
21
  DEFAULT_HOSTNAME = "localhost"
21
22
 
22
- logger = logging.getLogger(__name__)
23
+ structlogger = structlog.getLogger(__name__)
23
24
 
24
25
  LAST_ISSUED_TICKET_NUMBER_SUFFIX = "last_issued_ticket_number"
25
26
 
@@ -105,7 +106,10 @@ class ConcurrentRedisLockStore(LockStore):
105
106
 
106
107
  self.key_prefix = DEFAULT_CONCURRENT_REDIS_LOCK_STORE_KEY_PREFIX
107
108
  if key_prefix:
108
- logger.debug(f"Setting non-default redis key prefix: '{key_prefix}'.")
109
+ structlogger.debug(
110
+ "concurrent_redis_lock_store._set_key_prefix.non_default_key_prefix",
111
+ event_info=f"Setting non-default redis key prefix: '{key_prefix}'.",
112
+ )
109
113
  self._set_key_prefix(key_prefix)
110
114
 
111
115
  super().__init__()
@@ -116,9 +120,13 @@ class ConcurrentRedisLockStore(LockStore):
116
120
  key_prefix + ":" + DEFAULT_CONCURRENT_REDIS_LOCK_STORE_KEY_PREFIX
117
121
  )
118
122
  else:
119
- logger.warning(
120
- f"Omitting provided non-alphanumeric redis key prefix: '{key_prefix}'. "
121
- f"Using default '{self.key_prefix}' instead."
123
+ structlogger.warning(
124
+ "concurrent_redis_lock_store._set_key_prefix.default_instead_of_invalid_key_prefix",
125
+ event_info=(
126
+ f"Omitting provided non-alphanumeric "
127
+ f"redis key prefix: '{key_prefix}'. "
128
+ f"Using default '{self.key_prefix}' instead."
129
+ ),
122
130
  )
123
131
 
124
132
  def issue_ticket(
@@ -129,7 +137,10 @@ class ConcurrentRedisLockStore(LockStore):
129
137
  It's configured with `lock_lifetime` and associated with `conversation_id`.
130
138
  Creates a new lock if none is found.
131
139
  """
132
- logger.debug(f"Issuing ticket for conversation '{conversation_id}'.")
140
+ structlogger.debug(
141
+ "concurrent_redis_lock_store.issue_ticket",
142
+ event_info=f"Issuing ticket for conversation '{conversation_id}'.",
143
+ )
133
144
  try:
134
145
  lock = self.get_or_create_lock(conversation_id)
135
146
  lock.remove_expired_tickets()
@@ -164,9 +175,12 @@ class ConcurrentRedisLockStore(LockStore):
164
175
  redis_keys = self.red.keys(pattern)
165
176
 
166
177
  if not redis_keys:
167
- logger.debug(
168
- f"The lock store does not contain any key-value "
169
- f"items for conversation '{conversation_id}'."
178
+ structlogger.debug(
179
+ "concurrent_redis_lock_store.delete_lock_key_not_found",
180
+ event_info=(
181
+ f"The lock store does not contain any key-value "
182
+ f"items for conversation '{conversation_id}'."
183
+ ),
170
184
  )
171
185
  return None
172
186
 
@@ -2,7 +2,7 @@ import random
2
2
  from typing import Any, AsyncIterator, Iterable, List, Optional, Text
3
3
 
4
4
  import rasa.shared.utils.io
5
- from rasa.core.tracker_store import TrackerStore
5
+ from rasa.core.tracker_stores.tracker_store import TrackerStore
6
6
  from rasa.shared.core.trackers import DialogueStateTracker
7
7
  from rasa.shared.exceptions import RasaException
8
8
 
rasa/core/exporter.py CHANGED
@@ -10,7 +10,7 @@ import rasa.shared.utils.io
10
10
  from rasa.core.brokers.broker import EventBroker
11
11
  from rasa.core.brokers.pika import PikaEventBroker
12
12
  from rasa.core.constants import RASA_EXPORT_PROCESS_ID_HEADER_NAME
13
- from rasa.core.tracker_store import TrackerStore
13
+ from rasa.core.tracker_stores.tracker_store import TrackerStore
14
14
  from rasa.exceptions import (
15
15
  NoConversationsInTrackerStoreError,
16
16
  NoEventsToMigrateError,
rasa/core/lock_store.py CHANGED
@@ -2,18 +2,27 @@ from __future__ import annotations
2
2
 
3
3
  import asyncio
4
4
  import json
5
- import logging
6
5
  import os
7
6
  from contextlib import asynccontextmanager
8
- from typing import AsyncGenerator, Dict, Optional, Text, Union
7
+ from typing import Any, AsyncGenerator, Dict, Literal, Optional, Text, Union
8
+
9
+ import structlog
10
+ from pydantic import (
11
+ AnyUrl,
12
+ BaseModel,
13
+ Field,
14
+ NonNegativeInt,
15
+ model_validator,
16
+ )
9
17
 
10
18
  import rasa.shared.utils.common
11
19
  from rasa.core.constants import DEFAULT_LOCK_LIFETIME
12
20
  from rasa.core.lock import TicketLock
13
21
  from rasa.shared.exceptions import ConnectionException, RasaException
22
+ from rasa.shared.utils.io import raise_deprecation_warning
14
23
  from rasa.utils.endpoints import EndpointConfig
15
24
 
16
- logger = logging.getLogger(__name__)
25
+ structlogger = structlog.getLogger(__name__)
17
26
 
18
27
 
19
28
  def _get_lock_lifetime() -> int:
@@ -76,7 +85,10 @@ class LockStore:
76
85
 
77
86
  Creates a new lock if none is found.
78
87
  """
79
- logger.debug(f"Issuing ticket for conversation '{conversation_id}'.")
88
+ structlogger.debug(
89
+ "lock_store.issue_ticket",
90
+ event_info=f"Issuing ticket for conversation '{conversation_id}'.",
91
+ )
80
92
  try:
81
93
  lock = self.get_or_create_lock(conversation_id)
82
94
  ticket = lock.issue_ticket(lock_lifetime)
@@ -109,7 +121,10 @@ class LockStore:
109
121
  async def _acquire_lock(
110
122
  self, conversation_id: Text, ticket: int, wait_time_in_seconds: float
111
123
  ) -> TicketLock:
112
- logger.debug(f"Acquiring lock for conversation '{conversation_id}'.")
124
+ structlogger.debug(
125
+ "lock_store._acquiring_lock_for_conversation",
126
+ event_info=f"Acquiring lock for conversation '{conversation_id}'.",
127
+ )
113
128
  while True:
114
129
  # fetch lock in every iteration because lock might no longer exist
115
130
  lock = self.get_lock(conversation_id)
@@ -120,16 +135,22 @@ class LockStore:
120
135
 
121
136
  # acquire lock if it isn't locked
122
137
  if not lock.is_locked(ticket):
123
- logger.debug(f"Acquired lock for conversation '{conversation_id}'.")
138
+ structlogger.debug(
139
+ "lock_store._acquired_lock_for_conversation",
140
+ event_info=f"Acquired lock for conversation '{conversation_id}'.",
141
+ )
124
142
  return lock
125
143
 
126
144
  items_before_this = ticket - (lock.now_serving or 0)
127
145
 
128
- logger.debug(
129
- f"Failed to acquire lock for conversation ID '{conversation_id}' "
130
- f"because {items_before_this} other item(s) for this "
131
- f"conversation ID have to be finished processing first. "
132
- f"Retrying in {wait_time_in_seconds} seconds ..."
146
+ structlogger.debug(
147
+ "lock_store._retrying_lock_acquisition",
148
+ event_info=(
149
+ f"Failed to acquire lock for conversation ID '{conversation_id}' "
150
+ f"because {items_before_this} other item(s) for this "
151
+ f"conversation ID have to be finished processing first. "
152
+ f"Retrying in {wait_time_in_seconds} seconds ..."
153
+ ),
133
154
  )
134
155
 
135
156
  # sleep and update lock
@@ -186,9 +207,99 @@ class LockStore:
186
207
  @staticmethod
187
208
  def _log_deletion(conversation_id: Text, deletion_successful: bool) -> None:
188
209
  if deletion_successful:
189
- logger.debug(f"Deleted lock for conversation '{conversation_id}'.")
210
+ structlogger.debug(
211
+ "lock_store._deleted_lock_for_conversation",
212
+ event_info=f"Deleted lock for conversation '{conversation_id}'.",
213
+ )
190
214
  else:
191
- logger.debug(f"Could not delete lock for conversation '{conversation_id}'.")
215
+ structlogger.debug(
216
+ "lock_store._failed_to_delete_lock_for_conversation",
217
+ event_info=(
218
+ f"Could not delete lock for conversation '{conversation_id}'."
219
+ ),
220
+ )
221
+
222
+
223
+ class RedisLockStoreConfig(BaseModel):
224
+ host: Union[AnyUrl, Literal["localhost"]] = Field(
225
+ default="localhost", description="The host of the redis server."
226
+ )
227
+ port: NonNegativeInt = Field(
228
+ default=6379, ge=0, le=65535, description="The port of the redis server."
229
+ )
230
+ db: NonNegativeInt = Field(
231
+ default=0,
232
+ ge=0,
233
+ description="The name of the database within Redis "
234
+ "which should be used by Rasa",
235
+ )
236
+ username: Optional[str] = Field(
237
+ default=None,
238
+ description="The username which should be used for "
239
+ "authentication with the Redis database.",
240
+ )
241
+ password: Optional[str] = Field(
242
+ default=None,
243
+ description="The username which should be used for "
244
+ "authentication with the Redis database.",
245
+ )
246
+ use_ssl: bool = Field(
247
+ default=False,
248
+ serialization_alias="ssl",
249
+ description="True if SSL should be used for the connection to Redis.",
250
+ )
251
+ ssl_certfile: Optional[str] = Field(
252
+ default=None,
253
+ description="Path to the SSL certificate file.",
254
+ )
255
+ ssl_keyfile: Optional[str] = Field(
256
+ default=None, description="Path to the SSL private key file."
257
+ )
258
+ ssl_ca_certs: Optional[str] = Field(
259
+ default=None, description="Path to the SSL CA certificate file."
260
+ )
261
+ key_prefix: Optional[str] = Field(
262
+ default=None,
263
+ description="Prefix to prepend to all keys "
264
+ "used by the lock store. Must be alphanumeric.",
265
+ )
266
+ socket_timeout: float = Field(
267
+ default=DEFAULT_SOCKET_TIMEOUT_IN_SECONDS,
268
+ description="Timeout in seconds after which an exception "
269
+ "will be raised in case Redis doesn't respond "
270
+ "within `socket_timeout` seconds.",
271
+ )
272
+
273
+ @model_validator(mode="before")
274
+ @classmethod
275
+ def validate_url_and_host_properties(cls, data: Any) -> Any:
276
+ if isinstance(data, dict):
277
+ if bool(data.get("url", None)) and bool(data.get("host", None)):
278
+ raise RasaException(
279
+ "You cannot specify both 'url' and 'host' in the Redis lock store "
280
+ "configuration. Please use only one of them."
281
+ )
282
+
283
+ if data.get("url", None):
284
+ raise_deprecation_warning(
285
+ "The 'url' property in the redis lock store "
286
+ "configuration is deprecated. Please use 'host' instead."
287
+ )
288
+ data["host"] = data.pop("url")
289
+ return data
290
+
291
+ @model_validator(mode="after")
292
+ def verify_username_password(self) -> RedisLockStoreConfig:
293
+ if bool(self.username) ^ bool(self.password):
294
+ raise ValueError(
295
+ f"Expected username and password. "
296
+ f"Found: username: {'<has value>' if self.username else '<N/A>'}, "
297
+ f"password: {'<has value>' if self.password else '<N/A>'}"
298
+ )
299
+ return self
300
+
301
+ def to_strict_redis(self) -> Dict[str, Any]:
302
+ return self.model_dump(by_alias=True, exclude={"key_prefix"})
192
303
 
193
304
 
194
305
  class RedisLockStore(LockStore):
@@ -196,57 +307,28 @@ class RedisLockStore(LockStore):
196
307
 
197
308
  def __init__(
198
309
  self,
199
- host: Text = "localhost",
200
- port: int = 6379,
201
- db: int = 1,
202
- username: Optional[Text] = None,
203
- password: Optional[Text] = None,
204
- use_ssl: bool = False,
205
- ssl_certfile: Optional[Text] = None,
206
- ssl_keyfile: Optional[Text] = None,
207
- ssl_ca_certs: Optional[Text] = None,
208
- key_prefix: Optional[Text] = None,
209
- socket_timeout: float = DEFAULT_SOCKET_TIMEOUT_IN_SECONDS,
310
+ config: RedisLockStoreConfig = RedisLockStoreConfig(),
210
311
  ) -> None:
211
312
  """Create a lock store which uses Redis for persistence.
212
313
 
213
314
  Args:
214
- host: The host of the redis server.
215
- port: The port of the redis server.
216
- db: The name of the database within Redis which should be used by Rasa
217
- Open Source.
218
- username: The username which should be used for authentication with the
219
- Redis database.
220
- password: The password which should be used for authentication with the
221
- Redis database.
222
- use_ssl: `True` if SSL should be used for the connection to Redis.
223
- ssl_certfile: Path to the SSL certificate file.
224
- ssl_keyfile: Path to the SSL private key file.
225
- ssl_ca_certs: Path to the SSL CA certificate file.
226
- key_prefix: prefix to prepend to all keys used by the lock store. Must be
227
- alphanumeric.
228
- socket_timeout: Timeout in seconds after which an exception will be raised
229
- in case Redis doesn't respond within `socket_timeout` seconds.
315
+ config: Redis lock store configuration.
230
316
  """
231
317
  import redis
232
318
 
233
- self.red = redis.StrictRedis(
234
- host=host,
235
- port=int(port),
236
- db=int(db),
237
- username=username,
238
- password=password,
239
- ssl=use_ssl,
240
- ssl_certfile=ssl_certfile,
241
- ssl_keyfile=ssl_keyfile,
242
- ssl_ca_certs=ssl_ca_certs,
243
- socket_timeout=socket_timeout,
244
- )
319
+ self.config = config
320
+ self.red = redis.StrictRedis(**self.config.to_strict_redis())
245
321
 
246
322
  self.key_prefix = DEFAULT_REDIS_LOCK_STORE_KEY_PREFIX
247
- if key_prefix:
248
- logger.debug(f"Setting non-default redis key prefix: '{key_prefix}'.")
249
- self._set_key_prefix(key_prefix)
323
+ if self.config.key_prefix:
324
+ structlogger.debug(
325
+ "redis_lock_store._set_key_prefix.non_default_key_prefix",
326
+ event_info=(
327
+ f"Setting non-default "
328
+ f"redis key prefix: '{self.config.key_prefix}'.",
329
+ ),
330
+ )
331
+ self._set_key_prefix(self.config.key_prefix)
250
332
 
251
333
  super().__init__()
252
334
 
@@ -254,9 +336,13 @@ class RedisLockStore(LockStore):
254
336
  if isinstance(key_prefix, str) and key_prefix.isalnum():
255
337
  self.key_prefix = key_prefix + ":" + DEFAULT_REDIS_LOCK_STORE_KEY_PREFIX
256
338
  else:
257
- logger.warning(
258
- f"Omitting provided non-alphanumeric redis key prefix: '{key_prefix}'. "
259
- f"Using default '{self.key_prefix}' instead."
339
+ structlogger.warning(
340
+ "redis_lock_store._set_key_prefix.default_instead_of_invalid_key_prefix",
341
+ event_info=(
342
+ f"Omitting provided non-alphanumeric "
343
+ f"redis key prefix: '{key_prefix}'. "
344
+ f"Using default '{self.key_prefix}' instead."
345
+ ),
260
346
  )
261
347
 
262
348
  def get_lock(self, conversation_id: Text) -> Optional[TicketLock]:
@@ -313,7 +399,9 @@ def _create_from_endpoint_config(
313
399
 
314
400
  lock_store: LockStore = InMemoryLockStore()
315
401
  elif endpoint_config.type == "redis":
316
- lock_store = RedisLockStore(host=endpoint_config.url, **endpoint_config.kwargs)
402
+ config = RedisLockStoreConfig.model_validate(endpoint_config.to_dict())
403
+
404
+ lock_store = RedisLockStore(config)
317
405
  elif endpoint_config.type == "concurrent_redis":
318
406
  from rasa.core.concurrent_lock_store import ConcurrentRedisLockStore
319
407
 
@@ -321,7 +409,10 @@ def _create_from_endpoint_config(
321
409
  else:
322
410
  lock_store = _load_from_module_name_in_endpoint_config(endpoint_config)
323
411
 
324
- logger.debug(f"Connected to lock store '{lock_store.__class__.__name__}'.")
412
+ structlogger.debug(
413
+ "lock_store._create_from_endpoint_config.lock_store_connected",
414
+ event_info=f"Connected to lock store '{lock_store.__class__.__name__}'.",
415
+ )
325
416
 
326
417
  return lock_store
327
418
 
@@ -8,12 +8,14 @@ from rasa.core.nlg.response import TemplatedNaturalLanguageGenerator
8
8
  from rasa.core.nlg.summarize import summarize_conversation
9
9
  from rasa.shared.constants import (
10
10
  LLM_CONFIG_KEY,
11
+ MAX_COMPLETION_TOKENS_CONFIG_KEY,
11
12
  MODEL_CONFIG_KEY,
12
13
  MODEL_GROUP_ID_CONFIG_KEY,
13
14
  MODEL_NAME_CONFIG_KEY,
14
15
  OPENAI_PROVIDER,
15
16
  PROMPT_CONFIG_KEY,
16
17
  PROVIDER_CONFIG_KEY,
18
+ TEMPERATURE_CONFIG_KEY,
17
19
  TIMEOUT_CONFIG_KEY,
18
20
  )
19
21
  from rasa.shared.core.domain import KEY_RESPONSES_TEXT, Domain
@@ -57,8 +59,8 @@ DEFAULT_MAX_HISTORICAL_TURNS = 5
57
59
  DEFAULT_LLM_CONFIG = {
58
60
  PROVIDER_CONFIG_KEY: OPENAI_PROVIDER,
59
61
  MODEL_CONFIG_KEY: DEFAULT_OPENAI_GENERATE_MODEL_NAME,
60
- "temperature": 0.3,
61
- "max_tokens": DEFAULT_OPENAI_MAX_GENERATED_TOKENS,
62
+ TEMPERATURE_CONFIG_KEY: 0.3,
63
+ MAX_COMPLETION_TOKENS_CONFIG_KEY: DEFAULT_OPENAI_MAX_GENERATED_TOKENS,
62
64
  TIMEOUT_CONFIG_KEY: 5,
63
65
  }
64
66
 
@@ -3,7 +3,7 @@ from typing import Optional
3
3
  import structlog
4
4
  from jinja2 import Template
5
5
 
6
- from rasa.core.tracker_store import DialogueStateTracker
6
+ from rasa.shared.core.trackers import DialogueStateTracker
7
7
  from rasa.shared.providers.llm.llm_client import LLMClient
8
8
  from rasa.shared.utils.llm import (
9
9
  tracker_as_readable_transcript,