rasa-pro 3.13.0.dev5__py3-none-any.whl → 3.13.0.dev8__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 (266) hide show
  1. rasa/__main__.py +0 -3
  2. rasa/api.py +5 -1
  3. rasa/cli/arguments/default_arguments.py +13 -1
  4. rasa/cli/arguments/train.py +2 -0
  5. rasa/cli/dialogue_understanding_test.py +1 -1
  6. rasa/cli/e2e_test.py +1 -1
  7. rasa/cli/evaluate.py +2 -2
  8. rasa/cli/export.py +3 -3
  9. rasa/cli/llm_fine_tuning.py +12 -11
  10. rasa/cli/project_templates/defaults.py +133 -0
  11. rasa/cli/run.py +1 -1
  12. rasa/cli/studio/link.py +53 -0
  13. rasa/cli/studio/pull.py +78 -0
  14. rasa/cli/studio/push.py +78 -0
  15. rasa/cli/studio/studio.py +12 -0
  16. rasa/cli/studio/upload.py +8 -0
  17. rasa/cli/train.py +2 -1
  18. rasa/cli/utils.py +1 -1
  19. rasa/cli/x.py +1 -1
  20. rasa/constants.py +4 -0
  21. rasa/core/__init__.py +0 -16
  22. rasa/core/actions/action.py +5 -1
  23. rasa/core/actions/action_repeat_bot_messages.py +18 -22
  24. rasa/core/actions/action_run_slot_rejections.py +0 -1
  25. rasa/core/agent.py +18 -3
  26. rasa/core/available_endpoints.py +146 -0
  27. rasa/core/brokers/kafka.py +4 -0
  28. rasa/core/brokers/pika.py +5 -2
  29. rasa/core/brokers/sql.py +1 -1
  30. rasa/core/channels/botframework.py +2 -2
  31. rasa/core/channels/channel.py +2 -2
  32. rasa/core/channels/hangouts.py +8 -5
  33. rasa/core/channels/inspector/.eslintrc.cjs +12 -6
  34. rasa/core/channels/inspector/.prettierrc +5 -0
  35. rasa/core/channels/inspector/README.md +10 -4
  36. rasa/core/channels/inspector/dist/assets/{arc-9f75cc3b.js → arc-c4b064fc.js} +1 -1
  37. rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-7f34db23.js → blockDiagram-38ab4fdb-215b5026.js} +1 -1
  38. rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-948bab2c.js → c4Diagram-3d4e48cf-2b54a0a3.js} +1 -1
  39. rasa/core/channels/inspector/dist/assets/channel-3730f5fd.js +1 -0
  40. rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-53b0dd0e.js → classDiagram-70f12bd4-daacea5f.js} +1 -1
  41. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-fdf789e7.js → classDiagram-v2-f2320105-930d4dc2.js} +1 -1
  42. rasa/core/channels/inspector/dist/assets/clone-e847561e.js +1 -0
  43. rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-87c4ece5.js → createText-2e5e7dd3-83c206ba.js} +1 -1
  44. rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-5a8b0749.js → edges-e0da2a9e-b0eb01d0.js} +1 -1
  45. rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-66da90e2.js → erDiagram-9861fffd-17586500.js} +1 -1
  46. rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-10044f05.js → flowDb-956e92f1-be2a1776.js} +1 -1
  47. rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-f338f66a.js → flowDiagram-66a62f08-c2120ebd.js} +1 -1
  48. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-efbbfe00.js +1 -0
  49. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-b13140aa.js → flowchart-elk-definition-4a651766-a6ab5c48.js} +1 -1
  50. rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-f2b4a55a.js → ganttDiagram-c361ad54-ef613457.js} +1 -1
  51. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-dedc298d.js → gitGraphDiagram-72cf32ee-d59185b3.js} +1 -1
  52. rasa/core/channels/inspector/dist/assets/{graph-4ede11ff.js → graph-0f155405.js} +1 -1
  53. rasa/core/channels/inspector/dist/assets/{index-3862675e-65549d37.js → index-3862675e-d5f1d1b7.js} +1 -1
  54. rasa/core/channels/inspector/dist/assets/{index-3a23e736.js → index-47737d3a.js} +123 -123
  55. rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-65439671.js → infoDiagram-f8f76790-b07d141f.js} +1 -1
  56. rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-56d03d98.js → journeyDiagram-49397b02-1936d429.js} +1 -1
  57. rasa/core/channels/inspector/dist/assets/{layout-dd48f7f4.js → layout-dde8d0f3.js} +1 -1
  58. rasa/core/channels/inspector/dist/assets/{line-1569ad2c.js → line-0c2c7ee0.js} +1 -1
  59. rasa/core/channels/inspector/dist/assets/{linear-48bf4935.js → linear-35dd89a4.js} +1 -1
  60. rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-688504c1.js → mindmap-definition-fc14e90a-56192851.js} +1 -1
  61. rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-78b6d7e6.js → pieDiagram-8a3498a8-fc21ed78.js} +1 -1
  62. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-048b84b3.js → quadrantDiagram-120e2f19-25e98518.js} +1 -1
  63. rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-dd67f107.js → requirementDiagram-deff3bca-546ff1f5.js} +1 -1
  64. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-8128436e.js → sankeyDiagram-04a897e0-02d8b82d.js} +1 -1
  65. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-1a0d1461.js → sequenceDiagram-704730f1-3ca5a92e.js} +1 -1
  66. rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-46d388ed.js → stateDiagram-587899a1-128ea07c.js} +1 -1
  67. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-ea42951a.js → stateDiagram-v2-d93cdb3a-95f290af.js} +1 -1
  68. rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-7427ed0c.js → styles-6aaf32cf-4984898a.js} +1 -1
  69. rasa/core/channels/inspector/dist/assets/{styles-9a916d00-ff5e5a16.js → styles-9a916d00-1bf266ba.js} +1 -1
  70. rasa/core/channels/inspector/dist/assets/{styles-c10674c1-7b3680cf.js → styles-c10674c1-60521c63.js} +1 -1
  71. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-f860f2ad.js → svgDrawCommon-08f97a94-a25b6e12.js} +1 -1
  72. rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-2eebf0c8.js → timeline-definition-85554ec2-0fc086bf.js} +1 -1
  73. rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-5d7f4e96.js → xychartDiagram-e933f94c-44ee592e.js} +1 -1
  74. rasa/core/channels/inspector/dist/index.html +1 -1
  75. rasa/core/channels/inspector/package.json +3 -1
  76. rasa/core/channels/inspector/src/App.tsx +91 -90
  77. rasa/core/channels/inspector/src/components/Chat.tsx +45 -41
  78. rasa/core/channels/inspector/src/components/DiagramFlow.tsx +40 -40
  79. rasa/core/channels/inspector/src/components/DialogueInformation.tsx +57 -57
  80. rasa/core/channels/inspector/src/components/DialogueStack.tsx +36 -27
  81. rasa/core/channels/inspector/src/components/ExpandIcon.tsx +4 -4
  82. rasa/core/channels/inspector/src/components/FullscreenButton.tsx +7 -7
  83. rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +28 -12
  84. rasa/core/channels/inspector/src/components/NoActiveFlow.tsx +9 -9
  85. rasa/core/channels/inspector/src/components/RasaLogo.tsx +5 -5
  86. rasa/core/channels/inspector/src/components/RecruitmentPanel.tsx +55 -60
  87. rasa/core/channels/inspector/src/components/SaraDiagrams.tsx +5 -5
  88. rasa/core/channels/inspector/src/components/Slots.tsx +22 -22
  89. rasa/core/channels/inspector/src/components/Welcome.tsx +28 -31
  90. rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +245 -0
  91. rasa/core/channels/inspector/src/helpers/audio/microphone-processor.js +12 -0
  92. rasa/core/channels/inspector/src/helpers/audio/playback-processor.js +36 -0
  93. rasa/core/channels/inspector/src/helpers/conversation.ts +7 -7
  94. rasa/core/channels/inspector/src/helpers/formatters.test.ts +181 -181
  95. rasa/core/channels/inspector/src/helpers/formatters.ts +111 -111
  96. rasa/core/channels/inspector/src/helpers/utils.ts +78 -61
  97. rasa/core/channels/inspector/src/main.tsx +8 -8
  98. rasa/core/channels/inspector/src/theme/Button/Button.ts +8 -8
  99. rasa/core/channels/inspector/src/theme/Heading/Heading.ts +7 -7
  100. rasa/core/channels/inspector/src/theme/Input/Input.ts +9 -9
  101. rasa/core/channels/inspector/src/theme/Link/Link.ts +6 -6
  102. rasa/core/channels/inspector/src/theme/Modal/Modal.ts +13 -13
  103. rasa/core/channels/inspector/src/theme/Table/Table.tsx +10 -10
  104. rasa/core/channels/inspector/src/theme/Tooltip/Tooltip.ts +5 -5
  105. rasa/core/channels/inspector/src/theme/base/breakpoints.ts +7 -7
  106. rasa/core/channels/inspector/src/theme/base/colors.ts +64 -64
  107. rasa/core/channels/inspector/src/theme/base/fonts/fontFaces.css +21 -18
  108. rasa/core/channels/inspector/src/theme/base/radii.ts +8 -8
  109. rasa/core/channels/inspector/src/theme/base/shadows.ts +5 -5
  110. rasa/core/channels/inspector/src/theme/base/sizes.ts +5 -5
  111. rasa/core/channels/inspector/src/theme/base/space.ts +12 -12
  112. rasa/core/channels/inspector/src/theme/base/styles.ts +5 -5
  113. rasa/core/channels/inspector/src/theme/base/typography.ts +12 -12
  114. rasa/core/channels/inspector/src/theme/base/zIndices.ts +3 -3
  115. rasa/core/channels/inspector/src/theme/index.ts +38 -38
  116. rasa/core/channels/inspector/src/types.ts +56 -50
  117. rasa/core/channels/inspector/yarn.lock +5 -0
  118. rasa/core/channels/mattermost.py +1 -1
  119. rasa/core/channels/rasa_chat.py +2 -4
  120. rasa/core/channels/rest.py +5 -4
  121. rasa/core/channels/studio_chat.py +3 -2
  122. rasa/core/channels/vier_cvg.py +1 -2
  123. rasa/core/channels/voice_ready/audiocodes.py +35 -25
  124. rasa/core/channels/voice_stream/audiocodes.py +7 -4
  125. rasa/core/channels/voice_stream/genesys.py +2 -2
  126. rasa/core/channels/voice_stream/twilio_media_streams.py +10 -5
  127. rasa/core/channels/voice_stream/voice_channel.py +33 -22
  128. rasa/core/evaluation/marker_tracker_loader.py +1 -1
  129. rasa/core/exporter.py +1 -1
  130. rasa/core/http_interpreter.py +3 -7
  131. rasa/core/jobs.py +2 -1
  132. rasa/core/nlg/contextual_response_rephraser.py +38 -11
  133. rasa/core/nlg/generator.py +0 -1
  134. rasa/core/nlg/interpolator.py +2 -3
  135. rasa/core/nlg/summarize.py +40 -6
  136. rasa/core/persistor.py +55 -20
  137. rasa/core/policies/enterprise_search_policy.py +290 -66
  138. rasa/core/policies/enterprise_search_prompt_with_relevancy_check_and_citation_template.jinja2 +63 -0
  139. rasa/core/policies/flow_policy.py +1 -1
  140. rasa/core/policies/flows/flow_executor.py +96 -17
  141. rasa/core/policies/intentless_policy.py +24 -16
  142. rasa/core/processor.py +106 -53
  143. rasa/core/run.py +40 -13
  144. rasa/core/tracker_stores/__init__.py +0 -0
  145. rasa/core/{auth_retry_tracker_store.py → tracker_stores/auth_retry_tracker_store.py} +5 -1
  146. rasa/core/tracker_stores/dynamo_tracker_store.py +218 -0
  147. rasa/core/tracker_stores/mongo_tracker_store.py +206 -0
  148. rasa/core/tracker_stores/redis_tracker_store.py +219 -0
  149. rasa/core/tracker_stores/sql_tracker_store.py +555 -0
  150. rasa/core/tracker_stores/tracker_store.py +805 -0
  151. rasa/core/training/interactive.py +1 -1
  152. rasa/core/utils.py +24 -91
  153. rasa/dialogue_understanding/coexistence/intent_based_router.py +2 -1
  154. rasa/dialogue_understanding/coexistence/llm_based_router.py +8 -3
  155. rasa/dialogue_understanding/commands/can_not_handle_command.py +2 -0
  156. rasa/dialogue_understanding/commands/cancel_flow_command.py +2 -0
  157. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +2 -0
  158. rasa/dialogue_understanding/commands/clarify_command.py +6 -2
  159. rasa/dialogue_understanding/commands/command_syntax_manager.py +1 -0
  160. rasa/dialogue_understanding/commands/human_handoff_command.py +2 -0
  161. rasa/dialogue_understanding/commands/knowledge_answer_command.py +2 -0
  162. rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +2 -0
  163. rasa/dialogue_understanding/commands/set_slot_command.py +11 -1
  164. rasa/dialogue_understanding/commands/skip_question_command.py +2 -0
  165. rasa/dialogue_understanding/commands/start_flow_command.py +4 -0
  166. rasa/dialogue_understanding/commands/utils.py +26 -2
  167. rasa/dialogue_understanding/generator/__init__.py +7 -1
  168. rasa/dialogue_understanding/generator/command_generator.py +4 -2
  169. rasa/dialogue_understanding/generator/command_parser.py +2 -2
  170. rasa/dialogue_understanding/generator/command_parser_validator.py +63 -0
  171. rasa/dialogue_understanding/generator/constants.py +2 -2
  172. rasa/dialogue_understanding/generator/llm_based_command_generator.py +1 -1
  173. rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +78 -0
  174. rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +28 -463
  175. rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +147 -0
  176. rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +477 -0
  177. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +8 -58
  178. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +37 -25
  179. rasa/dialogue_understanding/patterns/domain_for_patterns.py +190 -0
  180. rasa/dialogue_understanding/processor/command_processor.py +3 -3
  181. rasa/dialogue_understanding/processor/command_processor_component.py +3 -3
  182. rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +17 -4
  183. rasa/dialogue_understanding/utils.py +68 -12
  184. rasa/dialogue_understanding_test/du_test_case.py +1 -1
  185. rasa/dialogue_understanding_test/du_test_runner.py +4 -22
  186. rasa/dialogue_understanding_test/test_case_simulation/test_case_tracker_simulator.py +2 -6
  187. rasa/e2e_test/e2e_test_runner.py +1 -1
  188. rasa/engine/constants.py +1 -1
  189. rasa/engine/recipes/default_recipe.py +26 -2
  190. rasa/engine/validation.py +3 -2
  191. rasa/hooks.py +2 -30
  192. rasa/keys +1 -0
  193. rasa/llm_fine_tuning/annotation_module.py +39 -9
  194. rasa/llm_fine_tuning/conversations.py +3 -0
  195. rasa/llm_fine_tuning/llm_data_preparation_module.py +66 -49
  196. rasa/llm_fine_tuning/paraphrasing/conversation_rephraser.py +4 -2
  197. rasa/llm_fine_tuning/paraphrasing/rephrase_validator.py +52 -44
  198. rasa/llm_fine_tuning/paraphrasing_module.py +10 -12
  199. rasa/llm_fine_tuning/storage.py +4 -4
  200. rasa/llm_fine_tuning/utils.py +63 -1
  201. rasa/model_manager/config.py +3 -1
  202. rasa/model_manager/model_api.py +89 -2
  203. rasa/model_manager/runner_service.py +8 -4
  204. rasa/model_manager/trainer_service.py +5 -4
  205. rasa/model_training.py +12 -3
  206. rasa/nlu/extractors/crf_entity_extractor.py +66 -16
  207. rasa/plugin.py +2 -12
  208. rasa/privacy/__init__.py +0 -0
  209. rasa/privacy/constants.py +83 -0
  210. rasa/privacy/event_broker_utils.py +77 -0
  211. rasa/privacy/privacy_config.py +281 -0
  212. rasa/privacy/privacy_config_schema.json +86 -0
  213. rasa/privacy/privacy_filter.py +340 -0
  214. rasa/privacy/privacy_manager.py +576 -0
  215. rasa/server.py +29 -4
  216. rasa/shared/constants.py +6 -0
  217. rasa/shared/core/constants.py +4 -3
  218. rasa/shared/core/domain.py +7 -0
  219. rasa/shared/core/events.py +99 -3
  220. rasa/shared/core/flows/flow.py +1 -2
  221. rasa/shared/core/flows/flows_yaml_schema.json +3 -0
  222. rasa/shared/core/flows/steps/collect.py +46 -2
  223. rasa/shared/core/slots.py +28 -0
  224. rasa/shared/exceptions.py +4 -0
  225. rasa/shared/providers/_configs/azure_openai_client_config.py +4 -0
  226. rasa/shared/providers/_configs/openai_client_config.py +4 -0
  227. rasa/shared/providers/embedding/_base_litellm_embedding_client.py +3 -0
  228. rasa/shared/providers/llm/_base_litellm_client.py +5 -2
  229. rasa/shared/utils/llm.py +161 -6
  230. rasa/shared/utils/yaml.py +32 -0
  231. rasa/studio/data_handler.py +3 -3
  232. rasa/studio/download/download.py +37 -60
  233. rasa/studio/download/flows.py +23 -31
  234. rasa/studio/link.py +200 -0
  235. rasa/studio/pull.py +94 -0
  236. rasa/studio/push.py +131 -0
  237. rasa/studio/upload.py +117 -67
  238. rasa/telemetry.py +84 -27
  239. rasa/tracing/config.py +4 -5
  240. rasa/tracing/constants.py +19 -1
  241. rasa/tracing/instrumentation/attribute_extractors.py +11 -3
  242. rasa/tracing/instrumentation/instrumentation.py +54 -3
  243. rasa/tracing/instrumentation/metrics.py +98 -15
  244. rasa/tracing/metric_instrument_provider.py +75 -3
  245. rasa/utils/common.py +1 -27
  246. rasa/utils/licensing.py +1 -2
  247. rasa/utils/log_utils.py +1 -45
  248. rasa/validator.py +2 -8
  249. rasa/version.py +1 -1
  250. {rasa_pro-3.13.0.dev5.dist-info → rasa_pro-3.13.0.dev8.dist-info}/METADATA +8 -9
  251. {rasa_pro-3.13.0.dev5.dist-info → rasa_pro-3.13.0.dev8.dist-info}/RECORD +254 -231
  252. rasa/anonymization/__init__.py +0 -2
  253. rasa/anonymization/anonymisation_rule_yaml_reader.py +0 -91
  254. rasa/anonymization/anonymization_pipeline.py +0 -286
  255. rasa/anonymization/anonymization_rule_executor.py +0 -266
  256. rasa/anonymization/anonymization_rule_orchestrator.py +0 -119
  257. rasa/anonymization/schemas/config.yml +0 -47
  258. rasa/anonymization/utils.py +0 -118
  259. rasa/core/channels/inspector/dist/assets/channel-dfa68278.js +0 -1
  260. rasa/core/channels/inspector/dist/assets/clone-edb7f119.js +0 -1
  261. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-65e7c670.js +0 -1
  262. rasa/core/channels/inspector/src/helpers/audiostream.ts +0 -191
  263. rasa/core/tracker_store.py +0 -1792
  264. {rasa_pro-3.13.0.dev5.dist-info → rasa_pro-3.13.0.dev8.dist-info}/NOTICE +0 -0
  265. {rasa_pro-3.13.0.dev5.dist-info → rasa_pro-3.13.0.dev8.dist-info}/WHEEL +0 -0
  266. {rasa_pro-3.13.0.dev5.dist-info → rasa_pro-3.13.0.dev8.dist-info}/entry_points.txt +0 -0
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,
@@ -1,4 +1,3 @@
1
- import copy
2
1
  import logging
