rasa-pro 3.10.16__py3-none-any.whl → 3.11.0__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 (240) hide show
  1. rasa/__main__.py +31 -15
  2. rasa/api.py +12 -2
  3. rasa/cli/arguments/default_arguments.py +24 -4
  4. rasa/cli/arguments/run.py +15 -0
  5. rasa/cli/arguments/shell.py +5 -1
  6. rasa/cli/arguments/train.py +17 -9
  7. rasa/cli/evaluate.py +7 -7
  8. rasa/cli/inspect.py +19 -7
  9. rasa/cli/interactive.py +1 -0
  10. rasa/cli/llm_fine_tuning.py +11 -14
  11. rasa/cli/project_templates/calm/config.yml +5 -7
  12. rasa/cli/project_templates/calm/endpoints.yml +15 -2
  13. rasa/cli/project_templates/tutorial/config.yml +8 -5
  14. rasa/cli/project_templates/tutorial/data/flows.yml +1 -1
  15. rasa/cli/project_templates/tutorial/data/patterns.yml +5 -0
  16. rasa/cli/project_templates/tutorial/domain.yml +14 -0
  17. rasa/cli/project_templates/tutorial/endpoints.yml +5 -0
  18. rasa/cli/run.py +7 -0
  19. rasa/cli/scaffold.py +4 -2
  20. rasa/cli/studio/upload.py +0 -15
  21. rasa/cli/train.py +14 -53
  22. rasa/cli/utils.py +14 -11
  23. rasa/cli/x.py +7 -7
  24. rasa/constants.py +3 -1
  25. rasa/core/actions/action.py +77 -33
  26. rasa/core/actions/action_hangup.py +29 -0
  27. rasa/core/actions/action_repeat_bot_messages.py +89 -0
  28. rasa/core/actions/e2e_stub_custom_action_executor.py +5 -1
  29. rasa/core/actions/http_custom_action_executor.py +4 -0
  30. rasa/core/agent.py +2 -2
  31. rasa/core/brokers/kafka.py +3 -1
  32. rasa/core/brokers/pika.py +3 -1
  33. rasa/core/channels/__init__.py +10 -6
  34. rasa/core/channels/channel.py +41 -4
  35. rasa/core/channels/development_inspector.py +150 -46
  36. rasa/core/channels/inspector/README.md +1 -1
  37. rasa/core/channels/inspector/dist/assets/{arc-b6e548fe.js → arc-bc141fb2.js} +1 -1
  38. rasa/core/channels/inspector/dist/assets/{c4Diagram-d0fbc5ce-fa03ac9e.js → c4Diagram-d0fbc5ce-be2db283.js} +1 -1
  39. rasa/core/channels/inspector/dist/assets/{classDiagram-936ed81e-ee67392a.js → classDiagram-936ed81e-55366915.js} +1 -1
  40. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-c3cb15f1-9b283fae.js → classDiagram-v2-c3cb15f1-bb529518.js} +1 -1
  41. rasa/core/channels/inspector/dist/assets/{createText-62fc7601-8b6fcc2a.js → createText-62fc7601-b0ec81d6.js} +1 -1
  42. rasa/core/channels/inspector/dist/assets/{edges-f2ad444c-22e77f4f.js → edges-f2ad444c-6166330c.js} +1 -1
  43. rasa/core/channels/inspector/dist/assets/{erDiagram-9d236eb7-60ffc87f.js → erDiagram-9d236eb7-5ccc6a8e.js} +1 -1
  44. rasa/core/channels/inspector/dist/assets/{flowDb-1972c806-9dd802e4.js → flowDb-1972c806-fca3bfe4.js} +1 -1
  45. rasa/core/channels/inspector/dist/assets/{flowDiagram-7ea5b25a-5fa1912f.js → flowDiagram-7ea5b25a-4739080f.js} +1 -1
  46. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-736177bf.js +1 -0
  47. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-abe16c3d-622a1fd2.js → flowchart-elk-definition-abe16c3d-7c1b0e0f.js} +1 -1
  48. rasa/core/channels/inspector/dist/assets/{ganttDiagram-9b5ea136-e285a63a.js → ganttDiagram-9b5ea136-772fd050.js} +1 -1
  49. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-99d0ae7c-f237bdca.js → gitGraphDiagram-99d0ae7c-8eae1dc9.js} +1 -1
  50. rasa/core/channels/inspector/dist/assets/{index-2c4b9a3b-4b03d70e.js → index-2c4b9a3b-f55afcdf.js} +1 -1
  51. rasa/core/channels/inspector/dist/assets/index-e7cef9de.js +1317 -0
  52. rasa/core/channels/inspector/dist/assets/{infoDiagram-736b4530-72a0fa5f.js → infoDiagram-736b4530-124d4a14.js} +1 -1
  53. rasa/core/channels/inspector/dist/assets/{journeyDiagram-df861f2b-82218c41.js → journeyDiagram-df861f2b-7c4fae44.js} +1 -1
  54. rasa/core/channels/inspector/dist/assets/{layout-78cff630.js → layout-b9885fb6.js} +1 -1
  55. rasa/core/channels/inspector/dist/assets/{line-5038b469.js → line-7c59abb6.js} +1 -1
  56. rasa/core/channels/inspector/dist/assets/{linear-c4fc4098.js → linear-4776f780.js} +1 -1
  57. rasa/core/channels/inspector/dist/assets/{mindmap-definition-beec6740-c33c8ea6.js → mindmap-definition-beec6740-2332c46c.js} +1 -1
  58. rasa/core/channels/inspector/dist/assets/{pieDiagram-dbbf0591-a8d03059.js → pieDiagram-dbbf0591-8fb39303.js} +1 -1
  59. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-4d7f4fd6-6a0e56b2.js → quadrantDiagram-4d7f4fd6-3c7180a2.js} +1 -1
  60. rasa/core/channels/inspector/dist/assets/{requirementDiagram-6fc4c22a-2dc7c7bd.js → requirementDiagram-6fc4c22a-e910bcb8.js} +1 -1
  61. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-8f13d901-2360fe39.js → sankeyDiagram-8f13d901-ead16c89.js} +1 -1
  62. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-b655622a-41b9f9ad.js → sequenceDiagram-b655622a-29a02a19.js} +1 -1
  63. rasa/core/channels/inspector/dist/assets/{stateDiagram-59f0c015-0aad326f.js → stateDiagram-59f0c015-042b3137.js} +1 -1
  64. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-2b26beab-9847d984.js → stateDiagram-v2-2b26beab-2178c0f3.js} +1 -1
  65. rasa/core/channels/inspector/dist/assets/{styles-080da4f6-564d890e.js → styles-080da4f6-23ffa4fc.js} +1 -1
  66. rasa/core/channels/inspector/dist/assets/{styles-3dcbcfbf-38957613.js → styles-3dcbcfbf-94f59763.js} +1 -1
  67. rasa/core/channels/inspector/dist/assets/{styles-9c745c82-f0fc6921.js → styles-9c745c82-78a6bebc.js} +1 -1
  68. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-4835440b-ef3c5a77.js → svgDrawCommon-4835440b-eae2a6f6.js} +1 -1
  69. rasa/core/channels/inspector/dist/assets/{timeline-definition-5b62e21b-bf3e91c1.js → timeline-definition-5b62e21b-5c968d92.js} +1 -1
  70. rasa/core/channels/inspector/dist/assets/{xychartDiagram-2b33534f-4d4026c0.js → xychartDiagram-2b33534f-fd3db0d5.js} +1 -1
  71. rasa/core/channels/inspector/dist/index.html +18 -17
  72. rasa/core/channels/inspector/index.html +17 -16
  73. rasa/core/channels/inspector/package.json +5 -1
  74. rasa/core/channels/inspector/src/App.tsx +118 -68
  75. rasa/core/channels/inspector/src/components/Chat.tsx +95 -0
  76. rasa/core/channels/inspector/src/components/DiagramFlow.tsx +11 -10
  77. rasa/core/channels/inspector/src/components/DialogueStack.tsx +10 -25
  78. rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +6 -3
  79. rasa/core/channels/inspector/src/helpers/audiostream.ts +165 -0
  80. rasa/core/channels/inspector/src/helpers/formatters.test.ts +10 -0
  81. rasa/core/channels/inspector/src/helpers/formatters.ts +107 -41
  82. rasa/core/channels/inspector/src/helpers/utils.ts +92 -7
  83. rasa/core/channels/inspector/src/types.ts +21 -1
  84. rasa/core/channels/inspector/yarn.lock +94 -1
  85. rasa/core/channels/rest.py +51 -46
  86. rasa/core/channels/socketio.py +28 -1
  87. rasa/core/channels/telegram.py +1 -1
  88. rasa/core/channels/twilio.py +1 -1
  89. rasa/core/channels/{audiocodes.py → voice_ready/audiocodes.py} +122 -69
  90. rasa/core/channels/{voice_aware → voice_ready}/jambonz.py +26 -8
  91. rasa/core/channels/{voice_aware → voice_ready}/jambonz_protocol.py +57 -5
  92. rasa/core/channels/{twilio_voice.py → voice_ready/twilio_voice.py} +64 -28
  93. rasa/core/channels/voice_ready/utils.py +37 -0
  94. rasa/core/channels/voice_stream/asr/__init__.py +0 -0
  95. rasa/core/channels/voice_stream/asr/asr_engine.py +89 -0
  96. rasa/core/channels/voice_stream/asr/asr_event.py +18 -0
  97. rasa/core/channels/voice_stream/asr/azure.py +129 -0
  98. rasa/core/channels/voice_stream/asr/deepgram.py +90 -0
  99. rasa/core/channels/voice_stream/audio_bytes.py +8 -0
  100. rasa/core/channels/voice_stream/browser_audio.py +107 -0
  101. rasa/core/channels/voice_stream/call_state.py +23 -0
  102. rasa/core/channels/voice_stream/tts/__init__.py +0 -0
  103. rasa/core/channels/voice_stream/tts/azure.py +106 -0
  104. rasa/core/channels/voice_stream/tts/cartesia.py +118 -0
  105. rasa/core/channels/voice_stream/tts/tts_cache.py +27 -0
  106. rasa/core/channels/voice_stream/tts/tts_engine.py +58 -0
  107. rasa/core/channels/voice_stream/twilio_media_streams.py +173 -0
  108. rasa/core/channels/voice_stream/util.py +57 -0
  109. rasa/core/channels/voice_stream/voice_channel.py +427 -0
  110. rasa/core/information_retrieval/qdrant.py +1 -0
  111. rasa/core/nlg/contextual_response_rephraser.py +45 -17
  112. rasa/{nlu → core}/persistor.py +203 -68
  113. rasa/core/policies/enterprise_search_policy.py +119 -63
  114. rasa/core/policies/flows/flow_executor.py +15 -22
  115. rasa/core/policies/intentless_policy.py +83 -28
  116. rasa/core/processor.py +25 -0
  117. rasa/core/run.py +12 -2
  118. rasa/core/secrets_manager/constants.py +4 -0
  119. rasa/core/secrets_manager/factory.py +8 -0
  120. rasa/core/secrets_manager/vault.py +11 -1
  121. rasa/core/training/interactive.py +33 -34
  122. rasa/core/utils.py +47 -21
  123. rasa/dialogue_understanding/coexistence/llm_based_router.py +41 -14
  124. rasa/dialogue_understanding/commands/__init__.py +6 -0
  125. rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +60 -0
  126. rasa/dialogue_understanding/commands/session_end_command.py +61 -0
  127. rasa/dialogue_understanding/commands/user_silence_command.py +59 -0
  128. rasa/dialogue_understanding/commands/utils.py +5 -0
  129. rasa/dialogue_understanding/generator/constants.py +2 -0
  130. rasa/dialogue_understanding/generator/flow_retrieval.py +47 -9
  131. rasa/dialogue_understanding/generator/llm_based_command_generator.py +38 -15
  132. rasa/dialogue_understanding/generator/llm_command_generator.py +1 -1
  133. rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +35 -13
  134. rasa/dialogue_understanding/generator/single_step/command_prompt_template.jinja2 +3 -0
  135. rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +60 -13
  136. rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +53 -0
  137. rasa/dialogue_understanding/patterns/repeat.py +37 -0
  138. rasa/dialogue_understanding/patterns/user_silence.py +37 -0
  139. rasa/dialogue_understanding/processor/command_processor.py +21 -1
  140. rasa/e2e_test/aggregate_test_stats_calculator.py +1 -11
  141. rasa/e2e_test/assertions.py +136 -61
  142. rasa/e2e_test/assertions_schema.yml +23 -0
  143. rasa/e2e_test/e2e_test_case.py +85 -6
  144. rasa/e2e_test/e2e_test_runner.py +2 -3
  145. rasa/e2e_test/utils/e2e_yaml_utils.py +1 -1
  146. rasa/engine/graph.py +3 -10
  147. rasa/engine/loader.py +12 -0
  148. rasa/engine/recipes/config_files/default_config.yml +0 -3
  149. rasa/engine/recipes/default_recipe.py +0 -1
  150. rasa/engine/recipes/graph_recipe.py +0 -1
  151. rasa/engine/runner/dask.py +2 -2
  152. rasa/engine/storage/local_model_storage.py +12 -42
  153. rasa/engine/storage/storage.py +1 -5
  154. rasa/engine/validation.py +527 -74
  155. rasa/model_manager/__init__.py +0 -0
  156. rasa/model_manager/config.py +40 -0
  157. rasa/model_manager/model_api.py +559 -0
  158. rasa/model_manager/runner_service.py +286 -0
  159. rasa/model_manager/socket_bridge.py +146 -0
  160. rasa/model_manager/studio_jwt_auth.py +86 -0
  161. rasa/model_manager/trainer_service.py +325 -0
  162. rasa/model_manager/utils.py +87 -0
  163. rasa/model_manager/warm_rasa_process.py +187 -0
  164. rasa/model_service.py +112 -0
  165. rasa/model_training.py +42 -23
  166. rasa/nlu/tokenizers/whitespace_tokenizer.py +3 -14
  167. rasa/server.py +4 -2
  168. rasa/shared/constants.py +60 -8
  169. rasa/shared/core/constants.py +13 -0
  170. rasa/shared/core/domain.py +107 -50
  171. rasa/shared/core/events.py +29 -0
  172. rasa/shared/core/flows/flow.py +5 -0
  173. rasa/shared/core/flows/flows_list.py +19 -6
  174. rasa/shared/core/flows/flows_yaml_schema.json +10 -0
  175. rasa/shared/core/flows/utils.py +39 -0
  176. rasa/shared/core/flows/validation.py +121 -0
  177. rasa/shared/core/flows/yaml_flows_io.py +15 -27
  178. rasa/shared/core/slots.py +5 -0
  179. rasa/shared/importers/importer.py +59 -41
  180. rasa/shared/importers/multi_project.py +23 -11
  181. rasa/shared/importers/rasa.py +12 -3
  182. rasa/shared/importers/remote_importer.py +196 -0
  183. rasa/shared/importers/utils.py +3 -1
  184. rasa/shared/nlu/training_data/formats/rasa_yaml.py +18 -3
  185. rasa/shared/nlu/training_data/training_data.py +18 -19
  186. rasa/shared/providers/_configs/litellm_router_client_config.py +220 -0
  187. rasa/shared/providers/_configs/model_group_config.py +167 -0
  188. rasa/shared/providers/_configs/openai_client_config.py +1 -1
  189. rasa/shared/providers/_configs/rasa_llm_client_config.py +73 -0
  190. rasa/shared/providers/_configs/self_hosted_llm_client_config.py +1 -0
  191. rasa/shared/providers/_configs/utils.py +16 -0
  192. rasa/shared/providers/_utils.py +79 -0
  193. rasa/shared/providers/embedding/_base_litellm_embedding_client.py +13 -29
  194. rasa/shared/providers/embedding/azure_openai_embedding_client.py +54 -21
  195. rasa/shared/providers/embedding/default_litellm_embedding_client.py +24 -0
  196. rasa/shared/providers/embedding/litellm_router_embedding_client.py +135 -0
  197. rasa/shared/providers/llm/_base_litellm_client.py +34 -22
  198. rasa/shared/providers/llm/azure_openai_llm_client.py +50 -29
  199. rasa/shared/providers/llm/default_litellm_llm_client.py +24 -0
  200. rasa/shared/providers/llm/litellm_router_llm_client.py +182 -0
  201. rasa/shared/providers/llm/rasa_llm_client.py +112 -0
  202. rasa/shared/providers/llm/self_hosted_llm_client.py +5 -29
  203. rasa/shared/providers/mappings.py +19 -0
  204. rasa/shared/providers/router/__init__.py +0 -0
  205. rasa/shared/providers/router/_base_litellm_router_client.py +183 -0
  206. rasa/shared/providers/router/router_client.py +73 -0
  207. rasa/shared/utils/common.py +40 -24
  208. rasa/shared/utils/health_check/__init__.py +0 -0
  209. rasa/shared/utils/health_check/embeddings_health_check_mixin.py +31 -0
  210. rasa/shared/utils/health_check/health_check.py +258 -0
  211. rasa/shared/utils/health_check/llm_health_check_mixin.py +31 -0
  212. rasa/shared/utils/io.py +27 -6
  213. rasa/shared/utils/llm.py +354 -44
  214. rasa/shared/utils/schemas/events.py +2 -0
  215. rasa/shared/utils/schemas/model_config.yml +0 -10
  216. rasa/shared/utils/yaml.py +181 -38
  217. rasa/studio/data_handler.py +3 -1
  218. rasa/studio/upload.py +160 -74
  219. rasa/telemetry.py +94 -17
  220. rasa/tracing/config.py +3 -1
  221. rasa/tracing/instrumentation/attribute_extractors.py +95 -18
  222. rasa/tracing/instrumentation/instrumentation.py +121 -0
  223. rasa/utils/common.py +5 -0
  224. rasa/utils/endpoints.py +27 -1
  225. rasa/utils/io.py +8 -16
  226. rasa/utils/log_utils.py +9 -2
  227. rasa/utils/sanic_error_handler.py +32 -0
  228. rasa/validator.py +110 -16
  229. rasa/version.py +1 -1
  230. {rasa_pro-3.10.16.dist-info → rasa_pro-3.11.0.dist-info}/METADATA +16 -14
  231. {rasa_pro-3.10.16.dist-info → rasa_pro-3.11.0.dist-info}/RECORD +236 -185
  232. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-1844e5a5.js +0 -1
  233. rasa/core/channels/inspector/dist/assets/index-a5d3e69d.js +0 -1040
  234. rasa/core/channels/voice_aware/utils.py +0 -20
  235. rasa/llm_fine_tuning/notebooks/unsloth_finetuning.ipynb +0 -407
  236. /rasa/core/channels/{voice_aware → voice_ready}/__init__.py +0 -0
  237. /rasa/core/channels/{voice_native → voice_stream}/__init__.py +0 -0
  238. {rasa_pro-3.10.16.dist-info → rasa_pro-3.11.0.dist-info}/NOTICE +0 -0
  239. {rasa_pro-3.10.16.dist-info → rasa_pro-3.11.0.dist-info}/WHEEL +0 -0
  240. {rasa_pro-3.10.16.dist-info → rasa_pro-3.11.0.dist-info}/entry_points.txt +0 -0
