rasa-pro 3.9.18__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 (662) hide show
  1. README.md +415 -0
  2. rasa/__init__.py +10 -0
  3. rasa/__main__.py +156 -0
  4. rasa/anonymization/__init__.py +2 -0
  5. rasa/anonymization/anonymisation_rule_yaml_reader.py +91 -0
  6. rasa/anonymization/anonymization_pipeline.py +286 -0
  7. rasa/anonymization/anonymization_rule_executor.py +260 -0
  8. rasa/anonymization/anonymization_rule_orchestrator.py +120 -0
  9. rasa/anonymization/schemas/config.yml +47 -0
  10. rasa/anonymization/utils.py +118 -0
  11. rasa/api.py +146 -0
  12. rasa/cli/__init__.py +5 -0
  13. rasa/cli/arguments/__init__.py +0 -0
  14. rasa/cli/arguments/data.py +81 -0
  15. rasa/cli/arguments/default_arguments.py +165 -0
  16. rasa/cli/arguments/evaluate.py +65 -0
  17. rasa/cli/arguments/export.py +51 -0
  18. rasa/cli/arguments/interactive.py +74 -0
  19. rasa/cli/arguments/run.py +204 -0
  20. rasa/cli/arguments/shell.py +13 -0
  21. rasa/cli/arguments/test.py +211 -0
  22. rasa/cli/arguments/train.py +263 -0
  23. rasa/cli/arguments/visualize.py +34 -0
  24. rasa/cli/arguments/x.py +30 -0
  25. rasa/cli/data.py +292 -0
  26. rasa/cli/e2e_test.py +586 -0
  27. rasa/cli/evaluate.py +222 -0
  28. rasa/cli/export.py +250 -0
  29. rasa/cli/inspect.py +63 -0
  30. rasa/cli/interactive.py +164 -0
  31. rasa/cli/license.py +65 -0
  32. rasa/cli/markers.py +78 -0
  33. rasa/cli/project_templates/__init__.py +0 -0
  34. rasa/cli/project_templates/calm/actions/__init__.py +0 -0
  35. rasa/cli/project_templates/calm/actions/action_template.py +27 -0
  36. rasa/cli/project_templates/calm/actions/add_contact.py +30 -0
  37. rasa/cli/project_templates/calm/actions/db.py +57 -0
  38. rasa/cli/project_templates/calm/actions/list_contacts.py +22 -0
  39. rasa/cli/project_templates/calm/actions/remove_contact.py +35 -0
  40. rasa/cli/project_templates/calm/config.yml +12 -0
  41. rasa/cli/project_templates/calm/credentials.yml +33 -0
  42. rasa/cli/project_templates/calm/data/flows/add_contact.yml +31 -0
  43. rasa/cli/project_templates/calm/data/flows/list_contacts.yml +14 -0
  44. rasa/cli/project_templates/calm/data/flows/remove_contact.yml +29 -0
  45. rasa/cli/project_templates/calm/db/contacts.json +10 -0
  46. rasa/cli/project_templates/calm/domain/add_contact.yml +39 -0
  47. rasa/cli/project_templates/calm/domain/list_contacts.yml +17 -0
  48. rasa/cli/project_templates/calm/domain/remove_contact.yml +38 -0
  49. rasa/cli/project_templates/calm/domain/shared.yml +10 -0
  50. rasa/cli/project_templates/calm/e2e_tests/cancelations/user_cancels_during_a_correction.yml +16 -0
  51. rasa/cli/project_templates/calm/e2e_tests/cancelations/user_changes_mind_on_a_whim.yml +7 -0
  52. rasa/cli/project_templates/calm/e2e_tests/corrections/user_corrects_contact_handle.yml +20 -0
  53. rasa/cli/project_templates/calm/e2e_tests/corrections/user_corrects_contact_name.yml +19 -0
  54. rasa/cli/project_templates/calm/e2e_tests/happy_paths/user_adds_contact_to_their_list.yml +15 -0
  55. rasa/cli/project_templates/calm/e2e_tests/happy_paths/user_lists_contacts.yml +5 -0
  56. rasa/cli/project_templates/calm/e2e_tests/happy_paths/user_removes_contact.yml +11 -0
  57. rasa/cli/project_templates/calm/e2e_tests/happy_paths/user_removes_contact_from_list.yml +12 -0
  58. rasa/cli/project_templates/calm/endpoints.yml +45 -0
  59. rasa/cli/project_templates/default/actions/__init__.py +0 -0
  60. rasa/cli/project_templates/default/actions/actions.py +27 -0
  61. rasa/cli/project_templates/default/config.yml +44 -0
  62. rasa/cli/project_templates/default/credentials.yml +33 -0
  63. rasa/cli/project_templates/default/data/nlu.yml +91 -0
  64. rasa/cli/project_templates/default/data/rules.yml +13 -0
  65. rasa/cli/project_templates/default/data/stories.yml +30 -0
  66. rasa/cli/project_templates/default/domain.yml +34 -0
  67. rasa/cli/project_templates/default/endpoints.yml +42 -0
  68. rasa/cli/project_templates/default/tests/test_stories.yml +91 -0
  69. rasa/cli/project_templates/tutorial/actions.py +22 -0
  70. rasa/cli/project_templates/tutorial/config.yml +11 -0
  71. rasa/cli/project_templates/tutorial/credentials.yml +33 -0
  72. rasa/cli/project_templates/tutorial/data/flows.yml +8 -0
  73. rasa/cli/project_templates/tutorial/data/patterns.yml +6 -0
  74. rasa/cli/project_templates/tutorial/domain.yml +21 -0
  75. rasa/cli/project_templates/tutorial/endpoints.yml +45 -0
  76. rasa/cli/run.py +135 -0
  77. rasa/cli/scaffold.py +269 -0
  78. rasa/cli/shell.py +141 -0
  79. rasa/cli/studio/__init__.py +0 -0
  80. rasa/cli/studio/download.py +62 -0
  81. rasa/cli/studio/studio.py +266 -0
  82. rasa/cli/studio/train.py +59 -0
  83. rasa/cli/studio/upload.py +77 -0
  84. rasa/cli/telemetry.py +102 -0
  85. rasa/cli/test.py +280 -0
  86. rasa/cli/train.py +260 -0
  87. rasa/cli/utils.py +464 -0
  88. rasa/cli/visualize.py +40 -0
  89. rasa/cli/x.py +206 -0
  90. rasa/constants.py +37 -0
  91. rasa/core/__init__.py +17 -0
  92. rasa/core/actions/__init__.py +0 -0
  93. rasa/core/actions/action.py +1225 -0
  94. rasa/core/actions/action_clean_stack.py +59 -0
  95. rasa/core/actions/action_exceptions.py +24 -0
  96. rasa/core/actions/action_run_slot_rejections.py +207 -0
  97. rasa/core/actions/action_trigger_chitchat.py +31 -0
  98. rasa/core/actions/action_trigger_flow.py +109 -0
  99. rasa/core/actions/action_trigger_search.py +31 -0
  100. rasa/core/actions/constants.py +5 -0
  101. rasa/core/actions/custom_action_executor.py +188 -0
  102. rasa/core/actions/forms.py +741 -0
  103. rasa/core/actions/grpc_custom_action_executor.py +251 -0
  104. rasa/core/actions/http_custom_action_executor.py +140 -0
  105. rasa/core/actions/loops.py +114 -0
  106. rasa/core/actions/two_stage_fallback.py +186 -0
  107. rasa/core/agent.py +555 -0
  108. rasa/core/auth_retry_tracker_store.py +122 -0
  109. rasa/core/brokers/__init__.py +0 -0
  110. rasa/core/brokers/broker.py +126 -0
  111. rasa/core/brokers/file.py +58 -0
  112. rasa/core/brokers/kafka.py +322 -0
  113. rasa/core/brokers/pika.py +386 -0
  114. rasa/core/brokers/sql.py +86 -0
  115. rasa/core/channels/__init__.py +55 -0
  116. rasa/core/channels/audiocodes.py +463 -0
  117. rasa/core/channels/botframework.py +338 -0
  118. rasa/core/channels/callback.py +84 -0
  119. rasa/core/channels/channel.py +419 -0
  120. rasa/core/channels/console.py +241 -0
  121. rasa/core/channels/development_inspector.py +93 -0
  122. rasa/core/channels/facebook.py +419 -0
  123. rasa/core/channels/hangouts.py +329 -0
  124. rasa/core/channels/inspector/.eslintrc.cjs +25 -0
  125. rasa/core/channels/inspector/.gitignore +23 -0
  126. rasa/core/channels/inspector/README.md +54 -0
  127. rasa/core/channels/inspector/assets/favicon.ico +0 -0
  128. rasa/core/channels/inspector/assets/rasa-chat.js +2 -0
  129. rasa/core/channels/inspector/custom.d.ts +3 -0
  130. rasa/core/channels/inspector/dist/assets/arc-b6e548fe.js +1 -0
  131. rasa/core/channels/inspector/dist/assets/array-9f3ba611.js +1 -0
  132. rasa/core/channels/inspector/dist/assets/c4Diagram-d0fbc5ce-fa03ac9e.js +10 -0
  133. rasa/core/channels/inspector/dist/assets/classDiagram-936ed81e-ee67392a.js +2 -0
  134. rasa/core/channels/inspector/dist/assets/classDiagram-v2-c3cb15f1-9b283fae.js +2 -0
  135. rasa/core/channels/inspector/dist/assets/createText-62fc7601-8b6fcc2a.js +7 -0
  136. rasa/core/channels/inspector/dist/assets/edges-f2ad444c-22e77f4f.js +4 -0
  137. rasa/core/channels/inspector/dist/assets/erDiagram-9d236eb7-60ffc87f.js +51 -0
  138. rasa/core/channels/inspector/dist/assets/flowDb-1972c806-9dd802e4.js +6 -0
  139. rasa/core/channels/inspector/dist/assets/flowDiagram-7ea5b25a-5fa1912f.js +4 -0
  140. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-1844e5a5.js +1 -0
  141. rasa/core/channels/inspector/dist/assets/flowchart-elk-definition-abe16c3d-622a1fd2.js +139 -0
  142. rasa/core/channels/inspector/dist/assets/ganttDiagram-9b5ea136-e285a63a.js +266 -0
  143. rasa/core/channels/inspector/dist/assets/gitGraphDiagram-99d0ae7c-f237bdca.js +70 -0
  144. rasa/core/channels/inspector/dist/assets/ibm-plex-mono-v4-latin-regular-128cfa44.ttf +0 -0
  145. rasa/core/channels/inspector/dist/assets/ibm-plex-mono-v4-latin-regular-21dbcb97.woff +0 -0
  146. rasa/core/channels/inspector/dist/assets/ibm-plex-mono-v4-latin-regular-222b5e26.svg +329 -0
  147. rasa/core/channels/inspector/dist/assets/ibm-plex-mono-v4-latin-regular-9ad89b2a.woff2 +0 -0
  148. rasa/core/channels/inspector/dist/assets/index-2c4b9a3b-4b03d70e.js +1 -0
  149. rasa/core/channels/inspector/dist/assets/index-3ee28881.css +1 -0
  150. rasa/core/channels/inspector/dist/assets/index-a5d3e69d.js +1040 -0
  151. rasa/core/channels/inspector/dist/assets/infoDiagram-736b4530-72a0fa5f.js +7 -0
  152. rasa/core/channels/inspector/dist/assets/init-77b53fdd.js +1 -0
  153. rasa/core/channels/inspector/dist/assets/journeyDiagram-df861f2b-82218c41.js +139 -0
  154. rasa/core/channels/inspector/dist/assets/lato-v14-latin-700-60c05ee4.woff +0 -0
  155. rasa/core/channels/inspector/dist/assets/lato-v14-latin-700-8335d9b8.svg +438 -0
  156. rasa/core/channels/inspector/dist/assets/lato-v14-latin-700-9cc39c75.ttf +0 -0
  157. rasa/core/channels/inspector/dist/assets/lato-v14-latin-700-ead13ccf.woff2 +0 -0
  158. rasa/core/channels/inspector/dist/assets/lato-v14-latin-regular-16705655.woff2 +0 -0
  159. rasa/core/channels/inspector/dist/assets/lato-v14-latin-regular-5aeb07f9.woff +0 -0
  160. rasa/core/channels/inspector/dist/assets/lato-v14-latin-regular-9c459044.ttf +0 -0
  161. rasa/core/channels/inspector/dist/assets/lato-v14-latin-regular-9e2898a4.svg +435 -0
  162. rasa/core/channels/inspector/dist/assets/layout-78cff630.js +1 -0
  163. rasa/core/channels/inspector/dist/assets/line-5038b469.js +1 -0
  164. rasa/core/channels/inspector/dist/assets/linear-c4fc4098.js +1 -0
  165. rasa/core/channels/inspector/dist/assets/mindmap-definition-beec6740-c33c8ea6.js +109 -0
  166. rasa/core/channels/inspector/dist/assets/ordinal-ba9b4969.js +1 -0
  167. rasa/core/channels/inspector/dist/assets/path-53f90ab3.js +1 -0
  168. rasa/core/channels/inspector/dist/assets/pieDiagram-dbbf0591-a8d03059.js +35 -0
  169. rasa/core/channels/inspector/dist/assets/quadrantDiagram-4d7f4fd6-6a0e56b2.js +7 -0
  170. rasa/core/channels/inspector/dist/assets/requirementDiagram-6fc4c22a-2dc7c7bd.js +52 -0
  171. rasa/core/channels/inspector/dist/assets/sankeyDiagram-8f13d901-2360fe39.js +8 -0
  172. rasa/core/channels/inspector/dist/assets/sequenceDiagram-b655622a-41b9f9ad.js +122 -0
  173. rasa/core/channels/inspector/dist/assets/stateDiagram-59f0c015-0aad326f.js +1 -0
  174. rasa/core/channels/inspector/dist/assets/stateDiagram-v2-2b26beab-9847d984.js +1 -0
  175. rasa/core/channels/inspector/dist/assets/styles-080da4f6-564d890e.js +110 -0
  176. rasa/core/channels/inspector/dist/assets/styles-3dcbcfbf-38957613.js +159 -0
  177. rasa/core/channels/inspector/dist/assets/styles-9c745c82-f0fc6921.js +207 -0
  178. rasa/core/channels/inspector/dist/assets/svgDrawCommon-4835440b-ef3c5a77.js +1 -0
  179. rasa/core/channels/inspector/dist/assets/timeline-definition-5b62e21b-bf3e91c1.js +61 -0
  180. rasa/core/channels/inspector/dist/assets/xychartDiagram-2b33534f-4d4026c0.js +7 -0
  181. rasa/core/channels/inspector/dist/index.html +41 -0
  182. rasa/core/channels/inspector/index.html +39 -0
  183. rasa/core/channels/inspector/jest.config.ts +13 -0
  184. rasa/core/channels/inspector/package.json +48 -0
  185. rasa/core/channels/inspector/setupTests.ts +2 -0
  186. rasa/core/channels/inspector/src/App.tsx +170 -0
  187. rasa/core/channels/inspector/src/components/DiagramFlow.tsx +107 -0
  188. rasa/core/channels/inspector/src/components/DialogueInformation.tsx +187 -0
  189. rasa/core/channels/inspector/src/components/DialogueStack.tsx +151 -0
  190. rasa/core/channels/inspector/src/components/ExpandIcon.tsx +16 -0
  191. rasa/core/channels/inspector/src/components/FullscreenButton.tsx +45 -0
  192. rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +19 -0
  193. rasa/core/channels/inspector/src/components/NoActiveFlow.tsx +21 -0
  194. rasa/core/channels/inspector/src/components/RasaLogo.tsx +32 -0
  195. rasa/core/channels/inspector/src/components/SaraDiagrams.tsx +39 -0
  196. rasa/core/channels/inspector/src/components/Slots.tsx +91 -0
  197. rasa/core/channels/inspector/src/components/Welcome.tsx +54 -0
  198. rasa/core/channels/inspector/src/helpers/formatters.test.ts +382 -0
  199. rasa/core/channels/inspector/src/helpers/formatters.ts +240 -0
  200. rasa/core/channels/inspector/src/helpers/utils.ts +42 -0
  201. rasa/core/channels/inspector/src/main.tsx +13 -0
  202. rasa/core/channels/inspector/src/theme/Button/Button.ts +29 -0
  203. rasa/core/channels/inspector/src/theme/Heading/Heading.ts +31 -0
  204. rasa/core/channels/inspector/src/theme/Input/Input.ts +27 -0
  205. rasa/core/channels/inspector/src/theme/Link/Link.ts +10 -0
  206. rasa/core/channels/inspector/src/theme/Modal/Modal.ts +47 -0
  207. rasa/core/channels/inspector/src/theme/Table/Table.tsx +38 -0
  208. rasa/core/channels/inspector/src/theme/Tooltip/Tooltip.ts +12 -0
  209. rasa/core/channels/inspector/src/theme/base/breakpoints.ts +8 -0
  210. rasa/core/channels/inspector/src/theme/base/colors.ts +88 -0
  211. rasa/core/channels/inspector/src/theme/base/fonts/fontFaces.css +29 -0
  212. rasa/core/channels/inspector/src/theme/base/fonts/ibm-plex-mono-v4-latin/ibm-plex-mono-v4-latin-regular.eot +0 -0
  213. rasa/core/channels/inspector/src/theme/base/fonts/ibm-plex-mono-v4-latin/ibm-plex-mono-v4-latin-regular.svg +329 -0
  214. rasa/core/channels/inspector/src/theme/base/fonts/ibm-plex-mono-v4-latin/ibm-plex-mono-v4-latin-regular.ttf +0 -0
  215. rasa/core/channels/inspector/src/theme/base/fonts/ibm-plex-mono-v4-latin/ibm-plex-mono-v4-latin-regular.woff +0 -0
  216. rasa/core/channels/inspector/src/theme/base/fonts/ibm-plex-mono-v4-latin/ibm-plex-mono-v4-latin-regular.woff2 +0 -0
  217. rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-700.eot +0 -0
  218. rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-700.svg +438 -0
  219. rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-700.ttf +0 -0
  220. rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-700.woff +0 -0
  221. rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-700.woff2 +0 -0
  222. rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-regular.eot +0 -0
  223. rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-regular.svg +435 -0
  224. rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-regular.ttf +0 -0
  225. rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-regular.woff +0 -0
  226. rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-regular.woff2 +0 -0
  227. rasa/core/channels/inspector/src/theme/base/radii.ts +9 -0
  228. rasa/core/channels/inspector/src/theme/base/shadows.ts +7 -0
  229. rasa/core/channels/inspector/src/theme/base/sizes.ts +7 -0
  230. rasa/core/channels/inspector/src/theme/base/space.ts +15 -0
  231. rasa/core/channels/inspector/src/theme/base/styles.ts +13 -0
  232. rasa/core/channels/inspector/src/theme/base/typography.ts +24 -0
  233. rasa/core/channels/inspector/src/theme/base/zIndices.ts +19 -0
  234. rasa/core/channels/inspector/src/theme/index.ts +101 -0
  235. rasa/core/channels/inspector/src/types.ts +64 -0
  236. rasa/core/channels/inspector/src/vite-env.d.ts +1 -0
  237. rasa/core/channels/inspector/tests/__mocks__/fileMock.ts +1 -0
  238. rasa/core/channels/inspector/tests/__mocks__/matchMedia.ts +16 -0
  239. rasa/core/channels/inspector/tests/__mocks__/styleMock.ts +1 -0
  240. rasa/core/channels/inspector/tests/renderWithProviders.tsx +14 -0
  241. rasa/core/channels/inspector/tsconfig.json +26 -0
  242. rasa/core/channels/inspector/tsconfig.node.json +10 -0
  243. rasa/core/channels/inspector/vite.config.ts +8 -0
  244. rasa/core/channels/inspector/yarn.lock +6156 -0
  245. rasa/core/channels/mattermost.py +229 -0
  246. rasa/core/channels/rasa_chat.py +126 -0
  247. rasa/core/channels/rest.py +225 -0
  248. rasa/core/channels/rocketchat.py +174 -0
  249. rasa/core/channels/slack.py +620 -0
  250. rasa/core/channels/socketio.py +274 -0
  251. rasa/core/channels/telegram.py +298 -0
  252. rasa/core/channels/twilio.py +169 -0
  253. rasa/core/channels/twilio_voice.py +367 -0
  254. rasa/core/channels/vier_cvg.py +374 -0
  255. rasa/core/channels/webexteams.py +134 -0
  256. rasa/core/concurrent_lock_store.py +210 -0
  257. rasa/core/constants.py +107 -0
  258. rasa/core/evaluation/__init__.py +0 -0
  259. rasa/core/evaluation/marker.py +267 -0
  260. rasa/core/evaluation/marker_base.py +923 -0
  261. rasa/core/evaluation/marker_stats.py +293 -0
  262. rasa/core/evaluation/marker_tracker_loader.py +103 -0
  263. rasa/core/exceptions.py +29 -0
  264. rasa/core/exporter.py +284 -0
  265. rasa/core/featurizers/__init__.py +0 -0
  266. rasa/core/featurizers/precomputation.py +410 -0
  267. rasa/core/featurizers/single_state_featurizer.py +421 -0
  268. rasa/core/featurizers/tracker_featurizers.py +1262 -0
  269. rasa/core/http_interpreter.py +89 -0
  270. rasa/core/information_retrieval/__init__.py +7 -0
  271. rasa/core/information_retrieval/faiss.py +121 -0
  272. rasa/core/information_retrieval/information_retrieval.py +129 -0
  273. rasa/core/information_retrieval/milvus.py +52 -0
  274. rasa/core/information_retrieval/qdrant.py +95 -0
  275. rasa/core/jobs.py +63 -0
  276. rasa/core/lock.py +139 -0
  277. rasa/core/lock_store.py +343 -0
  278. rasa/core/migrate.py +403 -0
  279. rasa/core/nlg/__init__.py +3 -0
  280. rasa/core/nlg/callback.py +146 -0
  281. rasa/core/nlg/contextual_response_rephraser.py +270 -0
  282. rasa/core/nlg/generator.py +230 -0
  283. rasa/core/nlg/interpolator.py +143 -0
  284. rasa/core/nlg/response.py +155 -0
  285. rasa/core/nlg/summarize.py +69 -0
  286. rasa/core/policies/__init__.py +0 -0
  287. rasa/core/policies/ensemble.py +329 -0
  288. rasa/core/policies/enterprise_search_policy.py +781 -0
  289. rasa/core/policies/enterprise_search_prompt_template.jinja2 +25 -0
  290. rasa/core/policies/enterprise_search_prompt_with_citation_template.jinja2 +60 -0
  291. rasa/core/policies/flow_policy.py +205 -0
  292. rasa/core/policies/flows/__init__.py +0 -0
  293. rasa/core/policies/flows/flow_exceptions.py +44 -0
  294. rasa/core/policies/flows/flow_executor.py +705 -0
  295. rasa/core/policies/flows/flow_step_result.py +43 -0
  296. rasa/core/policies/intentless_policy.py +922 -0
  297. rasa/core/policies/intentless_prompt_template.jinja2 +22 -0
  298. rasa/core/policies/memoization.py +538 -0
  299. rasa/core/policies/policy.py +725 -0
  300. rasa/core/policies/rule_policy.py +1273 -0
  301. rasa/core/policies/ted_policy.py +2169 -0
  302. rasa/core/policies/unexpected_intent_policy.py +1022 -0
  303. rasa/core/processor.py +1422 -0
  304. rasa/core/run.py +331 -0
  305. rasa/core/secrets_manager/__init__.py +0 -0
  306. rasa/core/secrets_manager/constants.py +32 -0
  307. rasa/core/secrets_manager/endpoints.py +391 -0
  308. rasa/core/secrets_manager/factory.py +233 -0
  309. rasa/core/secrets_manager/secret_manager.py +262 -0
  310. rasa/core/secrets_manager/vault.py +574 -0
  311. rasa/core/test.py +1335 -0
  312. rasa/core/tracker_store.py +1699 -0
  313. rasa/core/train.py +105 -0
  314. rasa/core/training/__init__.py +89 -0
  315. rasa/core/training/converters/__init__.py +0 -0
  316. rasa/core/training/converters/responses_prefix_converter.py +119 -0
  317. rasa/core/training/interactive.py +1745 -0
  318. rasa/core/training/story_conflict.py +381 -0
  319. rasa/core/training/training.py +93 -0
  320. rasa/core/utils.py +339 -0
  321. rasa/core/visualize.py +70 -0
  322. rasa/dialogue_understanding/__init__.py +0 -0
  323. rasa/dialogue_understanding/coexistence/__init__.py +0 -0
  324. rasa/dialogue_understanding/coexistence/constants.py +4 -0
  325. rasa/dialogue_understanding/coexistence/intent_based_router.py +196 -0
  326. rasa/dialogue_understanding/coexistence/llm_based_router.py +260 -0
  327. rasa/dialogue_understanding/coexistence/router_template.jinja2 +12 -0
  328. rasa/dialogue_understanding/commands/__init__.py +49 -0
  329. rasa/dialogue_understanding/commands/can_not_handle_command.py +70 -0
  330. rasa/dialogue_understanding/commands/cancel_flow_command.py +125 -0
  331. rasa/dialogue_understanding/commands/change_flow_command.py +44 -0
  332. rasa/dialogue_understanding/commands/chit_chat_answer_command.py +57 -0
  333. rasa/dialogue_understanding/commands/clarify_command.py +86 -0
  334. rasa/dialogue_understanding/commands/command.py +85 -0
  335. rasa/dialogue_understanding/commands/correct_slots_command.py +297 -0
  336. rasa/dialogue_understanding/commands/error_command.py +79 -0
  337. rasa/dialogue_understanding/commands/free_form_answer_command.py +9 -0
  338. rasa/dialogue_understanding/commands/handle_code_change_command.py +73 -0
  339. rasa/dialogue_understanding/commands/human_handoff_command.py +66 -0
  340. rasa/dialogue_understanding/commands/knowledge_answer_command.py +57 -0
  341. rasa/dialogue_understanding/commands/noop_command.py +54 -0
  342. rasa/dialogue_understanding/commands/set_slot_command.py +160 -0
  343. rasa/dialogue_understanding/commands/skip_question_command.py +75 -0
  344. rasa/dialogue_understanding/commands/start_flow_command.py +107 -0
  345. rasa/dialogue_understanding/generator/__init__.py +21 -0
  346. rasa/dialogue_understanding/generator/command_generator.py +343 -0
  347. rasa/dialogue_understanding/generator/constants.py +18 -0
  348. rasa/dialogue_understanding/generator/flow_document_template.jinja2 +4 -0
  349. rasa/dialogue_understanding/generator/flow_retrieval.py +412 -0
  350. rasa/dialogue_understanding/generator/llm_based_command_generator.py +467 -0
  351. rasa/dialogue_understanding/generator/llm_command_generator.py +67 -0
  352. rasa/dialogue_understanding/generator/multi_step/__init__.py +0 -0
  353. rasa/dialogue_understanding/generator/multi_step/fill_slots_prompt.jinja2 +62 -0
  354. rasa/dialogue_understanding/generator/multi_step/handle_flows_prompt.jinja2 +38 -0
  355. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +827 -0
  356. rasa/dialogue_understanding/generator/nlu_command_adapter.py +218 -0
  357. rasa/dialogue_understanding/generator/single_step/__init__.py +0 -0
  358. rasa/dialogue_understanding/generator/single_step/command_prompt_template.jinja2 +57 -0
  359. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +345 -0
  360. rasa/dialogue_understanding/patterns/__init__.py +0 -0
  361. rasa/dialogue_understanding/patterns/cancel.py +111 -0
  362. rasa/dialogue_understanding/patterns/cannot_handle.py +43 -0
  363. rasa/dialogue_understanding/patterns/chitchat.py +37 -0
  364. rasa/dialogue_understanding/patterns/clarify.py +97 -0
  365. rasa/dialogue_understanding/patterns/code_change.py +41 -0
  366. rasa/dialogue_understanding/patterns/collect_information.py +90 -0
  367. rasa/dialogue_understanding/patterns/completed.py +40 -0
  368. rasa/dialogue_understanding/patterns/continue_interrupted.py +42 -0
  369. rasa/dialogue_understanding/patterns/correction.py +278 -0
  370. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +248 -0
  371. rasa/dialogue_understanding/patterns/human_handoff.py +37 -0
  372. rasa/dialogue_understanding/patterns/internal_error.py +47 -0
  373. rasa/dialogue_understanding/patterns/search.py +37 -0
  374. rasa/dialogue_understanding/patterns/skip_question.py +38 -0
  375. rasa/dialogue_understanding/processor/__init__.py +0 -0
  376. rasa/dialogue_understanding/processor/command_processor.py +687 -0
  377. rasa/dialogue_understanding/processor/command_processor_component.py +39 -0
  378. rasa/dialogue_understanding/stack/__init__.py +0 -0
  379. rasa/dialogue_understanding/stack/dialogue_stack.py +178 -0
  380. rasa/dialogue_understanding/stack/frames/__init__.py +19 -0
  381. rasa/dialogue_understanding/stack/frames/chit_chat_frame.py +27 -0
  382. rasa/dialogue_understanding/stack/frames/dialogue_stack_frame.py +137 -0
  383. rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +157 -0
  384. rasa/dialogue_understanding/stack/frames/pattern_frame.py +10 -0
  385. rasa/dialogue_understanding/stack/frames/search_frame.py +27 -0
  386. rasa/dialogue_understanding/stack/utils.py +211 -0
  387. rasa/e2e_test/__init__.py +0 -0
  388. rasa/e2e_test/constants.py +11 -0
  389. rasa/e2e_test/e2e_test_case.py +366 -0
  390. rasa/e2e_test/e2e_test_result.py +34 -0
  391. rasa/e2e_test/e2e_test_runner.py +768 -0
  392. rasa/e2e_test/e2e_test_schema.yml +85 -0
  393. rasa/engine/__init__.py +0 -0
  394. rasa/engine/caching.py +463 -0
  395. rasa/engine/constants.py +17 -0
  396. rasa/engine/exceptions.py +14 -0
  397. rasa/engine/graph.py +637 -0
  398. rasa/engine/loader.py +36 -0
  399. rasa/engine/recipes/__init__.py +0 -0
  400. rasa/engine/recipes/config_files/default_config.yml +44 -0
  401. rasa/engine/recipes/default_components.py +99 -0
  402. rasa/engine/recipes/default_recipe.py +1251 -0
  403. rasa/engine/recipes/graph_recipe.py +79 -0
  404. rasa/engine/recipes/recipe.py +93 -0
  405. rasa/engine/runner/__init__.py +0 -0
  406. rasa/engine/runner/dask.py +250 -0
  407. rasa/engine/runner/interface.py +49 -0
  408. rasa/engine/storage/__init__.py +0 -0
  409. rasa/engine/storage/local_model_storage.py +246 -0
  410. rasa/engine/storage/resource.py +110 -0
  411. rasa/engine/storage/storage.py +203 -0
  412. rasa/engine/training/__init__.py +0 -0
  413. rasa/engine/training/components.py +176 -0
  414. rasa/engine/training/fingerprinting.py +64 -0
  415. rasa/engine/training/graph_trainer.py +256 -0
  416. rasa/engine/training/hooks.py +164 -0
  417. rasa/engine/validation.py +873 -0
  418. rasa/env.py +5 -0
  419. rasa/exceptions.py +69 -0
  420. rasa/graph_components/__init__.py +0 -0
  421. rasa/graph_components/converters/__init__.py +0 -0
  422. rasa/graph_components/converters/nlu_message_converter.py +48 -0
  423. rasa/graph_components/providers/__init__.py +0 -0
  424. rasa/graph_components/providers/domain_for_core_training_provider.py +87 -0
  425. rasa/graph_components/providers/domain_provider.py +71 -0
  426. rasa/graph_components/providers/flows_provider.py +74 -0
  427. rasa/graph_components/providers/forms_provider.py +44 -0
  428. rasa/graph_components/providers/nlu_training_data_provider.py +56 -0
  429. rasa/graph_components/providers/responses_provider.py +44 -0
  430. rasa/graph_components/providers/rule_only_provider.py +49 -0
  431. rasa/graph_components/providers/story_graph_provider.py +43 -0
  432. rasa/graph_components/providers/training_tracker_provider.py +55 -0
  433. rasa/graph_components/validators/__init__.py +0 -0
  434. rasa/graph_components/validators/default_recipe_validator.py +550 -0
  435. rasa/graph_components/validators/finetuning_validator.py +302 -0
  436. rasa/hooks.py +112 -0
  437. rasa/jupyter.py +63 -0
  438. rasa/markers/__init__.py +0 -0
  439. rasa/markers/marker.py +269 -0
  440. rasa/markers/marker_base.py +828 -0
  441. rasa/markers/upload.py +74 -0
  442. rasa/markers/validate.py +21 -0
  443. rasa/model.py +118 -0
  444. rasa/model_testing.py +457 -0
  445. rasa/model_training.py +536 -0
  446. rasa/nlu/__init__.py +7 -0
  447. rasa/nlu/classifiers/__init__.py +3 -0
  448. rasa/nlu/classifiers/classifier.py +5 -0
  449. rasa/nlu/classifiers/diet_classifier.py +1881 -0
  450. rasa/nlu/classifiers/fallback_classifier.py +192 -0
  451. rasa/nlu/classifiers/keyword_intent_classifier.py +188 -0
  452. rasa/nlu/classifiers/llm_intent_classifier.py +519 -0
  453. rasa/nlu/classifiers/logistic_regression_classifier.py +253 -0
  454. rasa/nlu/classifiers/mitie_intent_classifier.py +156 -0
  455. rasa/nlu/classifiers/regex_message_handler.py +56 -0
  456. rasa/nlu/classifiers/sklearn_intent_classifier.py +330 -0
  457. rasa/nlu/constants.py +77 -0
  458. rasa/nlu/convert.py +40 -0
  459. rasa/nlu/emulators/__init__.py +0 -0
  460. rasa/nlu/emulators/dialogflow.py +55 -0
  461. rasa/nlu/emulators/emulator.py +49 -0
  462. rasa/nlu/emulators/luis.py +86 -0
  463. rasa/nlu/emulators/no_emulator.py +10 -0
  464. rasa/nlu/emulators/wit.py +56 -0
  465. rasa/nlu/extractors/__init__.py +0 -0
  466. rasa/nlu/extractors/crf_entity_extractor.py +715 -0
  467. rasa/nlu/extractors/duckling_entity_extractor.py +206 -0
  468. rasa/nlu/extractors/entity_synonyms.py +178 -0
  469. rasa/nlu/extractors/extractor.py +470 -0
  470. rasa/nlu/extractors/mitie_entity_extractor.py +293 -0
  471. rasa/nlu/extractors/regex_entity_extractor.py +220 -0
  472. rasa/nlu/extractors/spacy_entity_extractor.py +95 -0
  473. rasa/nlu/featurizers/__init__.py +0 -0
  474. rasa/nlu/featurizers/dense_featurizer/__init__.py +0 -0
  475. rasa/nlu/featurizers/dense_featurizer/convert_featurizer.py +445 -0
  476. rasa/nlu/featurizers/dense_featurizer/dense_featurizer.py +57 -0
  477. rasa/nlu/featurizers/dense_featurizer/lm_featurizer.py +768 -0
  478. rasa/nlu/featurizers/dense_featurizer/mitie_featurizer.py +170 -0
  479. rasa/nlu/featurizers/dense_featurizer/spacy_featurizer.py +132 -0
  480. rasa/nlu/featurizers/featurizer.py +89 -0
  481. rasa/nlu/featurizers/sparse_featurizer/__init__.py +0 -0
  482. rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +867 -0
  483. rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +571 -0
  484. rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +271 -0
  485. rasa/nlu/featurizers/sparse_featurizer/sparse_featurizer.py +9 -0
  486. rasa/nlu/model.py +24 -0
  487. rasa/nlu/persistor.py +282 -0
  488. rasa/nlu/run.py +27 -0
  489. rasa/nlu/selectors/__init__.py +0 -0
  490. rasa/nlu/selectors/response_selector.py +987 -0
  491. rasa/nlu/test.py +1940 -0
  492. rasa/nlu/tokenizers/__init__.py +0 -0
  493. rasa/nlu/tokenizers/jieba_tokenizer.py +148 -0
  494. rasa/nlu/tokenizers/mitie_tokenizer.py +75 -0
  495. rasa/nlu/tokenizers/spacy_tokenizer.py +72 -0
  496. rasa/nlu/tokenizers/tokenizer.py +239 -0
  497. rasa/nlu/tokenizers/whitespace_tokenizer.py +106 -0
  498. rasa/nlu/utils/__init__.py +35 -0
  499. rasa/nlu/utils/bilou_utils.py +462 -0
  500. rasa/nlu/utils/hugging_face/__init__.py +0 -0
  501. rasa/nlu/utils/hugging_face/registry.py +108 -0
  502. rasa/nlu/utils/hugging_face/transformers_pre_post_processors.py +311 -0
  503. rasa/nlu/utils/mitie_utils.py +113 -0
  504. rasa/nlu/utils/pattern_utils.py +168 -0
  505. rasa/nlu/utils/spacy_utils.py +310 -0
  506. rasa/plugin.py +90 -0
  507. rasa/server.py +1551 -0
  508. rasa/shared/__init__.py +0 -0
  509. rasa/shared/constants.py +192 -0
  510. rasa/shared/core/__init__.py +0 -0
  511. rasa/shared/core/command_payload_reader.py +109 -0
  512. rasa/shared/core/constants.py +167 -0
  513. rasa/shared/core/conversation.py +46 -0
  514. rasa/shared/core/domain.py +2107 -0
  515. rasa/shared/core/events.py +2504 -0
  516. rasa/shared/core/flows/__init__.py +7 -0
  517. rasa/shared/core/flows/flow.py +362 -0
  518. rasa/shared/core/flows/flow_step.py +146 -0
  519. rasa/shared/core/flows/flow_step_links.py +319 -0
  520. rasa/shared/core/flows/flow_step_sequence.py +70 -0
  521. rasa/shared/core/flows/flows_list.py +223 -0
  522. rasa/shared/core/flows/flows_yaml_schema.json +217 -0
  523. rasa/shared/core/flows/nlu_trigger.py +117 -0
  524. rasa/shared/core/flows/steps/__init__.py +24 -0
  525. rasa/shared/core/flows/steps/action.py +56 -0
  526. rasa/shared/core/flows/steps/call.py +64 -0
  527. rasa/shared/core/flows/steps/collect.py +112 -0
  528. rasa/shared/core/flows/steps/constants.py +5 -0
  529. rasa/shared/core/flows/steps/continuation.py +36 -0
  530. rasa/shared/core/flows/steps/end.py +22 -0
  531. rasa/shared/core/flows/steps/internal.py +44 -0
  532. rasa/shared/core/flows/steps/link.py +51 -0
  533. rasa/shared/core/flows/steps/no_operation.py +48 -0
  534. rasa/shared/core/flows/steps/set_slots.py +50 -0
  535. rasa/shared/core/flows/steps/start.py +30 -0
  536. rasa/shared/core/flows/validation.py +527 -0
  537. rasa/shared/core/flows/yaml_flows_io.py +278 -0
  538. rasa/shared/core/generator.py +908 -0
  539. rasa/shared/core/slot_mappings.py +526 -0
  540. rasa/shared/core/slots.py +649 -0
  541. rasa/shared/core/trackers.py +1177 -0
  542. rasa/shared/core/training_data/__init__.py +0 -0
  543. rasa/shared/core/training_data/loading.py +89 -0
  544. rasa/shared/core/training_data/story_reader/__init__.py +0 -0
  545. rasa/shared/core/training_data/story_reader/story_reader.py +129 -0
  546. rasa/shared/core/training_data/story_reader/story_step_builder.py +168 -0
  547. rasa/shared/core/training_data/story_reader/yaml_story_reader.py +888 -0
  548. rasa/shared/core/training_data/story_writer/__init__.py +0 -0
  549. rasa/shared/core/training_data/story_writer/story_writer.py +76 -0
  550. rasa/shared/core/training_data/story_writer/yaml_story_writer.py +444 -0
  551. rasa/shared/core/training_data/structures.py +838 -0
  552. rasa/shared/core/training_data/visualization.html +146 -0
  553. rasa/shared/core/training_data/visualization.py +603 -0
  554. rasa/shared/data.py +249 -0
  555. rasa/shared/engine/__init__.py +0 -0
  556. rasa/shared/engine/caching.py +26 -0
  557. rasa/shared/exceptions.py +163 -0
  558. rasa/shared/importers/__init__.py +0 -0
  559. rasa/shared/importers/importer.py +704 -0
  560. rasa/shared/importers/multi_project.py +203 -0
  561. rasa/shared/importers/rasa.py +99 -0
  562. rasa/shared/importers/utils.py +34 -0
  563. rasa/shared/nlu/__init__.py +0 -0
  564. rasa/shared/nlu/constants.py +47 -0
  565. rasa/shared/nlu/interpreter.py +10 -0
  566. rasa/shared/nlu/training_data/__init__.py +0 -0
  567. rasa/shared/nlu/training_data/entities_parser.py +208 -0
  568. rasa/shared/nlu/training_data/features.py +492 -0
  569. rasa/shared/nlu/training_data/formats/__init__.py +10 -0
  570. rasa/shared/nlu/training_data/formats/dialogflow.py +163 -0
  571. rasa/shared/nlu/training_data/formats/luis.py +87 -0
  572. rasa/shared/nlu/training_data/formats/rasa.py +135 -0
  573. rasa/shared/nlu/training_data/formats/rasa_yaml.py +603 -0
  574. rasa/shared/nlu/training_data/formats/readerwriter.py +244 -0
  575. rasa/shared/nlu/training_data/formats/wit.py +52 -0
  576. rasa/shared/nlu/training_data/loading.py +137 -0
  577. rasa/shared/nlu/training_data/lookup_tables_parser.py +30 -0
  578. rasa/shared/nlu/training_data/message.py +490 -0
  579. rasa/shared/nlu/training_data/schemas/__init__.py +0 -0
  580. rasa/shared/nlu/training_data/schemas/data_schema.py +85 -0
  581. rasa/shared/nlu/training_data/schemas/nlu.yml +53 -0
  582. rasa/shared/nlu/training_data/schemas/responses.yml +70 -0
  583. rasa/shared/nlu/training_data/synonyms_parser.py +42 -0
  584. rasa/shared/nlu/training_data/training_data.py +730 -0
  585. rasa/shared/nlu/training_data/util.py +223 -0
  586. rasa/shared/providers/__init__.py +0 -0
  587. rasa/shared/providers/openai/__init__.py +0 -0
  588. rasa/shared/providers/openai/clients.py +43 -0
  589. rasa/shared/providers/openai/session_handler.py +110 -0
  590. rasa/shared/utils/__init__.py +0 -0
  591. rasa/shared/utils/cli.py +72 -0
  592. rasa/shared/utils/common.py +308 -0
  593. rasa/shared/utils/constants.py +4 -0
  594. rasa/shared/utils/io.py +415 -0
  595. rasa/shared/utils/llm.py +404 -0
  596. rasa/shared/utils/pykwalify_extensions.py +27 -0
  597. rasa/shared/utils/schemas/__init__.py +0 -0
  598. rasa/shared/utils/schemas/config.yml +2 -0
  599. rasa/shared/utils/schemas/domain.yml +145 -0
  600. rasa/shared/utils/schemas/events.py +212 -0
  601. rasa/shared/utils/schemas/model_config.yml +46 -0
  602. rasa/shared/utils/schemas/stories.yml +173 -0
  603. rasa/shared/utils/yaml.py +786 -0
  604. rasa/studio/__init__.py +0 -0
  605. rasa/studio/auth.py +268 -0
  606. rasa/studio/config.py +127 -0
  607. rasa/studio/constants.py +18 -0
  608. rasa/studio/data_handler.py +359 -0
  609. rasa/studio/download.py +483 -0
  610. rasa/studio/results_logger.py +137 -0
  611. rasa/studio/train.py +135 -0
  612. rasa/studio/upload.py +433 -0
  613. rasa/telemetry.py +1737 -0
  614. rasa/tracing/__init__.py +0 -0
  615. rasa/tracing/config.py +353 -0
  616. rasa/tracing/constants.py +62 -0
  617. rasa/tracing/instrumentation/__init__.py +0 -0
  618. rasa/tracing/instrumentation/attribute_extractors.py +672 -0
  619. rasa/tracing/instrumentation/instrumentation.py +1185 -0
  620. rasa/tracing/instrumentation/intentless_policy_instrumentation.py +144 -0
  621. rasa/tracing/instrumentation/metrics.py +294 -0
  622. rasa/tracing/metric_instrument_provider.py +205 -0
  623. rasa/utils/__init__.py +0 -0
  624. rasa/utils/beta.py +83 -0
  625. rasa/utils/cli.py +28 -0
  626. rasa/utils/common.py +635 -0
  627. rasa/utils/converter.py +53 -0
  628. rasa/utils/endpoints.py +302 -0
  629. rasa/utils/io.py +260 -0
  630. rasa/utils/licensing.py +534 -0
  631. rasa/utils/log_utils.py +174 -0
  632. rasa/utils/mapper.py +210 -0
  633. rasa/utils/ml_utils.py +145 -0
  634. rasa/utils/plotting.py +362 -0
  635. rasa/utils/singleton.py +23 -0
  636. rasa/utils/tensorflow/__init__.py +0 -0
  637. rasa/utils/tensorflow/callback.py +112 -0
  638. rasa/utils/tensorflow/constants.py +116 -0
  639. rasa/utils/tensorflow/crf.py +492 -0
  640. rasa/utils/tensorflow/data_generator.py +440 -0
  641. rasa/utils/tensorflow/environment.py +161 -0
  642. rasa/utils/tensorflow/exceptions.py +5 -0
  643. rasa/utils/tensorflow/feature_array.py +366 -0
  644. rasa/utils/tensorflow/layers.py +1565 -0
  645. rasa/utils/tensorflow/layers_utils.py +113 -0
  646. rasa/utils/tensorflow/metrics.py +281 -0
  647. rasa/utils/tensorflow/model_data.py +798 -0
  648. rasa/utils/tensorflow/model_data_utils.py +499 -0
  649. rasa/utils/tensorflow/models.py +935 -0
  650. rasa/utils/tensorflow/rasa_layers.py +1094 -0
  651. rasa/utils/tensorflow/transformer.py +640 -0
  652. rasa/utils/tensorflow/types.py +6 -0
  653. rasa/utils/train_utils.py +572 -0
  654. rasa/utils/url_tools.py +53 -0
  655. rasa/utils/yaml.py +54 -0
  656. rasa/validator.py +1337 -0
  657. rasa/version.py +3 -0
  658. rasa_pro-3.9.18.dist-info/METADATA +563 -0
  659. rasa_pro-3.9.18.dist-info/NOTICE +5 -0
  660. rasa_pro-3.9.18.dist-info/RECORD +662 -0
  661. rasa_pro-3.9.18.dist-info/WHEEL +4 -0
  662. rasa_pro-3.9.18.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,768 @@