3
2
  from typing import Any, Dict, Optional, Text
4
3
 
@@ -49,7 +48,6 @@ class RasaNLUHttpInterpreter:
49
48
  if not self.endpoint_config or self.endpoint_config.url is None:
50
49
  structlogger.error(
51
50
  "http.parse.text",
52
- text=copy.deepcopy(text),
53
51
  event_info="No rasa NLU server specified!",
54
52
  )
55
53
  return None
@@ -71,18 +69,16 @@ class RasaNLUHttpInterpreter:
71
69
  if resp.status == 200:
72
70
  return await resp.json()
73
71
  else:
74
- response_text = await resp.text()
75
72
  structlogger.error(
76
73
  "http.parse.text.failure",
77
- text=copy.deepcopy(text),
78
- response_text=copy.deepcopy(response_text),
74
+ event_info="Failed to parse text",
79
75
  )
80
76
  return None
81
- except Exception: # skipcq: PYL-W0703
77
+ except Exception as e: # skipcq: PYL-W0703
82
78
  # need to catch all possible exceptions when doing http requests
83
79
  # (timeouts, value errors, parser errors, ...)
84
80
  structlogger.exception(
85
81
  "http.parse.text.exception",
86
- text=copy.deepcopy(text),
82
+ event_info=f"Exception occurred while parsing text. Error: {e}",
87
83
  )