rasa/cli/train.py CHANGED
@@ -1,33 +1,25 @@
1
1
  import argparse
2
2
  import asyncio
3
- import os
4
3
  import sys
5
4
  from pathlib import Path
6
5
  from typing import Dict, List, Optional, Text, Union
7
6
 
8
7
  import structlog
9
- from tarsafe import TarSafe
10
8
 
11
9
  import rasa.cli.arguments.train as train_arguments
12
10
  import rasa.cli.utils
13
11
  import rasa.core.utils
14
12
  import rasa.utils.common
15
- from rasa.api import train as train_all
16
13
  from rasa.cli import SubParsersAction
17
- from rasa.core import ContextualResponseRephraser
18
14
  from rasa.core.nlg.generator import NaturalLanguageGenerator
19
15
  from rasa.core.train import do_compare_training
20
- from rasa.engine.validation import validate_api_type_config_key_usage
21
- from rasa.nlu.persistor import get_persistor
22
16
  from rasa.shared.constants import (
23
17
  CONFIG_MANDATORY_KEYS,
24
18
  CONFIG_MANDATORY_KEYS_CORE,
25
19
  CONFIG_MANDATORY_KEYS_NLU,
26
20
  DEFAULT_DATA_PATH,
27
21
  DEFAULT_DOMAIN_PATHS,
28
- LLM_CONFIG_KEY,
29
22
  )