1
+ import asyncio
2
+ import copy
3
+ import datetime
4
+ import difflib
5
+ import logging
6
+ from asyncio import CancelledError
7
+ from typing import Any, Dict, List, Optional, Text, Tuple, Union
8
+ from urllib.parse import urlparse
9
+
10
+ import rasa.shared.utils.io
11
+ import requests
12
+ from rasa.core.channels import CollectingOutputChannel, UserMessage
13
+ from rasa.core.exceptions import AgentNotReady
14
+ from rasa.core.utils import AvailableEndpoints
15
+ from rasa.shared.core.events import BotUttered, SlotSet, UserUttered
16
+ from rasa.shared.core.trackers import DialogueStateTracker
17
+ from rasa.shared.exceptions import RasaException
18
+ from rasa.utils.endpoints import EndpointConfig
19
+
20
+ from rasa.e2e_test.e2e_test_case import (
21
+ ActualStepOutput,
22
+ Fixture,
23
+ Metadata,
24
+ TestCase,
25
+ TestStep,
26
+ )
27
+ from rasa.e2e_test.e2e_test_result import (
28
+ NO_RESPONSE,
29
+ NO_SLOT,
30
+ TestFailure,
31
+ TestResult,
32
+ )
33
+
34
+ from rasa.telemetry import track_e2e_test_run
35
+
36
+ logger = logging.getLogger(__name__)
37
+ TEST_TURNS_TYPE = Dict[int, Union[TestStep, ActualStepOutput]]
38
+
39
+
40
+ class E2ETestRunner:
41
+ def __init__(
42
+ self,
43
+ model_path: Optional[Text] = None,
44
+ model_server: Optional[EndpointConfig] = None,
45
+ remote_storage: Optional[Text] = None,
46
+ endpoints: Optional[AvailableEndpoints] = None,
47
+ ) -> None:
48
+ """Initializes the E2E test suite runner.
49
+
50
+ Args:
51
+ model_path: Path to the model.
52
+ model_server: Model server configuration.
53
+ remote_storage: Remote storage configuration.
54
+ endpoints: Endpoints configuration.
55
+ """
56
+ import rasa.core.agent
57
+
58
+ logger.warning(
59
+ "Started running end-to-end testing. "
60
+ "Note that this feature is not intended for use in a "
61
+ "production environment. Don't use it to process sensitive data. "
62
+ "If you do, it's at your own risk. "
63
+ "We're looking forward to your feedback."
64
+ )
65
+
66
+ if endpoints:
67
+ self._action_server_is_reachable(endpoints)
68
+
69
+ self.agent = asyncio.run(
70
+ rasa.core.agent.load_agent(
71
+ model_path=model_path,
72
+ model_server=model_server,
73
+ remote_storage=remote_storage,
74
+ endpoints=endpoints,
75
+ )
76
+ )
77
+
78
+ if not self.agent.is_ready():
79
+ raise AgentNotReady(
80
+ "Agent needs to be prepared before usage. "
81
+ "Please check that the agent was able to "
82
+ "load the trained model."
83
+ )
84
+
85
+ async def run_prediction_loop(
86
+ self,
87
+ collector: CollectingOutputChannel,
88
+ steps: List[TestStep],
89
+ sender_id: Text,
90
+ test_case_metadata: Optional[Metadata] = None,
91
+ input_metadata: Optional[List[Metadata]] = None,
92
+ ) -> TEST_TURNS_TYPE:
93
+ """Runs dialogue prediction.
94
+
95
+ Args:
96
+ collector: Output channel.
97
+ steps: List of steps to run.
98
+ sender_id: The test case name with added timestamp suffix.
99
+
100
+ Returns:
101
+ Test turns: {turn_sequence (int) : TestStep or ActualStepOutput}.
102
+ """
103
+ turns: TEST_TURNS_TYPE = {}
104
+ event_cursor = 0
105
+
106
+ if not self.agent.processor:
107
+ return turns
108
+
109
+ tracker = await self.agent.processor.fetch_tracker_with_initial_session(
110
+ sender_id, output_channel=collector
111
+ )
112
+ # turn -1 i used to contain events that happen during
113
+ # the start of the session and before the first user message
114
+ # TestStep is a placeholder just for the sake of having a turn
115
+ # to specify the actor
116
+ turns[-1], event_cursor = self.get_actual_step_output(
117
+ tracker, TestStep(actor="bot", text=None), event_cursor
118
+ )
119
+
120
+ for position, step in enumerate(steps):
121
+ if step.actor != "user":
122
+ turns[position] = step
123
+ continue
124
+ elif not step.text:
125
+ rasa.shared.utils.io.raise_warning(
126
+ f"The test case '{sender_id}' contains a `user` step in line "
127
+ f"{position + 1} without a text value. "
128
+ f"Skipping this step and proceeding to the next user step.",
129
+ UserWarning,
130
+ )
131
+ continue
132
+
133
+ metadata = test_case_metadata.metadata if test_case_metadata else {}
134
+
135
+ if input_metadata:
136
+ step_metadata = self.filter_metadata_for_input(
137
+ step.metadata_name, input_metadata
138
+ )
139
+ step_metadata_dict = step_metadata.metadata if step_metadata else {}
140
+ metadata = self.merge_metadata(
141
+ sender_id, step.text, metadata, step_metadata_dict
142
+ )
143
+
144
+ try:
145
+ await self.agent.handle_message(
146
+ UserMessage(
147
+ step.text,
148
+ collector,
149
+ sender_id,
150
+ metadata=metadata,
151
+ )
152
+ )
153
+ except CancelledError:
154
+ logger.error(
155
+ f"Message handling timed out for user message '{step.text}'.",
156
+ exc_info=True,
157
+ )
158
+ except Exception:
159
+ logger.exception(
160
+ f"An exception occurred while handling "
161
+ f"user message '{step.text}'."
162
+ )
163
+ tracker = await self.agent.tracker_store.retrieve(sender_id) # type: ignore[assignment]
164
+ turns[position], event_cursor = self.get_actual_step_output(
165
+ tracker, step, event_cursor
166
+ )
167
+ return turns
168
+
169
+ @staticmethod
170
+ def merge_metadata(
171
+ sender_id: Text,
172
+ step_text: Text,
173
+ test_case_metadata: Dict[Text, Text],
174
+ step_metadata: Dict[Text, Text],
175
+ ) -> Dict[Text, Text]:
176
+ """Merges the test case and user step metadata.
177
+
178
+ Args:
179
+ sender_id: The test case name with added timestamp suffix.
180
+ step_text: The user step text.
181
+ test_case_metadata: The test case metadata dict.
182
+ step_metadata: The user step metadata dict.
183
+
184
+ Returns:
185
+ A dictionary with the merged metadata.
186
+ """
187
+ if not test_case_metadata:
188
+ return step_metadata
189
+ if not step_metadata:
190
+ return test_case_metadata
191
+
192
+ keys_to_overwrite = []
193
+
194
+ for key in step_metadata.keys():
195
+ if key in test_case_metadata.keys():
196
+ keys_to_overwrite.append(key)
197
+
198
+ if keys_to_overwrite:
199
+ test_case_name = sender_id.rsplit("_", 1)[0]
200
+ logger.warning(
201
+ f"Metadata {keys_to_overwrite} exist in both the test case "
202
+ f"'{test_case_name}' and the user step '{step_text}'. "
203
+ "The user step metadata takes precedence and will "
204
+ "override the test case metadata."
205
+ )
206
+
207
+ merged_metadata = copy.deepcopy(test_case_metadata)
208
+ merged_metadata.update(step_metadata)
209
+
210
+ return merged_metadata
211
+
212
+ @staticmethod
213
+ def get_actual_step_output(
214
+ tracker: DialogueStateTracker,
215
+ test_step: TestStep,
216
+ event_cursor: int,
217
+ ) -> Tuple[ActualStepOutput, int]:
218
+ """Returns the events that are generated from the current step.
219
+
220
+ Args:
221
+ tracker: The tracker for the current test case.
222
+ test_step: The test step.
223
+ event_cursor: The event cursor where the previous step left off.
224
+
225
+ Returns:
226
+ The events generated from the current step and the updated event
227
+ cursor position.
228
+ """
229
+ session_events = list(tracker.events)[event_cursor:]
230
+ if session_events:
231
+ event_cursor += len(session_events)
232
+ return (
233
+ ActualStepOutput.from_test_step(
234
+ test_step,
235
+ [
236
+ event
237
+ for event in session_events
238
+ if isinstance(event, (BotUttered, UserUttered, SlotSet))
239
+ ],
240
+ ),
241
+ event_cursor,
242
+ )
243
+ else:
244
+ logger.warning(
245
+ f"No events found for '{tracker.sender_id}' after processing test "
246
+ f"step '{test_step.text}'."
247
+ )
248
+ # if there are no events, we still want to return an
249
+ # ActualStepOutput object with the test step as the
250
+ # response to be able to generate a diff
251
+ return (
252
+ ActualStepOutput.from_test_step(
253
+ test_step,
254
+ [
255
+ UserUttered(text=test_step.text),
256
+ BotUttered(text=NO_RESPONSE),
257
+ ],
258
+ ),
259
+ event_cursor,
260
+ )
261
+
262
+ @classmethod
263
+ def generate_test_result(
264
+ cls,
265
+ test_turns: TEST_TURNS_TYPE,
266
+ test_case: TestCase,
267
+ ) -> TestResult:
268
+ """Generates test result.
269
+
270
+ Args:
271
+ test_turns: the turns that happened when running the test case or test step.
272
+ test_case: the `TestCase` instance.
273
+
274
+ Returns:
275
+ Test result.
276
+ """
277
+ test_failures = cls.find_test_failures(test_turns, test_case)
278
+ difference = []
279
+ first_failure = None
280
+ if test_failures:
281
+ first_failure = test_failures[0][0]
282
+ difference = cls.human_readable_diff(test_turns, test_failures)
283
+ else:
284
+ difference = []
285
+
286
+ return TestResult(
287
+ pass_status=len(test_failures) == 0,
288
+ test_case=test_case,
289
+ difference=difference,
290
+ error_line=first_failure.error_line if first_failure else None,
291
+ )
292
+
293
+ @classmethod
294
+ def _resolve_successful_bot_utter(
295
+ cls,
296
+ expected_result: TestStep,
297
+ test_response: ActualStepOutput,
298
+ ) -> str:
299
+ """Returns the diff text for a successful bot utter test step."""
300
+ for event in test_response.bot_uttered_events:
301
+ if expected_result.matches_event(event):
302
+ # remove the event that is already matched so
303
+ # that we dont compare against it again
304
+ test_response.remove_bot_uttered_event(event)
305
+ if expected_result.text is not None:
306
+ text = f"{expected_result.actor}: {expected_result.text}"
307
+ elif expected_result.template is not None:
308
+ text = f"{expected_result.actor}: {expected_result.template}"
309
+ break
310
+
311
+ return text
312
+
313
+ @classmethod
314
+ def _resolve_successful_set_slot(
315
+ cls,
316
+ expected_result: TestStep,
317
+ test_response: ActualStepOutput,
318
+ ) -> str:
319
+ """Returns the diff text for a successful set slot test step."""
320
+ slot_name = expected_result.get_slot_name()
321
+ text = f"slot_was_set: {slot_name}"
322
+
323
+ for event in test_response.slot_set_events:
324
+ if expected_result.matches_event(event):
325
+ # remove the event that is already matched so
326
+ # that we dont compare against it again
327
+ test_response.remove_slot_set_event(event)
328
+ if event.value is not None:
329
+ text += f": {event.value} ({type(event.value).__name__})"
330
+ break
331
+
332
+ return text
333
+
334
+ @classmethod
335
+ def _resolve_successful_slot_was_not_set(cls, expected_result: TestStep) -> str:
336
+ """Returns the diff text for a successful slot was not set test step."""
337
+ slot_name = expected_result.get_slot_name()
338
+ slot_value = expected_result.get_slot_value()
339
+ text = f"slot_was_not_set: {slot_name}"
340
+ if expected_result.is_slot_instance_dict():
341
+ text += f": {slot_value}"
342
+
343
+ return text
344
+
345
+ @classmethod
346
+ def _find_first_non_matched_utterance(
347
+ cls,
348
+ test_response: ActualStepOutput,
349
+ bot_utter_test_steps: List[TestStep],
350
+ ) -> Optional[BotUttered]:
351
+ """Finds the first non matched utterance in events (if any)."""
352
+ bot_events = test_response.bot_uttered_events
353
+ matching_events = []
354
+ for event in bot_events:
355
+ for test_step in bot_utter_test_steps:
356
+ if test_step.matches_event(event):
357
+ matching_events.append(event)
358
+ break
359
+ not_matching_events = [
360
+ event for event in bot_events if event not in matching_events
361
+ ]
362
+ return not_matching_events[0] if not_matching_events else None
363
+
364
+ @classmethod
365
+ def _handle_fail_diff(
366
+ cls,
367
+ failed_step: TestStep,
368
+ test_response: ActualStepOutput,
369
+ bot_utter_test_steps: List[TestStep],
370
+ ) -> Tuple[str, str]:
371
+ """Handles generating the diff text for a failed test step."""
372
+ if failed_step.text is not None:
373
+ diff_test_text = f"{failed_step.actor}: {failed_step.text}"
374
+ diff_actual_text = NO_RESPONSE
375
+ event: Optional[Union[BotUttered, SlotSet]] = (
376
+ cls._find_first_non_matched_utterance(
377
+ test_response, bot_utter_test_steps
378
+ )
379
+ )
380
+ if event and isinstance(event, BotUttered):
381
+ test_response.remove_bot_uttered_event(event)
382
+ diff_actual_text = f"bot: {event.text}"
383
+
384
+ elif failed_step.template is not None:
385
+ diff_test_text = f"{failed_step.actor}: {failed_step.template}"
386
+ diff_actual_text = NO_RESPONSE
387
+ event = cls._find_first_non_matched_utterance(
388
+ test_response, bot_utter_test_steps
389
+ )
390
+ if event:
391
+ test_response.remove_bot_uttered_event(event)
392
+ diff_actual_text = f"bot: {event.metadata.get('utter_action')}"
393
+
394
+ elif failed_step.slot_was_set:
395
+ slot_name = failed_step.get_slot_name()
396
+
397
+ diff_test_text = f"slot_was_set: {slot_name}"
398
+ if failed_step.is_slot_instance_dict():
399
+ slot_value = failed_step.get_slot_value()
400
+ diff_test_text += f": {slot_value} ({type(slot_value).__name__})"
401
+
402
+ diff_actual_text = NO_SLOT
403
+ for event in test_response.slot_set_events:
404
+ if slot_name == event.key:
405
+ diff_actual_text = (
406
+ f"slot_was_set: {event.key}: {event.value} "
407
+ f"({type(event.value).__name__})"
408
+ )
409
+ test_response.remove_slot_set_event(event)
410
+ break
411
+
412
+ elif failed_step.slot_was_not_set:
413
+ slot_name = failed_step.get_slot_name()
414
+
415
+ diff_test_text = f"slot_was_not_set: {slot_name}"
416
+ if failed_step.is_slot_instance_dict():
417
+ slot_value = failed_step.get_slot_value()
418
+ diff_test_text += f": {slot_value}"
419
+
420
+ for event in test_response.slot_set_events:
421
+ if slot_name == event.key:
422
+ diff_actual_text = (
423
+ f"slot_was_set: {event.key}: {event.value} "
424
+ f"({type(event.value).__name__})"
425
+ )
426
+ test_response.remove_slot_set_event(event)
427
+ break
428
+
429
+ return diff_test_text, diff_actual_text
430
+
431
+ @classmethod
432
+ def _select_bot_utter_turns(
433
+ cls,
434
+ test_turns: TEST_TURNS_TYPE,
435
+ start_index: int,
436
+ ) -> List[TestStep]:
437
+ """Selects the TestSteps from the test turns that match BotUttered events."""
438
+ bot_utter_turns = []
439
+ for index in range(start_index, len(test_turns) - 1):
440
+ test_turn = test_turns[index]
441
+ if isinstance(test_turn, TestStep):
442
+ if test_turn.text is not None or test_turn.template is not None:
443
+ bot_utter_turns.append(test_turn)
444
+ elif isinstance(test_turn, ActualStepOutput):
445
+ break
446
+
447
+ return bot_utter_turns
448
+
449
+ @classmethod
450
+ def human_readable_diff(
451
+ cls,
452
+ test_turns: TEST_TURNS_TYPE,
453
+ fail_positions: List[Tuple[TestFailure, int]],
454
+ ) -> List[str]:
455
+ """Returns a human readable diff of the test case and the actual conversation.
456
+
457
+ Given an ordered list of test steps and actual conversation events, this
458
+ method will return a human readable diff of the two.
459
+ The diff uses difflib to compare the two lists and will highlight
460
+ differences between the two in a pytest style diff.
461
+
462
+ Args:
463
+ test_turns: The transcript of test cases and events.
464
+ fail_positions: The positions of the test failures.
465
+
466
+ Returns:
467
+ The human readable diff.
468
+ """
469
+ actual_transcript = []
470
+ expected_transcript = []
471
+ failure_points = {position for _, position in fail_positions}
472
+ # This will only be used when the TestCase is not started
473
+ # with a user step
474
+ latest_response: ActualStepOutput = test_turns[-1] # type: ignore[assignment]
475
+
476
+ for index in range(max(failure_points) + 1):
477
+ test_result = test_turns[index]
478
+ if index in failure_points:
479
+ diff_test_text, diff_actual_text = cls._handle_fail_diff(
480
+ test_result, # type: ignore[arg-type]
481
+ latest_response,
482
+ cls._select_bot_utter_turns(test_turns, index),
483
+ ) # test_result can only be TestStep in failure_points
484
+ actual_transcript.append(diff_actual_text)
485
+ expected_transcript.append(diff_test_text)
486
+ continue
487
+
488
+ if isinstance(test_result, TestStep):
489
+ if test_result.text is not None or test_result.template is not None:
490
+ diff_test_text = cls._resolve_successful_bot_utter(
491
+ expected_result=test_result,
492
+ test_response=latest_response,
493
+ )
494
+
495
+ if test_result.slot_was_set:
496
+ diff_test_text = cls._resolve_successful_set_slot(
497
+ expected_result=test_result,
498
+ test_response=latest_response,
499
+ )
500
+
501
+ if test_result.slot_was_not_set:
502
+ diff_test_text = cls._resolve_successful_slot_was_not_set(
503
+ expected_result=test_result,
504
+ )
505
+
506
+ elif isinstance(test_result, ActualStepOutput):
507
+ latest_response = test_result
508
+ event = test_result.get_user_uttered_event()
509
+ if event:
510
+ diff_test_text = f"{test_result.actor}: {event.text}"
511
+ else:
512
+ raise RasaException(
513
+ f"Bot did not catch user "
514
+ f"event: {test_result.actor}: {test_result.text}."
515
+ )
516
+ else:
517
+ raise ValueError(f"Unexpected test result type: {type(test_result)}")
518
+
519
+ # test passed in these cases so it's the same
520
+ actual_transcript.append(diff_test_text)
521
+ expected_transcript.append(diff_test_text)
522
+
523
+ return list(difflib.ndiff(actual_transcript, expected_transcript))
524
+
525
+ @classmethod
526
+ def find_test_failures(
527
+ cls,
528
+ test_turns: TEST_TURNS_TYPE,
529
+ test_case: TestCase,
530
+ ) -> List[Tuple[TestFailure, int]]:
531
+ """Finds the test failures in the transcript.
532
+
533
+ Args:
534
+ test_turns: The transcript of test cases and events.
535
+ test_case: The test case.
536
+
537
+ Returns:
538
+ The test failures or an empty list if there is no test failure.
539
+ """
540
+ # This will only be used when the TestCase is not started
541
+ # with a user step
542
+ latest_response: ActualStepOutput = test_turns[-1] # type: ignore[assignment]
543
+ failures = []
544
+ position = 0
545
+ match = None
546
+ for position in range(len(test_turns) - 1):
547
+ turn_value = test_turns[position]
548
+ if isinstance(turn_value, ActualStepOutput):
549
+ latest_response = turn_value
550
+ elif isinstance(turn_value, TestStep):
551
+ if turn_value.text is not None or turn_value.template is not None:
552
+ match = cls._does_match_exist(
553
+ latest_response.bot_uttered_events, turn_value
554
+ )
555
+ if turn_value.slot_was_set:
556
+ match = cls._does_match_exist(
557
+ latest_response.slot_set_events, turn_value
558
+ )
559
+ if turn_value.slot_was_not_set:
560
+ match = not cls._does_match_exist(
561
+ latest_response.slot_set_events, turn_value
562
+ )
563
+ if not match:
564
+ failures.append((TestFailure(test_case, turn_value.line), position))
565
+ else:
566
+ raise ValueError(f"Unexpected turn value type: {type(turn_value)}")
567
+
568
+ return failures
569
+
570
+ @classmethod
571
+ def _does_match_exist(
572
+ cls,
573
+ actual_events: Optional[List[Union[UserUttered, BotUttered, SlotSet]]],
574
+ expected: TestStep,
575
+ ) -> bool:
576
+ if not actual_events:
577
+ return False
578
+
579
+ match = False
580
+ for event in actual_events:
581
+ if expected.matches_event(event):
582
+ return True
583
+ return match
584
+
585
+ async def set_up_fixtures(
586
+ self,
587
+ fixtures: List[Fixture],
588
+ sender_id: Text,
589
+ ) -> None:
590
+ """Sets slots in the tracker as defined by the input fixtures.
591
+
592
+ Args:
593
+ fixtures: List of `Fixture` objects.
594
+ sender_id: The conversation id.
595
+ """
596
+ if not fixtures:
597
+ return
598
+ if not self.agent.processor:
599
+ return
600
+
601
+ tracker = await self.agent.processor.fetch_tracker_with_initial_session(
602
+ sender_id, output_channel=CollectingOutputChannel()
603
+ )
604
+
605
+ for fixture in fixtures:
606
+ for slot_name, slot_value in fixture.slots_set.items():
607
+ tracker.update(SlotSet(slot_name, slot_value))
608
+
609
+ await self.agent.tracker_store.save(tracker)
610
+
611
+ @staticmethod
612
+ def filter_fixtures_for_test_case(
613
+ test_case: TestCase, fixtures: List[Fixture]
614
+ ) -> List[Fixture]:
615
+ """Filters the input fixtures for the input test case.
616
+
617
+ Args:
618
+ test_case: The test case.
619
+ fixtures: The fixtures.
620
+
621
+ Returns:
622
+ The filtered fixtures.
623
+ """
624
+ return list(
625
+ filter(
626
+ lambda fixture: test_case.fixture_names
627
+ and fixture.name in test_case.fixture_names,
628
+ fixtures,
629
+ )
630
+ )
631
+
632
+ @staticmethod
633
+ def filter_metadata_for_input(
634
+ metadata_name: Optional[Text], test_suite_metadata: List[Metadata]
635
+ ) -> Optional[Metadata]:
636
+ """Filters the test suite metadata for a metadata name.
637
+
638
+ Args:
639
+ metadata_name: The test case or user step metadata name.
640
+ test_suite_metadata: The top level list of all metadata definitions.
641
+
642
+ Returns:
643
+ The filtered metadata.
644
+ """
645
+ if not metadata_name:
646
+ return None
647
+
648
+ filtered_metadata = list(
649
+ filter(
650
+ lambda metadata: metadata_name and metadata.name == metadata_name,
651
+ test_suite_metadata,
652
+ )
653
+ )
654
+
655
+ if not filtered_metadata:
656
+ logger.warning(
657
+ f"Metadata '{metadata_name}' is not defined in the input metadata."
658
+ )
659
+ return None
660
+
661
+ return filtered_metadata[0]
662
+
663
+ async def run_tests(
664
+ self,
665
+ input_test_cases: List[TestCase],
666
+ input_fixtures: List[Fixture],
667
+ fail_fast: bool = False,
668
+ **kwargs: Any,
669
+ ) -> List["TestResult"]:
670
+ """Runs the test cases.
671
+
672
+ Args:
673
+ input_test_cases: Input test cases.
674
+ input_fixtures: Input fixtures.
675
+ fail_fast: Whether to fail fast.
676
+ **kwargs: Additional arguments which are passed here.
677
+
678
+ Returns:
679
+ List of test results.
680
+ """
681
+ results = []
682
+ input_metadata = kwargs.get("input_metadata", None)
683
+
684
+ # telemetry call for tracking test runs
685
+ track_e2e_test_run(input_test_cases, input_fixtures, input_metadata)
686
+
687
+ for test_case in input_test_cases:
688
+ collector = CollectingOutputChannel()
689
+
690
+ # add timestamp suffix to ensure sender_id is unique
691
+ sender_id = f"{test_case.name}_{datetime.datetime.now()}"
692
+
693
+ if input_fixtures:
694
+ test_fixtures = self.filter_fixtures_for_test_case(
695
+ test_case, input_fixtures
696
+ )
697
+ await self.set_up_fixtures(test_fixtures, sender_id)
698
+
699
+ test_case_metadata = None
700
+ if input_metadata:
701
+ test_case_metadata = self.filter_metadata_for_input(
702
+ test_case.metadata_name, input_metadata
703
+ )
704
+
705
+ tracker = await self.run_prediction_loop(
706
+ collector,
707
+ test_case.steps,
708
+ sender_id,
709
+ test_case_metadata,
710
+ input_metadata,
711
+ )
712
+
713
+ test_result = self.generate_test_result(tracker, test_case)
714
+ results.append(test_result)
715
+
716
+ if fail_fast and not test_result.pass_status:
717
+ break
718
+
719
+ return results
720
+
721
+ @staticmethod
722
+ def _action_server_is_reachable(endpoints: AvailableEndpoints) -> None:
723
+ """Calls the action server health endpoint."""
724
+ if not endpoints.action:
725
+ logger.debug(
726
+ "No action endpoint configured. Skipping the health check of the "
727
+ "action server."
728
+ )
729
+ return
730
+
731
+ if not endpoints.action.url:
732
+ logger.debug(
733
+ "Action endpoint URL is not defined in the endpoint configuration."
734
+ )
735
+ return
736
+
737
+ logger.debug(
738
+ "Detected action URL in the endpoint configuration.\n"
739
+ f"Action Server URL: {endpoints.action.url}\n"
740
+ "Sending a health request to the action endpoint."
741
+ )
742
+ url = urlparse(endpoints.action.url)
743
+ # replace /<path> with just /health
744
+ url = url._replace(path="/health").geturl() # type: ignore[assignment]
745
+ try:
746
+ response = requests.get(url, timeout=3)
747
+ except requests.exceptions.ConnectionError as error:
748
+ raise RasaException(
749
+ "Action endpoint could not be reached. "
750
+ "Actions server URL is defined in your endpoint configuration as "
751
+ f"'{endpoints.action.url}'.\n"
752
+ "Please make sure your action server is running and properly "
753
+ "configured. Since running e2e tests without a action server may "
754
+ f"lead to unpredictable results.\n{error}"
755
+ )
756
+
757
+ if response.status_code != 200:
758
+ raise RasaException(
759
+ "Action endpoint is responding, but health status responded with "
760
+ f"code {response.status_code}. Make sure your action server"
761
+ " is properly configured and that the '/health' endpoint is available."
762
+ )
763
+
764
+ logger.debug(
765
+ "Action endpoint has responded successfully.\n"
766
+ f"Response message: {response.text}\n"
767
+ f"Response status code: {response.status_code}."
768
+ )