rasa-pro 3.13.7__py3-none-any.whl → 3.14.0.dev1__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/__init__.py +0 -0
- rasa/agents/agent_factory.py +122 -0
- rasa/agents/agent_manager.py +162 -0
- rasa/agents/constants.py +31 -0
- rasa/agents/core/__init__.py +0 -0
- rasa/agents/core/agent_protocol.py +108 -0
- rasa/agents/core/types.py +70 -0
- rasa/agents/exceptions.py +8 -0
- rasa/agents/protocol/__init__.py +5 -0
- rasa/agents/protocol/a2a/__init__.py +0 -0
- rasa/agents/protocol/a2a/a2a_agent.py +51 -0
- rasa/agents/protocol/mcp/__init__.py +0 -0
- rasa/agents/protocol/mcp/mcp_base_agent.py +697 -0
- rasa/agents/protocol/mcp/mcp_open_agent.py +275 -0
- rasa/agents/protocol/mcp/mcp_task_agent.py +447 -0
- rasa/agents/schemas/__init__.py +6 -0
- rasa/agents/schemas/agent_input.py +24 -0
- rasa/agents/schemas/agent_output.py +26 -0
- rasa/agents/schemas/agent_tool_result.py +51 -0
- rasa/agents/schemas/agent_tool_schema.py +112 -0
- rasa/agents/templates/__init__.py +0 -0
- rasa/agents/templates/mcp_open_agent_prompt_template.jinja2 +15 -0
- rasa/agents/templates/mcp_task_agent_prompt_template.jinja2 +13 -0
- rasa/agents/utils.py +72 -0
- rasa/api.py +5 -0
- rasa/cli/arguments/default_arguments.py +12 -0
- rasa/cli/arguments/run.py +2 -0
- rasa/cli/dialogue_understanding_test.py +4 -0
- rasa/cli/e2e_test.py +4 -0
- rasa/cli/inspect.py +3 -0
- rasa/cli/llm_fine_tuning.py +5 -0
- rasa/cli/run.py +4 -0
- rasa/cli/shell.py +3 -0
- rasa/cli/train.py +2 -2
- rasa/constants.py +6 -0
- rasa/core/actions/action.py +69 -39
- rasa/core/actions/action_run_slot_rejections.py +1 -1
- rasa/core/agent.py +16 -0
- rasa/core/available_agents.py +196 -0
- rasa/core/available_endpoints.py +30 -0
- rasa/core/channels/development_inspector.py +47 -14
- rasa/core/channels/inspector/dist/assets/{arc-0b11fe30.js → arc-2e78c586.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{blockDiagram-38ab4fdb-9eef30a7.js → blockDiagram-38ab4fdb-806b712e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-3d4e48cf-03e94f28.js → c4Diagram-3d4e48cf-0745efa9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/channel-c436ca7c.js +1 -0
- rasa/core/channels/inspector/dist/assets/{classDiagram-70f12bd4-95c09eba.js → classDiagram-70f12bd4-7bd1082b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-f2320105-38e8446c.js → classDiagram-v2-f2320105-d937ba49.js} +1 -1
- rasa/core/channels/inspector/dist/assets/clone-50dd656b.js +1 -0
- rasa/core/channels/inspector/dist/assets/{createText-2e5e7dd3-57dc3038.js → createText-2e5e7dd3-a2a564ca.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-e0da2a9e-4bac0545.js → edges-e0da2a9e-b5256940.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9861fffd-81795c90.js → erDiagram-9861fffd-e6883ad2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-956e92f1-89489ae6.js → flowDb-956e92f1-e576fc02.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-66a62f08-cd152627.js → flowDiagram-66a62f08-2e298d01.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-2b2aeaf8.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-4a651766-3da369bc.js → flowchart-elk-definition-4a651766-dd7b150a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-c361ad54-85ec16f8.js → ganttDiagram-c361ad54-5b79575c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-72cf32ee-495bc140.js → gitGraphDiagram-72cf32ee-3016f40a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{graph-1ec4d266.js → graph-3e19170f.js} +1 -1
- rasa/core/channels/inspector/dist/assets/index-1bd9135e.js +1353 -0
- rasa/core/channels/inspector/dist/assets/{index-3862675e-0a0e97c9.js → index-3862675e-eb9c86de.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{infoDiagram-f8f76790-4d54bcde.js → infoDiagram-f8f76790-b4280e4d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-49397b02-dc097114.js → journeyDiagram-49397b02-556091f8.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-1a08981e.js → layout-08436411.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-95f7f1d3.js → line-683c4f3b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-97e69543.js → linear-cee6d791.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-fc14e90a-8c71ff03.js → mindmap-definition-fc14e90a-a0bf0b1a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-8a3498a8-f14c71c7.js → pieDiagram-8a3498a8-3730d5c4.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-120e2f19-f1d3c9ff.js → quadrantDiagram-120e2f19-12a20fed.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-deff3bca-bfa2412f.js → requirementDiagram-deff3bca-b9732102.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-04a897e0-53f2c97b.js → sankeyDiagram-04a897e0-a2e72776.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-704730f1-319d7c0e.js → sequenceDiagram-704730f1-8b7a76bb.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-587899a1-76a09418.js → stateDiagram-587899a1-e65853ac.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-d93cdb3a-a67f15d4.js → stateDiagram-v2-d93cdb3a-6f58a44b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-6aaf32cf-0654e7c3.js → styles-6aaf32cf-df25b934.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9a916d00-1394bb9d.js → styles-9a916d00-88357141.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-c10674c1-e4c5bdae.js → styles-c10674c1-d600174d.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-08f97a94-50957104.js → svgDrawCommon-08f97a94-4adc3e0b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-85554ec2-b0885a6a.js → timeline-definition-85554ec2-42816fa1.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-e933f94c-79e6541a.js → xychartDiagram-e933f94c-621eb66a.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +2 -2
- rasa/core/channels/inspector/index.html +1 -1
- rasa/core/channels/inspector/src/App.tsx +53 -7
- rasa/core/channels/inspector/src/components/Chat.tsx +3 -2
- rasa/core/channels/inspector/src/components/DiagramFlow.tsx +1 -1
- rasa/core/channels/inspector/src/components/DialogueStack.tsx +7 -5
- rasa/core/channels/inspector/src/components/LatencyDisplay.tsx +268 -0
- rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +6 -2
- rasa/core/channels/inspector/src/helpers/audio/audiostream.ts +8 -3
- rasa/core/channels/inspector/src/helpers/formatters.ts +24 -3
- rasa/core/channels/inspector/src/theme/base/styles.ts +19 -1
- rasa/core/channels/inspector/src/types.ts +12 -0
- rasa/core/channels/studio_chat.py +125 -34
- rasa/core/channels/voice_ready/twilio_voice.py +1 -1
- rasa/core/channels/voice_stream/audiocodes.py +9 -6
- rasa/core/channels/voice_stream/browser_audio.py +39 -4
- rasa/core/channels/voice_stream/call_state.py +13 -2
- rasa/core/channels/voice_stream/genesys.py +16 -13
- rasa/core/channels/voice_stream/jambonz.py +13 -11
- rasa/core/channels/voice_stream/twilio_media_streams.py +14 -13
- rasa/core/channels/voice_stream/util.py +11 -1
- rasa/core/channels/voice_stream/voice_channel.py +101 -29
- rasa/core/constants.py +4 -0
- rasa/core/nlg/contextual_response_rephraser.py +11 -7
- rasa/core/nlg/generator.py +21 -5
- rasa/core/nlg/response.py +43 -6
- rasa/core/nlg/translate.py +8 -0
- rasa/core/policies/enterprise_search_policy.py +4 -2
- rasa/core/policies/flow_policy.py +2 -2
- rasa/core/policies/flows/flow_executor.py +374 -35
- rasa/core/policies/flows/mcp_tool_executor.py +240 -0
- rasa/core/processor.py +6 -1
- rasa/core/run.py +8 -1
- rasa/core/utils.py +21 -1
- rasa/dialogue_understanding/commands/__init__.py +8 -0
- rasa/dialogue_understanding/commands/cancel_flow_command.py +97 -4
- rasa/dialogue_understanding/commands/chit_chat_answer_command.py +11 -0
- rasa/dialogue_understanding/commands/continue_agent_command.py +91 -0
- rasa/dialogue_understanding/commands/knowledge_answer_command.py +11 -0
- rasa/dialogue_understanding/commands/restart_agent_command.py +146 -0
- rasa/dialogue_understanding/commands/start_flow_command.py +129 -8
- rasa/dialogue_understanding/commands/utils.py +6 -2
- rasa/dialogue_understanding/generator/command_parser.py +4 -0
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +50 -12
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_claude_3_5_sonnet_20240620_template.jinja2 +61 -0
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v2_gpt_4o_2024_11_20_template.jinja2 +61 -0
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_claude_3_5_sonnet_20240620_template.jinja2 +81 -0
- rasa/dialogue_understanding/generator/prompt_templates/agent_command_prompt_v3_gpt_4o_2024_11_20_template.jinja2 +81 -0
- rasa/dialogue_understanding/generator/single_step/compact_llm_command_generator.py +7 -6
- rasa/dialogue_understanding/generator/single_step/search_ready_llm_command_generator.py +7 -6
- rasa/dialogue_understanding/generator/single_step/single_step_based_llm_command_generator.py +41 -2
- rasa/dialogue_understanding/patterns/continue_interrupted.py +163 -1
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +51 -7
- rasa/dialogue_understanding/stack/dialogue_stack.py +123 -2
- rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +57 -0
- rasa/dialogue_understanding/stack/utils.py +3 -2
- rasa/dialogue_understanding_test/du_test_runner.py +7 -2
- rasa/dialogue_understanding_test/du_test_schema.yml +3 -3
- rasa/e2e_test/e2e_test_runner.py +5 -0
- rasa/e2e_test/e2e_test_schema.yml +3 -3
- rasa/model_manager/model_api.py +1 -1
- rasa/model_manager/socket_bridge.py +8 -2
- rasa/server.py +10 -0
- rasa/shared/agents/__init__.py +0 -0
- rasa/shared/agents/utils.py +35 -0
- rasa/shared/constants.py +5 -0
- rasa/shared/core/constants.py +12 -1
- rasa/shared/core/domain.py +5 -5
- rasa/shared/core/events.py +319 -0
- rasa/shared/core/flows/flows_list.py +2 -2
- rasa/shared/core/flows/flows_yaml_schema.json +101 -186
- rasa/shared/core/flows/steps/call.py +51 -5
- rasa/shared/core/flows/validation.py +45 -7
- rasa/shared/core/flows/yaml_flows_io.py +3 -3
- rasa/shared/providers/llm/_base_litellm_client.py +39 -7
- rasa/shared/providers/llm/litellm_router_llm_client.py +8 -4
- rasa/shared/providers/llm/llm_client.py +7 -3
- rasa/shared/providers/llm/llm_response.py +49 -0
- rasa/shared/providers/llm/self_hosted_llm_client.py +8 -4
- rasa/shared/utils/common.py +2 -1
- rasa/shared/utils/llm.py +28 -5
- rasa/shared/utils/mcp/__init__.py +0 -0
- rasa/shared/utils/mcp/server_connection.py +157 -0
- rasa/shared/utils/schemas/events.py +42 -0
- rasa/studio/upload.py +4 -7
- rasa/tracing/instrumentation/instrumentation.py +4 -2
- rasa/utils/common.py +53 -0
- rasa/utils/licensing.py +21 -10
- rasa/utils/plotting.py +1 -1
- rasa/version.py +1 -1
- {rasa_pro-3.13.7.dist-info → rasa_pro-3.14.0.dev1.dist-info}/METADATA +16 -15
- {rasa_pro-3.13.7.dist-info → rasa_pro-3.14.0.dev1.dist-info}/RECORD +174 -137
- rasa/core/channels/inspector/dist/assets/channel-51d02e9e.js +0 -1
- rasa/core/channels/inspector/dist/assets/clone-cc738fa6.js +0 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-96b9c2cf-0c716443.js +0 -1
- rasa/core/channels/inspector/dist/assets/index-c804b295.js +0 -1335
- {rasa_pro-3.13.7.dist-info → rasa_pro-3.14.0.dev1.dist-info}/NOTICE +0 -0
- {rasa_pro-3.13.7.dist-info → rasa_pro-3.14.0.dev1.dist-info}/WHEEL +0 -0
- {rasa_pro-3.13.7.dist-info → rasa_pro-3.14.0.dev1.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
import json
|
|
3
|
+
from typing import Any, Dict, List, Optional
|
|
4
|
+
|
|
5
|
+
import structlog
|
|
6
|
+
|
|
7
|
+
from rasa.agents.constants import (
|
|
8
|
+
KEY_CONTENT,
|
|
9
|
+
KEY_ROLE,
|
|
10
|
+
KEY_TOOL_CALL_ID,
|
|
11
|
+
TOOL_ADDITIONAL_PROPERTIES_KEY,
|
|
12
|
+
TOOL_DESCRIPTION_KEY,
|
|
13
|
+
TOOL_NAME_KEY,
|
|
14
|
+
TOOL_PARAMETERS_KEY,
|
|
15
|
+
TOOL_PROPERTIES_KEY,
|
|
16
|
+
TOOL_REQUIRED_KEY,
|
|
17
|
+
TOOL_STRICT_KEY,
|
|
18
|
+
TOOL_TYPE_FUNCTION_KEY,
|
|
19
|
+
TOOL_TYPE_KEY,
|
|
20
|
+
)
|
|
21
|
+
from rasa.agents.core.types import AgentStatus, ProtocolType
|
|
22
|
+
from rasa.agents.protocol.mcp.mcp_base_agent import MCPBaseAgent
|
|
23
|
+
from rasa.agents.schemas import (
|
|
24
|
+
AgentInput,
|
|
25
|
+
AgentOutput,
|
|
26
|
+
AgentToolResult,
|
|
27
|
+
)
|
|
28
|
+
from rasa.core.available_agents import AgentMCPServerConfig, ProtocolConfig
|
|
29
|
+
from rasa.shared.agents.utils import make_agent_identifier
|
|
30
|
+
from rasa.shared.constants import (
|
|
31
|
+
ROLE_TOOL,
|
|
32
|
+
)
|
|
33
|
+
from rasa.shared.providers.llm.llm_response import LLMResponse, LLMToolCall
|
|
34
|
+
|
|
35
|
+
DEFAULT_OPEN_AGENT_PROMPT_TEMPLATE = importlib.resources.read_text(
|
|
36
|
+
"rasa.agents.templates", "mcp_open_agent_prompt_template.jinja2"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
KEY_TASK_COMPLETED = "task_completed"
|
|
40
|
+
|
|
41
|
+
TASK_COMPLETED_TOOL = {
|
|
42
|
+
TOOL_TYPE_KEY: TOOL_TYPE_FUNCTION_KEY,
|
|
43
|
+
TOOL_TYPE_FUNCTION_KEY: {
|
|
44
|
+
TOOL_NAME_KEY: KEY_TASK_COMPLETED,
|
|
45
|
+
TOOL_DESCRIPTION_KEY: "Signal that the MCP agent has FULLY completed its "
|
|
46
|
+
"primary task. Once you have presented your findings, follow-up with "
|
|
47
|
+
"a message summarizing the completed task in a comprehensive and well-written "
|
|
48
|
+
"manner. Avoid repeating information already provided in the conversation.",
|
|
49
|
+
TOOL_PARAMETERS_KEY: {
|
|
50
|
+
TOOL_TYPE_KEY: "object",
|
|
51
|
+
TOOL_PROPERTIES_KEY: {
|
|
52
|
+
"message": {
|
|
53
|
+
TOOL_TYPE_KEY: "string",
|
|
54
|
+
TOOL_DESCRIPTION_KEY: "A message describing the completed task.",
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
TOOL_REQUIRED_KEY: ["message"],
|
|
58
|
+
TOOL_ADDITIONAL_PROPERTIES_KEY: False,
|
|
59
|
+
},
|
|
60
|
+
TOOL_STRICT_KEY: True,
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
structlogger = structlog.get_logger()
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class MCPOpenAgent(MCPBaseAgent):
|
|
68
|
+
"""MCP protocol implementation."""
|
|
69
|
+
|
|
70
|
+
def __init__(
|
|
71
|
+
self,
|
|
72
|
+
name: str,
|
|
73
|
+
description: str,
|
|
74
|
+
protocol_type: ProtocolConfig,
|
|
75
|
+
server_configs: List[AgentMCPServerConfig],
|
|
76
|
+
llm_config: Optional[Dict[str, Any]] = None,
|
|
77
|
+
prompt_template: Optional[str] = None,
|
|
78
|
+
timeout: Optional[int] = None,
|
|
79
|
+
max_retries: Optional[int] = None,
|
|
80
|
+
):
|
|
81
|
+
super().__init__(
|
|
82
|
+
name,
|
|
83
|
+
description,
|
|
84
|
+
protocol_type,
|
|
85
|
+
server_configs,
|
|
86
|
+
llm_config,
|
|
87
|
+
prompt_template,
|
|
88
|
+
timeout,
|
|
89
|
+
max_retries,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
@property
|
|
93
|
+
def protocol_type(self) -> ProtocolType:
|
|
94
|
+
return ProtocolType.MCP_OPEN
|
|
95
|
+
|
|
96
|
+
@staticmethod
|
|
97
|
+
def get_default_prompt_template() -> str:
|
|
98
|
+
return DEFAULT_OPEN_AGENT_PROMPT_TEMPLATE
|
|
99
|
+
|
|
100
|
+
@staticmethod
|
|
101
|
+
def get_task_completed_tool() -> Dict[str, Any]:
|
|
102
|
+
"""Get the task completed tool for MCP. Override to customize/disable."""
|
|
103
|
+
return TASK_COMPLETED_TOOL
|
|
104
|
+
|
|
105
|
+
@classmethod
|
|
106
|
+
def get_agent_specific_built_in_tools(
|
|
107
|
+
cls, agent_input: AgentInput
|
|
108
|
+
) -> List[Dict[str, Any]]:
|
|
109
|
+
"""Get agentic specific built-in tools."""
|
|
110
|
+
return [cls.get_task_completed_tool()]
|
|
111
|
+
|
|
112
|
+
def _run_task_completed_tool(
|
|
113
|
+
self,
|
|
114
|
+
tool_call: LLMToolCall,
|
|
115
|
+
agent_input: AgentInput,
|
|
116
|
+
tool_results: Dict[str, AgentToolResult],
|
|
117
|
+
) -> AgentOutput:
|
|
118
|
+
"""Run the task completed tool."""
|
|
119
|
+
# Create the agent tool result for the task completed tool.
|
|
120
|
+
|
|
121
|
+
tool_result = AgentToolResult(
|
|
122
|
+
tool_name=tool_call.tool_name,
|
|
123
|
+
result=tool_call.tool_args.get("message", "Task completed"),
|
|
124
|
+
)
|
|
125
|
+
tool_results[tool_call.id] = tool_result
|
|
126
|
+
|
|
127
|
+
# Create the agent output for the task completed tool.
|
|
128
|
+
return AgentOutput(
|
|
129
|
+
id=agent_input.id,
|
|
130
|
+
status=AgentStatus.COMPLETED,
|
|
131
|
+
response_message=tool_result.result,
|
|
132
|
+
tool_results=self._get_tool_results_for_agent_output(
|
|
133
|
+
agent_input, tool_results
|
|
134
|
+
),
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
async def send_message(self, agent_input: AgentInput) -> AgentOutput:
|
|
138
|
+
"""Send a message to the LLM and return the response."""
|
|
139
|
+
messages = self.build_messages_for_llm_request(agent_input)
|
|
140
|
+
tool_results: Dict[str, AgentToolResult] = {}
|
|
141
|
+
# Convert available tools to OpenAI JSON format
|
|
142
|
+
tools_in_openai_format = [
|
|
143
|
+
tool.to_openai_json_format()
|
|
144
|
+
for tool in self.get_available_tools(agent_input)
|
|
145
|
+
]
|
|
146
|
+
|
|
147
|
+
for iteration in range(self.MAX_ITERATIONS):
|
|
148
|
+
try:
|
|
149
|
+
# Make the LLM call using the llm_client
|
|
150
|
+
structlogger.info(
|
|
151
|
+
"mcp_open_agent.send_message.sending_message_to_llm",
|
|
152
|
+
messages=messages,
|
|
153
|
+
event_info=f"Sending message to LLM (iteration {iteration + 1})",
|
|
154
|
+
agent_name=self._name,
|
|
155
|
+
agent_id=str(make_agent_identifier(self._name, self.protocol_type)),
|
|
156
|
+
)
|
|
157
|
+
llm_response = LLMResponse.ensure_llm_response(
|
|
158
|
+
await self.llm_client.acompletion(
|
|
159
|
+
messages, tools=tools_in_openai_format
|
|
160
|
+
)
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# If no response from LLM, return an error output.
|
|
164
|
+
if llm_response is None or not (
|
|
165
|
+
llm_response.choices or llm_response.tool_calls
|
|
166
|
+
):
|
|
167
|
+
event_info = "No response from LLM."
|
|
168
|
+
structlogger.warning(
|
|
169
|
+
"mcp_open_agent.send_message.no_llm_response",
|
|
170
|
+
event_info=event_info,
|
|
171
|
+
agent_name=self._name,
|
|
172
|
+
agent_id=str(
|
|
173
|
+
make_agent_identifier(self._name, self.protocol_type)
|
|
174
|
+
),
|
|
175
|
+
)
|
|
176
|
+
return AgentOutput(
|
|
177
|
+
id=agent_input.id,
|
|
178
|
+
status=AgentStatus.RECOVERABLE_ERROR,
|
|
179
|
+
error_message=event_info,
|
|
180
|
+
tool_results=self._get_tool_results_for_agent_output(
|
|
181
|
+
agent_input, tool_results
|
|
182
|
+
),
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
# If no tool calls, return the response directly with input required.
|
|
186
|
+
if not llm_response.tool_calls and len(llm_response.choices) == 1:
|
|
187
|
+
return AgentOutput(
|
|
188
|
+
id=agent_input.id,
|
|
189
|
+
status=AgentStatus.INPUT_REQUIRED,
|
|
190
|
+
response_message=llm_response.choices[0],
|
|
191
|
+
tool_results=self._get_tool_results_for_agent_output(
|
|
192
|
+
agent_input, tool_results
|
|
193
|
+
),
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
# If there are tool calls, process them.
|
|
197
|
+
if llm_response.tool_calls:
|
|
198
|
+
# Add the assistant message with tool calls to the messages.
|
|
199
|
+
messages.append(
|
|
200
|
+
self._get_assistant_message_with_tool_calls(llm_response)
|
|
201
|
+
)
|
|
202
|
+
for tool_call in llm_response.tool_calls:
|
|
203
|
+
structlogger.info(
|
|
204
|
+
"mcp_open_agent.send_message.tool_call",
|
|
205
|
+
event_info=(
|
|
206
|
+
f"Processing tool call `{tool_call.tool_name}` with "
|
|
207
|
+
f"args: {tool_call.tool_args}"
|
|
208
|
+
),
|
|
209
|
+
tool_name=tool_call.tool_name,
|
|
210
|
+
tool_args=json.dumps(tool_call.tool_args),
|
|
211
|
+
agent_name=self._name,
|
|
212
|
+
agent_id=str(
|
|
213
|
+
make_agent_identifier(self._name, self.protocol_type)
|
|
214
|
+
),
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
# Agent signals task completion.
|
|
218
|
+
if tool_call.tool_name == KEY_TASK_COMPLETED:
|
|
219
|
+
return self._run_task_completed_tool(
|
|
220
|
+
tool_call, agent_input, tool_results
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
else:
|
|
224
|
+
# Execute the tool call.
|
|
225
|
+
tool_output = await self._execute_tool_call(
|
|
226
|
+
tool_call.tool_name,
|
|
227
|
+
tool_call.tool_args,
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
# If the tool call failed, generate an agent error output.
|
|
231
|
+
if tool_output.is_error or tool_output.result is None:
|
|
232
|
+
return self._generate_agent_error_output(
|
|
233
|
+
tool_output, agent_input, tool_call
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
# Store the tool output in the tool_results.
|
|
237
|
+
tool_results[tool_call.id] = tool_output
|
|
238
|
+
|
|
239
|
+
# Add the tool call message to the messages.
|
|
240
|
+
messages.append(
|
|
241
|
+
{
|
|
242
|
+
KEY_ROLE: ROLE_TOOL,
|
|
243
|
+
KEY_TOOL_CALL_ID: tool_call.id,
|
|
244
|
+
KEY_CONTENT: tool_output.result,
|
|
245
|
+
}
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
except Exception as e:
|
|
249
|
+
structlogger.error(
|
|
250
|
+
"mcp_open_agent.send_message.error_in_agent_loop",
|
|
251
|
+
event_info=f"Failed to send message: {e}",
|
|
252
|
+
user_message=agent_input.user_message,
|
|
253
|
+
agent_name=self._name,
|
|
254
|
+
agent_id=str(make_agent_identifier(self._name, self.protocol_type)),
|
|
255
|
+
)
|
|
256
|
+
return AgentOutput(
|
|
257
|
+
id=agent_input.id,
|
|
258
|
+
status=AgentStatus.FATAL_ERROR,
|
|
259
|
+
response_message=f"I encountered an error: {e!s}",
|
|
260
|
+
tool_results=self._get_tool_results_for_agent_output(
|
|
261
|
+
agent_input, tool_results
|
|
262
|
+
),
|
|
263
|
+
error_message=str(e),
|
|
264
|
+
)
|
|
265
|
+
return AgentOutput(
|
|
266
|
+
id=agent_input.id,
|
|
267
|
+
status=AgentStatus.COMPLETED,
|
|
268
|
+
response_message=(
|
|
269
|
+
"I've completed my research but couldn't provide a final answer within"
|
|
270
|
+
"the allowed steps."
|
|
271
|
+
),
|
|
272
|
+
tool_results=self._get_tool_results_for_agent_output(
|
|
273
|
+
agent_input, tool_results
|
|
274
|
+
),
|
|
275
|
+
)
|