mirror of https://github.com/kortix-ai/suna.git
chore(dev): properly process MCP results
This commit is contained in:
parent
fa463fb09c
commit
546d5078ea
|
@ -170,6 +170,20 @@ async def run_agent(
|
|||
qualified_name = mcp_config.get('qualifiedName', 'unknown')
|
||||
mcp_info += f"- {server_name} (use prefix: mcp_{qualified_name}_)\n"
|
||||
|
||||
# Add critical instructions for using search results
|
||||
mcp_info += "\n🚨 CRITICAL MCP TOOL RESULT INSTRUCTIONS 🚨\n"
|
||||
mcp_info += "When you use ANY MCP (Model Context Protocol) tools:\n"
|
||||
mcp_info += "1. ALWAYS read and use the EXACT results returned by the MCP tool\n"
|
||||
mcp_info += "2. For search tools: ONLY cite URLs, sources, and information from the actual search results\n"
|
||||
mcp_info += "3. For any tool: Base your response entirely on the tool's output - do NOT add external information\n"
|
||||
mcp_info += "4. DO NOT fabricate, invent, hallucinate, or make up any sources, URLs, or data\n"
|
||||
mcp_info += "5. If you need more information, call the MCP tool again with different parameters\n"
|
||||
mcp_info += "6. When writing reports/summaries: Reference ONLY the data from MCP tool results\n"
|
||||
mcp_info += "7. If the MCP tool doesn't return enough information, explicitly state this limitation\n"
|
||||
mcp_info += "8. Always double-check that every fact, URL, and reference comes from the MCP tool output\n"
|
||||
mcp_info += "\nIMPORTANT: MCP tool results are your PRIMARY and ONLY source of truth for external data!\n"
|
||||
mcp_info += "NEVER supplement MCP results with your training data or make assumptions beyond what the tools provide.\n"
|
||||
|
||||
system_content += mcp_info
|
||||
|
||||
system_message = { "role": "system", "content": system_content }
|
||||
|
|
|
@ -134,26 +134,41 @@ class MCPToolWrapper(Tool):
|
|||
server_name = parts[1] if len(parts) > 1 else "unknown"
|
||||
original_tool_name = parts[2] if len(parts) > 2 else tool_name
|
||||
|
||||
# Enhance the result with metadata for better frontend display
|
||||
enhanced_result = {
|
||||
"mcp_metadata": {
|
||||
"server_name": server_name,
|
||||
"tool_name": original_tool_name,
|
||||
"full_tool_name": tool_name,
|
||||
"arguments_count": len(arguments) if isinstance(arguments, dict) else 0,
|
||||
"is_mcp_tool": True
|
||||
},
|
||||
"content": result.get("content", ""),
|
||||
"isError": result.get("isError", False),
|
||||
"raw_result": result
|
||||
}
|
||||
|
||||
# Check if it's an error
|
||||
if result.get("isError", False):
|
||||
return self.fail_response(json.dumps(enhanced_result, indent=2))
|
||||
error_result = {
|
||||
"mcp_metadata": {
|
||||
"server_name": server_name,
|
||||
"tool_name": original_tool_name,
|
||||
"full_tool_name": tool_name,
|
||||
"arguments_count": len(arguments) if isinstance(arguments, dict) else 0,
|
||||
"is_mcp_tool": True
|
||||
},
|
||||
"content": result.get("content", ""),
|
||||
"isError": True,
|
||||
"raw_result": result
|
||||
}
|
||||
return self.fail_response(json.dumps(error_result, indent=2))
|
||||
|
||||
# Format the result in an LLM-friendly way with content first
|
||||
actual_content = result.get("content", "")
|
||||
|
||||
# Create a clear, LLM-friendly response that puts the content first
|
||||
llm_friendly_result = f"""MCP Tool Result from {server_name.upper()}:
|
||||
|
||||
{actual_content}
|
||||
|
||||
---
|
||||
Tool Metadata: {json.dumps({
|
||||
"server": server_name,
|
||||
"tool": original_tool_name,
|
||||
"full_tool_name": tool_name,
|
||||
"arguments_used": arguments,
|
||||
"is_mcp_tool": True
|
||||
}, indent=2)}"""
|
||||
|
||||
# Return successful result with enhanced metadata
|
||||
return self.success_response(json.dumps(enhanced_result, indent=2))
|
||||
# Return successful result with LLM-friendly formatting
|
||||
return self.success_response(llm_friendly_result)
|
||||
|
||||
except ValueError as e:
|
||||
# Handle specific MCP errors (like invalid tool name format)
|
||||
|
|
|
@ -1456,6 +1456,36 @@ class ResponseProcessor:
|
|||
)
|
||||
return message_obj # Return the full message object
|
||||
|
||||
# Check if this is an MCP tool (function_name starts with "call_mcp_tool")
|
||||
function_name = tool_call.get("function_name", "")
|
||||
if function_name == "call_mcp_tool":
|
||||
# Special handling for MCP tools - make content prominent and LLM-friendly
|
||||
result_role = "user" if strategy == "user_message" else "assistant"
|
||||
|
||||
# Extract the actual content from the ToolResult
|
||||
if hasattr(result, 'output'):
|
||||
mcp_content = str(result.output)
|
||||
else:
|
||||
mcp_content = str(result)
|
||||
|
||||
# Create a simple, LLM-friendly message format that puts content first
|
||||
simple_message = {
|
||||
"role": result_role,
|
||||
"content": mcp_content # Direct content, no complex nesting
|
||||
}
|
||||
|
||||
logger.info(f"Adding MCP tool result with simplified format for LLM visibility")
|
||||
self.trace.event(name="adding_mcp_tool_result_simplified", level="DEFAULT", status_message="Adding MCP tool result with simplified format for LLM visibility")
|
||||
|
||||
message_obj = await self.add_message(
|
||||
thread_id=thread_id,
|
||||
type="tool",
|
||||
content=simple_message,
|
||||
is_llm_message=True,
|
||||
metadata=metadata
|
||||
)
|
||||
return message_obj
|
||||
|
||||
# For XML and other non-native tools, use the new structured format
|
||||
# Determine message role based on strategy
|
||||
result_role = "user" if strategy == "user_message" else "assistant"
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -156,7 +156,7 @@ export function SidebarLeft({
|
|||
<Store className="h-4 w-4" />
|
||||
<span className="flex items-center justify-between w-full">
|
||||
Marketplace
|
||||
<Badge variant="secondary" className="ml-2 text-xs border bg-green-200/50 dark:bg-green-900/40 text-green-700 dark:text-green-300">
|
||||
<Badge variant="secondary" className="ml-2 text-xs border bg-blue-200/50 dark:bg-blue-900/40 text-blue-700 dark:text-blue-300">
|
||||
New
|
||||
</Badge>
|
||||
</span>
|
||||
|
|
Loading…
Reference in New Issue