88
84
  return None
rasa/core/jobs.py CHANGED
@@ -1,12 +1,13 @@
1
1
  import asyncio
2
2
  import logging
3
+ from typing import Optional
3
4
 
4
5
  from apscheduler.schedulers.asyncio import AsyncIOScheduler
5
6
  from pytz import UnknownTimeZoneError, utc
6
7
 
7
8
  import rasa.shared.utils.io
8
9
 
9
- __scheduler = None
10
+ __scheduler: Optional[AsyncIOScheduler] = None
10
11
 
11
12
  logger = logging.getLogger(__name__)
12
13
 
@@ -5,15 +5,20 @@ from jinja2 import Template
5
5
 
6
6
  from rasa import telemetry
7
7
  from rasa.core.nlg.response import TemplatedNaturalLanguageGenerator
8
- from rasa.core.nlg.summarize import summarize_conversation
8
+ from rasa.core.nlg.summarize import (
9
+ _count_multiple_utterances_as_single_turn,
10
+ summarize_conversation,
11
+ )
9
12
  from rasa.shared.constants import (
10
13
  LLM_CONFIG_KEY,
14
+ MAX_COMPLETION_TOKENS_CONFIG_KEY,
11
15
  MODEL_CONFIG_KEY,
12
16
  MODEL_GROUP_ID_CONFIG_KEY,
13
17
  MODEL_NAME_CONFIG_KEY,
14
18
  OPENAI_PROVIDER,
15
19
  PROMPT_CONFIG_KEY,
16
20
  PROVIDER_CONFIG_KEY,
21
+ TEMPERATURE_CONFIG_KEY,
17
22
  TIMEOUT_CONFIG_KEY,
18
23
  )