30
- from rasa.shared.exceptions import RasaException
31
23
  from rasa.shared.importers.importer import TrainingDataImporter
32
24
 
33
25
  structlogger = structlog.getLogger(__name__)
@@ -44,7 +36,7 @@ def add_subparser(
44
36
  """
45
37
  train_parser = subparsers.add_parser(
46
38
  "train",
47
- help="Trains a Rasa model using your CALM flows, NLU data and stories.",
39
+ help="Trains a Rasa model using your NLU data and stories.",
48
40
  parents=parents,
49
41
  formatter_class=argparse.ArgumentDefaultsHelpFormatter,
50
42
  )
@@ -78,12 +70,6 @@ def add_subparser(
78
70
  def _check_nlg_endpoint_validity(endpoint: Union[Path, str]) -> None:
79
71
  try:
80
72
  endpoints = rasa.core.utils.read_endpoints_from_path(endpoint)
81
- if endpoints.nlg is not None:
82
- validate_api_type_config_key_usage(
83
- endpoints.nlg.kwargs,
84
- LLM_CONFIG_KEY,
85
- ContextualResponseRephraser.__name__,
86
- )
87
73
  NaturalLanguageGenerator.create(endpoints.nlg)
88
74
  except Exception as e:
89
75
  structlogger.error(
@@ -97,37 +83,6 @@ def _check_nlg_endpoint_validity(endpoint: Union[Path, str]) -> None:
97
83
  sys.exit(1)
98
84
 
99
85
 
100
- def retrieve_and_unpack_bot_config_from_remote_storage(
101
- args: argparse.Namespace,
102
- ) -> None:
103
- """Retrieve and unpack bot config from remote storage.
104
-
105
- Bot config is retrieved from remote storage and unpacked
106
- to the current working directory.
107
- """
108
- persistor = get_persistor(args.remote_storage)
109
- if persistor is None:
110
- raise RasaException(
111
- f"Could not find a persistor for "
112
- f"the storage type '{args.remote_storage}'."
113
- )
114
-
115
- current_working_directory = os.getcwd()
116
-
117
- persistor.retrieve(args.remote_bot_config_path, current_working_directory)
118
-
119
- remote_bot_config_tar_file_name = os.path.basename(args.remote_bot_config_path)
120
-
121
- with TarSafe.open(remote_bot_config_tar_file_name, "r:gz") as tar:
122
- tar.extractall(path=current_working_directory)
123
-
124
- structlogger.debug(
125
- "rasa.train.retrieve_and_unpack_bot_config.remove_downloaded_archive",
126
- training_data_path=args.remote_bot_config_path,
127
- )
128
- os.remove(Path(current_working_directory).joinpath(remote_bot_config_tar_file_name))
129
-
130
-
131
86
  def run_training(args: argparse.Namespace, can_exit: bool = False) -> Optional[Text]:
132
87
  """Trains a model.
133
88
 
@@ -139,9 +94,7 @@ def run_training(args: argparse.Namespace, can_exit: bool = False) -> Optional[T
139
94
  Returns:
140
95
  Path to a trained model or `None` if training was not successful.
141
96
  """
142
- # retrieve and unpack bot_config from remote storage
143
- if hasattr(args, "remote_bot_config_path") and args.remote_bot_config_path:
144
- retrieve_and_unpack_bot_config_from_remote_storage(args)
97
+ from rasa.api import train as train_all
145
98
 
146
99
  domain = rasa.cli.utils.get_validated_path(
147
100
  args.domain, "domain", DEFAULT_DOMAIN_PATHS, none_is_valid=True
@@ -157,16 +110,20 @@ def run_training(args: argparse.Namespace, can_exit: bool = False) -> Optional[T
157
110
  for f in args.data
158
111
  ]
159
112
 
113
+ training_data_importer = TrainingDataImporter.load_from_config(
114
+ domain_path=domain, training_data_paths=args.data, config_path=config
115
+ )
116
+
160
117
  if not args.skip_validation:
161
118
  structlogger.info(
162
119
  "cli.train.run_training",
163
120
  event_info="Started validating domain and training data...",
164
121
  )
165
- importer = TrainingDataImporter.load_from_config(
166
- domain_path=domain, training_data_paths=args.data, config_path=config
167
- )
122
+
168
123
  rasa.cli.utils.validate_files(
169
- args.fail_on_validation_warnings, args.validation_max_history, importer
124
+ args.fail_on_validation_warnings,
125
+ args.validation_max_history,
126
+ training_data_importer,
170
127
  )
171
128
 
172
129
  training_result = train_all(
@@ -185,6 +142,8 @@ def run_training(args: argparse.Namespace, can_exit: bool = False) -> Optional[T
185
142
  model_to_finetune=_model_for_finetuning(args),
186
143
  finetuning_epoch_fraction=args.epoch_fraction,
187
144
  remote_storage=args.remote_storage,
145
+ file_importer=training_data_importer,
146
+ keep_local_model_copy=args.keep_local_model_copy,
188
147
  )
189
148
  if training_result.code != 0 and can_exit:
190
149
  sys.exit(training_result.code)
@@ -243,6 +202,7 @@ def run_core_training(args: argparse.Namespace) -> Optional[Text]:
243
202
  additional_arguments=additional_arguments,
244
203
  model_to_finetune=_model_for_finetuning(args),
245
204
  finetuning_epoch_fraction=args.epoch_fraction,
205
+ keep_local_model_copy=args.keep_local_model_copy,
246
206
  )
247
207
  )
248
208
  else:
@@ -284,6 +244,7 @@ def run_nlu_training(args: argparse.Namespace) -> Optional[Text]:
284
244
  domain=args.domain,
285
245
  model_to_finetune=_model_for_finetuning(args),
286
246
  finetuning_epoch_fraction=args.epoch_fraction,
247
+ keep_local_model_copy=args.keep_local_model_copy,
287
248
  )
288
249
  )
289
250
 
rasa/cli/utils.py CHANGED
@@ -1,32 +1,30 @@
1
+ import json
1
2
  import argparse
3
+ import structlog
2
4
  import importlib
3
- import json
4
5
  import os
5
6
  import sys
6
7
  import time
7
8
  from pathlib import Path
8
9
  from types import FrameType
9
- from typing import TYPE_CHECKING, Any, Dict, List, Optional, Text, Union, overload
10
-
10
+ from typing import Any, Dict, List, Optional, TYPE_CHECKING, Text, Union, overload
11
11
  import randomname
12
- import structlog
13
12
 
14
13
  import rasa.shared.utils.cli
15
14
  import rasa.shared.utils.io
16
- from rasa import telemetry
15
+ from rasa.shared.importers.importer import TrainingDataImporter
17
16
  from rasa.shared.constants import (
18
17
  ASSISTANT_ID_DEFAULT_VALUE,
19
18
  ASSISTANT_ID_KEY,
20
19
  DEFAULT_CONFIG_PATH,
21
20
  )
22
- from rasa.shared.importers.importer import TrainingDataImporter
21
+ from rasa import telemetry
23
22
  from rasa.shared.utils.yaml import read_config_file
24
23
  from rasa.utils.io import write_yaml
25
24
 
26
25
  if TYPE_CHECKING:
27
26
  from questionary import Question
28
27
  from typing_extensions import Literal
29
-
30
28
  from rasa.validator import Validator
31
29
 
32
30
  structlogger = structlog.get_logger()
@@ -307,7 +305,7 @@ def _validate_domain(validator: "Validator") -> bool:
307
305
  valid_forms_in_stories_rules = validator.verify_forms_in_stories_rules()
308
306
  valid_form_slots = validator.verify_form_slots()
309
307
  valid_slot_mappings = validator.verify_slot_mappings()
310
- valid_responses = validator.check_for_no_empty_paranthesis_in_responses()
308
+ valid_responses = validator.check_for_no_empty_parenthesis_in_responses()
311
309
  valid_buttons = validator.validate_button_payloads()
312
310
  return (
313
311
  valid_domain_validity
@@ -472,10 +470,15 @@ def get_e2e_results_file_name(
472
470
  ) -> str:
473
471
  """Returns the name of the e2e results file."""
474
472
  if results_output_path.is_dir():
475
- file_name = str(results_output_path) + f"/e2e_results_{result_type}.yml"
473
+ file_name = results_output_path / f"e2e_results_{result_type}.yml"
476
474
  else:
477
475
  parent = results_output_path.parent
478
476
  stem = results_output_path.stem
479
- file_name = str(parent) + f"/{stem}_{result_type}.yml"
477
+ file_name = parent / f"{stem}_{result_type}.yml"
478
+
479
+ return str(file_name)
480
+
480
481
 
481
- return file_name
482
+ def is_skip_validation_flag_set() -> bool:
483
+ """Checks if the skip validation flag is set."""
484
+ return "--skip-validation" in sys.argv
rasa/cli/x.py CHANGED
@@ -1,25 +1,25 @@
1
1
  import argparse
2
2
  import asyncio
3
3
  import logging
4
- from pathlib import Path
5
4
  import signal
5
+ from pathlib import Path
6
6
  from typing import Iterable, List, Optional, Text, Tuple, Union
7
7
 
8
8
  import aiohttp
9
9
  import ruamel.yaml as yaml
10
10
 
11
+ import rasa.cli.utils
12
+ import rasa.shared.utils.cli
13
+ import rasa.shared.utils.io
14
+ import rasa.utils.common
15
+ import rasa.utils.io
11
16
  from rasa.cli import SubParsersAction
12
17
  from rasa.cli.arguments import x as arguments
13
- import rasa.cli.utils
18
+ from rasa.core.utils import AvailableEndpoints
14
19
  from rasa.shared.constants import (
15
20
  DEFAULT_CREDENTIALS_PATH,
16
21
  DEFAULT_ENDPOINTS_PATH,
17
22
  )
18
- from rasa.core.utils import AvailableEndpoints
19
- import rasa.shared.utils.cli
20
- import rasa.shared.utils.io
21
- import rasa.utils.common
22
- import rasa.utils.io
23
23
  from rasa.shared.utils.yaml import read_config_file
24
24
 
25
25
  logger = logging.getLogger(__name__)
rasa/constants.py CHANGED
@@ -18,7 +18,7 @@ CONFIG_TELEMETRY_ID = "rasa_user_id"
18
18
  CONFIG_TELEMETRY_ENABLED = "enabled"
19
19
  CONFIG_TELEMETRY_DATE = "date"
20
20
 
21
- MINIMUM_COMPATIBLE_VERSION = "3.10.12"
21
+ MINIMUM_COMPATIBLE_VERSION = "3.11.0rc1"
22
22
 
23
23
  GLOBAL_USER_CONFIG_PATH = os.path.expanduser("~/.config/rasa/global.yml")
24
24
 
@@ -39,5 +39,7 @@ ENV_CPU_INTRA_OP_CONFIG = "TF_INTRA_OP_PARALLELISM_THREADS"
39
39
 
40
40
  MODEL_ARCHIVE_EXTENSION = "tar.gz"
41
41
 
42
+ DEFAULT_BUCKET_NAME = "rasa-models"
43
+
42
44
  HTTP_STATUS_FORBIDDEN = 403
43
45
  HTTP_STATUS_NOT_FOUND = 404
@@ -13,6 +13,8 @@ from typing import (
13
13
  cast,
14
14
  )
15
15
 
16
+ from jsonschema import Draft202012Validator
17
+
16
18
  import rasa.core
17
19
  import rasa.shared.utils.io
18
20
  from rasa.core.actions.custom_action_executor import (
@@ -101,7 +103,6 @@ if TYPE_CHECKING:
101
103
  from rasa.core.nlg import NaturalLanguageGenerator
102
104
  from rasa.shared.core.events import IntentPrediction
103
105
 
104
-
105
106
  logger = logging.getLogger(__name__)
106
107
 
107
108
 
@@ -112,6 +113,8 @@ def default_actions(action_endpoint: Optional[EndpointConfig] = None) -> List["A
112
113
  from rasa.core.actions.action_trigger_chitchat import ActionTriggerChitchat
113
114
  from rasa.core.actions.action_trigger_search import ActionTriggerSearch
114
115
  from rasa.core.actions.two_stage_fallback import TwoStageFallbackAction
116
+ from rasa.core.actions.action_hangup import ActionHangup
117
+ from rasa.core.actions.action_repeat_bot_messages import ActionRepeatBotMessages
115
118
  from rasa.dialogue_understanding.patterns.cancel import ActionCancelFlow
116
119
  from rasa.dialogue_understanding.patterns.clarify import ActionClarifyFlows
117
120
  from rasa.dialogue_understanding.patterns.correction import ActionCorrectFlowSlot
@@ -138,6 +141,8 @@ def default_actions(action_endpoint: Optional[EndpointConfig] = None) -> List["A
138
141
  ActionTriggerSearch(),
139
142
  ActionTriggerChitchat(),
140
143
  ActionResetRouting(),
144
+ ActionHangup(),
145
+ ActionRepeatBotMessages(),
141
146
  ]
142
147
 
143
148
 
@@ -721,6 +726,77 @@ class ActionDeactivateLoop(Action):
721
726
  return [ActiveLoop(None), SlotSet(REQUESTED_SLOT, None)]
722
727
 
723
728
 
729
+ class RemoteActionJSONValidator:
730
+ """
731
+ A validator class for ensuring that the JSON response from a custom action executor
732
+ adheres to the expected schema.
733
+ """
734
+
735
+ @staticmethod
736
+ def action_response_format_spec() -> Dict[Text, Any]:
737
+ """Expected response schema for an Action endpoint.
738
+
739
+ Used for validation of the response returned from the
740
+ Action endpoint.
741
+
742
+ Returns:
743
+ Dict[Text, Any]: A dictionary representing the JSON schema for validation.
744
+ """
745
+ schema = {
746
+ "type": "object",
747
+ "properties": {
748
+ "events": EVENTS_SCHEMA,
749
+ "responses": {"type": "array", "items": {"type": "object"}},
750
+ },
751
+ }
752
+ return schema
753
+
754
+ @classmethod
755
+ def validate(cls, result: Dict[Text, Any]) -> bool:
756
+ """
757
+ Validate the given JSON result against the expected Action response schema.
758
+
759
+ This method uses a cached JSON schema validator to check if the provided result
760
+ conforms to the predefined schema.
761
+
762
+ Args:
763
+ result (Dict[Text, Any]): The JSON response to validate.
764
+
765
+ Returns:
766
+ bool: True if validation is successful.
767
+
768
+ Raises:
769
+ ValidationError: If the JSON response does not conform to the schema.
770
+ """
771
+ from jsonschema import ValidationError
772
+
773
+ try:
774
+ validator = cls.get_action_response_validator()
775
+ validator.validate(
776
+ result, RemoteActionJSONValidator.action_response_format_spec()
777
+ )
778
+ return True
779
+ except ValidationError as e:
780
+ e.message += (
781
+ f". Failed to validate Action server response from API, "
782
+ f"make sure your response from the Action endpoint is valid. "
783
+ f"For more information about the format visit "
784
+ f"{DOCS_BASE_URL}/custom-actions"
785
+ )
786
+ raise e
787
+
788
+ @classmethod
789
+ @lru_cache(maxsize=1)
790
+ def get_action_response_validator(cls) -> Draft202012Validator:
791
+ """
792
+ Retrieve a cached JSON schema validator for the Action response schema.
793
+
794
+ Returns:
795
+ Draft202012Validator: An instance of the JSON schema validator.
796
+ """
797
+ return Draft202012Validator(cls.action_response_format_spec())
798
+
799
+
724
800
  class RemoteAction(Action):
725
801
  def __init__(
726
802
  self,
@@ -779,37 +855,6 @@ class RemoteAction(Action):
779
855
  f"Found url '{self.action_endpoint.url}'."
780
856
  )
781
857
 
782
- @staticmethod
783
- def action_response_format_spec() -> Dict[Text, Any]:
784
- """Expected response schema for an Action endpoint.
785
-
786
- Used for validation of the response returned from the
787
- Action endpoint.
788
- """
789
- schema = {
790
- "type": "object",
791
- "properties": {
792
- "events": EVENTS_SCHEMA,
793
- "responses": {"type": "array", "items": {"type": "object"}},
794
- },
795
- }
796
- return schema
797
-
798
- def _validate_action_result(self, result: Dict[Text, Any]) -> bool:
799
- from jsonschema import ValidationError, validate
800
-
801
- try:
802
- validate(result, self.action_response_format_spec())
803
- return True
804
- except ValidationError as e:
805
- e.message += (
806
- f". Failed to validate Action server response from API, "
807
- f"make sure your response from the Action endpoint is valid. "
808
- f"For more information about the format visit "
809
- f"{DOCS_BASE_URL}/custom-actions"
810
- )
811
- raise e
812
-
813
858
  @staticmethod
814
859
  async def _utter_responses(
815
860
  responses: List[Dict[Text, Any]],
@@ -861,7 +906,6 @@ class RemoteAction(Action):
861
906
  domain=domain,
862
907
  tracker=tracker,
863
908
  )
864
- self._validate_action_result(response)
865
909
 
866
910
  events_json = response.get("events", [])
867
911
  responses = response.get("responses", [])
@@ -0,0 +1,29 @@
1
+ from typing import Optional, Dict, Any, List
2
+
3
+ from rasa.core.actions.action import Action
4
+ from rasa.core.channels import OutputChannel
5
+ from rasa.core.nlg import NaturalLanguageGenerator
6
+ from rasa.shared.core.constants import ACTION_HANGUP
7
+ from rasa.shared.core.domain import Domain
8
+ from rasa.shared.core.events import Event, SessionEnded
9
+ from rasa.shared.core.trackers import DialogueStateTracker
10
+
11
+
12
+ class ActionHangup(Action):
13
+ """Action which hangs up the call."""
14
+
15
+ def name(self) -> str:
16
+ """Return the name of the action."""
17
+ return ACTION_HANGUP
18
+
19
+ async def run(
20
+ self,
21
+ output_channel: OutputChannel,
22
+ nlg: NaturalLanguageGenerator,
23
+ tracker: DialogueStateTracker,
24
+ domain: Domain,
25
+ metadata: Optional[Dict[str, Any]] = None,
26
+ ) -> List[Event]:
27
+ """Ask the output channel to hang up the call."""
28
+ await output_channel.hangup(tracker.sender_id)
29
+ return [SessionEnded(metadata={"_reason": "hangup"})]
@@ -0,0 +1,89 @@
1
+ from typing import Optional, Dict, Any, List
2
+
3
+ from rasa.core.actions.action import Action
4
+ from rasa.core.channels import OutputChannel
5
+ from rasa.core.nlg import NaturalLanguageGenerator
6
+ from rasa.dialogue_understanding.patterns.collect_information import (
7
+ CollectInformationPatternFlowStackFrame,
8
+ )
9
+ from rasa.dialogue_understanding.patterns.repeat import (
10
+ RepeatBotMessagesPatternFlowStackFrame,
11
+ )
12
+ from rasa.dialogue_understanding.patterns.user_silence import (
13
+ UserSilencePatternFlowStackFrame,
14
+ )
15
+ from rasa.shared.core.constants import ACTION_REPEAT_BOT_MESSAGES
16
+ from rasa.shared.core.domain import Domain
17
+ from rasa.shared.core.events import Event, BotUttered, UserUttered
18
+ from rasa.shared.core.trackers import DialogueStateTracker
19
+
20
+
21
+ class ActionRepeatBotMessages(Action):
22
+ """Action to repeat bot messages"""
23
+
24
+ def name(self) -> str:
25
+ """Return the name of the action."""
26
+ return ACTION_REPEAT_BOT_MESSAGES
27
+
28
+ def _get_last_bot_events(self, tracker: DialogueStateTracker) -> List[Event]:
29
+ """Get the last consecutive bot events before the most recent user message.
30
+
31
+ This function scans the dialogue history in reverse to find the last sequence of
32
+ bot responses that occurred without any user interruption. It filters out all
33
+ non-utterance events and stops when it encounters a user message after finding
34
+ bot messages.
35
+
36
+ Args:
37
+ tracker: DialogueStateTracker containing the conversation events.
38
+
39
+ Returns:
40
+ List[Event]: A list of consecutive BotUttered events that occurred
41
+ most recently, in chronological order. Returns an empty list
42
+ if no bot messages are found or if the last message was from
43
+ the user.
44
+
45
+ Example:
46
+ For events: [User1, Bot1, Bot2, User2, Bot4, Bot5, User3]
47
+ Returns: [Bot4, Bot5] (the last two bot events)
48
+ The elif condition doesn't break when it sees User3 event.
49
+ But it does at User2 event.
50
+ """
51
+ # Skip action if we are in a collect information step whose
52
+ # default behavior is to repeat anyways
53
+ top_frame = tracker.stack.top(
54
+ lambda frame: isinstance(frame, RepeatBotMessagesPatternFlowStackFrame)
55
+ or isinstance(frame, UserSilencePatternFlowStackFrame)
56
+ )
57
+ if isinstance(top_frame, CollectInformationPatternFlowStackFrame):
58
+ return []
59
+ # filter user and bot events
60
+ filtered = [
61
+ e for e in tracker.events if isinstance(e, (BotUttered, UserUttered))
62
+ ]
63
+ bot_events: List[Event] = []
64
+
65
+ # find the last BotUttered events
66
+ for e in reversed(filtered):
67
+ if isinstance(e, BotUttered):
68
+ # insert instead of append because the list is reversed
69
+ bot_events.insert(0, e)
70
+
71
+ # stop if a UserUttered event is found
72
+ # only if we have collected some bot events already
73
+ # this condition skips the first N UserUttered events
74
+ elif bot_events:
75
+ break
76
+
77
+ return bot_events
78
+
79
+ async def run(
80
+ self,
81
+ output_channel: OutputChannel,
82
+ nlg: NaturalLanguageGenerator,
83
+ tracker: DialogueStateTracker,
84
+ domain: Domain,
85
+ metadata: Optional[Dict[str, Any]] = None,
86
+ ) -> List[Event]:
87
+ """Send the last bot messages to the channel again"""
88
+ bot_events = self._get_last_bot_events(tracker)
89
+ return bot_events
@@ -61,8 +61,12 @@ class E2EStubCustomActionExecutor(CustomActionExecutor):
61
61
  domain: "Domain",
62
62
  include_domain: bool = False,
63
63
  ) -> Dict[Text, Any]:
64
+ from rasa.core.actions.action import RemoteActionJSONValidator
65
+
64
66
  structlogger.debug(
65
67
  "action.e2e_stub_custom_action_executor.run",
66
68
  action_name=self.action_name,
67
69
  )
68
- return self.stub_custom_action.as_dict()
70
+ response = self.stub_custom_action.as_dict()
71
+ RemoteActionJSONValidator.validate(response)
72
+ return response
@@ -66,6 +66,8 @@ class HTTPCustomActionExecutor(CustomActionExecutor):
66
66
  Raises:
67
67
  RasaException: If an error occurs while making the HTTP request.
68
68
  """
69
+ from rasa.core.actions.action import RemoteActionJSONValidator
70
+
69
71
  try:
70
72
  logger.debug(
71
73
  "Calling action endpoint to run action '{}'.".format(self.action_name)
@@ -80,6 +82,8 @@ class HTTPCustomActionExecutor(CustomActionExecutor):
80
82
  if response is None:
81
83
  response = {}
82
84
 
85
+ RemoteActionJSONValidator.validate(response)
86
+
83
87
  return response
84
88
 
85
89
  except ClientResponseError as e:
rasa/core/agent.py CHANGED
@@ -19,6 +19,7 @@ from rasa.core.exceptions import AgentNotReady
19
19
  from rasa.core.http_interpreter import RasaNLUHttpInterpreter
20
20
  from rasa.core.lock_store import InMemoryLockStore, LockStore
21
21
  from rasa.core.nlg import NaturalLanguageGenerator, TemplatedNaturalLanguageGenerator
22
+ from rasa.core.persistor import StorageType
22
23
  from rasa.core.policies.policy import PolicyPrediction
23
24
  from rasa.core.processor import MessageProcessor
24
25
  from rasa.core.tracker_store import (
@@ -28,7 +29,6 @@ from rasa.core.tracker_store import (
28
29
  )
29
30
  from rasa.core.utils import AvailableEndpoints
30
31
  from rasa.exceptions import ModelNotFound
31
- from rasa.nlu.persistor import StorageType
32
32
  from rasa.nlu.utils import is_url
33
33
  from rasa.shared.constants import DEFAULT_SENDER_ID
34
34
  from rasa.shared.core.domain import Domain
@@ -544,7 +544,7 @@ class Agent:
544
544
 
545
545
  def load_model_from_remote_storage(self, model_name: Text) -> None:
546
546
  """Loads an Agent from remote storage."""
547
- from rasa.nlu.persistor import get_persistor
547
+ from rasa.core.persistor import get_persistor
548
548
 
549
549
  persistor = get_persistor(self.remote_storage)
550
550
 
@@ -2,6 +2,8 @@ import asyncio
2
2
  import os
3
3
  import json
4
4
  import logging
5
+ from functools import cached_property
6
+
5
7
  import structlog
6
8
  import threading
7
9
  from asyncio import AbstractEventLoop
@@ -270,7 +272,7 @@ class KafkaEventBroker(EventBroker):
270
272
  if self.producer:
271
273
  self.producer.flush()
272
274
 
273
- @rasa.shared.utils.common.lazy_property
275
+ @cached_property
274
276
  def rasa_environment(self) -> Optional[Text]:
275
277
  """Get value of the `RASA_ENVIRONMENT` environment variable."""
276
278
  return os.environ.get("RASA_ENVIRONMENT", "RASA_ENVIRONMENT_NOT_SET")
rasa/core/brokers/pika.py CHANGED
@@ -1,6 +1,8 @@
1
1
  import asyncio
2
2
  import json
3
3
  import logging
4
+ from functools import cached_property
5
+
4
6
  import structlog
5
7
  import os
6
8
  import ssl
@@ -333,7 +335,7 @@ class PikaEventBroker(EventBroker):
333
335
  delivery_mode=aio_pika.DeliveryMode.PERSISTENT,
334
336
  )
335
337
 
336
- @rasa.shared.utils.common.lazy_property
338
+ @cached_property
337
339
  def rasa_environment(self) -> Optional[Text]:
338
340
  """Get value of the `RASA_ENVIRONMENT` environment variable."""
339
341
  return os.environ.get("RASA_ENVIRONMENT")
@@ -21,13 +21,16 @@ from rasa.core.channels.rocketchat import RocketChatInput
21
21
  from rasa.core.channels.slack import SlackInput
22
22
  from rasa.core.channels.telegram import TelegramInput
23
23
  from rasa.core.channels.twilio import TwilioInput
24
- from rasa.core.channels.twilio_voice import TwilioVoiceInput
25
- from rasa.core.channels.voice_aware.jambonz import JambonzVoiceAwareInput
24
+ from rasa.core.channels.voice_ready.twilio_voice import TwilioVoiceInput
25
+ from rasa.core.channels.voice_ready.jambonz import JambonzVoiceReadyInput
26
+ from rasa.core.channels.voice_ready.audiocodes import AudiocodesInput
27
+ from rasa.core.channels.voice_stream.browser_audio import BrowserAudioInputChannel
26
28
  from rasa.core.channels.webexteams import WebexTeamsInput
27
29
  from rasa.core.channels.hangouts import HangoutsInput
28
- from rasa.core.channels.audiocodes import AudiocodesInput
29
- from rasa.core.channels.development_inspector import DevelopmentInspectInput
30
30
  from rasa.core.channels.vier_cvg import CVGInput
31
+ from rasa.core.channels.voice_stream.twilio_media_streams import (
32
+ TwilioMediaStreamsInputChannel,
33
+ )
31
34
 
32
35
  input_channel_classes: List[Type[InputChannel]] = [
33
36
  CmdlineInput,
@@ -46,9 +49,10 @@ input_channel_classes: List[Type[InputChannel]] = [
46
49
  WebexTeamsInput,
47
50
  HangoutsInput,
48
51
  AudiocodesInput,
49
- DevelopmentInspectInput,
50
52
  CVGInput,
51
- JambonzVoiceAwareInput,
53
+ JambonzVoiceReadyInput,
54
+ TwilioMediaStreamsInputChannel,
55
+ BrowserAudioInputChannel,
52
56
  ]
53
57
 
54
58
  # Mapping from an input channel name to its class to allow name based lookup.