rasa-pro 3.12.35__py3-none-any.whl → 3.12.37__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.
- rasa/core/actions/action_clean_stack.py +32 -0
- rasa/core/actions/constants.py +4 -0
- rasa/core/actions/custom_action_executor.py +70 -12
- rasa/core/actions/grpc_custom_action_executor.py +41 -2
- rasa/core/actions/http_custom_action_executor.py +49 -25
- rasa/core/channels/voice_stream/voice_channel.py +2 -0
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +6 -3
- rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +18 -8
- rasa/dialogue_understanding/processor/command_processor.py +12 -3
- rasa/shared/core/flows/flow.py +8 -2
- rasa/shared/providers/_configs/azure_openai_client_config.py +4 -5
- rasa/shared/providers/_configs/default_litellm_client_config.py +4 -4
- rasa/shared/providers/_configs/litellm_router_client_config.py +3 -2
- rasa/shared/providers/_configs/openai_client_config.py +5 -7
- rasa/shared/providers/_configs/rasa_llm_client_config.py +4 -4
- rasa/shared/providers/_configs/self_hosted_llm_client_config.py +4 -4
- rasa/shared/providers/llm/_base_litellm_client.py +42 -13
- rasa/shared/providers/llm/litellm_router_llm_client.py +38 -15
- rasa/shared/providers/llm/self_hosted_llm_client.py +34 -32
- rasa/utils/endpoints.py +6 -0
- rasa/version.py +1 -1
- {rasa_pro-3.12.35.dist-info → rasa_pro-3.12.37.dist-info}/METADATA +4 -4
- {rasa_pro-3.12.35.dist-info → rasa_pro-3.12.37.dist-info}/RECORD +26 -26
- {rasa_pro-3.12.35.dist-info → rasa_pro-3.12.37.dist-info}/NOTICE +0 -0
- {rasa_pro-3.12.35.dist-info → rasa_pro-3.12.37.dist-info}/WHEEL +0 -0
- {rasa_pro-3.12.35.dist-info → rasa_pro-3.12.37.dist-info}/entry_points.txt +0 -0
|
@@ -4,9 +4,11 @@ from typing import Any, Dict, List, Optional
|
|
|
4
4
|
|
|
5
5
|
import structlog
|
|
6
6
|
|
|
7
|
+
import rasa.dialogue_understanding.stack.utils
|
|
7
8
|
from rasa.core.actions.action import Action
|
|
8
9
|
from rasa.core.channels import OutputChannel
|
|
9
10
|
from rasa.core.nlg import NaturalLanguageGenerator
|
|
11
|
+
from rasa.dialogue_understanding.patterns.code_change import FLOW_PATTERN_CODE_CHANGE_ID
|
|
10
12
|
from rasa.dialogue_understanding.stack.dialogue_stack import DialogueStack
|
|
11
13
|
from rasa.dialogue_understanding.stack.frames import (
|
|
12
14
|
BaseFlowStackFrame,
|
|
@@ -41,6 +43,15 @@ class ActionCleanStack(Action):
|
|
|
41
43
|
"""Clean the stack."""
|
|
42
44
|
structlogger.debug("action_clean_stack.run")
|
|
43
45
|
new_frames = []
|
|
46
|
+
top_flow_frame = rasa.dialogue_understanding.stack.utils.top_flow_frame(
|
|
47
|
+
tracker.stack, ignore_call_frames=False
|
|
48
|
+
)
|
|
49
|
+
top_user_flow_frame = (
|
|
50
|
+
rasa.dialogue_understanding.stack.utils.top_user_flow_frame(
|
|
51
|
+
tracker.stack, ignore_call_and_link_frames=False
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
|
|
44
55
|
# Set all frames to their end step, filter out any non-BaseFlowStackFrames
|
|
45
56
|
for frame in tracker.stack.frames:
|
|
46
57
|
if isinstance(frame, BaseFlowStackFrame):
|
|
@@ -56,4 +67,25 @@ class ActionCleanStack(Action):
|
|
|
56
67
|
new_frames.append(frame)
|
|
57
68
|
new_stack = DialogueStack.from_dict([frame.as_dict() for frame in new_frames])
|
|
58
69
|
|
|
70
|
+
# Check if the action is being called from within a user flow
|
|
71
|
+
if (
|
|
72
|
+
top_flow_frame
|
|
73
|
+
and top_flow_frame.flow_id != FLOW_PATTERN_CODE_CHANGE_ID
|
|
74
|
+
and top_user_flow_frame
|
|
75
|
+
and top_user_flow_frame.flow_id == top_flow_frame.flow_id
|
|
76
|
+
):
|
|
77
|
+
# The action is being called from within a user flow on the stack.
|
|
78
|
+
# If there are other frames on the stack, we need to make sure
|
|
79
|
+
# the last executed frame is the end step of the current user flow so
|
|
80
|
+
# that we can trigger pattern_completed for this user flow.
|
|
81
|
+
new_stack.pop()
|
|
82
|
+
structlogger.debug(
|
|
83
|
+
"action_clean_stack.pushing_user_frame_at_the_bottom_of_stack",
|
|
84
|
+
flow_id=top_user_flow_frame.flow_id,
|
|
85
|
+
)
|
|
86
|
+
new_stack.push(
|
|
87
|
+
top_user_flow_frame,
|
|
88
|
+
index=0,
|
|
89
|
+
)
|
|
90
|
+
|
|
59
91
|
return tracker.create_stack_updated_events(new_stack)
|
rasa/core/actions/constants.py
CHANGED
|
@@ -3,3 +3,7 @@ SELECTIVE_DOMAIN = "enable_selective_domain"
|
|
|
3
3
|
|
|
4
4
|
SSL_CLIENT_CERT_FIELD = "ssl_client_cert"
|
|
5
5
|
SSL_CLIENT_KEY_FIELD = "ssl_client_key"
|
|
6
|
+
|
|
7
|
+
# Special marker key used by EndpointConfig to indicate 449 status
|
|
8
|
+
# without raising an exception
|
|
9
|
+
MISSING_DOMAIN_MARKER = "missing_domain"
|
|
@@ -2,7 +2,10 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import abc
|
|
4
4
|
import logging
|
|
5
|
-
from
|
|
5
|
+
from enum import Enum
|
|
6
|
+
from typing import TYPE_CHECKING, Any, Dict, Optional, Text
|
|
7
|
+
|
|
8
|
+
from pydantic import BaseModel
|
|
6
9
|
|
|
7
10
|
import rasa
|
|
8
11
|
from rasa.core.actions.action_exceptions import DomainNotFound
|
|
@@ -19,6 +22,23 @@ if TYPE_CHECKING:
|
|
|
19
22
|
logger = logging.getLogger(__name__)
|
|
20
23
|
|
|
21
24
|
|
|
25
|
+
class ActionResultType(Enum):
|
|
26
|
+
SUCCESS = "success"
|
|
27
|
+
RETRY_WITH_DOMAIN = "retry_with_domain"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ActionResult(BaseModel):
|
|
31
|
+
"""Result of custom action execution.
|
|
32
|
+
|
|
33
|
+
This is used to avoid raising exceptions for expected conditions
|
|
34
|
+
like missing domain (449 status code), which would otherwise be
|
|
35
|
+
captured by tracing as errors.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
result_type: ActionResultType
|
|
39
|
+
response: Optional[Dict[Text, Any]] = None
|
|
40
|
+
|
|
41
|
+
|
|
22
42
|
class CustomActionExecutor(abc.ABC):
|
|
23
43
|
"""Interface for custom action executors.
|
|
24
44
|
|
|
@@ -45,6 +65,34 @@ class CustomActionExecutor(abc.ABC):
|
|
|
45
65
|
"""
|
|
46
66
|
pass
|
|
47
67
|
|
|
68
|
+
async def run_with_result(
|
|
69
|
+
self,
|
|
70
|
+
tracker: "DialogueStateTracker",
|
|
71
|
+
domain: "Domain",
|
|
72
|
+
include_domain: bool = False,
|
|
73
|
+
) -> ActionResult:
|
|
74
|
+
"""Executes the custom action and returns a result.
|
|
75
|
+
|
|
76
|
+
This method is used to avoid raising exceptions for expected conditions
|
|
77
|
+
like missing domain, which would otherwise be captured by tracing as errors.
|
|
78
|
+
|
|
79
|
+
By default, this method calls the run method and wraps the response
|
|
80
|
+
for backward compatibility.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
tracker: The current state of the dialogue.
|
|
84
|
+
domain: The domain object containing domain-specific information.
|
|
85
|
+
include_domain: If True, the domain is included in the request.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
ActionResult containing the response and result type.
|
|
89
|
+
"""
|
|
90
|
+
try:
|
|
91
|
+
response = await self.run(tracker, domain, include_domain)
|
|
92
|
+
return ActionResult(result_type=ActionResultType.SUCCESS, response=response)
|
|
93
|
+
except DomainNotFound:
|
|
94
|
+
return ActionResult(result_type=ActionResultType.RETRY_WITH_DOMAIN)
|
|
95
|
+
|
|
48
96
|
|
|
49
97
|
class NoEndpointCustomActionExecutor(CustomActionExecutor):
|
|
50
98
|
"""Implementation of a custom action executor when endpoint is not set.
|
|
@@ -163,13 +211,13 @@ class RetryCustomActionExecutor(CustomActionExecutor):
|
|
|
163
211
|
domain: "Domain",
|
|
164
212
|
include_domain: bool = False,
|
|
165
213
|
) -> Dict[Text, Any]:
|
|
166
|
-
"""Runs the wrapped custom action executor.
|
|
214
|
+
"""Runs the wrapped custom action executor with retry logic.
|
|
167
215
|
|
|
168
216
|
First request to the action server is made with/without the domain
|
|
169
217
|
as specified by the `include_domain` parameter.
|
|
170
218
|
|
|
171
|
-
If the action server responds with a
|
|
172
|
-
|
|
219
|
+
If the action server responds with a missing domain indication,
|
|
220
|
+
retries the request with the domain included.
|
|
173
221
|
|
|
174
222
|
Args:
|
|
175
223
|
tracker: The current state of the dialogue.
|
|
@@ -178,14 +226,24 @@ class RetryCustomActionExecutor(CustomActionExecutor):
|
|
|
178
226
|
|
|
179
227
|
Returns:
|
|
180
228
|
The response from the execution of the custom action.
|
|
229
|
+
|
|
230
|
+
Raises:
|
|
231
|
+
DomainNotFound: If the action server still requires domain after retry.
|
|
181
232
|
"""
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
233
|
+
result = await self._custom_action_executor.run_with_result(
|
|
234
|
+
tracker,
|
|
235
|
+
domain,
|
|
236
|
+
include_domain=include_domain,
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
if result.result_type == ActionResultType.RETRY_WITH_DOMAIN:
|
|
240
|
+
# Retry with domain included
|
|
241
|
+
result = await self._custom_action_executor.run_with_result(
|
|
190
242
|
tracker, domain, include_domain=True
|
|
191
243
|
)
|
|
244
|
+
|
|
245
|
+
# If still missing domain after retry, raise error
|
|
246
|
+
if result.result_type == ActionResultType.RETRY_WITH_DOMAIN:
|
|
247
|
+
raise DomainNotFound()
|
|
248
|
+
|
|
249
|
+
return result.response if result.response is not None else {}
|
|
@@ -11,6 +11,8 @@ from rasa_sdk.grpc_py import action_webhook_pb2, action_webhook_pb2_grpc
|
|
|
11
11
|
from rasa.core.actions.action_exceptions import DomainNotFound
|
|
12
12
|
from rasa.core.actions.constants import SSL_CLIENT_CERT_FIELD, SSL_CLIENT_KEY_FIELD
|
|
13
13
|
from rasa.core.actions.custom_action_executor import (
|
|
14
|
+
ActionResult,
|
|
15
|
+
ActionResultType,
|
|
14
16
|
CustomActionExecutor,
|
|
15
17
|
CustomActionRequestWriter,
|
|
16
18
|
)
|
|
@@ -101,13 +103,51 @@ class GRPCCustomActionExecutor(CustomActionExecutor):
|
|
|
101
103
|
|
|
102
104
|
Returns:
|
|
103
105
|
Response from the action server.
|
|
106
|
+
Returns empty dict if domain is missing.
|
|
107
|
+
|
|
108
|
+
Raises:
|
|
109
|
+
RasaException: If an error occurs while making the gRPC request
|
|
110
|
+
(other than missing domain).
|
|
104
111
|
"""
|
|
112
|
+
result = await self.run_with_result(tracker, domain, include_domain)
|
|
113
|
+
|
|
114
|
+
# Return empty dict for retry cases to avoid raising exceptions
|
|
115
|
+
# RetryCustomActionExecutor will handle the retry logic
|
|
116
|
+
if result.result_type == ActionResultType.RETRY_WITH_DOMAIN:
|
|
117
|
+
return {}
|
|
118
|
+
|
|
119
|
+
return result.response if result.response is not None else {}
|
|
120
|
+
|
|
121
|
+
async def run_with_result(
|
|
122
|
+
self,
|
|
123
|
+
tracker: "DialogueStateTracker",
|
|
124
|
+
domain: "Domain",
|
|
125
|
+
include_domain: bool = False,
|
|
126
|
+
) -> ActionResult:
|
|
127
|
+
"""Execute the custom action and return an ActionResult.
|
|
128
|
+
|
|
129
|
+
This method avoids raising DomainNotFound exception for missing domain,
|
|
130
|
+
instead returning an ActionResult with RETRY_WITH_DOMAIN type.
|
|
131
|
+
This prevents tracing from capturing this expected condition as an error.
|
|
105
132
|
|
|
133
|
+
Args:
|
|
134
|
+
tracker: Tracker for the current conversation.
|
|
135
|
+
domain: Domain of the assistant.
|
|
136
|
+
include_domain: If True, the domain is included in the request.
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
ActionResult containing the response and result type.
|
|
140
|
+
"""
|
|
106
141
|
request = self._create_payload(
|
|
107
142
|
tracker=tracker, domain=domain, include_domain=include_domain
|
|
108
143
|
)
|
|
109
144
|
|
|
110
|
-
|
|
145
|
+
try:
|
|
146
|
+
response = self._request(request)
|
|
147
|
+
return ActionResult(result_type=ActionResultType.SUCCESS, response=response)
|
|
148
|
+
except DomainNotFound:
|
|
149
|
+
# Return retry result instead of raising DomainNotFound
|
|
150
|
+
return ActionResult(result_type=ActionResultType.RETRY_WITH_DOMAIN)
|
|
111
151
|
|
|
112
152
|
def _request(
|
|
113
153
|
self,
|
|
@@ -121,7 +161,6 @@ class GRPCCustomActionExecutor(CustomActionExecutor):
|
|
|
121
161
|
Returns:
|
|
122
162
|
Response from the action server.
|
|
123
163
|
"""
|
|
124
|
-
|
|
125
164
|
client = self._create_grpc_client()
|
|
126
165
|
metadata = self._build_metadata()
|
|
127
166
|
try:
|
|
@@ -4,8 +4,11 @@ from typing import TYPE_CHECKING, Any, Dict, Optional
|
|
|
4
4
|
|
|
5
5
|
import aiohttp
|
|
6
6
|
|
|
7
|
-
from rasa.core.actions.action_exceptions import ActionExecutionRejection
|
|
7
|
+
from rasa.core.actions.action_exceptions import ActionExecutionRejection
|
|
8
|
+
from rasa.core.actions.constants import MISSING_DOMAIN_MARKER
|
|
8
9
|
from rasa.core.actions.custom_action_executor import (
|
|
10
|
+
ActionResult,
|
|
11
|
+
ActionResultType,
|
|
9
12
|
CustomActionExecutor,
|
|
10
13
|
CustomActionRequestWriter,
|
|
11
14
|
)
|
|
@@ -18,12 +21,12 @@ from rasa.shared.core.domain import Domain
|
|
|
18
21
|
from rasa.shared.core.trackers import DialogueStateTracker
|
|
19
22
|
from rasa.shared.exceptions import RasaException
|
|
20
23
|
from rasa.utils.common import get_bool_env_variable
|
|
24
|
+
from rasa.utils.endpoints import ClientResponseError, EndpointConfig
|
|
21
25
|
|
|
22
26
|
if TYPE_CHECKING:
|
|
23
27
|
from rasa.shared.core.domain import Domain
|
|
24
28
|
from rasa.shared.core.trackers import DialogueStateTracker
|
|
25
29
|
|
|
26
|
-
from rasa.utils.endpoints import ClientResponseError, EndpointConfig
|
|
27
30
|
|
|
28
31
|
logger = logging.getLogger(__name__)
|
|
29
32
|
|
|
@@ -62,9 +65,40 @@ class HTTPCustomActionExecutor(CustomActionExecutor):
|
|
|
62
65
|
|
|
63
66
|
Returns:
|
|
64
67
|
A dictionary containing the response from the custom action endpoint.
|
|
68
|
+
Returns empty dict if domain is missing (449 status).
|
|
65
69
|
|
|
66
70
|
Raises:
|
|
67
|
-
RasaException: If an error occurs while making the HTTP request
|
|
71
|
+
RasaException: If an error occurs while making the HTTP request
|
|
72
|
+
(other than missing domain).
|
|
73
|
+
"""
|
|
74
|
+
result = await self.run_with_result(tracker, domain, include_domain)
|
|
75
|
+
|
|
76
|
+
# Return empty dict for retry cases to avoid raising exceptions
|
|
77
|
+
# RetryCustomActionExecutor will handle the retry logic
|
|
78
|
+
if result.result_type == ActionResultType.RETRY_WITH_DOMAIN:
|
|
79
|
+
return {}
|
|
80
|
+
|
|
81
|
+
return result.response if result.response is not None else {}
|
|
82
|
+
|
|
83
|
+
async def run_with_result(
|
|
84
|
+
self,
|
|
85
|
+
tracker: "DialogueStateTracker",
|
|
86
|
+
domain: Optional["Domain"] = None,
|
|
87
|
+
include_domain: bool = False,
|
|
88
|
+
) -> ActionResult:
|
|
89
|
+
"""Execute the custom action and return an ActionResult.
|
|
90
|
+
|
|
91
|
+
This method avoids raising DomainNotFound exception for 449 status code,
|
|
92
|
+
instead returning an ActionResult with RETRY_WITH_DOMAIN type.
|
|
93
|
+
This prevents tracing from capturing this expected condition as an error.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
tracker: The current state of the dialogue.
|
|
97
|
+
domain: The domain object containing domain-specific information.
|
|
98
|
+
include_domain: If True, the domain is included in the request.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
ActionResult containing the response and result type.
|
|
68
102
|
"""
|
|
69
103
|
from rasa.core.actions.action import RemoteActionJSONValidator
|
|
70
104
|
|
|
@@ -77,14 +111,23 @@ class HTTPCustomActionExecutor(CustomActionExecutor):
|
|
|
77
111
|
tracker=tracker, domain=domain, include_domain=include_domain
|
|
78
112
|
)
|
|
79
113
|
|
|
80
|
-
|
|
114
|
+
assert self.action_endpoint is not None
|
|
115
|
+
response = await self.action_endpoint.request(
|
|
116
|
+
json=json_body,
|
|
117
|
+
method="post",
|
|
118
|
+
timeout=DEFAULT_REQUEST_TIMEOUT,
|
|
119
|
+
compress=self.should_compress,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
# Check if we got the special marker for 449 status (missing domain)
|
|
123
|
+
if isinstance(response, dict) and response.get(MISSING_DOMAIN_MARKER):
|
|
124
|
+
return ActionResult(result_type=ActionResultType.RETRY_WITH_DOMAIN)
|
|
81
125
|
|
|
82
126
|
if response is None:
|
|
83
127
|
response = {}
|
|
84
128
|
|
|
85
129
|
RemoteActionJSONValidator.validate(response)
|
|
86
|
-
|
|
87
|
-
return response
|
|
130
|
+
return ActionResult(result_type=ActionResultType.SUCCESS, response=response)
|
|
88
131
|
|
|
89
132
|
except ClientResponseError as e:
|
|
90
133
|
if e.status == 400:
|
|
@@ -131,22 +174,3 @@ class HTTPCustomActionExecutor(CustomActionExecutor):
|
|
|
131
174
|
"and returns a 200 once the action is executed. "
|
|
132
175
|
"Error: {}".format(self.action_name, status, e)
|
|
133
176
|
)
|
|
134
|
-
|
|
135
|
-
async def _perform_request_with_retries(
|
|
136
|
-
self,
|
|
137
|
-
json_body: Dict[str, Any],
|
|
138
|
-
) -> Any:
|
|
139
|
-
"""Attempts to perform the request with retries if necessary."""
|
|
140
|
-
assert self.action_endpoint is not None
|
|
141
|
-
try:
|
|
142
|
-
return await self.action_endpoint.request(
|
|
143
|
-
json=json_body,
|
|
144
|
-
method="post",
|
|
145
|
-
timeout=DEFAULT_REQUEST_TIMEOUT,
|
|
146
|
-
compress=self.should_compress,
|
|
147
|
-
)
|
|
148
|
-
except ClientResponseError as e:
|
|
149
|
-
# Repeat the request because Domain was not in the payload
|
|
150
|
-
if e.status == 449:
|
|
151
|
-
raise DomainNotFound()
|
|
152
|
-
raise e
|
|
@@ -153,6 +153,8 @@ class VoiceOutputChannel(OutputChannel):
|
|
|
153
153
|
async def send_start_marker(self, recipient_id: str) -> None:
|
|
154
154
|
"""Send a marker message before the first audio chunk."""
|
|
155
155
|
# Default implementation uses the generic marker message
|
|
156
|
+
call_state.is_bot_speaking = True # type: ignore[attr-defined]
|
|
157
|
+
VoiceInputChannel._cancel_silence_timeout_watcher()
|
|
156
158
|
await self.send_marker_message(recipient_id)
|
|
157
159
|
|
|
158
160
|
async def send_intermediate_marker(self, recipient_id: str) -> None:
|
|
@@ -60,7 +60,9 @@ structlogger = structlog.get_logger()
|
|
|
60
60
|
class LLMBasedCommandGenerator(
|
|
61
61
|
LLMHealthCheckMixin, GraphComponent, CommandGenerator, ABC
|
|
62
62
|
):
|
|
63
|
-
"""
|
|
63
|
+
"""This class provides common functionality for all LLM-based command generators.
|
|
64
|
+
|
|
65
|
+
An abstract class defining interface and common functionality
|
|
64
66
|
of an LLM-based command generators.
|
|
65
67
|
"""
|
|
66
68
|
|
|
@@ -172,8 +174,9 @@ class LLMBasedCommandGenerator(
|
|
|
172
174
|
def train(
|
|
173
175
|
self, training_data: TrainingData, flows: FlowsList, domain: Domain
|
|
174
176
|
) -> Resource:
|
|
175
|
-
"""
|
|
176
|
-
|
|
177
|
+
"""Trains the LLM-based command generator and prepares flow retrieval data.
|
|
178
|
+
|
|
179
|
+
Stores all flows into a vector store.
|
|
177
180
|
"""
|
|
178
181
|
self.perform_llm_health_check(
|
|
179
182
|
self.config.get(LLM_CONFIG_KEY),
|
|
@@ -567,7 +567,23 @@ class CompactLLMCommandGenerator(LLMBasedCommandGenerator):
|
|
|
567
567
|
log_context: Optional[Literal["init", "fingerprint_addon"]] = None,
|
|
568
568
|
) -> Optional[str]:
|
|
569
569
|
"""Get the prompt template from the config or the default prompt template."""
|
|
570
|
-
|
|
570
|
+
if prompt_template is not None:
|
|
571
|
+
return prompt_template
|
|
572
|
+
|
|
573
|
+
# Try to load the template from the given path or fallback to the default for
|
|
574
|
+
# the component.
|
|
575
|
+
custom_prompt_template_path = config.get(PROMPT_TEMPLATE_CONFIG_KEY)
|
|
576
|
+
if custom_prompt_template_path is not None:
|
|
577
|
+
custom_prompt_template = get_prompt_template(
|
|
578
|
+
custom_prompt_template_path,
|
|
579
|
+
None, # Default will be based on the model
|
|
580
|
+
log_source_component=CompactLLMCommandGenerator.__name__,
|
|
581
|
+
log_source_method=log_context,
|
|
582
|
+
)
|
|
583
|
+
if custom_prompt_template is not None:
|
|
584
|
+
return custom_prompt_template
|
|
585
|
+
|
|
586
|
+
# Fallback to the default prompt template based on the model.
|
|
571
587
|
default_command_prompt_template = get_default_prompt_template_based_on_model(
|
|
572
588
|
llm_config=config.get(LLM_CONFIG_KEY, {}) or {},
|
|
573
589
|
model_prompt_mapping=MODEL_PROMPT_MAPPER,
|
|
@@ -577,10 +593,4 @@ class CompactLLMCommandGenerator(LLMBasedCommandGenerator):
|
|
|
577
593
|
log_source_method=log_context,
|
|
578
594
|
)
|
|
579
595
|
|
|
580
|
-
|
|
581
|
-
return prompt_template or get_prompt_template(
|
|
582
|
-
config.get(PROMPT_TEMPLATE_CONFIG_KEY),
|
|
583
|
-
default_command_prompt_template,
|
|
584
|
-
log_source_component=CompactLLMCommandGenerator.__name__,
|
|
585
|
-
log_source_method=log_context,
|
|
586
|
-
)
|
|
596
|
+
return default_command_prompt_template
|
|
@@ -477,6 +477,18 @@ def clean_up_commands(
|
|
|
477
477
|
else:
|
|
478
478
|
clean_commands.append(command)
|
|
479
479
|
|
|
480
|
+
# ensure that there is only one command of a certain command type
|
|
481
|
+
clean_commands = ensure_max_number_of_command_type(
|
|
482
|
+
clean_commands, CannotHandleCommand, 1
|
|
483
|
+
)
|
|
484
|
+
clean_commands = ensure_max_number_of_command_type(
|
|
485
|
+
clean_commands, RepeatBotMessagesCommand, 1
|
|
486
|
+
)
|
|
487
|
+
clean_commands = ensure_max_number_of_command_type(
|
|
488
|
+
clean_commands, ChitChatAnswerCommand, 1
|
|
489
|
+
)
|
|
490
|
+
|
|
491
|
+
# filter out cannot handle commands if there are other commands present
|
|
480
492
|
# when coexistence is enabled, by default there will be a SetSlotCommand
|
|
481
493
|
# for the ROUTE_TO_CALM_SLOT slot.
|
|
482
494
|
if tracker.has_coexistence_routing_slot and len(clean_commands) > 2:
|
|
@@ -484,9 +496,6 @@ def clean_up_commands(
|
|
|
484
496
|
elif not tracker.has_coexistence_routing_slot and len(clean_commands) > 1:
|
|
485
497
|
clean_commands = filter_cannot_handle_command(clean_commands)
|
|
486
498
|
|
|
487
|
-
clean_commands = ensure_max_number_of_command_type(
|
|
488
|
-
clean_commands, RepeatBotMessagesCommand, 1
|
|
489
|
-
)
|
|
490
499
|
structlogger.debug(
|
|
491
500
|
"command_processor.clean_up_commands.final_commands",
|
|
492
501
|
command=clean_commands,
|
rasa/shared/core/flows/flow.py
CHANGED
|
@@ -296,9 +296,15 @@ class Flow:
|
|
|
296
296
|
|
|
297
297
|
def get_collect_steps(self) -> List[CollectInformationFlowStep]:
|
|
298
298
|
"""Return all CollectInformationFlowSteps in the flow."""
|
|
299
|
-
collect_steps = []
|
|
299
|
+
collect_steps: List[CollectInformationFlowStep] = []
|
|
300
300
|
for step in self.steps_with_calls_resolved:
|
|
301
|
-
|
|
301
|
+
# Only add collect steps that are not already in the list.
|
|
302
|
+
# This is to avoid returning duplicate collect steps from called flows
|
|
303
|
+
# in case the called flow is called multiple times.
|
|
304
|
+
if (
|
|
305
|
+
isinstance(step, CollectInformationFlowStep)
|
|
306
|
+
and step not in collect_steps
|
|
307
|
+
):
|
|
302
308
|
collect_steps.append(step)
|
|
303
309
|
return collect_steps
|
|
304
310
|
|
|
@@ -167,8 +167,9 @@ class OAuthConfigWrapper(OAuth, BaseModel):
|
|
|
167
167
|
|
|
168
168
|
@dataclass
|
|
169
169
|
class AzureOpenAIClientConfig:
|
|
170
|
-
"""Parses configuration for Azure OpenAI client
|
|
171
|
-
|
|
170
|
+
"""Parses configuration for Azure OpenAI client.
|
|
171
|
+
|
|
172
|
+
Resolves aliases and raises deprecation warnings.
|
|
172
173
|
|
|
173
174
|
Raises:
|
|
174
175
|
ValueError: Raised in cases of invalid configuration:
|
|
@@ -301,9 +302,7 @@ class AzureOpenAIClientConfig:
|
|
|
301
302
|
|
|
302
303
|
|
|
303
304
|
def is_azure_openai_config(config: dict) -> bool:
|
|
304
|
-
"""Check whether the configuration is meant to configure
|
|
305
|
-
an Azure OpenAI client.
|
|
306
|
-
"""
|
|
305
|
+
"""Check whether the configuration is meant to configure an Azure OpenAI client."""
|
|
307
306
|
# Resolve any aliases that are specific to Azure OpenAI configuration
|
|
308
307
|
config = AzureOpenAIClientConfig.resolve_config_aliases(config)
|
|
309
308
|
|
|
@@ -40,8 +40,9 @@ FORBIDDEN_KEYS = [
|
|
|
40
40
|
|
|
41
41
|
@dataclass
|
|
42
42
|
class DefaultLiteLLMClientConfig:
|
|
43
|
-
"""Parses configuration for default LiteLLM client
|
|
44
|
-
|
|
43
|
+
"""Parses configuration for default LiteLLM client.
|
|
44
|
+
|
|
45
|
+
Resolves aliases and raises deprecation warnings.
|
|
45
46
|
|
|
46
47
|
Raises:
|
|
47
48
|
ValueError: Raised in cases of invalid configuration:
|
|
@@ -72,8 +73,7 @@ class DefaultLiteLLMClientConfig:
|
|
|
72
73
|
|
|
73
74
|
@classmethod
|
|
74
75
|
def from_dict(cls, config: dict) -> DefaultLiteLLMClientConfig:
|
|
75
|
-
"""
|
|
76
|
-
Initializes a dataclass from the passed config.
|
|
76
|
+
"""Initializes a dataclass from the passed config.
|
|
77
77
|
|
|
78
78
|
Args:
|
|
79
79
|
config: (dict) The config from which to initialize.
|
|
@@ -38,8 +38,9 @@ _LITELLM_UNSUPPORTED_KEYS = [
|
|
|
38
38
|
|
|
39
39
|
@dataclass
|
|
40
40
|
class LiteLLMRouterClientConfig:
|
|
41
|
-
"""Parses configuration for a LiteLLM Router client.
|
|
42
|
-
|
|
41
|
+
"""Parses configuration for a LiteLLM Router client.
|
|
42
|
+
|
|
43
|
+
The configuration is expected to be in the following format:
|
|
43
44
|
|
|
44
45
|
{
|
|
45
46
|
"id": "model_group_id",
|
|
@@ -64,8 +64,9 @@ FORBIDDEN_KEYS = [
|
|
|
64
64
|
|
|
65
65
|
@dataclass
|
|
66
66
|
class OpenAIClientConfig:
|
|
67
|
-
"""Parses configuration for
|
|
68
|
-
|
|
67
|
+
"""Parses configuration for OpenAI client.
|
|
68
|
+
|
|
69
|
+
Resolves aliases and raises deprecation warnings.
|
|
69
70
|
|
|
70
71
|
Raises:
|
|
71
72
|
ValueError: Raised in cases of invalid configuration:
|
|
@@ -118,8 +119,7 @@ class OpenAIClientConfig:
|
|
|
118
119
|
|
|
119
120
|
@classmethod
|
|
120
121
|
def from_dict(cls, config: dict) -> OpenAIClientConfig:
|
|
121
|
-
"""
|
|
122
|
-
Initializes a dataclass from the passed config.
|
|
122
|
+
"""Initializes a dataclass from the passed config.
|
|
123
123
|
|
|
124
124
|
Args:
|
|
125
125
|
config: (dict) The config from which to initialize.
|
|
@@ -168,9 +168,7 @@ class OpenAIClientConfig:
|
|
|
168
168
|
|
|
169
169
|
|
|
170
170
|
def is_openai_config(config: dict) -> bool:
|
|
171
|
-
"""Check whether the configuration is meant to configure
|
|
172
|
-
an OpenAI client.
|
|
173
|
-
"""
|
|
171
|
+
"""Check whether the configuration is meant to configure an OpenAI client."""
|
|
174
172
|
# Process the config to handle all the aliases
|
|
175
173
|
config = OpenAIClientConfig.resolve_config_aliases(config)
|
|
176
174
|
|
|
@@ -22,8 +22,9 @@ structlogger = structlog.get_logger()
|
|
|
22
22
|
|
|
23
23
|
@dataclass
|
|
24
24
|
class RasaLLMClientConfig:
|
|
25
|
-
"""Parses configuration for a Rasa Hosted LiteLLM client
|
|
26
|
-
|
|
25
|
+
"""Parses configuration for a Rasa Hosted LiteLLM client.
|
|
26
|
+
|
|
27
|
+
Checks required keys present.
|
|
27
28
|
|
|
28
29
|
Raises:
|
|
29
30
|
ValueError: Raised in cases of invalid configuration:
|
|
@@ -40,8 +41,7 @@ class RasaLLMClientConfig:
|
|
|
40
41
|
|
|
41
42
|
@classmethod
|
|
42
43
|
def from_dict(cls, config: dict) -> RasaLLMClientConfig:
|
|
43
|
-
"""
|
|
44
|
-
Initializes a dataclass from the passed config.
|
|
44
|
+
"""Initializes a dataclass from the passed config.
|
|
45
45
|
|
|
46
46
|
Args:
|
|
47
47
|
config: (dict) The config from which to initialize.
|
|
@@ -61,8 +61,9 @@ FORBIDDEN_KEYS = [
|
|
|
61
61
|
|
|
62
62
|
@dataclass
|
|
63
63
|
class SelfHostedLLMClientConfig:
|
|
64
|
-
"""Parses configuration for Self Hosted LiteLLM client
|
|
65
|
-
|
|
64
|
+
"""Parses configuration for Self Hosted LiteLLM client.
|
|
65
|
+
|
|
66
|
+
Resolves aliases and raises deprecation warnings.
|
|
66
67
|
|
|
67
68
|
Raises:
|
|
68
69
|
ValueError: Raised in cases of invalid configuration:
|
|
@@ -116,8 +117,7 @@ class SelfHostedLLMClientConfig:
|
|
|
116
117
|
|
|
117
118
|
@classmethod
|
|
118
119
|
def from_dict(cls, config: dict) -> SelfHostedLLMClientConfig:
|
|
119
|
-
"""
|
|
120
|
-
Initializes a dataclass from the passed config.
|
|
120
|
+
"""Initializes a dataclass from the passed config.
|
|
121
121
|
|
|
122
122
|
Args:
|
|
123
123
|
config: (dict) The config from which to initialize.
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import asyncio
|
|
3
4
|
import logging
|
|
4
5
|
from abc import abstractmethod
|
|
5
|
-
from typing import Any, Dict, List, Union, cast
|
|
6
|
+
from typing import Any, Dict, List, NoReturn, Union, cast
|
|
6
7
|
|
|
7
8
|
import structlog
|
|
8
9
|
from litellm import acompletion, completion, validate_environment
|
|
9
10
|
|
|
11
|
+
from rasa.core.constants import DEFAULT_REQUEST_TIMEOUT
|
|
10
12
|
from rasa.shared.constants import (
|
|
11
13
|
_VALIDATE_ENVIRONMENT_MISSING_KEYS_KEY,
|
|
12
14
|
API_BASE_CONFIG_KEY,
|
|
@@ -57,26 +59,24 @@ class _BaseLiteLLMClient:
|
|
|
57
59
|
@property
|
|
58
60
|
@abstractmethod
|
|
59
61
|
def config(self) -> dict:
|
|
60
|
-
"""Returns the configuration for that the llm client
|
|
61
|
-
in dictionary form.
|
|
62
|
-
"""
|
|
62
|
+
"""Returns the configuration for that the llm client in dictionary form."""
|
|
63
63
|
pass
|
|
64
64
|
|
|
65
65
|
@property
|
|
66
66
|
@abstractmethod
|
|
67
67
|
def _litellm_model_name(self) -> str:
|
|
68
|
-
"""Returns the value of LiteLLM's model parameter
|
|
69
|
-
completion/acompletion in LiteLLM format:
|
|
68
|
+
"""Returns the value of LiteLLM's model parameter.
|
|
70
69
|
|
|
70
|
+
To be used in completion/acompletion in LiteLLM format:
|
|
71
71
|
<provider>/<model or deployment name>
|
|
72
72
|
"""
|
|
73
73
|
pass
|
|
74
74
|
|
|
75
75
|
@property
|
|
76
76
|
def _litellm_extra_parameters(self) -> Dict[str, Any]:
|
|
77
|
-
"""Returns a dictionary of extra parameters
|
|
78
|
-
parameters as well as LiteLLM specific input parameters.
|
|
77
|
+
"""Returns a dictionary of extra parameters.
|
|
79
78
|
|
|
79
|
+
Includes model parameters as well as LiteLLM specific input parameters.
|
|
80
80
|
By default, this returns an empty dictionary (no extra parameters).
|
|
81
81
|
"""
|
|
82
82
|
return {}
|
|
@@ -96,8 +96,9 @@ class _BaseLiteLLMClient:
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
def validate_client_setup(self) -> None:
|
|
99
|
-
"""Perform client validation.
|
|
100
|
-
|
|
99
|
+
"""Perform client validation.
|
|
100
|
+
|
|
101
|
+
By default only environment variables are validated.
|
|
101
102
|
|
|
102
103
|
Raises:
|
|
103
104
|
ProviderClientValidationError if validation fails.
|
|
@@ -178,8 +179,16 @@ class _BaseLiteLLMClient:
|
|
|
178
179
|
try:
|
|
179
180
|
formatted_messages = self._get_formatted_messages(messages)
|
|
180
181
|
arguments = resolve_environment_variables(self._completion_fn_args)
|
|
181
|
-
|
|
182
|
+
timeout = self._litellm_extra_parameters.get(
|
|
183
|
+
"timeout", DEFAULT_REQUEST_TIMEOUT
|
|
184
|
+
)
|
|
185
|
+
response = await asyncio.wait_for(
|
|
186
|
+
acompletion(messages=formatted_messages, **arguments),
|
|
187
|
+
timeout=timeout,
|
|
188
|
+
)
|
|
182
189
|
return self._format_response(response)
|
|
190
|
+
except asyncio.TimeoutError:
|
|
191
|
+
self._handle_timeout_error()
|
|
183
192
|
except Exception as e:
|
|
184
193
|
message = ""
|
|
185
194
|
from rasa.shared.providers.llm.self_hosted_llm_client import (
|
|
@@ -199,6 +208,25 @@ class _BaseLiteLLMClient:
|
|
|
199
208
|
)
|
|
200
209
|
raise ProviderClientAPIException(e, message)
|
|
201
210
|
|
|
211
|
+
def _handle_timeout_error(self) -> NoReturn:
|
|
212
|
+
"""Handle asyncio.TimeoutError and raise ProviderClientAPIException.
|
|
213
|
+
|
|
214
|
+
Raises:
|
|
215
|
+
ProviderClientAPIException: Always raised with formatted timeout error.
|
|
216
|
+
"""
|
|
217
|
+
timeout = self._litellm_extra_parameters.get("timeout", DEFAULT_REQUEST_TIMEOUT)
|
|
218
|
+
error_message = (
|
|
219
|
+
f"APITimeoutError - Request timed out. Error_str: "
|
|
220
|
+
f"Request timed out. - timeout value={timeout:.6f}, "
|
|
221
|
+
f"time taken={timeout:.6f} seconds"
|
|
222
|
+
)
|
|
223
|
+
# nosemgrep: semgrep.rules.pii-positional-arguments-in-logging
|
|
224
|
+
# Error message contains only numeric timeout values, not PII
|
|
225
|
+
structlogger.error(
|
|
226
|
+
f"{self.__class__.__name__.lower()}.llm.timeout", error=error_message
|
|
227
|
+
)
|
|
228
|
+
raise ProviderClientAPIException(asyncio.TimeoutError(error_message)) from None
|
|
229
|
+
|
|
202
230
|
def _get_formatted_messages(
|
|
203
231
|
self, messages: Union[List[dict], List[str], str]
|
|
204
232
|
) -> List[Dict[str, str]]:
|
|
@@ -280,8 +308,9 @@ class _BaseLiteLLMClient:
|
|
|
280
308
|
|
|
281
309
|
@staticmethod
|
|
282
310
|
def _ensure_certificates() -> None:
|
|
283
|
-
"""Configures SSL certificates for LiteLLM.
|
|
284
|
-
|
|
311
|
+
"""Configures SSL certificates for LiteLLM.
|
|
312
|
+
|
|
313
|
+
This method is invoked during client initialization.
|
|
285
314
|
|
|
286
315
|
LiteLLM may utilize `openai` clients or other providers that require
|
|
287
316
|
SSL verification settings through the `SSL_VERIFY` / `SSL_CERTIFICATE`
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import asyncio
|
|
3
4
|
import logging
|
|
4
5
|
from typing import Any, Dict, List, Union
|
|
5
6
|
|
|
6
7
|
import structlog
|
|
7
8
|
|
|
9
|
+
from rasa.core.constants import DEFAULT_REQUEST_TIMEOUT
|
|
8
10
|
from rasa.shared.exceptions import ProviderClientAPIException
|
|
9
11
|
from rasa.shared.providers._configs.litellm_router_client_config import (
|
|
10
12
|
LiteLLMRouterClientConfig,
|
|
@@ -79,13 +81,14 @@ class LiteLLMRouterLLMClient(_BaseLiteLLMRouterClient, _BaseLiteLLMClient):
|
|
|
79
81
|
|
|
80
82
|
@suppress_logs(log_level=logging.WARNING)
|
|
81
83
|
def _text_completion(self, prompt: Union[List[str], str]) -> LLMResponse:
|
|
82
|
-
"""
|
|
83
|
-
Synchronously generate completions for given prompt.
|
|
84
|
+
"""Synchronously generate completions for given prompt.
|
|
84
85
|
|
|
85
86
|
Args:
|
|
86
87
|
prompt: Prompt to generate the completion for.
|
|
88
|
+
|
|
87
89
|
Returns:
|
|
88
90
|
List of message completions.
|
|
91
|
+
|
|
89
92
|
Raises:
|
|
90
93
|
ProviderClientAPIException: If the API request fails.
|
|
91
94
|
"""
|
|
@@ -103,28 +106,36 @@ class LiteLLMRouterLLMClient(_BaseLiteLLMRouterClient, _BaseLiteLLMClient):
|
|
|
103
106
|
|
|
104
107
|
@suppress_logs(log_level=logging.WARNING)
|
|
105
108
|
async def _atext_completion(self, prompt: Union[List[str], str]) -> LLMResponse:
|
|
106
|
-
"""
|
|
107
|
-
Asynchronously generate completions for given prompt.
|
|
109
|
+
"""Asynchronously generate completions for given prompt.
|
|
108
110
|
|
|
109
111
|
Args:
|
|
110
112
|
prompt: Prompt to generate the completion for.
|
|
113
|
+
|
|
111
114
|
Returns:
|
|
112
115
|
List of message completions.
|
|
116
|
+
|
|
113
117
|
Raises:
|
|
114
118
|
ProviderClientAPIException: If the API request fails.
|
|
115
119
|
"""
|
|
116
120
|
try:
|
|
117
|
-
|
|
118
|
-
|
|
121
|
+
timeout = self._litellm_extra_parameters.get(
|
|
122
|
+
"timeout", DEFAULT_REQUEST_TIMEOUT
|
|
123
|
+
)
|
|
124
|
+
response = await asyncio.wait_for(
|
|
125
|
+
self.router_client.atext_completion(
|
|
126
|
+
prompt=prompt, **self._completion_fn_args
|
|
127
|
+
),
|
|
128
|
+
timeout=timeout,
|
|
119
129
|
)
|
|
120
130
|
return self._format_text_completion_response(response)
|
|
131
|
+
except asyncio.TimeoutError:
|
|
132
|
+
self._handle_timeout_error()
|
|
121
133
|
except Exception as e:
|
|
122
134
|
raise ProviderClientAPIException(e)
|
|
123
135
|
|
|
124
136
|
@suppress_logs(log_level=logging.WARNING)
|
|
125
137
|
def completion(self, messages: Union[List[dict], List[str], str]) -> LLMResponse:
|
|
126
|
-
"""
|
|
127
|
-
Synchronously generate completions for given list of messages.
|
|
138
|
+
"""Synchronously generate completions for given list of messages.
|
|
128
139
|
|
|
129
140
|
Method overrides the base class method to call the appropriate
|
|
130
141
|
completion method based on the configuration. If the chat completions
|
|
@@ -140,8 +151,10 @@ class LiteLLMRouterLLMClient(_BaseLiteLLMRouterClient, _BaseLiteLLMClient):
|
|
|
140
151
|
- a list of messages. Each message is a string and will be formatted
|
|
141
152
|
as a user message.
|
|
142
153
|
- a single message as a string which will be formatted as user message.
|
|
154
|
+
|
|
143
155
|
Returns:
|
|
144
156
|
List of message completions.
|
|
157
|
+
|
|
145
158
|
Raises:
|
|
146
159
|
ProviderClientAPIException: If the API request fails.
|
|
147
160
|
"""
|
|
@@ -160,8 +173,7 @@ class LiteLLMRouterLLMClient(_BaseLiteLLMRouterClient, _BaseLiteLLMClient):
|
|
|
160
173
|
async def acompletion(
|
|
161
174
|
self, messages: Union[List[dict], List[str], str]
|
|
162
175
|
) -> LLMResponse:
|
|
163
|
-
"""
|
|
164
|
-
Asynchronously generate completions for given list of messages.
|
|
176
|
+
"""Asynchronously generate completions for given list of messages.
|
|
165
177
|
|
|
166
178
|
Method overrides the base class method to call the appropriate
|
|
167
179
|
completion method based on the configuration. If the chat completions
|
|
@@ -177,8 +189,10 @@ class LiteLLMRouterLLMClient(_BaseLiteLLMRouterClient, _BaseLiteLLMClient):
|
|
|
177
189
|
- a list of messages. Each message is a string and will be formatted
|
|
178
190
|
as a user message.
|
|
179
191
|
- a single message as a string which will be formatted as user message.
|
|
192
|
+
|
|
180
193
|
Returns:
|
|
181
194
|
List of message completions.
|
|
195
|
+
|
|
182
196
|
Raises:
|
|
183
197
|
ProviderClientAPIException: If the API request fails.
|
|
184
198
|
"""
|
|
@@ -186,19 +200,28 @@ class LiteLLMRouterLLMClient(_BaseLiteLLMRouterClient, _BaseLiteLLMClient):
|
|
|
186
200
|
return await self._atext_completion(messages)
|
|
187
201
|
try:
|
|
188
202
|
formatted_messages = self._get_formatted_messages(messages)
|
|
189
|
-
|
|
190
|
-
|
|
203
|
+
timeout = self._litellm_extra_parameters.get(
|
|
204
|
+
"timeout", DEFAULT_REQUEST_TIMEOUT
|
|
205
|
+
)
|
|
206
|
+
response = await asyncio.wait_for(
|
|
207
|
+
self.router_client.acompletion(
|
|
208
|
+
messages=formatted_messages,
|
|
209
|
+
**self._completion_fn_args,
|
|
210
|
+
),
|
|
211
|
+
timeout=timeout,
|
|
191
212
|
)
|
|
192
213
|
return self._format_response(response)
|
|
214
|
+
except asyncio.TimeoutError:
|
|
215
|
+
self._handle_timeout_error()
|
|
193
216
|
except Exception as e:
|
|
194
217
|
raise ProviderClientAPIException(e)
|
|
195
218
|
|
|
196
219
|
@property
|
|
197
220
|
def _completion_fn_args(self) -> Dict[str, Any]:
|
|
198
|
-
"""Returns the completion arguments
|
|
199
|
-
LiteLLM's completion functions.
|
|
200
|
-
"""
|
|
221
|
+
"""Returns the completion arguments.
|
|
201
222
|
|
|
223
|
+
For invoking a call through LiteLLM's completion functions.
|
|
224
|
+
"""
|
|
202
225
|
return {
|
|
203
226
|
**self._litellm_extra_parameters,
|
|
204
227
|
LITE_LLM_MODEL_FIELD: self.model_group_id,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import asyncio
|
|
3
4
|
import logging
|
|
4
5
|
import os
|
|
5
6
|
from typing import Any, Dict, List, Optional, Union
|
|
@@ -7,6 +8,7 @@ from typing import Any, Dict, List, Optional, Union
|
|
|
7
8
|
import structlog
|
|
8
9
|
from litellm import atext_completion, text_completion
|
|
9
10
|
|
|
11
|
+
from rasa.core.constants import DEFAULT_REQUEST_TIMEOUT
|
|
10
12
|
from rasa.shared.constants import (
|
|
11
13
|
API_KEY,
|
|
12
14
|
SELF_HOSTED_VLLM_API_KEY_ENV_VAR,
|
|
@@ -28,7 +30,7 @@ structlogger = structlog.get_logger()
|
|
|
28
30
|
|
|
29
31
|
|
|
30
32
|
class SelfHostedLLMClient(_BaseLiteLLMClient):
|
|
31
|
-
"""A client for interfacing with Self Hosted LLM endpoints
|
|
33
|
+
"""A client for interfacing with Self Hosted LLM endpoints.
|
|
32
34
|
|
|
33
35
|
Parameters:
|
|
34
36
|
model (str): The model or deployment name.
|
|
@@ -95,8 +97,7 @@ class SelfHostedLLMClient(_BaseLiteLLMClient):
|
|
|
95
97
|
|
|
96
98
|
@property
|
|
97
99
|
def provider(self) -> str:
|
|
98
|
-
"""
|
|
99
|
-
Returns the provider name for the self hosted llm client.
|
|
100
|
+
"""Returns the provider name for the self hosted llm client.
|
|
100
101
|
|
|
101
102
|
Returns:
|
|
102
103
|
String representing the provider name.
|
|
@@ -105,8 +106,7 @@ class SelfHostedLLMClient(_BaseLiteLLMClient):
|
|
|
105
106
|
|
|
106
107
|
@property
|
|
107
108
|
def model(self) -> str:
|
|
108
|
-
"""
|
|
109
|
-
Returns the model name for the self hosted llm client.
|
|
109
|
+
"""Returns the model name for the self hosted llm client.
|
|
110
110
|
|
|
111
111
|
Returns:
|
|
112
112
|
String representing the model name.
|
|
@@ -115,8 +115,7 @@ class SelfHostedLLMClient(_BaseLiteLLMClient):
|
|
|
115
115
|
|
|
116
116
|
@property
|
|
117
117
|
def api_base(self) -> str:
|
|
118
|
-
"""
|
|
119
|
-
Returns the base URL for the API endpoint.
|
|
118
|
+
"""Returns the base URL for the API endpoint.
|
|
120
119
|
|
|
121
120
|
Returns:
|
|
122
121
|
String representing the base URL.
|
|
@@ -125,8 +124,7 @@ class SelfHostedLLMClient(_BaseLiteLLMClient):
|
|
|
125
124
|
|
|
126
125
|
@property
|
|
127
126
|
def api_type(self) -> Optional[str]:
|
|
128
|
-
"""
|
|
129
|
-
Returns the type of the API endpoint. Currently only OpenAI is supported.
|
|
127
|
+
"""Returns the type of the API endpoint. Currently only OpenAI is supported.
|
|
130
128
|
|
|
131
129
|
Returns:
|
|
132
130
|
String representing the API type.
|
|
@@ -135,8 +133,7 @@ class SelfHostedLLMClient(_BaseLiteLLMClient):
|
|
|
135
133
|
|
|
136
134
|
@property
|
|
137
135
|
def api_version(self) -> Optional[str]:
|
|
138
|
-
"""
|
|
139
|
-
Returns the version of the API endpoint.
|
|
136
|
+
"""Returns the version of the API endpoint.
|
|
140
137
|
|
|
141
138
|
Returns:
|
|
142
139
|
String representing the API version.
|
|
@@ -145,8 +142,8 @@ class SelfHostedLLMClient(_BaseLiteLLMClient):
|
|
|
145
142
|
|
|
146
143
|
@property
|
|
147
144
|
def config(self) -> Dict:
|
|
148
|
-
"""
|
|
149
|
-
|
|
145
|
+
"""Returns the configuration for the self hosted llm client.
|
|
146
|
+
|
|
150
147
|
Returns:
|
|
151
148
|
Dictionary containing the configuration.
|
|
152
149
|
"""
|
|
@@ -163,9 +160,9 @@ class SelfHostedLLMClient(_BaseLiteLLMClient):
|
|
|
163
160
|
|
|
164
161
|
@property
|
|
165
162
|
def _litellm_model_name(self) -> str:
|
|
166
|
-
"""Returns the value of LiteLLM's model parameter
|
|
167
|
-
completion/acompletion in LiteLLM format:
|
|
163
|
+
"""Returns the value of LiteLLM's model parameter.
|
|
168
164
|
|
|
165
|
+
To be used in completion/acompletion in LiteLLM format:
|
|
169
166
|
<hosted_vllm>/<model or deployment name>
|
|
170
167
|
"""
|
|
171
168
|
if self.model and f"{SELF_HOSTED_VLLM_PREFIX}/" not in self.model:
|
|
@@ -174,15 +171,17 @@ class SelfHostedLLMClient(_BaseLiteLLMClient):
|
|
|
174
171
|
|
|
175
172
|
@property
|
|
176
173
|
def _litellm_extra_parameters(self) -> Dict[str, Any]:
|
|
177
|
-
"""Returns optional configuration parameters
|
|
178
|
-
|
|
174
|
+
"""Returns optional configuration parameters.
|
|
175
|
+
|
|
176
|
+
Specific to the client provider and deployed model.
|
|
179
177
|
"""
|
|
180
178
|
return self._extra_parameters
|
|
181
179
|
|
|
182
180
|
@property
|
|
183
181
|
def _completion_fn_args(self) -> Dict[str, Any]:
|
|
184
|
-
"""Returns the completion arguments
|
|
185
|
-
|
|
182
|
+
"""Returns the completion arguments.
|
|
183
|
+
|
|
184
|
+
For invoking a call through LiteLLM's completion functions.
|
|
186
185
|
"""
|
|
187
186
|
fn_args = super()._completion_fn_args
|
|
188
187
|
fn_args.update(
|
|
@@ -195,13 +194,14 @@ class SelfHostedLLMClient(_BaseLiteLLMClient):
|
|
|
195
194
|
|
|
196
195
|
@suppress_logs(log_level=logging.WARNING)
|
|
197
196
|
def _text_completion(self, prompt: Union[List[str], str]) -> LLMResponse:
|
|
198
|
-
"""
|
|
199
|
-
Synchronously generate completions for given prompt.
|
|
197
|
+
"""Synchronously generate completions for given prompt.
|
|
200
198
|
|
|
201
199
|
Args:
|
|
202
200
|
prompt: Prompt to generate the completion for.
|
|
201
|
+
|
|
203
202
|
Returns:
|
|
204
203
|
List of message completions.
|
|
204
|
+
|
|
205
205
|
Raises:
|
|
206
206
|
ProviderClientAPIException: If the API request fails.
|
|
207
207
|
"""
|
|
@@ -213,26 +213,28 @@ class SelfHostedLLMClient(_BaseLiteLLMClient):
|
|
|
213
213
|
|
|
214
214
|
@suppress_logs(log_level=logging.WARNING)
|
|
215
215
|
async def _atext_completion(self, prompt: Union[List[str], str]) -> LLMResponse:
|
|
216
|
-
"""
|
|
217
|
-
Asynchronously generate completions for given prompt.
|
|
216
|
+
"""Asynchronously generate completions for given prompt.
|
|
218
217
|
|
|
219
218
|
Args:
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
with the following keys:
|
|
223
|
-
- content: The message content.
|
|
224
|
-
- role: The role of the message (e.g. user or system).
|
|
225
|
-
- a list of messages. Each message is a string and will be formatted
|
|
226
|
-
as a user message.
|
|
227
|
-
- a single message as a string which will be formatted as user message.
|
|
219
|
+
prompt: Prompt to generate the completion for.
|
|
220
|
+
|
|
228
221
|
Returns:
|
|
229
222
|
List of message completions.
|
|
223
|
+
|
|
230
224
|
Raises:
|
|
231
225
|
ProviderClientAPIException: If the API request fails.
|
|
232
226
|
"""
|
|
233
227
|
try:
|
|
234
|
-
|
|
228
|
+
timeout = self._litellm_extra_parameters.get(
|
|
229
|
+
"timeout", DEFAULT_REQUEST_TIMEOUT
|
|
230
|
+
)
|
|
231
|
+
response = await asyncio.wait_for(
|
|
232
|
+
atext_completion(prompt=prompt, **self._completion_fn_args),
|
|
233
|
+
timeout=timeout,
|
|
234
|
+
)
|
|
235
235
|
return self._format_text_completion_response(response)
|
|
236
|
+
except asyncio.TimeoutError:
|
|
237
|
+
self._handle_timeout_error()
|
|
236
238
|
except Exception as e:
|
|
237
239
|
raise ProviderClientAPIException(e)
|
|
238
240
|
|
rasa/utils/endpoints.py
CHANGED
|
@@ -8,6 +8,7 @@ import structlog
|
|
|
8
8
|
from aiohttp.client_exceptions import ContentTypeError
|
|
9
9
|
from sanic.request import Request
|
|
10
10
|
|
|
11
|
+
from rasa.core.actions.constants import MISSING_DOMAIN_MARKER
|
|
11
12
|
from rasa.core.constants import DEFAULT_REQUEST_TIMEOUT
|
|
12
13
|
from rasa.shared.exceptions import FileNotFoundException
|
|
13
14
|
from rasa.shared.utils.yaml import read_config_file
|
|
@@ -207,6 +208,11 @@ class EndpointConfig:
|
|
|
207
208
|
ssl=sslcontext,
|
|
208
209
|
**kwargs,
|
|
209
210
|
) as response:
|
|
211
|
+
if response.status == 449:
|
|
212
|
+
# Return a special marker that HTTPCustomActionExecutor can detect
|
|
213
|
+
# This avoids raising an exception for this expected case
|
|
214
|
+
return {MISSING_DOMAIN_MARKER: True}
|
|
215
|
+
|
|
210
216
|
if response.status >= 400:
|
|
211
217
|
raise ClientResponseError(
|
|
212
218
|
response.status,
|
rasa/version.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: rasa-pro
|
|
3
|
-
Version: 3.12.
|
|
3
|
+
Version: 3.12.37
|
|
4
4
|
Summary: State-of-the-art open-core Conversational AI framework for Enterprises that natively leverages generative AI for effortless assistant development.
|
|
5
5
|
Keywords: nlp,machine-learning,machine-learning-library,bot,bots,botkit,rasa conversational-agents,conversational-ai,chatbot,chatbot-framework,bot-framework
|
|
6
6
|
Author: Rasa Technologies GmbH
|
|
@@ -60,8 +60,8 @@ Requires-Dist: jsonpatch (>=1.33,<2.0)
|
|
|
60
60
|
Requires-Dist: jsonpickle (>=3.3.0,<3.4)
|
|
61
61
|
Requires-Dist: jsonschema (>=4.22)
|
|
62
62
|
Requires-Dist: keras (==2.14.0)
|
|
63
|
-
Requires-Dist: langchain (>=0.
|
|
64
|
-
Requires-Dist: langchain-community (>=0.
|
|
63
|
+
Requires-Dist: langchain (>=0.3.27,<0.4.0)
|
|
64
|
+
Requires-Dist: langchain-community (>=0.3.29,<0.4.0)
|
|
65
65
|
Requires-Dist: langcodes (>=3.5.0,<4.0.0)
|
|
66
66
|
Requires-Dist: litellm (>=1.69.0,<1.70.0)
|
|
67
67
|
Requires-Dist: matplotlib (>=3.7,<3.8)
|
|
@@ -138,7 +138,7 @@ Requires-Dist: tensorflow_hub (>=0.13.0,<0.14.0)
|
|
|
138
138
|
Requires-Dist: terminaltables (>=3.1.10,<3.2.0)
|
|
139
139
|
Requires-Dist: tiktoken (>=0.7.0,<0.8.0)
|
|
140
140
|
Requires-Dist: tqdm (>=4.66.2,<5.0.0)
|
|
141
|
-
Requires-Dist: transformers (>=4.
|
|
141
|
+
Requires-Dist: transformers (>=4.38.2,<4.39.0) ; extra == "transformers" or extra == "full"
|
|
142
142
|
Requires-Dist: twilio (>=8.4,<8.5)
|
|
143
143
|
Requires-Dist: types-protobuf (==4.25.0.20240417)
|
|
144
144
|
Requires-Dist: typing-extensions (>=4.7.1,<5.0.0)
|
|
@@ -93,7 +93,7 @@ rasa/constants.py,sha256=2a_0Cn-xiJIyZ7ze2N2N59X3CmE8MHVib6B_zIGv_OI,1408
|
|
|
93
93
|
rasa/core/__init__.py,sha256=wTSmsFlgK0Ylvuyq20q9APwpT5xyVJYZfzhs4rrkciM,456
|
|
94
94
|
rasa/core/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
95
95
|
rasa/core/actions/action.py,sha256=gsxIFNgSKeNV2yBaqwR4_K5-cvWCKapcFTeSFo0qA2c,42667
|
|
96
|
-
rasa/core/actions/action_clean_stack.py,sha256=
|
|
96
|
+
rasa/core/actions/action_clean_stack.py,sha256=Zs3Pq9za8HamJq3H6IYTXd8dKE-NC0ThSWgdbTNmCFU,3670
|
|
97
97
|
rasa/core/actions/action_exceptions.py,sha256=hghzXYN6VeHC-O_O7WiPesCNV86ZTkHgG90ZnQcbai8,724
|
|
98
98
|
rasa/core/actions/action_hangup.py,sha256=o5iklHG-F9IcRgWis5C6AumVXznxzAV3o9zdduhozEM,994
|
|
99
99
|
rasa/core/actions/action_repeat_bot_messages.py,sha256=T7bJH0fsxFQgbkCZZ5dnPi8v18-2X9QZZLfAHmmn7WI,3466
|
|
@@ -101,13 +101,13 @@ rasa/core/actions/action_run_slot_rejections.py,sha256=Rng5h-h5b63HisUeSFZXQ3FnN
|
|
|
101
101
|
rasa/core/actions/action_trigger_chitchat.py,sha256=krOPqCXBihxOskqmm05A4mFEm4lj4ohvzuddy7rELVQ,1084
|
|
102
102
|
rasa/core/actions/action_trigger_flow.py,sha256=IydYAGafTtoY6XSgCX124xJQhzudUg8JAICstqsV3VA,3487
|
|
103
103
|
rasa/core/actions/action_trigger_search.py,sha256=QfYqnaGRCqRYJ4msYsLAbnVYW5ija_tqhCcKIN8aEfw,1064
|
|
104
|
-
rasa/core/actions/constants.py,sha256=
|
|
105
|
-
rasa/core/actions/custom_action_executor.py,sha256=
|
|
104
|
+
rasa/core/actions/constants.py,sha256=7ek4eYaaDzDudP40pFJ38nU2f-Kh2cnvhEff8mr3jsE,301
|
|
105
|
+
rasa/core/actions/custom_action_executor.py,sha256=mcs8xfZn9lbp5uV2JLhDFC64ivnH5J7ZzpFxaHpJ1jc,8212
|
|
106
106
|
rasa/core/actions/direct_custom_actions_executor.py,sha256=zGHI3cXVRfyzaaGSH7VePXHQxsDAvF0iAZSEcOuM-_M,4026
|
|
107
107
|
rasa/core/actions/e2e_stub_custom_action_executor.py,sha256=D-kECC1QjVLv4owNxstW2xJPPsXTGfGepvquMeWB_ec,2282
|
|
108
108
|
rasa/core/actions/forms.py,sha256=MPGxp3vg-EgFcU5UQYqWM2tycSFIuoF6vWvNSSWPhSA,26967
|
|
109
|
-
rasa/core/actions/grpc_custom_action_executor.py,sha256=
|
|
110
|
-
rasa/core/actions/http_custom_action_executor.py,sha256=
|
|
109
|
+
rasa/core/actions/grpc_custom_action_executor.py,sha256=GMzO_JaocQJjoPZ0yFvBkFHKwhl6SlFZOnt4By-1ZAI,10761
|
|
110
|
+
rasa/core/actions/http_custom_action_executor.py,sha256=GLYxCjoj-GohrVaqxjNtm9npN47kYZfHa06u15ThTBQ,6662
|
|
111
111
|
rasa/core/actions/loops.py,sha256=3-kt_Sn_Y05PLYoYMsnuIn9e5mxYp31DJIx2omqy0dU,3531
|
|
112
112
|
rasa/core/actions/two_stage_fallback.py,sha256=k8PkD25fvH3kThG9lpC6oLMK7o15kV4yEbv2E2nyans,6065
|
|
113
113
|
rasa/core/agent.py,sha256=NX3qqrzi2Qi5isJw5yR7dyN4hIZnhmaV1GoVySX9Omk,20750
|
|
@@ -291,7 +291,7 @@ rasa/core/channels/voice_stream/tts/tts_cache.py,sha256=K4S2d8zWX2h2ylYALp7IdqFS
|
|
|
291
291
|
rasa/core/channels/voice_stream/tts/tts_engine.py,sha256=JMCWGHxT8QiqKoBeI6F4RX_-Q9EEqG3vUtkgOUnlt-w,1812
|
|
292
292
|
rasa/core/channels/voice_stream/twilio_media_streams.py,sha256=cM09rwGpbyFD9lCfmWBjHE1XS-F4ufpSbvwJACHpVmI,9094
|
|
293
293
|
rasa/core/channels/voice_stream/util.py,sha256=d0Tl0tGAnVj3SgGovsUMHx-QL44nrPI29OTYKYleH0U,1987
|
|
294
|
-
rasa/core/channels/voice_stream/voice_channel.py,sha256=
|
|
294
|
+
rasa/core/channels/voice_stream/voice_channel.py,sha256=sR23RYw2czPoDzM__2WfnDqHPIVkVoWesuz7OVqKylI,20046
|
|
295
295
|
rasa/core/channels/webexteams.py,sha256=z_o_jnc6B7hsHpd6XorImFkF43wB4yx_kiTPKAjPSuo,4805
|
|
296
296
|
rasa/core/concurrent_lock_store.py,sha256=ycd-aeJJWXIokMRimCdQFHdwuMfl512hZSUHE8oSd2c,7722
|
|
297
297
|
rasa/core/constants.py,sha256=dEokmEf6XkOFA_xpuwjqwNtlZv-a5Tz5dLMRc7Vu4CU,4070
|
|
@@ -400,7 +400,7 @@ rasa/dialogue_understanding/generator/command_parser.py,sha256=wf6FSgqBw5F0legg0
|
|
|
400
400
|
rasa/dialogue_understanding/generator/constants.py,sha256=ulqmLIwrBOZLyhsCChI_4CdOnA0I8MfuBxxuKGyFp7U,1130
|
|
401
401
|
rasa/dialogue_understanding/generator/flow_document_template.jinja2,sha256=f4H6vVd-_nX_RtutMh1xD3ZQE_J2OyuPHAtiltfiAPY,253
|
|
402
402
|
rasa/dialogue_understanding/generator/flow_retrieval.py,sha256=D-D6bvYt_GDLoRQzhvlTEPnmZI4ceESLJBLWrMgUyrA,18120
|
|
403
|
-
rasa/dialogue_understanding/generator/llm_based_command_generator.py,sha256=
|
|
403
|
+
rasa/dialogue_understanding/generator/llm_based_command_generator.py,sha256=VHUecm7-alZ8POedNYzQoQWALqRx8VUPXnNVOCfVTOY,23705
|
|
404
404
|
rasa/dialogue_understanding/generator/llm_command_generator.py,sha256=z7jhIJ3W_5GFH-p15kVoWbigMIoY8fIJjc_j_uX7yxw,2581
|
|
405
405
|
rasa/dialogue_understanding/generator/multi_step/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
406
406
|
rasa/dialogue_understanding/generator/multi_step/fill_slots_prompt.jinja2,sha256=Y0m673tAML3cFPaLM-urMXDsBYUUcXIw9YUpkAhGUuA,2933
|
|
@@ -412,7 +412,7 @@ rasa/dialogue_understanding/generator/prompt_templates/command_prompt_template.j
|
|
|
412
412
|
rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2,sha256=z-cnFVfIE_kEnY1o52YE2CdCWwgYTv7R3xVxsjXWlnw,3808
|
|
413
413
|
rasa/dialogue_understanding/generator/prompt_templates/command_prompt_v2_gpt_4o_2024_11_20_template.jinja2,sha256=4076ARsy0E0iADBX6li19IoM3F4F-2wK3bL6UEOvCdo,3620
|
|
414
414
|
rasa/dialogue_understanding/generator/single_step/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
415
|
-
rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py,sha256=
|
|
415
|
+
rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py,sha256=6ND3gofyw3WIJY2pVDy2gBpa7AZoJLNnCQ6CKBs-H_I,22817
|
|
416
416
|
rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py,sha256=RWTPdeBfdGUmdFSUzdQejcbJJLhc_815G0g6AabTK04,5100
|
|
417
417
|
rasa/dialogue_understanding/generator/utils.py,sha256=jxtb-AfngN59y2rHynqJDK80xM_yooEvr3aW1MWl6H0,2760
|
|
418
418
|
rasa/dialogue_understanding/patterns/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -436,7 +436,7 @@ rasa/dialogue_understanding/patterns/skip_question.py,sha256=fJ1MC0WEEtS-BpnGJEf
|
|
|
436
436
|
rasa/dialogue_understanding/patterns/user_silence.py,sha256=xP-QMnd-MsybH5z4g01hBv4OLOHcw6m3rc26LQfe2zo,1140
|
|
437
437
|
rasa/dialogue_understanding/patterns/validate_slot.py,sha256=hqd5AEGT3M3HLNhMwuI9W9kZNCvgU6GyI-2xc2b4kz8,2085
|
|
438
438
|
rasa/dialogue_understanding/processor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
439
|
-
rasa/dialogue_understanding/processor/command_processor.py,sha256=
|
|
439
|
+
rasa/dialogue_understanding/processor/command_processor.py,sha256=bLjqIMvsjLMFQdghuffsTHzQEw8xkTaTE-BXA3gV2kQ,33889
|
|
440
440
|
rasa/dialogue_understanding/processor/command_processor_component.py,sha256=rkErI_Uo7s3LsEojUSGSRbWGyGaX7GtGOYSJn0V-TI4,1650
|
|
441
441
|
rasa/dialogue_understanding/stack/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
442
442
|
rasa/dialogue_understanding/stack/dialogue_stack.py,sha256=cYV6aQeh0EuOJHODDqK3biqXozYTX8baPgLwHhPxFqs,5244
|
|
@@ -634,7 +634,7 @@ rasa/shared/core/domain.py,sha256=piJu4Kr2exC9ehC3e2oNaxPxXkeIhOYoQJQQOuzMw18,81
|
|
|
634
634
|
rasa/shared/core/events.py,sha256=kTUWSpDepj3kpjjXveYXz3h2XcIQV3Sq8h7MTbx5fMw,86489
|
|
635
635
|
rasa/shared/core/flows/__init__.py,sha256=Z4pBY0qcEbHeOwgmKsyg2Nz4dX9CF67fFCwj2KXSMpg,180
|
|
636
636
|
rasa/shared/core/flows/constants.py,sha256=uno5qtsWl8lxELsDe04_5tJH1tBgj6uRRr_g83s10xA,404
|
|
637
|
-
rasa/shared/core/flows/flow.py,sha256=
|
|
637
|
+
rasa/shared/core/flows/flow.py,sha256=Avb7hwO_NUFwnR53Jp4DhHxZA6s3CDcKNtGDSYONwn0,28712
|
|
638
638
|
rasa/shared/core/flows/flow_path.py,sha256=xstwahZBU5cfMY46mREA4NoOGlKLBRAqeP_mJ3UZqOI,2283
|
|
639
639
|
rasa/shared/core/flows/flow_step.py,sha256=ZvjXz1Fs5FR1_BlGBitOEYRnLhzk-bBYv1CC2Oi6iWQ,4537
|
|
640
640
|
rasa/shared/core/flows/flow_step_links.py,sha256=U9c4MFASieJGp_-XMhR0hrxFQISCJAF4TQ0wEy4IjB0,10530
|
|
@@ -711,16 +711,16 @@ rasa/shared/nlu/training_data/util.py,sha256=SCd97o6dDhbodasRK3JuaiAA1Xcy0faEMTj
|
|
|
711
711
|
rasa/shared/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
712
712
|
rasa/shared/providers/_configs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
713
713
|
rasa/shared/providers/_configs/azure_entra_id_config.py,sha256=MnvWRlCN-nFv5wb8AtFPM1tymCr72jmhI-MQgZZphAs,19392
|
|
714
|
-
rasa/shared/providers/_configs/azure_openai_client_config.py,sha256=
|
|
714
|
+
rasa/shared/providers/_configs/azure_openai_client_config.py,sha256=yHG8pEWRKnqC1G7LaSVhOaXqpZc94hGJjw12t73F4b8,10796
|
|
715
715
|
rasa/shared/providers/_configs/client_config.py,sha256=nQ469h1XI970_7Vs49hNIpBIwlAeiAg-cwV0JFp7Hg0,1618
|
|
716
|
-
rasa/shared/providers/_configs/default_litellm_client_config.py,sha256=
|
|
716
|
+
rasa/shared/providers/_configs/default_litellm_client_config.py,sha256=FZL8HX-7TxG78nkWoszaHn7Q5cdUrlKI9HprYXZ4A9Y,4344
|
|
717
717
|
rasa/shared/providers/_configs/huggingface_local_embedding_client_config.py,sha256=q8ddTFwddDhx654ZQmg9eP_yo77N3Xg77hAmfXOmzPg,8200
|
|
718
|
-
rasa/shared/providers/_configs/litellm_router_client_config.py,sha256=
|
|
718
|
+
rasa/shared/providers/_configs/litellm_router_client_config.py,sha256=KsL4XeaOTzAAf3gQq9jouxj05NViB6GoXiYn2A567Vg,7266
|
|
719
719
|
rasa/shared/providers/_configs/model_group_config.py,sha256=gcvRY86StqCLqAOxLh-2sWEPxMNnwt43vR3QaviElZI,5618
|
|
720
720
|
rasa/shared/providers/_configs/oauth_config.py,sha256=eMHaXdSwiYqe4LC_UhDPJcrE7tqv3HDc8ghgkhwcYo4,791
|
|
721
|
-
rasa/shared/providers/_configs/openai_client_config.py,sha256=
|
|
722
|
-
rasa/shared/providers/_configs/rasa_llm_client_config.py,sha256=
|
|
723
|
-
rasa/shared/providers/_configs/self_hosted_llm_client_config.py,sha256=
|
|
721
|
+
rasa/shared/providers/_configs/openai_client_config.py,sha256=7LVfZGvbDuFMcBVDCanpYSHq__HO_ndpnDXGyTEP-6Y,5967
|
|
722
|
+
rasa/shared/providers/_configs/rasa_llm_client_config.py,sha256=6pxrhasLwrgbLMPJlMWG8Q0m4EsegIb108BhFugeDu4,2237
|
|
723
|
+
rasa/shared/providers/_configs/self_hosted_llm_client_config.py,sha256=AaoX-_Ik1UVJ-rb_w47wwk8Yb3f70lZS34sAqKzWRtk,5955
|
|
724
724
|
rasa/shared/providers/_configs/utils.py,sha256=u2Ram05YwQ7-frm_r8n9rafjZoF8i0qSC7XjYQRuPgo,3732
|
|
725
725
|
rasa/shared/providers/_ssl_verification_utils.py,sha256=vUnP0vocf0GQ0wG8IQpPcCet4c1C9-wQWQNckNWbDBk,4165
|
|
726
726
|
rasa/shared/providers/_utils.py,sha256=EZIrz3ugcI-9PWgC7v0VMUNYondAAOeeRLIE8ZmResw,5886
|
|
@@ -736,15 +736,15 @@ rasa/shared/providers/embedding/huggingface_local_embedding_client.py,sha256=Zo3
|
|
|
736
736
|
rasa/shared/providers/embedding/litellm_router_embedding_client.py,sha256=eafDk6IgQtL_kiKgpa6sJs1oATyRi2NT2leUFQsED2s,4551
|
|
737
737
|
rasa/shared/providers/embedding/openai_embedding_client.py,sha256=XNRGE7apo2v3kWRrtgxE-Gq4rvNko3IiXtvgC4krDYE,5429
|
|
738
738
|
rasa/shared/providers/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
739
|
-
rasa/shared/providers/llm/_base_litellm_client.py,sha256=
|
|
739
|
+
rasa/shared/providers/llm/_base_litellm_client.py,sha256=4vAbQihXHscPHOpxIWvVqhVMyu4f2X-JZDjZGDxiaSY,12872
|
|
740
740
|
rasa/shared/providers/llm/azure_openai_llm_client.py,sha256=ui85vothxR2P_-eLc4nLgbpjnpEKY2BXnIjLxBZoYz8,12504
|
|
741
741
|
rasa/shared/providers/llm/default_litellm_llm_client.py,sha256=xx-o-NX_mtx6AszK--ZRj8n8JyEJuVu1-42dt8AynBM,4083
|
|
742
|
-
rasa/shared/providers/llm/litellm_router_llm_client.py,sha256=
|
|
742
|
+
rasa/shared/providers/llm/litellm_router_llm_client.py,sha256=3EzRtWyGYqrBTKP7lFbq1tnzwhCcPJaLPfpzfhsoTnQ,8608
|
|
743
743
|
rasa/shared/providers/llm/llm_client.py,sha256=-hTCRsL-A3GCMRHtcyCgcCyra-9OJ8GUC-mURoRXH0k,3242
|
|
744
744
|
rasa/shared/providers/llm/llm_response.py,sha256=8mOpZdmh4-3yM7aOmNO0yEYUmRDErfoP7ZDMUuHr2Cc,3504
|
|
745
745
|
rasa/shared/providers/llm/openai_llm_client.py,sha256=rSdLj29Hl1Wm5G6Uwo77j4WqogK_3QIbTA7fyt63YAg,5013
|
|
746
746
|
rasa/shared/providers/llm/rasa_llm_client.py,sha256=44Tvtnkq4mxDIxtdrGUkwBWAvX1OLaswqmpAsyBH8e8,3504
|
|
747
|
-
rasa/shared/providers/llm/self_hosted_llm_client.py,sha256=
|
|
747
|
+
rasa/shared/providers/llm/self_hosted_llm_client.py,sha256=aPjRrwXClfcRayFLyq_grSyKrDoUvFQQzLvHELA10vM,10099
|
|
748
748
|
rasa/shared/providers/mappings.py,sha256=QSD3XWvhYCtBLNpGycN30vEnLULYIaqCsAtmfPfSZ3U,3674
|
|
749
749
|
rasa/shared/providers/router/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
750
750
|
rasa/shared/providers/router/_base_litellm_router_client.py,sha256=JV9lYnhIG_CWMtPB5nofjNdRO5V-Wl0DH-HyPm__eJ0,11003
|
|
@@ -791,7 +791,7 @@ rasa/utils/beta.py,sha256=h2xwGagMh2SnpMuqhkEAEjL7C_CyU6b1te7sbtF-lm4,3240
|
|
|
791
791
|
rasa/utils/cli.py,sha256=L-DT4nPdVBWfc2m1COHrziLitVWJxazSreb6JLbTho4,865
|
|
792
792
|
rasa/utils/common.py,sha256=n7SkgvhBVPFmtS4FS7osH9R0dzTgrlzt_4wsohY5rWg,21281
|
|
793
793
|
rasa/utils/converter.py,sha256=H4LHpoAK7MXMmvNZG_uSn0gbccCJvHtsA2-6Zya4u6M,1656
|
|
794
|
-
rasa/utils/endpoints.py,sha256=
|
|
794
|
+
rasa/utils/endpoints.py,sha256=5JqSUZbN20AlS9lM7KzhRVKwc8Xa17YZlbO1gXVVtig,10401
|
|
795
795
|
rasa/utils/io.py,sha256=LIAdQQqUPA-V_mdpgeQzPDzA4rmsdZLyVKc8j_0Z70Y,7161
|
|
796
796
|
rasa/utils/json_utils.py,sha256=SKtJzzsIRCAgNEQiBvWDDm9euMRBgJ-TyvCi2tXHH1w,1689
|
|
797
797
|
rasa/utils/licensing.py,sha256=f9K2geFK9j1loq6X9t3HGCzRBfxD-Pg7NStWX0lLu4k,20490
|
|
@@ -822,9 +822,9 @@ rasa/utils/train_utils.py,sha256=ClJx-6x3-h3Vt6mskacgkcCUJTMXjFPe3zAcy_DfmaU,212
|
|
|
822
822
|
rasa/utils/url_tools.py,sha256=dZ1HGkVdWTJB7zYEdwoDIrEuyX9HE5WsxKKFVsXBLE0,1218
|
|
823
823
|
rasa/utils/yaml.py,sha256=KjbZq5C94ZP7Jdsw8bYYF7HASI6K4-C_kdHfrnPLpSI,2000
|
|
824
824
|
rasa/validator.py,sha256=524VlFTYK0B3iXYveVD6BDC3K0j1QfpzJ9O-TAWczmc,83166
|
|
825
|
-
rasa/version.py,sha256=
|
|
826
|
-
rasa_pro-3.12.
|
|
827
|
-
rasa_pro-3.12.
|
|
828
|
-
rasa_pro-3.12.
|
|
829
|
-
rasa_pro-3.12.
|
|
830
|
-
rasa_pro-3.12.
|
|
825
|
+
rasa/version.py,sha256=iZ8zfgJNNtWAHrQj41VHNaYqkzPy-7OgLMgEU2siJ8I,118
|
|
826
|
+
rasa_pro-3.12.37.dist-info/METADATA,sha256=pQWqdn9j79NkqnJP843g8EPrrgaQKsIIN2_6-HzAf3I,10609
|
|
827
|
+
rasa_pro-3.12.37.dist-info/NOTICE,sha256=7HlBoMHJY9CL2GlYSfTQ-PZsVmLmVkYmMiPlTjhuCqA,218
|
|
828
|
+
rasa_pro-3.12.37.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
829
|
+
rasa_pro-3.12.37.dist-info/entry_points.txt,sha256=ckJ2SfEyTPgBqj_I6vm_tqY9dZF_LAPJZA335Xp0Q9U,43
|
|
830
|
+
rasa_pro-3.12.37.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|