rasa-pro 3.14.0.dev2__py3-none-any.whl → 3.14.0.dev3__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/agents/agent_manager.py +2 -2
- rasa/agents/constants.py +1 -0
- rasa/agents/protocol/mcp/mcp_base_agent.py +31 -54
- rasa/agents/protocol/mcp/mcp_open_agent.py +3 -2
- rasa/agents/protocol/mcp/mcp_task_agent.py +38 -16
- rasa/agents/schemas/__init__.py +8 -2
- rasa/agents/schemas/agent_input.py +15 -1
- rasa/agents/schemas/agent_tool_schema.py +23 -1
- rasa/agents/templates/mcp_task_agent_prompt_template.jinja2 +6 -2
- rasa/core/policies/flow_policy.py +2 -2
- rasa/core/policies/flows/flow_executor.py +54 -16
- rasa/core/policies/flows/mcp_tool_executor.py +48 -11
- rasa/dialogue_understanding/commands/start_flow_command.py +36 -1
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +5 -5
- rasa/dialogue_understanding/processor/command_processor.py +31 -15
- rasa/dialogue_understanding/stack/utils.py +14 -0
- rasa/shared/core/flows/flows_yaml_schema.json +12 -1
- rasa/shared/core/flows/steps/call.py +2 -0
- rasa/shared/core/flows/validation.py +3 -2
- rasa/utils/common.py +26 -0
- rasa/version.py +1 -1
- {rasa_pro-3.14.0.dev2.dist-info → rasa_pro-3.14.0.dev3.dist-info}/METADATA +1 -1
- {rasa_pro-3.14.0.dev2.dist-info → rasa_pro-3.14.0.dev3.dist-info}/RECORD +26 -26
- {rasa_pro-3.14.0.dev2.dist-info → rasa_pro-3.14.0.dev3.dist-info}/NOTICE +0 -0
- {rasa_pro-3.14.0.dev2.dist-info → rasa_pro-3.14.0.dev3.dist-info}/WHEEL +0 -0
- {rasa_pro-3.14.0.dev2.dist-info → rasa_pro-3.14.0.dev3.dist-info}/entry_points.txt +0 -0
rasa/agents/agent_manager.py
CHANGED
|
@@ -77,6 +77,8 @@ class AgentManager(metaclass=Singleton):
|
|
|
77
77
|
Raises:
|
|
78
78
|
ConnectionError: If the agent connection fails.
|
|
79
79
|
"""
|
|
80
|
+
# Add the agent to the manager
|
|
81
|
+
agent_identifier = make_agent_identifier(agent_name, protocol_type)
|
|
80
82
|
try:
|
|
81
83
|
# Create the agent client
|
|
82
84
|
client = AgentFactory.create_client(protocol_type, config)
|
|
@@ -84,8 +86,6 @@ class AgentManager(metaclass=Singleton):
|
|
|
84
86
|
# Connect the agent client
|
|
85
87
|
await client.connect()
|
|
86
88
|
|
|
87
|
-
# Add the agent to the manager
|
|
88
|
-
agent_identifier = make_agent_identifier(agent_name, protocol_type)
|
|
89
89
|
self._add_agent(agent_identifier, client)
|
|
90
90
|
structlogger.info(
|
|
91
91
|
"agent_manager.connect_agent.success",
|
rasa/agents/constants.py
CHANGED
|
@@ -5,6 +5,7 @@ TOOL_DESCRIPTION_KEY = "description"
|
|
|
5
5
|
TOOL_PARAMETERS_KEY = "parameters"
|
|
6
6
|
TOOL_STRICT_KEY = "strict"
|
|
7
7
|
TOOL_TYPE_FUNCTION_KEY = "function"
|
|
8
|
+
TOOL_EXECUTOR_KEY = "tool_executor"
|
|
8
9
|
|
|
9
10
|
# MCP Tool related constants (secondary)
|
|
10
11
|
TOOL_ADDITIONAL_PROPERTIES_KEY = "additionalProperties"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from abc import abstractmethod
|
|
3
|
+
from inspect import isawaitable
|
|
3
4
|
from typing import Any, Dict, List, Optional, Tuple
|
|
4
5
|
|
|
5
6
|
import structlog
|
|
@@ -25,6 +26,7 @@ from rasa.agents.schemas import (
|
|
|
25
26
|
AgentOutput,
|
|
26
27
|
AgentToolResult,
|
|
27
28
|
AgentToolSchema,
|
|
29
|
+
CustomToolSchema,
|
|
28
30
|
)
|
|
29
31
|
from rasa.core.available_agents import AgentConfig, AgentMCPServerConfig, ProtocolConfig
|
|
30
32
|
from rasa.shared.agents.utils import make_agent_identifier
|
|
@@ -112,6 +114,12 @@ class MCPBaseAgent(AgentProtocol):
|
|
|
112
114
|
# Stores the MCP tools for the agent.
|
|
113
115
|
self._mcp_tools: List[AgentToolSchema] = []
|
|
114
116
|
|
|
117
|
+
# Stores the custom tools for the agent.
|
|
118
|
+
self._custom_tools: List[CustomToolSchema] = [
|
|
119
|
+
CustomToolSchema.from_dict(tool)
|
|
120
|
+
for tool in self.get_custom_tool_definitions()
|
|
121
|
+
]
|
|
122
|
+
|
|
115
123
|
# Maps the tool names to the MCP servers that provide them.
|
|
116
124
|
# key: tool name, value: server name.
|
|
117
125
|
self._tool_to_server_mapper: Dict[str, str] = {}
|
|
@@ -164,28 +172,29 @@ class MCPBaseAgent(AgentProtocol):
|
|
|
164
172
|
@classmethod
|
|
165
173
|
def get_agent_specific_built_in_tools(
|
|
166
174
|
cls, agent_input: AgentInput
|
|
167
|
-
) -> List[
|
|
175
|
+
) -> List[AgentToolSchema]:
|
|
168
176
|
"""Get agentic specific built-in tools."""
|
|
169
177
|
return []
|
|
170
178
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
This method can be overridden to provide
|
|
179
|
+
def get_custom_tool_definitions(self) -> List[Dict[str, Any]]:
|
|
180
|
+
"""Add custom tool definitions and their executors for MCP agents.
|
|
181
|
+
|
|
182
|
+
This method can be overridden to provide custom tools that the agent
|
|
175
183
|
can use during its operation. The tools should be defined in the OpenAI
|
|
176
184
|
JSON format, which includes the tool name, description, and parameters.
|
|
177
185
|
|
|
178
186
|
Refer: https://platform.openai.com/docs/guides/function-calling?api-mode=responses
|
|
179
187
|
|
|
180
|
-
|
|
181
|
-
|
|
188
|
+
Note:
|
|
189
|
+
The tool executor method should be a coroutine function that returns an
|
|
190
|
+
AgentToolResult object.
|
|
182
191
|
|
|
183
192
|
Returns:
|
|
184
|
-
A list of
|
|
193
|
+
A list of custom tool definitions along with their tool executor method.
|
|
185
194
|
|
|
186
195
|
Example:
|
|
187
196
|
```python
|
|
188
|
-
def
|
|
197
|
+
def get_custom_tool_definitions(self) -> List[Dict[str, Any]]:
|
|
189
198
|
return [
|
|
190
199
|
{
|
|
191
200
|
"type": "function",
|
|
@@ -207,6 +216,7 @@ class MCPBaseAgent(AgentProtocol):
|
|
|
207
216
|
"required": ["location"],
|
|
208
217
|
},
|
|
209
218
|
},
|
|
219
|
+
"tool_executor": self.get_current_weather,
|
|
210
220
|
}
|
|
211
221
|
]
|
|
212
222
|
```
|
|
@@ -334,23 +344,17 @@ class MCPBaseAgent(AgentProtocol):
|
|
|
334
344
|
session = await connection.ensure_active_session()
|
|
335
345
|
return await session.list_tools()
|
|
336
346
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
built_in_tools = []
|
|
341
|
-
if agent_specific_built_in_tools := cls.get_agent_specific_built_in_tools(
|
|
342
|
-
agent_input
|
|
343
|
-
):
|
|
344
|
-
built_in_tools.extend(agent_specific_built_in_tools)
|
|
345
|
-
if additional_tools := cls.get_additional_tools(agent_input):
|
|
346
|
-
built_in_tools.extend(additional_tools)
|
|
347
|
-
return [
|
|
348
|
-
AgentToolSchema.from_openai_json_format(tool) for tool in built_in_tools
|
|
349
|
-
]
|
|
347
|
+
def get_custom_tools(self) -> List[AgentToolSchema]:
|
|
348
|
+
"""Get the custom tools for the agent."""
|
|
349
|
+
return [tool.tool_definition for tool in self._custom_tools]
|
|
350
350
|
|
|
351
351
|
def get_available_tools(self, agent_input: AgentInput) -> List[AgentToolSchema]:
|
|
352
352
|
"""Get the available tools for the agent."""
|
|
353
|
-
return
|
|
353
|
+
return (
|
|
354
|
+
self._mcp_tools
|
|
355
|
+
+ self.get_agent_specific_built_in_tools(agent_input)
|
|
356
|
+
+ self.get_custom_tools()
|
|
357
|
+
)
|
|
354
358
|
|
|
355
359
|
async def _get_filtered_tools_from_server(
|
|
356
360
|
self,
|
|
@@ -567,33 +571,6 @@ class MCPBaseAgent(AgentProtocol):
|
|
|
567
571
|
),
|
|
568
572
|
)
|
|
569
573
|
|
|
570
|
-
async def execute_additional_tool(
|
|
571
|
-
self, tool_name: str, arguments: Dict[str, Any]
|
|
572
|
-
) -> Optional[AgentToolResult]:
|
|
573
|
-
"""Execute additional tool. Override to add logic for specific tool.
|
|
574
|
-
|
|
575
|
-
Args:
|
|
576
|
-
tool_name: The name of the tool to execute.
|
|
577
|
-
arguments: The arguments to pass to the tool.
|
|
578
|
-
|
|
579
|
-
Returns:
|
|
580
|
-
The result of the tool execution as an AgentOutput object.
|
|
581
|
-
|
|
582
|
-
Example:
|
|
583
|
-
```python
|
|
584
|
-
async def execute_additional_tool(
|
|
585
|
-
self, tool_name: str, arguments: Dict[str, Any]
|
|
586
|
-
) -> Optional[AgentToolResult]:
|
|
587
|
-
if tool_name == "get_location":
|
|
588
|
-
return get_location_tool(arguments)
|
|
589
|
-
elif tool_name == "get_current_weather":
|
|
590
|
-
return get_current_weather_tool(arguments)
|
|
591
|
-
return None
|
|
592
|
-
|
|
593
|
-
```
|
|
594
|
-
"""
|
|
595
|
-
return None
|
|
596
|
-
|
|
597
574
|
async def _execute_tool_call(
|
|
598
575
|
self, tool_name: str, arguments: Dict[str, Any]
|
|
599
576
|
) -> AgentToolResult:
|
|
@@ -610,10 +587,10 @@ class MCPBaseAgent(AgentProtocol):
|
|
|
610
587
|
The result of the tool execution as an AgentToolResult object.
|
|
611
588
|
"""
|
|
612
589
|
try:
|
|
613
|
-
|
|
614
|
-
tool_name
|
|
615
|
-
|
|
616
|
-
|
|
590
|
+
for custom_tool in self._custom_tools:
|
|
591
|
+
if custom_tool.tool_name == tool_name:
|
|
592
|
+
result = custom_tool.tool_executor(arguments)
|
|
593
|
+
return await result if isawaitable(result) else result
|
|
617
594
|
except Exception as e:
|
|
618
595
|
return AgentToolResult(
|
|
619
596
|
tool_name=tool_name,
|
|
@@ -24,6 +24,7 @@ from rasa.agents.schemas import (
|
|
|
24
24
|
AgentInput,
|
|
25
25
|
AgentOutput,
|
|
26
26
|
AgentToolResult,
|
|
27
|
+
AgentToolSchema,
|
|
27
28
|
)
|
|
28
29
|
from rasa.core.available_agents import AgentMCPServerConfig, ProtocolConfig
|
|
29
30
|
from rasa.shared.agents.utils import make_agent_identifier
|
|
@@ -105,9 +106,9 @@ class MCPOpenAgent(MCPBaseAgent):
|
|
|
105
106
|
@classmethod
|
|
106
107
|
def get_agent_specific_built_in_tools(
|
|
107
108
|
cls, agent_input: AgentInput
|
|
108
|
-
) -> List[
|
|
109
|
+
) -> List[AgentToolSchema]:
|
|
109
110
|
"""Get agentic specific built-in tools."""
|
|
110
|
-
return [cls.get_task_completed_tool()]
|
|
111
|
+
return [AgentToolSchema.from_openai_json_format(cls.get_task_completed_tool())]
|
|
111
112
|
|
|
112
113
|
def _run_task_completed_tool(
|
|
113
114
|
self,
|
|
@@ -18,7 +18,9 @@ from rasa.agents.schemas import (
|
|
|
18
18
|
AgentInput,
|
|
19
19
|
AgentOutput,
|
|
20
20
|
AgentToolResult,
|
|
21
|
+
AgentToolSchema,
|
|
21
22
|
)
|
|
23
|
+
from rasa.agents.schemas.agent_input import AgentInputSlot
|
|
22
24
|
from rasa.core.available_agents import AgentMCPServerConfig, ProtocolConfig
|
|
23
25
|
from rasa.shared.agents.utils import make_agent_identifier
|
|
24
26
|
from rasa.shared.constants import (
|
|
@@ -70,11 +72,18 @@ class MCPTaskAgent(MCPBaseAgent):
|
|
|
70
72
|
@classmethod
|
|
71
73
|
def get_agent_specific_built_in_tools(
|
|
72
74
|
cls, agent_input: AgentInput
|
|
73
|
-
) -> List[
|
|
75
|
+
) -> List[AgentToolSchema]:
|
|
74
76
|
"""Get agentic specific built-in tools."""
|
|
77
|
+
slot_names = cls._get_slot_names_from_exit_conditions(agent_input)
|
|
78
|
+
slot_definitions = [
|
|
79
|
+
slot for slot in agent_input.slots if slot.name in slot_names
|
|
80
|
+
]
|
|
81
|
+
|
|
75
82
|
return [
|
|
76
|
-
|
|
77
|
-
|
|
83
|
+
AgentToolSchema.from_openai_json_format(
|
|
84
|
+
cls.get_slot_specific_set_slot_tool(slot)
|
|
85
|
+
)
|
|
86
|
+
for slot in slot_definitions
|
|
78
87
|
]
|
|
79
88
|
|
|
80
89
|
@classmethod
|
|
@@ -89,11 +98,11 @@ class MCPTaskAgent(MCPBaseAgent):
|
|
|
89
98
|
for name in re.findall(r"\bslots\.(\w+)", condition)
|
|
90
99
|
}
|
|
91
100
|
|
|
101
|
+
slot_names = agent_input.slot_names
|
|
102
|
+
|
|
92
103
|
# Keep only slots that actually exist in agent_input.slots
|
|
93
104
|
valid_slot_names = [
|
|
94
|
-
slot_name
|
|
95
|
-
for slot_name in extracted_slot_names
|
|
96
|
-
if slot_name in agent_input.slots
|
|
105
|
+
slot_name for slot_name in extracted_slot_names if slot_name in slot_names
|
|
97
106
|
]
|
|
98
107
|
|
|
99
108
|
structlogger.debug(
|
|
@@ -105,15 +114,18 @@ class MCPTaskAgent(MCPBaseAgent):
|
|
|
105
114
|
return valid_slot_names
|
|
106
115
|
|
|
107
116
|
@classmethod
|
|
108
|
-
def get_slot_specific_set_slot_tool(cls,
|
|
117
|
+
def get_slot_specific_set_slot_tool(cls, slot: AgentInputSlot) -> Dict[str, Any]:
|
|
109
118
|
"""Get the set slot tool."""
|
|
119
|
+
tool_description = f"Set the slot '{slot.name}' to a specific value. "
|
|
120
|
+
tool_description += f"The slot type is {slot.type}."
|
|
121
|
+
if slot.type == "categorical":
|
|
122
|
+
tool_description += f" The allowed values are: {slot.allowed_values}."
|
|
123
|
+
|
|
110
124
|
return {
|
|
111
125
|
"type": "function",
|
|
112
126
|
"function": {
|
|
113
|
-
"name": f"set_slot_{
|
|
114
|
-
|
|
115
|
-
# (if present) to the description as well.
|
|
116
|
-
"description": f"Set the slot {slot_name} to a specific value.",
|
|
127
|
+
"name": f"set_slot_{slot.name}",
|
|
128
|
+
"description": tool_description,
|
|
117
129
|
"parameters": {
|
|
118
130
|
"type": "object",
|
|
119
131
|
"properties": {
|
|
@@ -234,12 +246,22 @@ class MCPTaskAgent(MCPBaseAgent):
|
|
|
234
246
|
),
|
|
235
247
|
)
|
|
236
248
|
|
|
249
|
+
def render_prompt_template(self, context: AgentInput) -> str:
|
|
250
|
+
"""Render the prompt template with the provided inputs."""
|
|
251
|
+
slot_names = self._get_slot_names_from_exit_conditions(context)
|
|
252
|
+
|
|
253
|
+
return Template(self.prompt_template).render(
|
|
254
|
+
**context.model_dump(exclude={"id", "timestamp", "events"}),
|
|
255
|
+
description=self._description,
|
|
256
|
+
slot_names=slot_names,
|
|
257
|
+
)
|
|
258
|
+
|
|
237
259
|
async def send_message(self, agent_input: AgentInput) -> AgentOutput:
|
|
238
260
|
"""Send a message to the LLM and return the response."""
|
|
239
261
|
messages = self.build_messages_for_llm_request(agent_input)
|
|
240
262
|
tool_results: Dict[str, AgentToolResult] = {}
|
|
241
263
|
|
|
242
|
-
|
|
264
|
+
_slot_values = {slot.name: slot.value for slot in agent_input.slots}
|
|
243
265
|
_available_tools = self.get_available_tools(agent_input)
|
|
244
266
|
_available_tools_names = [tool.name for tool in _available_tools]
|
|
245
267
|
|
|
@@ -337,10 +359,10 @@ class MCPTaskAgent(MCPBaseAgent):
|
|
|
337
359
|
tool_call.tool_name
|
|
338
360
|
):
|
|
339
361
|
if (
|
|
340
|
-
slot_name in
|
|
362
|
+
slot_name in _slot_values
|
|
341
363
|
and "slot_value" in tool_call.tool_args
|
|
342
364
|
):
|
|
343
|
-
|
|
365
|
+
_slot_values.update(
|
|
344
366
|
self._run_set_slot_tool(
|
|
345
367
|
slot_name, tool_call.tool_args
|
|
346
368
|
)
|
|
@@ -392,13 +414,13 @@ class MCPTaskAgent(MCPBaseAgent):
|
|
|
392
414
|
)
|
|
393
415
|
|
|
394
416
|
exit_met, internal_error = self._is_exit_conditions_met(
|
|
395
|
-
agent_input,
|
|
417
|
+
agent_input, _slot_values
|
|
396
418
|
)
|
|
397
419
|
|
|
398
420
|
# Agent signals task completion if exit conditions are met.
|
|
399
421
|
if exit_met:
|
|
400
422
|
return self._generate_agent_task_completed_output(
|
|
401
|
-
agent_input,
|
|
423
|
+
agent_input, _slot_values, tool_results
|
|
402
424
|
)
|
|
403
425
|
|
|
404
426
|
# If an internal error occurred while checking the exit
|
rasa/agents/schemas/__init__.py
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
from rasa.agents.schemas.agent_input import AgentInput
|
|
2
2
|
from rasa.agents.schemas.agent_output import AgentOutput
|
|
3
3
|
from rasa.agents.schemas.agent_tool_result import AgentToolResult
|
|
4
|
-
from rasa.agents.schemas.agent_tool_schema import AgentToolSchema
|
|
4
|
+
from rasa.agents.schemas.agent_tool_schema import AgentToolSchema, CustomToolSchema
|
|
5
5
|
|
|
6
|
-
__all__ = [
|
|
6
|
+
__all__ = [
|
|
7
|
+
"AgentInput",
|
|
8
|
+
"AgentOutput",
|
|
9
|
+
"AgentToolSchema",
|
|
10
|
+
"AgentToolResult",
|
|
11
|
+
"CustomToolSchema",
|
|
12
|
+
]
|
|
@@ -5,12 +5,21 @@ from pydantic import BaseModel
|
|
|
5
5
|
from rasa.shared.core.events import Event
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
class AgentInputSlot(BaseModel):
|
|
9
|
+
"""A class that represents the schema of the input slot to the agent."""
|
|
10
|
+
|
|
11
|
+
name: str
|
|
12
|
+
value: Any
|
|
13
|
+
type: str
|
|
14
|
+
allowed_values: Optional[List[Any]] = None
|
|
15
|
+
|
|
16
|
+
|
|
8
17
|
class AgentInput(BaseModel):
|
|
9
18
|
"""A class that represents the schema of the input to the agent."""
|
|
10
19
|
|
|
11
20
|
id: str
|
|
12
21
|
user_message: str
|
|
13
|
-
slots:
|
|
22
|
+
slots: List[AgentInputSlot]
|
|
14
23
|
conversation_history: str
|
|
15
24
|
events: List[Event]
|
|
16
25
|
metadata: Dict[str, Any]
|
|
@@ -22,3 +31,8 @@ class AgentInput(BaseModel):
|
|
|
22
31
|
"""
|
|
23
32
|
|
|
24
33
|
arbitrary_types_allowed = True
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def slot_names(self) -> List[str]:
|
|
37
|
+
"""Get the names of the slots in the input."""
|
|
38
|
+
return [slot.name for slot in self.slots]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Any, Dict, Optional
|
|
1
|
+
from typing import Any, Callable, Dict, Optional
|
|
2
2
|
|
|
3
3
|
from mcp import Tool
|
|
4
4
|
from pydantic import BaseModel
|
|
@@ -6,6 +6,7 @@ from pydantic import BaseModel
|
|
|
6
6
|
from rasa.agents.constants import (
|
|
7
7
|
TOOL_ADDITIONAL_PROPERTIES_KEY,
|
|
8
8
|
TOOL_DESCRIPTION_KEY,
|
|
9
|
+
TOOL_EXECUTOR_KEY,
|
|
9
10
|
TOOL_NAME_KEY,
|
|
10
11
|
TOOL_PARAMETERS_KEY,
|
|
11
12
|
TOOL_PROPERTIES_KEY,
|
|
@@ -110,3 +111,24 @@ class AgentToolSchema(BaseModel):
|
|
|
110
111
|
TOOL_TYPE_KEY: TOOL_TYPE_FUNCTION_KEY,
|
|
111
112
|
TOOL_TYPE_FUNCTION_KEY: self.model_dump(exclude={TOOL_TYPE_KEY}),
|
|
112
113
|
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class CustomToolSchema(BaseModel):
|
|
117
|
+
"""A class that represents the schema of a custom agent tool."""
|
|
118
|
+
|
|
119
|
+
tool_name: str
|
|
120
|
+
tool_definition: AgentToolSchema
|
|
121
|
+
tool_executor: Callable
|
|
122
|
+
|
|
123
|
+
@classmethod
|
|
124
|
+
def from_dict(cls, config: Dict[str, Any]) -> "CustomToolSchema":
|
|
125
|
+
"""Convert a custom tool config to CustomToolSchema."""
|
|
126
|
+
agent_tool_schema = AgentToolSchema.from_openai_json_format(config)
|
|
127
|
+
if TOOL_EXECUTOR_KEY not in config:
|
|
128
|
+
raise ValueError("Custom tool executor is required.")
|
|
129
|
+
|
|
130
|
+
return cls(
|
|
131
|
+
tool_name=agent_tool_schema.name,
|
|
132
|
+
tool_definition=agent_tool_schema,
|
|
133
|
+
tool_executor=config[TOOL_EXECUTOR_KEY],
|
|
134
|
+
)
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
You are a helpful assistant that should assist the user in the best possible way.
|
|
2
2
|
|
|
3
|
-
###
|
|
3
|
+
### Description of your capabilities
|
|
4
4
|
{{ description }}
|
|
5
5
|
|
|
6
|
+
### Task
|
|
7
|
+
* Use the tools available to gather the required information to set the following slots: {{ slot_names }}.
|
|
8
|
+
* In order to set the slot values, use the `set_slot_<slot_name>` tool.
|
|
9
|
+
|
|
6
10
|
### Instructions
|
|
7
11
|
* Always make sure to output responses to the user in a clear, helpful format.
|
|
8
12
|
* Always avoid asking multiple questions at once. Ask questions sequentially one at a time and wait for the user's response before proceeding to next question.
|
|
@@ -10,4 +14,4 @@ You are a helpful assistant that should assist the user in the best possible way
|
|
|
10
14
|
* Strictly avoid making up information or ability to take some action which is not available in `tool` provided.
|
|
11
15
|
|
|
12
16
|
### Conversation history
|
|
13
|
-
{{ conversation_history }}
|
|
17
|
+
{{ conversation_history }}
|
|
@@ -138,7 +138,7 @@ class FlowPolicy(Policy):
|
|
|
138
138
|
# create executor and predict next action
|
|
139
139
|
try:
|
|
140
140
|
prediction = await flow_executor.advance_flows(
|
|
141
|
-
tracker, domain.action_names_or_texts, flows
|
|
141
|
+
tracker, domain.action_names_or_texts, flows, domain.slots
|
|
142
142
|
)
|
|
143
143
|
return self._create_prediction_result(
|
|
144
144
|
prediction.action_name,
|
|
@@ -165,7 +165,7 @@ class FlowPolicy(Policy):
|
|
|
165
165
|
events = tracker.create_stack_updated_events(updated_stack)
|
|
166
166
|
tracker.update_with_events(events)
|
|
167
167
|
prediction = await flow_executor.advance_flows(
|
|
168
|
-
tracker, domain.action_names_or_texts, flows
|
|
168
|
+
tracker, domain.action_names_or_texts, flows, domain.slots
|
|
169
169
|
)
|
|
170
170
|
collected_events = events + (prediction.events or [])
|
|
171
171
|
return self._create_prediction_result(
|
|
@@ -16,6 +16,7 @@ from rasa.agents.constants import (
|
|
|
16
16
|
)
|
|
17
17
|
from rasa.agents.core.types import AgentStatus, ProtocolType
|
|
18
18
|
from rasa.agents.schemas import AgentInput, AgentOutput
|
|
19
|
+
from rasa.agents.schemas.agent_input import AgentInputSlot
|
|
19
20
|
from rasa.core.available_agents import AvailableAgents
|
|
20
21
|
from rasa.core.available_endpoints import AvailableEndpoints
|
|
21
22
|
from rasa.core.constants import ACTIVE_FLOW_METADATA_KEY, STEP_ID_METADATA_KEY
|
|
@@ -103,7 +104,7 @@ from rasa.shared.core.flows.steps import (
|
|
|
103
104
|
SetSlotsFlowStep,
|
|
104
105
|
)
|
|
105
106
|
from rasa.shared.core.flows.steps.constants import START_STEP
|
|
106
|
-
from rasa.shared.core.slots import Slot, SlotRejection
|
|
107
|
+
from rasa.shared.core.slots import CategoricalSlot, Slot, SlotRejection
|
|
107
108
|
from rasa.shared.core.trackers import DialogueStateTracker
|
|
108
109
|
from rasa.shared.utils.llm import tracker_as_readable_transcript
|
|
109
110
|
|
|
@@ -387,7 +388,10 @@ def reset_scoped_slots(
|
|
|
387
388
|
|
|
388
389
|
|
|
389
390
|
async def advance_flows(
|
|
390
|
-
tracker: DialogueStateTracker,
|
|
391
|
+
tracker: DialogueStateTracker,
|
|
392
|
+
available_actions: List[str],
|
|
393
|
+
flows: FlowsList,
|
|
394
|
+
slots: List[Slot],
|
|
391
395
|
) -> FlowActionPrediction:
|
|
392
396
|
"""Advance the current flows until the next action.
|
|
393
397
|
|
|
@@ -395,6 +399,7 @@ async def advance_flows(
|
|
|
395
399
|
tracker: The tracker to get the next action for.
|
|
396
400
|
available_actions: The actions that are available in the domain.
|
|
397
401
|
flows: All flows.
|
|
402
|
+
slots: The slots that are available in the domain.
|
|
398
403
|
|
|
399
404
|
Returns:
|
|
400
405
|
The predicted action and the events to run.
|
|
@@ -404,13 +409,16 @@ async def advance_flows(
|
|
|
404
409
|
# if there are no flows, there is nothing to do
|
|
405
410
|
return FlowActionPrediction(None, 0.0)
|
|
406
411
|
|
|
407
|
-
return await advance_flows_until_next_action(
|
|
412
|
+
return await advance_flows_until_next_action(
|
|
413
|
+
tracker, available_actions, flows, slots
|
|
414
|
+
)
|
|
408
415
|
|
|
409
416
|
|
|
410
417
|
async def advance_flows_until_next_action(
|
|
411
418
|
tracker: DialogueStateTracker,
|
|
412
419
|
available_actions: List[str],
|
|
413
420
|
flows: FlowsList,
|
|
421
|
+
slots: List[Slot],
|
|
414
422
|
) -> FlowActionPrediction:
|
|
415
423
|
"""Advance the flow and select the next action to execute.
|
|
416
424
|
|
|
@@ -476,6 +484,7 @@ async def advance_flows_until_next_action(
|
|
|
476
484
|
available_actions,
|
|
477
485
|
flows,
|
|
478
486
|
previous_step_id,
|
|
487
|
+
slots,
|
|
479
488
|
)
|
|
480
489
|
new_events = step_result.events
|
|
481
490
|
if (
|
|
@@ -586,6 +595,7 @@ async def run_step(
|
|
|
586
595
|
available_actions: List[str],
|
|
587
596
|
flows: FlowsList,
|
|
588
597
|
previous_step_id: str,
|
|
598
|
+
slots: List[Slot],
|
|
589
599
|
) -> FlowStepResult:
|
|
590
600
|
"""Run a single step of a flow.
|
|
591
601
|
|
|
@@ -604,6 +614,7 @@ async def run_step(
|
|
|
604
614
|
available_actions: The actions that are available in the domain.
|
|
605
615
|
flows: All flows.
|
|
606
616
|
previous_step_id: The ID of the previous step.
|
|
617
|
+
slots: The slots that are available in the domain.
|
|
607
618
|
|
|
608
619
|
Returns:
|
|
609
620
|
A result of running the step describing where to transition to.
|
|
@@ -643,7 +654,7 @@ async def run_step(
|
|
|
643
654
|
return _run_link_step(initial_events, stack, step)
|
|
644
655
|
|
|
645
656
|
elif isinstance(step, CallFlowStep):
|
|
646
|
-
return await _run_call_step(initial_events, stack, step, tracker)
|
|
657
|
+
return await _run_call_step(initial_events, stack, step, tracker, slots)
|
|
647
658
|
|
|
648
659
|
elif isinstance(step, SetSlotsFlowStep):
|
|
649
660
|
return _run_set_slot_step(initial_events, step)
|
|
@@ -717,12 +728,13 @@ async def _run_call_step(
|
|
|
717
728
|
stack: DialogueStack,
|
|
718
729
|
step: CallFlowStep,
|
|
719
730
|
tracker: DialogueStateTracker,
|
|
731
|
+
slots: List[Slot],
|
|
720
732
|
) -> FlowStepResult:
|
|
721
733
|
structlogger.debug("flow.step.run.call")
|
|
722
734
|
if step.is_calling_mcp_tool():
|
|
723
735
|
return await call_mcp_tool(initial_events, stack, step, tracker)
|
|
724
736
|
elif step.is_calling_agent():
|
|
725
|
-
return await run_agent(initial_events, stack, step, tracker)
|
|
737
|
+
return await run_agent(initial_events, stack, step, tracker, slots)
|
|
726
738
|
else:
|
|
727
739
|
stack.push(
|
|
728
740
|
UserFlowStackFrame(
|
|
@@ -885,6 +897,7 @@ async def run_agent(
|
|
|
885
897
|
stack: DialogueStack,
|
|
886
898
|
step: CallFlowStep,
|
|
887
899
|
tracker: DialogueStateTracker,
|
|
900
|
+
slots: List[Slot],
|
|
888
901
|
) -> FlowStepResult:
|
|
889
902
|
"""Run an agent call step."""
|
|
890
903
|
structlogger.debug(
|
|
@@ -942,7 +955,7 @@ async def run_agent(
|
|
|
942
955
|
user_message=tracker.latest_message.text or ""
|
|
943
956
|
if tracker.latest_message
|
|
944
957
|
else "",
|
|
945
|
-
slots=
|
|
958
|
+
slots=_prepare_slots_for_agent(tracker.current_slot_values(), slots),
|
|
946
959
|
conversation_history=tracker_as_readable_transcript(tracker),
|
|
947
960
|
events=tracker.current_state().get("events") or [],
|
|
948
961
|
metadata=agent_input_metadata,
|
|
@@ -1156,18 +1169,43 @@ async def _call_agent_with_retry(
|
|
|
1156
1169
|
)
|
|
1157
1170
|
|
|
1158
1171
|
|
|
1159
|
-
def
|
|
1160
|
-
|
|
1172
|
+
def _prepare_slots_for_agent(
|
|
1173
|
+
slot_values: Dict[str, Any], slot_definitions: List[Slot]
|
|
1174
|
+
) -> List[AgentInputSlot]:
|
|
1175
|
+
"""Prepare the slots for the agent.
|
|
1176
|
+
|
|
1177
|
+
Filter out slots that should not be forwarded to agents.
|
|
1178
|
+
Add the slot type and allowed values to the slot dictionary.
|
|
1161
1179
|
|
|
1162
1180
|
Args:
|
|
1163
|
-
|
|
1181
|
+
slot_values: The full slot dictionary from the tracker.
|
|
1182
|
+
slot_definitions: The slot definitions from the domain.
|
|
1164
1183
|
|
|
1165
1184
|
Returns:
|
|
1166
|
-
A
|
|
1167
|
-
`SLOTS_EXCLUDED_FOR_AGENT`.
|
|
1185
|
+
A list of slots containing the name, current value, type, and allowed values.
|
|
1168
1186
|
"""
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
for
|
|
1172
|
-
|
|
1173
|
-
|
|
1187
|
+
|
|
1188
|
+
def _get_slot_definition(slot_name: str) -> Optional[Slot]:
|
|
1189
|
+
for slot in slot_definitions:
|
|
1190
|
+
if slot.name == slot_name:
|
|
1191
|
+
return slot
|
|
1192
|
+
return None
|
|
1193
|
+
|
|
1194
|
+
filtered_slots: List[AgentInputSlot] = []
|
|
1195
|
+
for key, value in slot_values.items():
|
|
1196
|
+
if key in SLOTS_EXCLUDED_FOR_AGENT:
|
|
1197
|
+
continue
|
|
1198
|
+
slot_definition = _get_slot_definition(key)
|
|
1199
|
+
if slot_definition:
|
|
1200
|
+
filtered_slots.append(
|
|
1201
|
+
AgentInputSlot(
|
|
1202
|
+
name=key,
|
|
1203
|
+
value=value,
|
|
1204
|
+
type=slot_definition.type_name if slot_definition else "any",
|
|
1205
|
+
allowed_values=slot_definition.values
|
|
1206
|
+
if isinstance(slot_definition, CategoricalSlot)
|
|
1207
|
+
else None,
|
|
1208
|
+
)
|
|
1209
|
+
)
|
|
1210
|
+
|
|
1211
|
+
return filtered_slots
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import json
|
|
2
|
+
import operator
|
|
3
|
+
from functools import reduce
|
|
2
4
|
from typing import Any, Dict, List, Optional
|
|
3
5
|
|
|
4
6
|
import structlog
|
|
@@ -17,10 +19,12 @@ from rasa.shared.core.events import Event, SlotSet
|
|
|
17
19
|
from rasa.shared.core.flows.steps import CallFlowStep
|
|
18
20
|
from rasa.shared.core.trackers import DialogueStateTracker
|
|
19
21
|
from rasa.shared.utils.mcp.server_connection import MCPServerConnection
|
|
22
|
+
from rasa.utils.common import ensure_jsonified_iterable
|
|
20
23
|
|
|
21
24
|
structlogger = structlog.get_logger()
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
CONFIG_RESULT_KEY = "result_key"
|
|
27
|
+
CONFIG_SLOT = "slot"
|
|
24
28
|
|
|
25
29
|
|
|
26
30
|
async def call_mcp_tool(
|
|
@@ -101,7 +105,7 @@ async def _execute_mcp_tool_call(
|
|
|
101
105
|
result = await mcp_server.call_tool(step.call, arguments)
|
|
102
106
|
|
|
103
107
|
# Handle tool execution result
|
|
104
|
-
if result.isError:
|
|
108
|
+
if result is None or result.isError:
|
|
105
109
|
return _handle_mcp_tool_error(
|
|
106
110
|
stack,
|
|
107
111
|
initial_events,
|
|
@@ -121,12 +125,20 @@ async def _execute_mcp_tool_call(
|
|
|
121
125
|
tool_name=step.call,
|
|
122
126
|
mcp_server=step.mcp_server,
|
|
123
127
|
result_content=result.content,
|
|
128
|
+
result_structured_content=result.structuredContent,
|
|
124
129
|
)
|
|
125
130
|
|
|
126
131
|
# Process successful result
|
|
127
|
-
set_slot_event
|
|
128
|
-
|
|
129
|
-
|
|
132
|
+
if set_slot_event := _process_tool_result(result, step.mapping["output"]):
|
|
133
|
+
initial_events.extend(set_slot_event)
|
|
134
|
+
else:
|
|
135
|
+
return _handle_mcp_tool_error(
|
|
136
|
+
stack,
|
|
137
|
+
initial_events,
|
|
138
|
+
f"Failed to process tool result for '{step.call}'.",
|
|
139
|
+
tool_name=step.call,
|
|
140
|
+
mcp_server=step.mcp_server,
|
|
141
|
+
)
|
|
130
142
|
|
|
131
143
|
return ContinueFlowWithNextStep(events=initial_events)
|
|
132
144
|
|
|
@@ -203,16 +215,41 @@ def _prepare_tool_arguments(
|
|
|
203
215
|
return arguments
|
|
204
216
|
|
|
205
217
|
|
|
218
|
+
def _jsonify_slot_value(value: Any) -> str | int | float | bool | None:
|
|
219
|
+
"""Prepare value for SlotSet: iterables -> JSON string, primitives -> as-is"""
|
|
220
|
+
if isinstance(value, (list, dict)) and len(value):
|
|
221
|
+
return json.dumps(ensure_jsonified_iterable(value))
|
|
222
|
+
return value
|
|
223
|
+
|
|
224
|
+
|
|
206
225
|
def _process_tool_result(
|
|
207
226
|
result: CallToolResult,
|
|
208
|
-
output_mapping: str,
|
|
209
|
-
) -> Optional[SlotSet]:
|
|
227
|
+
output_mapping: List[Dict[str, str]],
|
|
228
|
+
) -> Optional[List[SlotSet]]:
|
|
210
229
|
"""Create a SetSlot event for the tool result."""
|
|
211
230
|
try:
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
231
|
+
_result_as_dict = {"result": result.model_dump()}
|
|
232
|
+
slots = []
|
|
233
|
+
for mapping in output_mapping:
|
|
234
|
+
try:
|
|
235
|
+
# Use reduce to navigate through nested keys in the result
|
|
236
|
+
slot_value = reduce(
|
|
237
|
+
operator.getitem,
|
|
238
|
+
mapping[CONFIG_RESULT_KEY].split("."),
|
|
239
|
+
_result_as_dict,
|
|
240
|
+
)
|
|
241
|
+
slots.append(
|
|
242
|
+
SlotSet(mapping[CONFIG_SLOT], _jsonify_slot_value(slot_value))
|
|
243
|
+
)
|
|
244
|
+
except (KeyError, TypeError):
|
|
245
|
+
structlogger.error(
|
|
246
|
+
"call_mcp_tool.result_key_not_found_in_tool_result",
|
|
247
|
+
slot=mapping[CONFIG_SLOT],
|
|
248
|
+
result_key=mapping[CONFIG_RESULT_KEY],
|
|
249
|
+
result=_result_as_dict,
|
|
250
|
+
)
|
|
251
|
+
return None
|
|
252
|
+
return slots
|
|
216
253
|
except Exception as e:
|
|
217
254
|
structlogger.error(
|
|
218
255
|
"call_mcp_tool.result_processing_failed",
|
|
@@ -21,7 +21,9 @@ from rasa.dialogue_understanding.stack.frames.flow_stack_frame import (
|
|
|
21
21
|
FlowStackFrameType,
|
|
22
22
|
UserFlowStackFrame,
|
|
23
23
|
)
|
|
24
|
+
from rasa.dialogue_understanding.stack.frames.pattern_frame import PatternFlowStackFrame
|
|
24
25
|
from rasa.dialogue_understanding.stack.utils import (
|
|
26
|
+
is_continue_interrupted_flow_active,
|
|
25
27
|
top_user_flow_frame,
|
|
26
28
|
user_flows_on_the_stack,
|
|
27
29
|
)
|
|
@@ -97,13 +99,26 @@ class StartFlowCommand(Command):
|
|
|
97
99
|
# if the original top flow is the same as the flow to start, the flow is
|
|
98
100
|
# already active, do nothing
|
|
99
101
|
if original_top_flow is not None and original_top_flow.id == self.flow:
|
|
100
|
-
|
|
102
|
+
# in case continue_interrupted is not active, skip the already active start
|
|
103
|
+
# flow command
|
|
104
|
+
if not is_continue_interrupted_flow_active(stack):
|
|
105
|
+
return []
|
|
106
|
+
|
|
107
|
+
# if the continue interrupted flow is active, and the command generator
|
|
108
|
+
# predicted a start flow command for the flow which is on top of the stack,
|
|
109
|
+
# we just need to remove the pattern_continue_interrupted frame(s) from the
|
|
110
|
+
# stack
|
|
111
|
+
stack = _remove_pattern_continue_interrupted_frames(stack)
|
|
112
|
+
return applied_events + tracker.create_stack_updated_events(stack)
|
|
101
113
|
|
|
102
114
|
# if the flow is already on the stack, resume it
|
|
103
115
|
if (
|
|
104
116
|
self.flow in user_flows_on_the_stack(stack)
|
|
105
117
|
and original_user_frame is not None
|
|
106
118
|
):
|
|
119
|
+
# if pattern_continue_interrupted is active, we need to remove it
|
|
120
|
+
# from the stack before resuming the flow
|
|
121
|
+
stack = _remove_pattern_continue_interrupted_frames(stack)
|
|
107
122
|
return self.resume_flow(tracker, stack, original_user_frame)
|
|
108
123
|
|
|
109
124
|
frame_type = FlowStackFrameType.REGULAR
|
|
@@ -265,3 +280,23 @@ class StartFlowCommand(Command):
|
|
|
265
280
|
frames_to_resume.append(frame)
|
|
266
281
|
|
|
267
282
|
return list(frames_to_resume), frame_to_resume
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def _remove_pattern_continue_interrupted_frames(stack: DialogueStack) -> DialogueStack:
|
|
286
|
+
"""Remove pattern_continue_interrupted frames from the stack."""
|
|
287
|
+
if not is_continue_interrupted_flow_active(stack):
|
|
288
|
+
return stack
|
|
289
|
+
|
|
290
|
+
# remove pattern_continue_interrupted from the stack
|
|
291
|
+
top_frame = stack.top()
|
|
292
|
+
while isinstance(top_frame, PatternFlowStackFrame):
|
|
293
|
+
# If the top frame is a pattern frame, we need to remove it
|
|
294
|
+
# before continuing with the active user flow frame.
|
|
295
|
+
# This prevents the pattern frame
|
|
296
|
+
# from being left on the stack when the flow is started
|
|
297
|
+
# which would prevent pattern_completed to be triggered
|
|
298
|
+
# once the user flow is completed.
|
|
299
|
+
stack.pop()
|
|
300
|
+
top_frame = stack.top()
|
|
301
|
+
|
|
302
|
+
return stack
|
|
@@ -135,13 +135,13 @@ slots:
|
|
|
135
135
|
type: bool
|
|
136
136
|
initial_value: false
|
|
137
137
|
confirmation_continue_interrupted_flow:
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
- type: controlled
|
|
138
|
+
type: bool
|
|
139
|
+
mappings:
|
|
140
|
+
- type: from_llm
|
|
142
141
|
interrupted_flow_to_continue:
|
|
143
142
|
type: text
|
|
144
|
-
|
|
143
|
+
mappings:
|
|
144
|
+
- type: from_llm
|
|
145
145
|
|
|
146
146
|
flows:
|
|
147
147
|
pattern_cancel_flow:
|
|
@@ -37,6 +37,7 @@ from rasa.dialogue_understanding.stack.frames import (
|
|
|
37
37
|
BaseFlowStackFrame,
|
|
38
38
|
)
|
|
39
39
|
from rasa.dialogue_understanding.stack.utils import (
|
|
40
|
+
is_continue_interrupted_flow_active,
|
|
40
41
|
top_flow_frame,
|
|
41
42
|
top_user_flow_frame,
|
|
42
43
|
)
|
|
@@ -428,22 +429,9 @@ def clean_up_commands(
|
|
|
428
429
|
)
|
|
429
430
|
|
|
430
431
|
elif isinstance(command, StartFlowCommand):
|
|
431
|
-
|
|
432
|
-
tracker
|
|
432
|
+
clean_commands = clean_up_start_flow_command(
|
|
433
|
+
clean_commands, tracker, command
|
|
433
434
|
)
|
|
434
|
-
top_flow_id = top_user_frame.flow_id if top_user_frame else ""
|
|
435
|
-
|
|
436
|
-
if top_flow_id == command.flow:
|
|
437
|
-
# drop a start flow command if the starting flow is equal
|
|
438
|
-
# to the currently active flow
|
|
439
|
-
structlogger.debug(
|
|
440
|
-
"command_processor.clean_up_commands."
|
|
441
|
-
"skip_command_flow_already_active",
|
|
442
|
-
command=command,
|
|
443
|
-
)
|
|
444
|
-
continue
|
|
445
|
-
|
|
446
|
-
clean_commands.append(command)
|
|
447
435
|
|
|
448
436
|
# handle chitchat command differently from other free-form answer commands
|
|
449
437
|
elif isinstance(command, ChitChatAnswerCommand):
|
|
@@ -529,6 +517,34 @@ def ensure_max_number_of_command_type(
|
|
|
529
517
|
return filtered
|
|
530
518
|
|
|
531
519
|
|
|
520
|
+
def clean_up_start_flow_command(
|
|
521
|
+
clean_commands: List[Command],
|
|
522
|
+
tracker: DialogueStateTracker,
|
|
523
|
+
command: StartFlowCommand,
|
|
524
|
+
) -> List[Command]:
|
|
525
|
+
"""Clean up a start flow command."""
|
|
526
|
+
continue_interrupted_flow_active = is_continue_interrupted_flow_active(
|
|
527
|
+
tracker.stack
|
|
528
|
+
)
|
|
529
|
+
|
|
530
|
+
top_user_frame = top_user_flow_frame(
|
|
531
|
+
tracker.stack, ignore_call_and_link_frames=False
|
|
532
|
+
)
|
|
533
|
+
top_flow_id = top_user_frame.flow_id if top_user_frame else ""
|
|
534
|
+
|
|
535
|
+
if top_flow_id == command.flow and not continue_interrupted_flow_active:
|
|
536
|
+
# drop a start flow command if the starting flow is equal
|
|
537
|
+
# to the currently active flow
|
|
538
|
+
structlogger.debug(
|
|
539
|
+
"command_processor.clean_up_commands." "skip_command_flow_already_active",
|
|
540
|
+
command=command,
|
|
541
|
+
)
|
|
542
|
+
return clean_commands
|
|
543
|
+
|
|
544
|
+
clean_commands.append(command)
|
|
545
|
+
return clean_commands
|
|
546
|
+
|
|
547
|
+
|
|
532
548
|
def clean_up_clarify_command(
|
|
533
549
|
commands_so_far: List[Command],
|
|
534
550
|
all_commands: List[Command],
|
|
@@ -231,3 +231,17 @@ def get_collect_steps_excluding_ask_before_filling_for_active_flow(
|
|
|
231
231
|
for step in active_flow.get_collect_steps()
|
|
232
232
|
if not step.ask_before_filling
|
|
233
233
|
)
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def is_continue_interrupted_flow_active(stack: DialogueStack) -> bool:
|
|
237
|
+
"""Check if the continue interrupted flow is active."""
|
|
238
|
+
from rasa.dialogue_understanding.patterns.continue_interrupted import (
|
|
239
|
+
ContinueInterruptedPatternFlowStackFrame,
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
for frame in reversed(stack.frames):
|
|
243
|
+
if isinstance(frame, ContinueInterruptedPatternFlowStackFrame):
|
|
244
|
+
return True
|
|
245
|
+
if isinstance(frame, UserFlowStackFrame):
|
|
246
|
+
return False
|
|
247
|
+
return False
|
|
@@ -233,7 +233,18 @@
|
|
|
233
233
|
}
|
|
234
234
|
}
|
|
235
235
|
},
|
|
236
|
-
"output": {
|
|
236
|
+
"output": {
|
|
237
|
+
"type": "array",
|
|
238
|
+
"items": {
|
|
239
|
+
"type": "object",
|
|
240
|
+
"additionalProperties": false,
|
|
241
|
+
"required": ["slot", "result_key"],
|
|
242
|
+
"properties": {
|
|
243
|
+
"slot": {"type": "string"},
|
|
244
|
+
"result_key": {"type": "string"}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
237
248
|
}
|
|
238
249
|
},
|
|
239
250
|
"exit_if": {
|
|
@@ -18,11 +18,13 @@ class CallFlowStep(FlowStep):
|
|
|
18
18
|
call: Text
|
|
19
19
|
"""The flow to be called or the ID of the agent to be called."""
|
|
20
20
|
called_flow_reference: Optional["Flow"] = None
|
|
21
|
+
|
|
21
22
|
# MCP Tool calling
|
|
22
23
|
"""The MCP server that hosts the tool to be called."""
|
|
23
24
|
mcp_server: Optional[str] = None
|
|
24
25
|
"""The input and output mapping for the MCP tool."""
|
|
25
26
|
mapping: Optional[Dict[str, Any]] = None
|
|
27
|
+
|
|
26
28
|
# Call agent exit condition
|
|
27
29
|
"""A list of slot predicates that determine when to exit the agent loop."""
|
|
28
30
|
exit_if: Optional[List[str]] = None
|
|
@@ -595,14 +595,15 @@ def validate_call_steps(flows: "FlowsList") -> None:
|
|
|
595
595
|
if not isinstance(step, CallFlowStep):
|
|
596
596
|
continue
|
|
597
597
|
|
|
598
|
+
_is_step_calling_agent = step.is_calling_agent()
|
|
598
599
|
if (
|
|
599
|
-
not
|
|
600
|
+
not _is_step_calling_agent
|
|
600
601
|
and flows.flow_by_id(step.call) is None
|
|
601
602
|
and not step.is_calling_mcp_tool()
|
|
602
603
|
):
|
|
603
604
|
raise UnresolvedCallStepException(step.call, flow.id, step.id)
|
|
604
605
|
|
|
605
|
-
if step.exit_if and not
|
|
606
|
+
if step.exit_if and not _is_step_calling_agent:
|
|
606
607
|
# exit_if is only allowed for call steps that call an agent
|
|
607
608
|
raise RasaException(
|
|
608
609
|
f"Call step '{step.id}' in flow '{flow.id}' has an 'exit_if' "
|
rasa/utils/common.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import copy
|
|
2
2
|
import inspect
|
|
3
|
+
import json
|
|
3
4
|
import logging
|
|
4
5
|
import logging.config
|
|
5
6
|
import logging.handlers
|
|
@@ -699,3 +700,28 @@ def get_bool_env_variable(variable_name: str, default_variable_value: bool) -> b
|
|
|
699
700
|
f"Available values are `{true_values + false_values}`"
|
|
700
701
|
)
|
|
701
702
|
return value.lower() in true_values
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
def try_parse_json(value: Any) -> Any:
|
|
706
|
+
"""If value is a JSON string, parse it into a dict/list, else return as-is."""
|
|
707
|
+
if isinstance(value, str):
|
|
708
|
+
try:
|
|
709
|
+
return json.loads(value)
|
|
710
|
+
except json.JSONDecodeError:
|
|
711
|
+
return value
|
|
712
|
+
return value
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
def ensure_jsonified_iterable(value: Any) -> Any:
|
|
716
|
+
"""Convert iterables to JSON strings, flatten nested JSON strings in dicts/lists."""
|
|
717
|
+
if isinstance(value, dict):
|
|
718
|
+
# Recursively process dict values
|
|
719
|
+
return {
|
|
720
|
+
key: ensure_jsonified_iterable(try_parse_json(val))
|
|
721
|
+
for key, val in value.items()
|
|
722
|
+
}
|
|
723
|
+
elif isinstance(value, list):
|
|
724
|
+
# Recursively process each item
|
|
725
|
+
return [ensure_jsonified_iterable(try_parse_json(val)) for val in value]
|
|
726
|
+
# Keep primitives as-is
|
|
727
|
+
return value
|
rasa/version.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: rasa-pro
|
|
3
|
-
Version: 3.14.0.
|
|
3
|
+
Version: 3.14.0.dev3
|
|
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
|
|
@@ -2,8 +2,8 @@ rasa/__init__.py,sha256=YXG8RzVxiSJ__v-AewtV453YoCbmzWlHsU_4S0O2XpE,206
|
|
|
2
2
|
rasa/__main__.py,sha256=TVYPpDdKKnTxC9RRaPxAaoDosH8-UDMBPfd-UP7YBGg,6645
|
|
3
3
|
rasa/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
rasa/agents/agent_factory.py,sha256=7v7mdMrTnG5KEg6gCmwPtlT637I6xight90h--syh_c,4675
|
|
5
|
-
rasa/agents/agent_manager.py,sha256=
|
|
6
|
-
rasa/agents/constants.py,sha256=
|
|
5
|
+
rasa/agents/agent_manager.py,sha256=NVrE3IEwKhlhA9YdbBsnSDBFbkBDbWrmAkIe06LAXiQ,5957
|
|
6
|
+
rasa/agents/constants.py,sha256=0Uc2ZWHChauubr3g84YCT6-E0lLrbtZ-oju3dUuTfzY,914
|
|
7
7
|
rasa/agents/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
8
|
rasa/agents/core/agent_protocol.py,sha256=gqWignz64lnYWzv1GgYEdj5221nU_vNW49LhOMRZBpY,3397
|
|
9
9
|
rasa/agents/core/types.py,sha256=5Ht6m5lgaNAtdmeCybBTA6MUoNeGPWaGgQgPsBCoYUw,2164
|
|
@@ -12,17 +12,17 @@ rasa/agents/protocol/__init__.py,sha256=rDR_QdaWuHvkHTKF1MmgzjIk7T8m__KJIK9wtjQn
|
|
|
12
12
|
rasa/agents/protocol/a2a/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
rasa/agents/protocol/a2a/a2a_agent.py,sha256=t1voRAwp5RSDK7r5lT7T0DITagkXXvaX4QXoXi087S0,1662
|
|
14
14
|
rasa/agents/protocol/mcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
rasa/agents/protocol/mcp/mcp_base_agent.py,sha256=
|
|
16
|
-
rasa/agents/protocol/mcp/mcp_open_agent.py,sha256=
|
|
17
|
-
rasa/agents/protocol/mcp/mcp_task_agent.py,sha256=
|
|
18
|
-
rasa/agents/schemas/__init__.py,sha256=
|
|
19
|
-
rasa/agents/schemas/agent_input.py,sha256=
|
|
15
|
+
rasa/agents/protocol/mcp/mcp_base_agent.py,sha256=rOSvuIaqp4MDPqRL9EEWsvxTQGtYl0dzLhQJhBmNjmI,25938
|
|
16
|
+
rasa/agents/protocol/mcp/mcp_open_agent.py,sha256=U-dRX2U_r-3Ep7iuk_fkrNqY822tGLucWfEW72zXtiY,10811
|
|
17
|
+
rasa/agents/protocol/mcp/mcp_task_agent.py,sha256=3xFnIOWQSG-zD9fPBXDBGU4v_qxnj95psjwAdcIqDtA,19022
|
|
18
|
+
rasa/agents/schemas/__init__.py,sha256=6iNKhFCh3UTFTfIeYJpRyMKvENucXpBZ7IiqNGOaM_Q,384
|
|
19
|
+
rasa/agents/schemas/agent_input.py,sha256=11LK0cMnuU29gwZD-zs0BOepnVfxxeWuY0Ax4nb6LPE,970
|
|
20
20
|
rasa/agents/schemas/agent_output.py,sha256=Gc5W-d9ZGBY3JmTNVLiMCtw09my482HM-kWPSy34Evs,784
|
|
21
21
|
rasa/agents/schemas/agent_tool_result.py,sha256=HkjFxn0f4_ubkAKLwxpC6kj0ciCf5FXSG7yaqTmsHKg,1689
|
|
22
|
-
rasa/agents/schemas/agent_tool_schema.py,sha256=
|
|
22
|
+
rasa/agents/schemas/agent_tool_schema.py,sha256=V79xiei2Dkkuy_ivBKkoA7R3Z_bR7VbfvULguFP7JAk,4586
|
|
23
23
|
rasa/agents/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
24
|
rasa/agents/templates/mcp_open_agent_prompt_template.jinja2,sha256=2sW5_oO1xqMdeLTd93ONLclN4CmNexu9py0nHg3gj5w,1139
|
|
25
|
-
rasa/agents/templates/mcp_task_agent_prompt_template.jinja2,sha256=
|
|
25
|
+
rasa/agents/templates/mcp_task_agent_prompt_template.jinja2,sha256=EW5qB0Fx5SGcLvbn5776SJyaTRqXTqq61KF8kYjJrMI,878
|
|
26
26
|
rasa/agents/utils.py,sha256=AsKTP4OXFgOWOeXxnnc9suWUWshkTopSiNZL7mpXj68,2471
|
|
27
27
|
rasa/api.py,sha256=GLO3rTiGJ1HV9EZe3yEDD1ymtqP9t_JIeFwoOoP95I4,6542
|
|
28
28
|
rasa/cli/__init__.py,sha256=eO5vp9rFCANtbTVU-pxN3iMBKw4p9WRcgzytt9MzinY,115
|
|
@@ -351,12 +351,12 @@ rasa/core/policies/enterprise_search_policy_config.py,sha256=rTIGBrfGfe_lvsYQW1c
|
|
|
351
351
|
rasa/core/policies/enterprise_search_prompt_template.jinja2,sha256=dCS_seyBGxMQoMsOjjvPp0dd31OSzZCJSZeev1FJK5Q,1187
|
|
352
352
|
rasa/core/policies/enterprise_search_prompt_with_citation_template.jinja2,sha256=va9rpP97dN3PKoJZOVfyuISt3cPBlb10Pqyz25RwO_Q,3294
|
|
353
353
|
rasa/core/policies/enterprise_search_prompt_with_relevancy_check_and_citation_template.jinja2,sha256=b_8ZzK1ar0SvLZRFS8d9tHWvYS7Xb8xPJiBKg-UcyAM,3743
|
|
354
|
-
rasa/core/policies/flow_policy.py,sha256=
|
|
354
|
+
rasa/core/policies/flow_policy.py,sha256=Ulh3pjc1Yi4oJ4oLdmMgv9_SxcqO39m2AohhZaOEJgM,7510
|
|
355
355
|
rasa/core/policies/flows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
356
356
|
rasa/core/policies/flows/flow_exceptions.py,sha256=_FQuN-cerQDM1pivce9bz4zylh5UYkljvYS1gjDukHI,1527
|
|
357
|
-
rasa/core/policies/flows/flow_executor.py,sha256=
|
|
357
|
+
rasa/core/policies/flows/flow_executor.py,sha256=PxoF7dQe9kksbF5zOAPwUEXNphtN6qYCm1kScL3piB0,42631
|
|
358
358
|
rasa/core/policies/flows/flow_step_result.py,sha256=agjPrD6lahGSe2ViO5peBeoMdI9ngVGRSgtytgxmJmg,1360
|
|
359
|
-
rasa/core/policies/flows/mcp_tool_executor.py,sha256=
|
|
359
|
+
rasa/core/policies/flows/mcp_tool_executor.py,sha256=EUyJ5puyYnClGMAeP2zebQ4dQYjH8DHFMJAVo-ZuRow,9384
|
|
360
360
|
rasa/core/policies/intentless_policy.py,sha256=1A7FSkI4PQdN3t1p3GQhSImmO-m6UVCUzzEsjxz4nKc,38040
|
|
361
361
|
rasa/core/policies/intentless_prompt_template.jinja2,sha256=KhIL3cruMmkxhrs5oVbqgSvK6ZiN_6TQ_jXrgtEB-ZY,677
|
|
362
362
|
rasa/core/policies/memoization.py,sha256=CX2d3yP7FehSMW92Wi9NYLZei7tBzoT3T6yybu-Nb5s,19377
|
|
@@ -419,7 +419,7 @@ rasa/dialogue_understanding/commands/session_end_command.py,sha256=ZecUpYZDTX_68
|
|
|
419
419
|
rasa/dialogue_understanding/commands/session_start_command.py,sha256=FA4yocMnFt5bn2dmXj48S4Pq_yTlEnOBxgK_mq-qAxg,1704
|
|
420
420
|
rasa/dialogue_understanding/commands/set_slot_command.py,sha256=VWyv98yk65Jg-unKmytrbNeEsdNUfVkq7TrUzAMNQAs,7299
|
|
421
421
|
rasa/dialogue_understanding/commands/skip_question_command.py,sha256=SlPeY0__XiRocUzBVW13kecxVNL5t7XtbOKvvVIWccQ,3387
|
|
422
|
-
rasa/dialogue_understanding/commands/start_flow_command.py,sha256=
|
|
422
|
+
rasa/dialogue_understanding/commands/start_flow_command.py,sha256=pQlC9wRcjRurieUT44-cHAUo8Hgi3j1oICDLK4bG5KQ,10965
|
|
423
423
|
rasa/dialogue_understanding/commands/user_silence_command.py,sha256=DQjRfZk09sV1o2emnLkmX7cZpsJwBHNeJGBDQVkejjY,1686
|
|
424
424
|
rasa/dialogue_understanding/commands/utils.py,sha256=OpK_virArtaQaFbrV0v57MXB5SH_CIIQ2UQelNYjN9A,4814
|
|
425
425
|
rasa/dialogue_understanding/constants.py,sha256=_kB0edGV23uvhujlF193N2jk6YG0R6LC599YDX5B5vo,129
|
|
@@ -464,7 +464,7 @@ rasa/dialogue_understanding/patterns/collect_information.py,sha256=8YWvhFTt8CJML
|
|
|
464
464
|
rasa/dialogue_understanding/patterns/completed.py,sha256=7qkyUj2d__2R3mpwWVmQpfwCCbJruBrjRZbmbDr3Zbo,1278
|
|
465
465
|
rasa/dialogue_understanding/patterns/continue_interrupted.py,sha256=FQRM0c9ly7LT_CpoY27dHumjhSUcrDkpY7vBo8d_ShU,7484
|
|
466
466
|
rasa/dialogue_understanding/patterns/correction.py,sha256=7fQ02-JU1CGZiTjTi9YqmD1F4o-9Tv5WCAXnFgZlvtY,11380
|
|
467
|
-
rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml,sha256=
|
|
467
|
+
rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml,sha256=dKve0DQxR2g-yMdOLtBI1RkiV1sqbY8BfQIcLBmMFM8,12883
|
|
468
468
|
rasa/dialogue_understanding/patterns/domain_for_patterns.py,sha256=Zv_lCJn4nbkxeNYOPGsR0V8tmYAUsM_Ho_9to8hku-o,6493
|
|
469
469
|
rasa/dialogue_understanding/patterns/human_handoff.py,sha256=1hkSdL6kui42rZc7zERZ9R7nLyvRHi_tHgNU7FyrhAQ,1132
|
|
470
470
|
rasa/dialogue_understanding/patterns/internal_error.py,sha256=APCKVv16M6mSQ4upu4UwG0yIaaKTyr7uB2yV8ZtpMzo,1609
|
|
@@ -476,7 +476,7 @@ rasa/dialogue_understanding/patterns/skip_question.py,sha256=fJ1MC0WEEtS-BpnGJEf
|
|
|
476
476
|
rasa/dialogue_understanding/patterns/user_silence.py,sha256=xP-QMnd-MsybH5z4g01hBv4OLOHcw6m3rc26LQfe2zo,1140
|
|
477
477
|
rasa/dialogue_understanding/patterns/validate_slot.py,sha256=hqd5AEGT3M3HLNhMwuI9W9kZNCvgU6GyI-2xc2b4kz8,2085
|
|
478
478
|
rasa/dialogue_understanding/processor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
479
|
-
rasa/dialogue_understanding/processor/command_processor.py,sha256=
|
|
479
|
+
rasa/dialogue_understanding/processor/command_processor.py,sha256=QgJGKM9rkY6FoBoXbYYcuyl21flEd_xuMkLoSxVSU6w,33927
|
|
480
480
|
rasa/dialogue_understanding/processor/command_processor_component.py,sha256=rkErI_Uo7s3LsEojUSGSRbWGyGaX7GtGOYSJn0V-TI4,1650
|
|
481
481
|
rasa/dialogue_understanding/stack/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
482
482
|
rasa/dialogue_understanding/stack/dialogue_stack.py,sha256=UmE5r1Jy0Yy-JIJHb4nQQhbQM-GDySnvZqFDXMCbk64,9528
|
|
@@ -486,7 +486,7 @@ rasa/dialogue_understanding/stack/frames/dialogue_stack_frame.py,sha256=SBTmCV4S
|
|
|
486
486
|
rasa/dialogue_understanding/stack/frames/flow_stack_frame.py,sha256=h0qeWxPSEj0lWC2TMSjBHc_H4oYWrbOvX_24kAxY8Zk,7253
|
|
487
487
|
rasa/dialogue_understanding/stack/frames/pattern_frame.py,sha256=EVrYWv5dCP7XTvNV-HqtOOrseP-IkF0jD2_JacAvIYw,235
|
|
488
488
|
rasa/dialogue_understanding/stack/frames/search_frame.py,sha256=Eo6tSSbJpslKcs6DLu250NmtoKMe4bDHC8_ebx5sJ60,759
|
|
489
|
-
rasa/dialogue_understanding/stack/utils.py,sha256=
|
|
489
|
+
rasa/dialogue_understanding/stack/utils.py,sha256=VFdxx5j9s8Y0ywPCYNFajugDgyeWvFDNgvWQ9ellZo0,8782
|
|
490
490
|
rasa/dialogue_understanding/utils.py,sha256=p-KVd7VF21HFHwRMHp5zAnOcMs_BMkVnDgY17TLSUy8,7804
|
|
491
491
|
rasa/dialogue_understanding_test/README.md,sha256=klUCq_FYd0MkIeyxlwYCfsB9EEsSmXUpTTDTxdR7EPc,17764
|
|
492
492
|
rasa/dialogue_understanding_test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -690,11 +690,11 @@ rasa/shared/core/flows/flow_step.py,sha256=b1O2b5sJJP9lyPzcAStNJITYcPQWlyIlsu2qX
|
|
|
690
690
|
rasa/shared/core/flows/flow_step_links.py,sha256=UNlE8xuhi-8R3CL2HPLEp0sAaKP_Obhv5yHSRNsiP8Q,11054
|
|
691
691
|
rasa/shared/core/flows/flow_step_sequence.py,sha256=yFtG_1ihI7hUK8I1izawMWVPPct4uh1iW2U0BVeCzUk,2537
|
|
692
692
|
rasa/shared/core/flows/flows_list.py,sha256=k3EsDTh6L7CSSeLmUInRbeU5lat29wofWs9FrYjerrw,9397
|
|
693
|
-
rasa/shared/core/flows/flows_yaml_schema.json,sha256=
|
|
693
|
+
rasa/shared/core/flows/flows_yaml_schema.json,sha256=CYqn3utfKxt2JbsuMmrLX6_m0NMyANidb2u2b8D-S1c,11631
|
|
694
694
|
rasa/shared/core/flows/nlu_trigger.py,sha256=ujLXFo5WjIwtwRVEdxZkaE2fbd4KEmayeFPAd1mF26I,4352
|
|
695
695
|
rasa/shared/core/flows/steps/__init__.py,sha256=jvJp02o9_Wx-rZeQ3SYiLVMpO6ulS1yKuiiKg0ld_nE,655
|
|
696
696
|
rasa/shared/core/flows/steps/action.py,sha256=fRtNXLCK-r74tX3-rHyn_eKv7cRYRoNfEW2lCK0VdrQ,1920
|
|
697
|
-
rasa/shared/core/flows/steps/call.py,sha256=
|
|
697
|
+
rasa/shared/core/flows/steps/call.py,sha256=zl1NjBY1-YulIZeBcZFvtEXTNbpkPChhaM8QujcTXrs,4191
|
|
698
698
|
rasa/shared/core/flows/steps/collect.py,sha256=XQSGnPeC_vS-qDvJInBc5uZ9-9p-AQZZXRAh7LMCfnE,5775
|
|
699
699
|
rasa/shared/core/flows/steps/constants.py,sha256=DCxrEUGbJciBknHm-_t4tmcnH19IZKP-WYxqix9gm7M,132
|
|
700
700
|
rasa/shared/core/flows/steps/continuation.py,sha256=5Rzayr80FsgS4bAajuRObVvVcLqPEh9nxGbT2te85xY,1498
|
|
@@ -705,7 +705,7 @@ rasa/shared/core/flows/steps/no_operation.py,sha256=ofcJmmqKHpjHDp23ZgAMVs60blwf
|
|
|
705
705
|
rasa/shared/core/flows/steps/set_slots.py,sha256=NnPyHxY5gBiJ83qTbxRmgKh8BIMdi9U1TT71EfV35eE,1710
|
|
706
706
|
rasa/shared/core/flows/steps/start.py,sha256=AJpKIm0S3GZYLEs3ybXW0Zrq03Pu9lvirNahiUy2I6k,1010
|
|
707
707
|
rasa/shared/core/flows/utils.py,sha256=wqPWuEgYcbGMTs6wuckX400Sq1_Jz8yKYd2t91p3e8U,2270
|
|
708
|
-
rasa/shared/core/flows/validation.py,sha256=
|
|
708
|
+
rasa/shared/core/flows/validation.py,sha256=fSCqZJTaJK_YcHIMAsYTwtxJX68Dy6M5ENoRWae5WI4,29969
|
|
709
709
|
rasa/shared/core/flows/yaml_flows_io.py,sha256=mctlsJ8rX2Ci0_PDpl0Bb8cRJQOZtCt18a5nFxttyTU,18264
|
|
710
710
|
rasa/shared/core/generator.py,sha256=UAuBPu5UjUhL9djVK-PvrWZcNhRACOEgnRsTleV7eeY,35686
|
|
711
711
|
rasa/shared/core/policies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -850,7 +850,7 @@ rasa/tracing/metric_instrument_provider.py,sha256=FjdvAhKvJNKhvJPyFw1wWG6DWmlSyb
|
|
|
850
850
|
rasa/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
851
851
|
rasa/utils/beta.py,sha256=h2xwGagMh2SnpMuqhkEAEjL7C_CyU6b1te7sbtF-lm4,3240
|
|
852
852
|
rasa/utils/cli.py,sha256=L-DT4nPdVBWfc2m1COHrziLitVWJxazSreb6JLbTho4,865
|
|
853
|
-
rasa/utils/common.py,sha256=
|
|
853
|
+
rasa/utils/common.py,sha256=BsA4V6AAoICNAXsnvzZJfpy41KURwetJk8YUT1ivdxk,24208
|
|
854
854
|
rasa/utils/converter.py,sha256=H4LHpoAK7MXMmvNZG_uSn0gbccCJvHtsA2-6Zya4u6M,1656
|
|
855
855
|
rasa/utils/endpoints.py,sha256=jX9xSI_3KJ-NpzymyfaO-Zj-ISaWbA4ql2Kx3NulBvE,10905
|
|
856
856
|
rasa/utils/io.py,sha256=LIAdQQqUPA-V_mdpgeQzPDzA4rmsdZLyVKc8j_0Z70Y,7161
|
|
@@ -883,9 +883,9 @@ rasa/utils/train_utils.py,sha256=ClJx-6x3-h3Vt6mskacgkcCUJTMXjFPe3zAcy_DfmaU,212
|
|
|
883
883
|
rasa/utils/url_tools.py,sha256=dZ1HGkVdWTJB7zYEdwoDIrEuyX9HE5WsxKKFVsXBLE0,1218
|
|
884
884
|
rasa/utils/yaml.py,sha256=KjbZq5C94ZP7Jdsw8bYYF7HASI6K4-C_kdHfrnPLpSI,2000
|
|
885
885
|
rasa/validator.py,sha256=fhRlHQvuBkiup0FnNYmwRmqQwC3QpdCJt0TuvW4jMaI,83125
|
|
886
|
-
rasa/version.py,sha256
|
|
887
|
-
rasa_pro-3.14.0.
|
|
888
|
-
rasa_pro-3.14.0.
|
|
889
|
-
rasa_pro-3.14.0.
|
|
890
|
-
rasa_pro-3.14.0.
|
|
891
|
-
rasa_pro-3.14.0.
|
|
886
|
+
rasa/version.py,sha256=-lUY2RKs3DkzuaGMLEs_Mu_Euh3syH3jLT7nS6OB_iU,122
|
|
887
|
+
rasa_pro-3.14.0.dev3.dist-info/METADATA,sha256=l9P5Y9t6Jj27y9_9_YccH10b8Lz5rAAWHPWRDnebGyQ,10615
|
|
888
|
+
rasa_pro-3.14.0.dev3.dist-info/NOTICE,sha256=7HlBoMHJY9CL2GlYSfTQ-PZsVmLmVkYmMiPlTjhuCqA,218
|
|
889
|
+
rasa_pro-3.14.0.dev3.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
890
|
+
rasa_pro-3.14.0.dev3.dist-info/entry_points.txt,sha256=ckJ2SfEyTPgBqj_I6vm_tqY9dZF_LAPJZA335Xp0Q9U,43
|
|
891
|
+
rasa_pro-3.14.0.dev3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|