19
24
  from rasa.shared.core.domain import KEY_RESPONSES_TEXT, Domain
@@ -53,12 +58,13 @@ RESPONSE_SUMMARISE_CONVERSATION_KEY = "summarize_conversation"
53
58
  DEFAULT_REPHRASE_ALL = False
54
59
  DEFAULT_SUMMARIZE_HISTORY = True
55
60
  DEFAULT_MAX_HISTORICAL_TURNS = 5
61
+ DEFAULT_COUNT_MULTIPLE_UTTERANCES_AS_SINGLE_TURN = True
56
62
 
57
63
  DEFAULT_LLM_CONFIG = {
58
64
  PROVIDER_CONFIG_KEY: OPENAI_PROVIDER,
59
65
  MODEL_CONFIG_KEY: DEFAULT_OPENAI_GENERATE_MODEL_NAME,
60
- "temperature": 0.3,
61
- "max_tokens": DEFAULT_OPENAI_MAX_GENERATED_TOKENS,
66
+ TEMPERATURE_CONFIG_KEY: 0.3,
67
+ MAX_COMPLETION_TOKENS_CONFIG_KEY: DEFAULT_OPENAI_MAX_GENERATED_TOKENS,
62
68
  TIMEOUT_CONFIG_KEY: 5,
63
69
  }
