mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-27 09:08:14 +00:00
feat: Add Merge Agent Handler tool (#3911)
Some checks failed
Some checks failed
* feat: Add Merge Agent Handler tool * Fix linting issues * Empty
This commit is contained in:
@@ -90,6 +90,9 @@ from crewai_tools.tools.json_search_tool.json_search_tool import JSONSearchTool
|
||||
from crewai_tools.tools.linkup.linkup_search_tool import LinkupSearchTool
|
||||
from crewai_tools.tools.llamaindex_tool.llamaindex_tool import LlamaIndexTool
|
||||
from crewai_tools.tools.mdx_search_tool.mdx_search_tool import MDXSearchTool
|
||||
from crewai_tools.tools.merge_agent_handler_tool.merge_agent_handler_tool import (
|
||||
MergeAgentHandlerTool,
|
||||
)
|
||||
from crewai_tools.tools.mongodb_vector_search_tool.vector_search import (
|
||||
MongoDBVectorSearchConfig,
|
||||
MongoDBVectorSearchTool,
|
||||
@@ -235,6 +238,7 @@ __all__ = [
|
||||
"LlamaIndexTool",
|
||||
"MCPServerAdapter",
|
||||
"MDXSearchTool",
|
||||
"MergeAgentHandlerTool",
|
||||
"MongoDBVectorSearchConfig",
|
||||
"MongoDBVectorSearchTool",
|
||||
"MultiOnTool",
|
||||
|
||||
@@ -79,6 +79,9 @@ from crewai_tools.tools.json_search_tool.json_search_tool import JSONSearchTool
|
||||
from crewai_tools.tools.linkup.linkup_search_tool import LinkupSearchTool
|
||||
from crewai_tools.tools.llamaindex_tool.llamaindex_tool import LlamaIndexTool
|
||||
from crewai_tools.tools.mdx_search_tool.mdx_search_tool import MDXSearchTool
|
||||
from crewai_tools.tools.merge_agent_handler_tool.merge_agent_handler_tool import (
|
||||
MergeAgentHandlerTool,
|
||||
)
|
||||
from crewai_tools.tools.mongodb_vector_search_tool import (
|
||||
MongoDBToolSchema,
|
||||
MongoDBVectorSearchConfig,
|
||||
@@ -218,6 +221,7 @@ __all__ = [
|
||||
"LinkupSearchTool",
|
||||
"LlamaIndexTool",
|
||||
"MDXSearchTool",
|
||||
"MergeAgentHandlerTool",
|
||||
"MongoDBToolSchema",
|
||||
"MongoDBVectorSearchConfig",
|
||||
"MongoDBVectorSearchTool",
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
# MergeAgentHandlerTool Documentation
|
||||
|
||||
## Description
|
||||
|
||||
This tool is a wrapper around the Merge Agent Handler platform and gives your agent access to third-party tools and integrations via the Model Context Protocol (MCP). Merge Agent Handler securely manages authentication, permissions, and monitoring of all tool interactions across platforms like Linear, Jira, Slack, GitHub, and many more.
|
||||
|
||||
## Installation
|
||||
|
||||
### Step 1: Set up a virtual environment (recommended)
|
||||
|
||||
It's recommended to use a virtual environment to avoid conflicts with other packages:
|
||||
|
||||
```shell
|
||||
# Create a virtual environment
|
||||
python3 -m venv venv
|
||||
|
||||
# Activate the virtual environment
|
||||
# On macOS/Linux:
|
||||
source venv/bin/activate
|
||||
|
||||
# On Windows:
|
||||
# venv\Scripts\activate
|
||||
```
|
||||
|
||||
### Step 2: Install CrewAI Tools
|
||||
|
||||
To incorporate this tool into your project, install CrewAI with tools support:
|
||||
|
||||
```shell
|
||||
pip install 'crewai[tools]'
|
||||
```
|
||||
|
||||
### Step 3: Set up your Agent Handler credentials
|
||||
|
||||
You'll need to set up your Agent Handler API key. You can get your API key from the [Agent Handler dashboard](https://ah.merge.dev).
|
||||
|
||||
```shell
|
||||
# Set the API key in your current terminal session
|
||||
export AGENT_HANDLER_API_KEY='your-api-key-here'
|
||||
|
||||
# Or add it to your shell profile for persistence (e.g., ~/.bashrc, ~/.zshrc)
|
||||
echo "export AGENT_HANDLER_API_KEY='your-api-key-here'" >> ~/.zshrc
|
||||
source ~/.zshrc
|
||||
```
|
||||
|
||||
**Alternative: Use a `.env` file**
|
||||
|
||||
You can also use a `.env` file in your project directory:
|
||||
|
||||
```shell
|
||||
# Create a .env file
|
||||
echo "AGENT_HANDLER_API_KEY=your-api-key-here" > .env
|
||||
|
||||
# Load it in your Python script
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv()
|
||||
```
|
||||
|
||||
**Note**: Make sure to add `.env` to your `.gitignore` to avoid committing secrets!
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before using this tool, you need to:
|
||||
|
||||
1. **Create a Tool Pack** in Agent Handler with the connectors and tools you want to use
|
||||
2. **Register a User** who will be executing the tools
|
||||
3. **Authenticate connectors** for the registered user (using Agent Handler Link)
|
||||
|
||||
You can do this via the [Agent Handler dashboard](https://ah.merge.dev) or the [Agent Handler API](https://docs.ah.merge.dev).
|
||||
|
||||
## Example Usage
|
||||
|
||||
### Example 1: Using a specific tool
|
||||
|
||||
The following example demonstrates how to initialize a specific tool and use it with a CrewAI agent:
|
||||
|
||||
```python
|
||||
from crewai_tools import MergeAgentHandlerTool
|
||||
from crewai import Agent, Task
|
||||
|
||||
# Initialize a specific tool
|
||||
create_issue_tool = MergeAgentHandlerTool.from_tool_name(
|
||||
tool_name="linear__create_issue",
|
||||
tool_pack_id="134e0111-0f67-44f6-98f0-597000290bb3",
|
||||
registered_user_id="91b2b905-e866-40c8-8be2-efe53827a0aa"
|
||||
)
|
||||
|
||||
# Define agent with the tool
|
||||
project_manager = Agent(
|
||||
role="Project Manager",
|
||||
goal="Create and manage project tasks efficiently",
|
||||
backstory=(
|
||||
"You are an experienced project manager who tracks tasks "
|
||||
"and issues across various project management tools."
|
||||
),
|
||||
verbose=True,
|
||||
tools=[create_issue_tool],
|
||||
)
|
||||
|
||||
# Execute task
|
||||
task = Task(
|
||||
description="Create a new issue in Linear titled 'Implement user authentication' with high priority",
|
||||
agent=project_manager,
|
||||
expected_output="Confirmation that the issue was created with its ID",
|
||||
)
|
||||
|
||||
task.execute()
|
||||
```
|
||||
|
||||
### Example 2: Loading all tools from a Tool Pack
|
||||
|
||||
You can load all tools from a Tool Pack at once:
|
||||
|
||||
```python
|
||||
from crewai_tools import MergeAgentHandlerTool
|
||||
from crewai import Agent, Task
|
||||
|
||||
# Load all tools from a Tool Pack
|
||||
tools = MergeAgentHandlerTool.from_tool_pack(
|
||||
tool_pack_id="134e0111-0f67-44f6-98f0-597000290bb3",
|
||||
registered_user_id="91b2b905-e866-40c8-8be2-efe53827a0aa"
|
||||
)
|
||||
|
||||
# Define agent with all tools
|
||||
support_agent = Agent(
|
||||
role="Support Engineer",
|
||||
goal="Handle customer support requests across multiple platforms",
|
||||
backstory=(
|
||||
"You are a skilled support engineer who can access customer "
|
||||
"data and create tickets across various support tools."
|
||||
),
|
||||
verbose=True,
|
||||
tools=tools,
|
||||
)
|
||||
```
|
||||
|
||||
### Example 3: Loading specific tools from a Tool Pack
|
||||
|
||||
You can also load only specific tools from a Tool Pack:
|
||||
|
||||
```python
|
||||
from crewai_tools import MergeAgentHandlerTool
|
||||
|
||||
# Load only specific tools
|
||||
tools = MergeAgentHandlerTool.from_tool_pack(
|
||||
tool_pack_id="134e0111-0f67-44f6-98f0-597000290bb3",
|
||||
registered_user_id="91b2b905-e866-40c8-8be2-efe53827a0aa",
|
||||
tool_names=["linear__create_issue", "linear__get_issues", "slack__send_message"]
|
||||
)
|
||||
```
|
||||
|
||||
### Example 4: Using with local/staging environment
|
||||
|
||||
For development, you can point to a different Agent Handler environment:
|
||||
|
||||
```python
|
||||
from crewai_tools import MergeAgentHandlerTool
|
||||
|
||||
# Use with local or staging environment
|
||||
tool = MergeAgentHandlerTool.from_tool_name(
|
||||
tool_name="linear__create_issue",
|
||||
tool_pack_id="your-tool-pack-id",
|
||||
registered_user_id="your-user-id",
|
||||
base_url="http://localhost:8000" # or your staging URL
|
||||
)
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### Class Methods
|
||||
|
||||
#### `from_tool_name()`
|
||||
|
||||
Create a single tool instance for a specific tool.
|
||||
|
||||
**Parameters:**
|
||||
- `tool_name` (str): Name of the tool (e.g., "linear__create_issue")
|
||||
- `tool_pack_id` (str): UUID of the Tool Pack
|
||||
- `registered_user_id` (str): UUID or origin_id of the registered user
|
||||
- `base_url` (str, optional): Base URL for Agent Handler API (defaults to "https://api.ah.merge.dev")
|
||||
|
||||
**Returns:** `MergeAgentHandlerTool` instance
|
||||
|
||||
#### `from_tool_pack()`
|
||||
|
||||
Create multiple tool instances from a Tool Pack.
|
||||
|
||||
**Parameters:**
|
||||
- `tool_pack_id` (str): UUID of the Tool Pack
|
||||
- `registered_user_id` (str): UUID or origin_id of the registered user
|
||||
- `tool_names` (List[str], optional): List of specific tool names to load. If None, loads all tools.
|
||||
- `base_url` (str, optional): Base URL for Agent Handler API (defaults to "https://api.ah.merge.dev")
|
||||
|
||||
**Returns:** `List[MergeAgentHandlerTool]` instances
|
||||
|
||||
## Available Connectors
|
||||
|
||||
Merge Agent Handler supports 100+ integrations including:
|
||||
|
||||
**Project Management:** Linear, Jira, Asana, Monday, ClickUp, Height, Shortcut
|
||||
|
||||
**Communication:** Slack, Microsoft Teams, Discord
|
||||
|
||||
**CRM:** Salesforce, HubSpot, Pipedrive
|
||||
|
||||
**Development:** GitHub, GitLab, Bitbucket
|
||||
|
||||
**Documentation:** Notion, Confluence, Google Docs
|
||||
|
||||
**And many more...**
|
||||
|
||||
For a complete list of available connectors and tools, visit the [Agent Handler documentation](https://docs.ah.merge.dev).
|
||||
|
||||
## Authentication
|
||||
|
||||
Agent Handler handles all authentication for you. Users authenticate to third-party services via Agent Handler Link, and the platform securely manages tokens and credentials. Your agents can then execute tools without worrying about authentication details.
|
||||
|
||||
## Security
|
||||
|
||||
All tool executions are:
|
||||
- **Logged and monitored** for audit trails
|
||||
- **Scanned for PII** to prevent sensitive data leaks
|
||||
- **Rate limited** based on your plan
|
||||
- **Permission-controlled** at the user and organization level
|
||||
|
||||
## Support
|
||||
|
||||
For questions or issues:
|
||||
- 📚 [Documentation](https://docs.ah.merge.dev)
|
||||
- 💬 [Discord Community](https://merge.dev/discord)
|
||||
- 📧 [Support Email](mailto:support@merge.dev)
|
||||
@@ -0,0 +1,8 @@
|
||||
"""Merge Agent Handler tool for CrewAI."""
|
||||
|
||||
from crewai_tools.tools.merge_agent_handler_tool.merge_agent_handler_tool import (
|
||||
MergeAgentHandlerTool,
|
||||
)
|
||||
|
||||
|
||||
__all__ = ["MergeAgentHandlerTool"]
|
||||
@@ -0,0 +1,362 @@
|
||||
"""Merge Agent Handler tools wrapper for CrewAI."""
|
||||
|
||||
import json
|
||||
import logging
|
||||
from typing import Any
|
||||
from uuid import uuid4
|
||||
|
||||
from crewai.tools import BaseTool, EnvVar
|
||||
from pydantic import BaseModel, Field, create_model
|
||||
import requests
|
||||
import typing_extensions as te
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MergeAgentHandlerToolError(Exception):
|
||||
"""Base exception for Merge Agent Handler tool errors."""
|
||||
|
||||
|
||||
|
||||
class MergeAgentHandlerTool(BaseTool):
|
||||
"""
|
||||
Wrapper for Merge Agent Handler tools.
|
||||
|
||||
This tool allows CrewAI agents to execute tools from Merge Agent Handler,
|
||||
which provides secure access to third-party integrations via the Model Context Protocol (MCP).
|
||||
|
||||
Agent Handler manages authentication, permissions, and monitoring of all tool interactions.
|
||||
"""
|
||||
|
||||
tool_pack_id: str = Field(
|
||||
..., description="UUID of the Agent Handler Tool Pack to use"
|
||||
)
|
||||
registered_user_id: str = Field(
|
||||
..., description="UUID or origin_id of the registered user"
|
||||
)
|
||||
tool_name: str = Field(..., description="Name of the specific tool to execute")
|
||||
base_url: str = Field(
|
||||
default="https://ah-api.merge.dev",
|
||||
description="Base URL for Agent Handler API",
|
||||
)
|
||||
session_id: str | None = Field(
|
||||
default=None, description="MCP session ID (generated if not provided)"
|
||||
)
|
||||
env_vars: list[EnvVar] = Field(
|
||||
default_factory=lambda: [
|
||||
EnvVar(
|
||||
name="AGENT_HANDLER_API_KEY",
|
||||
description="Production API key for Agent Handler services",
|
||||
required=True,
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
def model_post_init(self, __context: Any) -> None:
|
||||
"""Initialize session ID if not provided."""
|
||||
super().model_post_init(__context)
|
||||
if self.session_id is None:
|
||||
self.session_id = str(uuid4())
|
||||
|
||||
def _get_api_key(self) -> str:
|
||||
"""Get the API key from environment variables."""
|
||||
import os
|
||||
|
||||
api_key = os.environ.get("AGENT_HANDLER_API_KEY")
|
||||
if not api_key:
|
||||
raise MergeAgentHandlerToolError(
|
||||
"AGENT_HANDLER_API_KEY environment variable is required. "
|
||||
"Set it with: export AGENT_HANDLER_API_KEY='your-key-here'"
|
||||
)
|
||||
return api_key
|
||||
|
||||
def _make_mcp_request(
|
||||
self, method: str, params: dict[str, Any] | None = None
|
||||
) -> dict[str, Any]:
|
||||
"""Make a JSON-RPC 2.0 MCP request to Agent Handler."""
|
||||
url = f"{self.base_url}/api/v1/tool-packs/{self.tool_pack_id}/registered-users/{self.registered_user_id}/mcp"
|
||||
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f"Bearer {self._get_api_key()}",
|
||||
"Mcp-Session-Id": self.session_id or str(uuid4()),
|
||||
}
|
||||
|
||||
payload: dict[str, Any] = {
|
||||
"jsonrpc": "2.0",
|
||||
"method": method,
|
||||
"id": str(uuid4()),
|
||||
}
|
||||
|
||||
if params:
|
||||
payload["params"] = params
|
||||
|
||||
# Log the full payload for debugging
|
||||
logger.debug(f"MCP Request to {url}: {json.dumps(payload, indent=2)}")
|
||||
|
||||
try:
|
||||
response = requests.post(url, json=payload, headers=headers, timeout=60)
|
||||
response.raise_for_status()
|
||||
result = response.json()
|
||||
|
||||
# Handle JSON-RPC error responses
|
||||
if "error" in result:
|
||||
error_msg = result["error"].get("message", "Unknown error")
|
||||
error_code = result["error"].get("code", -1)
|
||||
logger.error(
|
||||
f"Agent Handler API error (code {error_code}): {error_msg}"
|
||||
)
|
||||
raise MergeAgentHandlerToolError(f"API Error: {error_msg}")
|
||||
|
||||
return result
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Failed to call Agent Handler API: {e!s}")
|
||||
raise MergeAgentHandlerToolError(
|
||||
f"Failed to communicate with Agent Handler API: {e!s}"
|
||||
) from e
|
||||
|
||||
def _run(self, **kwargs: Any) -> Any:
|
||||
"""Execute the Agent Handler tool with the given arguments."""
|
||||
try:
|
||||
# Log what we're about to send
|
||||
logger.info(f"Executing {self.tool_name} with arguments: {kwargs}")
|
||||
|
||||
# Make the tool call via MCP
|
||||
result = self._make_mcp_request(
|
||||
method="tools/call",
|
||||
params={"name": self.tool_name, "arguments": kwargs},
|
||||
)
|
||||
|
||||
# Extract the actual result from the MCP response
|
||||
if "result" in result and "content" in result["result"]:
|
||||
content = result["result"]["content"]
|
||||
if content and len(content) > 0:
|
||||
# Parse the text content (it's JSON-encoded)
|
||||
text_content = content[0].get("text", "")
|
||||
try:
|
||||
return json.loads(text_content)
|
||||
except json.JSONDecodeError:
|
||||
return text_content
|
||||
|
||||
return result
|
||||
|
||||
except MergeAgentHandlerToolError:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"Unexpected error executing tool {self.tool_name}: {e!s}")
|
||||
raise MergeAgentHandlerToolError(f"Tool execution failed: {e!s}") from e
|
||||
|
||||
@classmethod
|
||||
def from_tool_name(
|
||||
cls,
|
||||
tool_name: str,
|
||||
tool_pack_id: str,
|
||||
registered_user_id: str,
|
||||
base_url: str = "https://ah-api.merge.dev",
|
||||
**kwargs: Any,
|
||||
) -> te.Self:
|
||||
"""
|
||||
Create a MergeAgentHandlerTool from a tool name.
|
||||
|
||||
Args:
|
||||
tool_name: Name of the tool (e.g., "linear__create_issue")
|
||||
tool_pack_id: UUID of the Tool Pack
|
||||
registered_user_id: UUID of the registered user
|
||||
base_url: Base URL for Agent Handler API (defaults to production)
|
||||
**kwargs: Additional arguments to pass to the tool
|
||||
|
||||
Returns:
|
||||
MergeAgentHandlerTool instance ready to use
|
||||
|
||||
Example:
|
||||
>>> tool = MergeAgentHandlerTool.from_tool_name(
|
||||
... tool_name="linear__create_issue",
|
||||
... tool_pack_id="134e0111-0f67-44f6-98f0-597000290bb3",
|
||||
... registered_user_id="91b2b905-e866-40c8-8be2-efe53827a0aa"
|
||||
... )
|
||||
"""
|
||||
# Create an empty args schema model (proper BaseModel subclass)
|
||||
empty_args_schema = create_model(f"{tool_name.replace('__', '_').title()}Args")
|
||||
|
||||
# Initialize session and get tool schema
|
||||
instance = cls(
|
||||
name=tool_name,
|
||||
description=f"Execute {tool_name} via Agent Handler",
|
||||
tool_pack_id=tool_pack_id,
|
||||
registered_user_id=registered_user_id,
|
||||
tool_name=tool_name,
|
||||
base_url=base_url,
|
||||
args_schema=empty_args_schema, # Empty schema that properly inherits from BaseModel
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
# Try to fetch the actual tool schema from Agent Handler
|
||||
try:
|
||||
result = instance._make_mcp_request(method="tools/list")
|
||||
if "result" in result and "tools" in result["result"]:
|
||||
tools = result["result"]["tools"]
|
||||
tool_schema = next(
|
||||
(t for t in tools if t.get("name") == tool_name), None
|
||||
)
|
||||
|
||||
if tool_schema:
|
||||
instance.description = tool_schema.get(
|
||||
"description", instance.description
|
||||
)
|
||||
|
||||
# Convert parameters schema to Pydantic model
|
||||
if "parameters" in tool_schema:
|
||||
try:
|
||||
params = tool_schema["parameters"]
|
||||
if params.get("type") == "object" and "properties" in params:
|
||||
# Build field definitions for Pydantic
|
||||
fields = {}
|
||||
properties = params["properties"]
|
||||
required = params.get("required", [])
|
||||
|
||||
for field_name, field_schema in properties.items():
|
||||
field_type = Any # Default type
|
||||
field_default = ... # Required by default
|
||||
|
||||
# Map JSON schema types to Python types
|
||||
json_type = field_schema.get("type", "string")
|
||||
if json_type == "string":
|
||||
field_type = str
|
||||
elif json_type == "integer":
|
||||
field_type = int
|
||||
elif json_type == "number":
|
||||
field_type = float
|
||||
elif json_type == "boolean":
|
||||
field_type = bool
|
||||
elif json_type == "array":
|
||||
field_type = list[Any]
|
||||
elif json_type == "object":
|
||||
field_type = dict[str, Any]
|
||||
|
||||
# Make field optional if not required
|
||||
if field_name not in required:
|
||||
field_type = field_type | None
|
||||
field_default = None
|
||||
|
||||
field_description = field_schema.get("description")
|
||||
if field_description:
|
||||
fields[field_name] = (
|
||||
field_type,
|
||||
Field(
|
||||
default=field_default,
|
||||
description=field_description,
|
||||
),
|
||||
)
|
||||
else:
|
||||
fields[field_name] = (field_type, field_default)
|
||||
|
||||
# Create the Pydantic model
|
||||
if fields:
|
||||
args_schema = create_model(
|
||||
f"{tool_name.replace('__', '_').title()}Args",
|
||||
**fields,
|
||||
)
|
||||
instance.args_schema = args_schema
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
f"Failed to create args schema for {tool_name}: {e!s}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
f"Failed to fetch tool schema for {tool_name}, using defaults: {e!s}"
|
||||
)
|
||||
|
||||
return instance
|
||||
|
||||
@classmethod
|
||||
def from_tool_pack(
|
||||
cls,
|
||||
tool_pack_id: str,
|
||||
registered_user_id: str,
|
||||
tool_names: list[str] | None = None,
|
||||
base_url: str = "https://ah-api.merge.dev",
|
||||
**kwargs: Any,
|
||||
) -> list[te.Self]:
|
||||
"""
|
||||
Create multiple MergeAgentHandlerTool instances from a Tool Pack.
|
||||
|
||||
Args:
|
||||
tool_pack_id: UUID of the Tool Pack
|
||||
registered_user_id: UUID or origin_id of the registered user
|
||||
tool_names: Optional list of specific tool names to load. If None, loads all tools.
|
||||
base_url: Base URL for Agent Handler API (defaults to production)
|
||||
**kwargs: Additional arguments to pass to each tool
|
||||
|
||||
Returns:
|
||||
List of MergeAgentHandlerTool instances
|
||||
|
||||
Example:
|
||||
>>> tools = MergeAgentHandlerTool.from_tool_pack(
|
||||
... tool_pack_id="134e0111-0f67-44f6-98f0-597000290bb3",
|
||||
... registered_user_id="91b2b905-e866-40c8-8be2-efe53827a0aa",
|
||||
... tool_names=["linear__create_issue", "linear__get_issues"]
|
||||
... )
|
||||
"""
|
||||
# Create a temporary instance to fetch the tool list
|
||||
temp_instance = cls(
|
||||
name="temp",
|
||||
description="temp",
|
||||
tool_pack_id=tool_pack_id,
|
||||
registered_user_id=registered_user_id,
|
||||
tool_name="temp",
|
||||
base_url=base_url,
|
||||
args_schema=BaseModel,
|
||||
)
|
||||
|
||||
try:
|
||||
# Fetch available tools
|
||||
result = temp_instance._make_mcp_request(method="tools/list")
|
||||
|
||||
if "result" not in result or "tools" not in result["result"]:
|
||||
raise MergeAgentHandlerToolError(
|
||||
"Failed to fetch tools from Agent Handler Tool Pack"
|
||||
)
|
||||
|
||||
available_tools = result["result"]["tools"]
|
||||
|
||||
# Filter tools if specific names were requested
|
||||
if tool_names:
|
||||
available_tools = [
|
||||
t for t in available_tools if t.get("name") in tool_names
|
||||
]
|
||||
|
||||
# Check if all requested tools were found
|
||||
found_names = {t.get("name") for t in available_tools}
|
||||
missing_names = set(tool_names) - found_names
|
||||
if missing_names:
|
||||
logger.warning(
|
||||
f"The following tools were not found in the Tool Pack: {missing_names}"
|
||||
)
|
||||
|
||||
# Create tool instances
|
||||
tools = []
|
||||
for tool_schema in available_tools:
|
||||
tool_name = tool_schema.get("name")
|
||||
if not tool_name:
|
||||
continue
|
||||
|
||||
tool = cls.from_tool_name(
|
||||
tool_name=tool_name,
|
||||
tool_pack_id=tool_pack_id,
|
||||
registered_user_id=registered_user_id,
|
||||
base_url=base_url,
|
||||
**kwargs,
|
||||
)
|
||||
tools.append(tool)
|
||||
|
||||
return tools
|
||||
|
||||
except MergeAgentHandlerToolError:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to create tools from Tool Pack: {e!s}")
|
||||
raise MergeAgentHandlerToolError(f"Failed to load Tool Pack: {e!s}") from e
|
||||
Reference in New Issue
Block a user