64
70
 
@@ -70,6 +76,7 @@ its meaning. Use simple {{language}}.
70
76
  Context / previous conversation with the user:
71
77
  {{history}}
72
78
 
79
+ Last user message:
73
80
  {{current_input}}
74
81
 
75
82
  Suggested AI Response: {{suggested_response}}
@@ -122,6 +129,11 @@ class ContextualResponseRephraser(
122
129
  "max_historical_turns", DEFAULT_MAX_HISTORICAL_TURNS
123
130
  )
124
131
 
132
+ self.count_multiple_utterances_as_single_turn = self.nlg_endpoint.kwargs.get(
133
+ "count_multiple_utterances_as_single_turn",
134
+ DEFAULT_COUNT_MULTIPLE_UTTERANCES_AS_SINGLE_TURN,
135
+ )
136
+
125
137
  self.llm_config = resolve_model_client_config(
126
138
  self.nlg_endpoint.kwargs.get(LLM_CONFIG_KEY),
127
139
  ContextualResponseRephraser.__name__,
@@ -258,8 +270,16 @@ class ContextualResponseRephraser(
258
270
  Returns:
259
271
  The history for the prompt.
260
272
  """
273
+ # Count multiple utterances by bot/user as single turn in conversation history
274
+ turns_wrapper = (
275
+ _count_multiple_utterances_as_single_turn
276
+ if self.count_multiple_utterances_as_single_turn
277
+ else None
278
+ )
261
279
  llm = llm_factory(self.llm_config, DEFAULT_LLM_CONFIG)
262
- return await summarize_conversation(tracker, llm, max_turns=5)
280
+ return await summarize_conversation(
281
+ tracker, llm, max_turns=5, turns_wrapper=turns_wrapper
282
+ )
263
283
 
264
284
  async def rephrase(
265
285
  self,
@@ -281,19 +301,26 @@ class ContextualResponseRephraser(
281
301
 
282
302
  prompt_template_text = self._template_for_response_rephrasing(response)
283
303
 
284
- # Retrieve inputs for the dynamic prompt
285
- latest_message = self._last_message_if_human(tracker)
286
- current_input = f"{USER}: {latest_message}" if latest_message else ""
304
+ # Last user message (=current input) should always be in prompt if available
305
+ last_message_by_user = getattr(tracker.latest_message, "text", "")
306
+ current_input = (
307
+ f"{USER}: {last_message_by_user}" if last_message_by_user else ""
308
+ )
287
309
 
288
310
  # Only summarise conversation history if flagged
289
311
  if self.summarize_history:
290
312
  history = await self._create_history(tracker)
291
313
  else:
292
- # make sure the transcript/history contains the last user utterance
314
+ # Count multiple utterances by bot/user as single turn
315
+ turns_wrapper = (
316
+ _count_multiple_utterances_as_single_turn
317
+ if self.count_multiple_utterances_as_single_turn
318
+ else None
319
+ )
293
320
  max_turns = max(self.max_historical_turns, 1)
294
- history = tracker_as_readable_transcript(tracker, max_turns=max_turns)
295
- # the history already contains the current input
296
- current_input = ""
321
+ history = tracker_as_readable_transcript(
322
+ tracker, max_turns=max_turns, turns_wrapper=turns_wrapper
323
+ )
297
324
 
298
325
  prompt = Template(prompt_template_text).render(
299
326
  history=history,
@@ -292,7 +292,6 @@ def _evaluate_predicate(constraint: str, filled_slots: Dict[Text, Any]) -> bool:
292
292
  structlogger.error(
293
293
  "rasa.core.nlg.generator.evaluate_conditional_response_predicate.error",
294
294
  predicate=constraint,
295
- document=document,
296
295
  error=str(e),
297
296
  )
298
297
  return False
@@ -1,4 +1,3 @@
1
- import copy
2
1
  import logging
3
2
  import re
4
3
  from typing import Any, Dict, List, Text, Union
@@ -70,9 +69,9 @@ def interpolate_format_template(response: Text, values: Dict[Text, Text]) -> Tex
70
69
  )
71
70
  structlogger.exception(
72
71
  "interpolator.interpolate.text",
73
- response=copy.deepcopy(response),
74
72
  placeholder_key=e.args[0],
75
73
  event_info=event_info,
74
+ error=str(e),
76
75
  )
77
76
  return response
78
77
 
@@ -98,9 +97,9 @@ def interpolate_jinja_template(response: Text, values: Dict[Text, Any]) -> Text:
98
97
  )
99
98
  structlogger.exception(
100
99
  "interpolator.interpolate.text",
101
- response=copy.deepcopy(response),
102
100
  placeholder_key=e.args[0],
103
101
  event_info=event_info,
102
+ error=str(e),
104
103
  )
105
104
  return response
106
105
 
@@ -1,9 +1,10 @@
1
- from typing import Optional
1
+ from itertools import groupby
2
+ from typing import Callable, List, Optional
2
3
 
3
4
  import structlog
4
5
  from jinja2 import Template
5
6
 
6
- from rasa.core.tracker_store import DialogueStateTracker
7
+ from rasa.shared.core.trackers import DialogueStateTracker
7
8
  from rasa.shared.providers.llm.llm_client import LLMClient
8
9
  from rasa.shared.utils.llm import (
9
10
  tracker_as_readable_transcript,
@@ -23,20 +24,49 @@ SUMMARY_PROMPT_TEMPLATE = Template(_DEFAULT_SUMMARIZER_TEMPLATE)
23
24
  MAX_TURNS_DEFAULT = 20
24
25
 
25
26
 
27
+ def _count_multiple_utterances_as_single_turn(transcript: List[str]) -> List[str]:
28
+ """Counts multiple utterances as a single turn.
29
+
30
+ Args:
31
+ transcript: the lines of the transcript
32
+
33
+ Returns:
34
+ transcript: with multiple utterances counted as a single turn
35
+ """
36
+ if not transcript:
37
+ return []
38
+
39
+ def get_speaker_label(line: str) -> str:
40
+ return line.partition(": ")[0] if ": " in line else ""
41
+
42
+ modified_transcript = [
43
+ f"{speaker}: {' '.join(line.partition(': ')[2] for line in group)}"
44
+ for speaker, group in groupby(transcript, key=get_speaker_label)
45
+ if speaker
46
+ ]
47
+
48
+ return modified_transcript
49
+
50
+
26
51
  def _create_summarization_prompt(
27
- tracker: DialogueStateTracker, max_turns: Optional[int]
52
+ tracker: DialogueStateTracker,
53
+ max_turns: Optional[int],
54
+ turns_wrapper: Optional[Callable[[List[str]], List[str]]],
28
55
  ) -> str:
29
56
  """Creates an LLM prompt to summarize the conversation in the tracker.
30
57
 
31
58
  Args:
32
59
  tracker: tracker of the conversation to be summarized
33
60
  max_turns: maximum number of turns to summarize
61
+ turns_wrapper: optional function to wrap the turns
34
62
 
35
63
 
36
64
  Returns:
37
65
  The prompt to summarize the conversation.
38
66
  """
39
- transcript = tracker_as_readable_transcript(tracker, max_turns=max_turns)
67
+ transcript = tracker_as_readable_transcript(
68
+ tracker, max_turns=max_turns, turns_wrapper=turns_wrapper
69
+ )
40
70
  return SUMMARY_PROMPT_TEMPLATE.render(
41
71
  conversation=transcript,
42
72
  )
@@ -46,6 +76,7 @@ async def summarize_conversation(
46
76
  tracker: DialogueStateTracker,
47
77
  llm: LLMClient,
48
78
  max_turns: Optional[int] = MAX_TURNS_DEFAULT,
79
+ turns_wrapper: Optional[Callable[[List[str]], List[str]]] = None,
49
80
  ) -> str:
50
81
  """Summarizes the dialogue using the LLM.
51
82
 
@@ -53,11 +84,12 @@ async def summarize_conversation(
53
84
  tracker: the tracker to summarize
54
85
  llm: the LLM to use for summarization
55
86
  max_turns: maximum number of turns to summarize
87
+ turns_wrapper: optional function to wrap the turns
56
88
 
57
89
  Returns:
58
90
  The summary of the dialogue.
59
91
  """
60
- prompt = _create_summarization_prompt(tracker, max_turns)
92
+ prompt = _create_summarization_prompt(tracker, max_turns, turns_wrapper)
61
93
  try:
62
94
  llm_response = await llm.acompletion(prompt)
63
95
  summarization = llm_response.choices[0].strip()
@@ -66,6 +98,8 @@ async def summarize_conversation(
66
98
  )
67
99
  return summarization
68
100
  except Exception as e:
69
- transcript = tracker_as_readable_transcript(tracker, max_turns=max_turns)
101
+ transcript = tracker_as_readable_transcript(
102
+ tracker, max_turns=max_turns, turns_wrapper=turns_wrapper
103
+ )
70
104
  structlogger.error("summarization.error", error=e)
71
105
  return transcript
rasa/core/persistor.py CHANGED
@@ -121,10 +121,12 @@ def get_persistor(storage: StorageType) -> Optional[Persistor]:
121
121
  class Persistor(abc.ABC):
122
122
  """Store models in cloud and fetch them when needed."""
123
123
 
124
- def persist(self, trained_model: str) -> None:
124
+ def persist(self, trained_model: str, remote_root_only: bool = False) -> None:
125
125
  """Uploads a trained model persisted in the `target_dir` to cloud storage."""
126
126
  absolute_file_key = self._create_file_key(trained_model)
127
- file_key = Path(absolute_file_key).name
127
+ file_key = (
128
+ Path(absolute_file_key).name if remote_root_only else absolute_file_key
129
+ )
128
130
  self._persist_tar(file_key, trained_model)
129
131
 
130
132
  def retrieve(self, model_name: Text, target_path: Text) -> Text:
@@ -143,30 +145,32 @@ class Persistor(abc.ABC):
143
145
  # ensure backward compatibility
144
146
  tar_name = self._tar_name(model_name)
145
147
  tar_name = self._create_file_key(tar_name)
146
- target_filename = os.path.basename(tar_name)
147
- self._retrieve_tar(target_filename)
148
- self._copy(os.path.basename(tar_name), target_path)
148
+ self._retrieve_tar(tar_name, target_path)
149
149
 
150
150
  if os.path.isdir(target_path):
151
151
  return os.path.join(target_path, model_name)
152
152
 
153
153
  return target_path
154
154
 
155
- def size_of_persisted_model(self, model_name: Text) -> int:
155
+ def size_of_persisted_model(
156
+ self, model_name: Text, target_path: Optional[str] = None
157
+ ) -> int:
156
158
  """Returns the size of the model that has been persisted to cloud storage.
157
159
 
158
160
  Args:
159
161
  model_name: The name of the model to retrieve.
162
+ target_path: The path to which the model should be saved.
160
163
  """
161
164
  tar_name = model_name
162
165
  if not model_name.endswith(MODEL_ARCHIVE_EXTENSION):
163
166
  # ensure backward compatibility
164
167
  tar_name = self._tar_name(model_name)
165
168
  tar_name = self._create_file_key(tar_name)
166
- target_filename = os.path.basename(tar_name)
167
- return self._retrieve_tar_size(target_filename)
169
+ return self._retrieve_tar_size(tar_name, target_path)
168
170
 
169
- def _retrieve_tar_size(self, filename: Text) -> int:
171
+ def _retrieve_tar_size(
172
+ self, filename: Text, target_path: Optional[str] = None
173
+ ) -> int:
170
174
  """Returns the size of the model that has been persisted to cloud storage."""
171
175
  structlogger.warning(
172
176
  "persistor.retrieve_tar_size.not_implemented",
@@ -179,11 +183,11 @@ class Persistor(abc.ABC):
179
183
  "size directly from the cloud storage."
180
184
  ),
181
185
  )
182
- self._retrieve_tar(filename)
186
+ self._retrieve_tar(filename, target_path)
183
187
  return os.path.getsize(os.path.basename(filename))
184
188
 
185
189
  @abc.abstractmethod
186
- def _retrieve_tar(self, filename: Text) -> None:
190
+ def _retrieve_tar(self, filename: str, target_path: Optional[str] = None) -> None:
187
191
  """Downloads a model previously persisted to cloud storage."""
188
192
  raise NotImplementedError
189
193
 
@@ -302,7 +306,9 @@ class AWSPersistor(Persistor):
302
306
  with open(tar_path, "rb") as f:
303
307
  self.s3.Object(self.bucket_name, file_key).put(Body=f)
304
308
 
305
- def _retrieve_tar_size(self, model_path: Text) -> int:
309
+ def _retrieve_tar_size(
310
+ self, model_path: Text, target_path: Optional[str] = None
311
+ ) -> int:
306
312
  """Returns the size of the model that has been persisted to s3."""
307
313
  try:
308
314
  obj = self.s3.Object(self.bucket_name, model_path)
@@ -310,7 +316,9 @@ class AWSPersistor(Persistor):
310
316
  except Exception:
311
317
  raise ModelNotFound()
312
318
 
313
- def _retrieve_tar(self, target_filename: str) -> None:
319
+ def _retrieve_tar(
320
+ self, target_filename: str, target_path: Optional[str] = None
321
+ ) -> None:
314
322
  """Downloads a model that has previously been persisted to s3."""
315
323
  from botocore import exceptions
316
324
 
@@ -320,8 +328,14 @@ class AWSPersistor(Persistor):
320
328
  f"in the bucket."
321
329
  )
322
330
 
331
+ tar_name = (
332
+ os.path.join(target_path, os.path.basename(target_filename))
333
+ if target_path
334
+ else os.path.basename(target_filename)
335
+ )
336
+
323
337
  try:
324
- with open(target_filename, "wb") as f:
338
+ with open(tar_name, "wb") as f:
325
339
  self.bucket.download_fileobj(target_filename, f)
326
340
 
327
341
  structlogger.debug(
@@ -425,7 +439,9 @@ class GCSPersistor(Persistor):
425
439
  blob = self.bucket.blob(file_key)
426
440
  blob.upload_from_filename(tar_path)
427
441
 
428
- def _retrieve_tar_size(self, target_filename: Text) -> int:
442
+ def _retrieve_tar_size(
443
+ self, target_filename: Text, target_path: Optional[str] = None
444
+ ) -> int:
429
445
  """Returns the size of the model that has been persisted to GCS."""
430
446
  try:
431
447
  blob = self.bucket.blob(target_filename)
@@ -433,13 +449,22 @@ class GCSPersistor(Persistor):
433
449
  except Exception:
434
450
  raise ModelNotFound()
435
451
 
436
- def _retrieve_tar(self, target_filename: Text) -> None:
452
+ def _retrieve_tar(
453
+ self, target_filename: str, target_path: Optional[str] = None
454
+ ) -> None:
437
455
  """Downloads a model that has previously been persisted to GCS."""
438
456
  from google.api_core import exceptions
439
457
 
440
458
  blob = self.bucket.blob(target_filename)
459
+
460
+ destination = (
461
+ os.path.join(target_path, os.path.basename(target_filename))
462
+ if target_path
463
+ else target_filename
464
+ )
465
+
441
466
  try:
442
- blob.download_to_filename(target_filename)
467
+ blob.download_to_filename(destination)
443
468
 
444
469
  structlogger.debug(
445
470
  "gcs_persistor.retrieve_tar.object_found", object_key=target_filename
@@ -500,7 +525,9 @@ class AzurePersistor(Persistor):
500
525
  with open(tar_path, "rb") as data:
501
526
  self._container_client().upload_blob(name=file_key, data=data)
502
527
 
503
- def _retrieve_tar_size(self, target_filename: Text) -> int:
528
+ def _retrieve_tar_size(
529
+ self, target_filename: Text, target_path: Optional[str] = None
530
+ ) -> int:
504
531
  """Returns the size of the model that has been persisted to Azure."""
505
532
  try:
506
533
  blob_client = self._container_client().get_blob_client(target_filename)
@@ -509,12 +536,20 @@ class AzurePersistor(Persistor):
509
536
  except Exception:
510
537
  raise ModelNotFound()
511
538
 
512
- def _retrieve_tar(self, target_filename: Text) -> None:
539
+ def _retrieve_tar(
540
+ self, target_filename: Text, target_path: Optional[str] = None
541
+ ) -> None:
513
542
  """Downloads a model that has previously been persisted to Azure."""
514
543
  from azure.core.exceptions import AzureError
515
544
 
545
+ destination = (
546
+ os.path.join(target_path, os.path.basename(target_filename))
547
+ if target_path
548
+ else target_filename
549
+ )
550
+
516
551
  try:
517
- with open(target_filename, "wb") as model_file:
552
+ with open(destination, "wb") as model_file:
518
553
  blob_client = self._container_client().get_blob_client(target_filename)
519
554
  download_stream = blob_client.download_blob()
520
555
  model_file.write(download_stream.readall())