Custom Tool Examples
Retrieve Menu Tool
This example shows a tool that extracts data from an external text file located in the AI agent's resources.
YAML Definition (retrieve_menu.yaml)
kind: Plugin
name: Retrieve Menu
description: Tool that shows restaurant menu to customers
dependencies:
- submodules/menu_impl.py
tools:
- kind: Tool
object_name: RetrieveMenu
name: retrieve_menu
description: Retrieves positions in the restaurant's menu available for ordering in advance
parameters: []
implementation: restaurant_tools.retrieve_menu
Python Implementation (menu_impl.py)
import os
from pathlib import Path
async def retrieve_menu(**kwargs) -> str:
available_menu = (Path(os.environ["RESOURCE_PATH"]) / "restaurant_menu.txt").read_text()
if available_menu:
return f"Positions available for ordering in advance: {available_menu}"
return "No positions are available for ordering in advance right now"
Field Explanation
| Field | Description |
|---|---|
object_name | Unique system name of the tool (RetrieveMenu) |
name | Name visible to the LLM agent (retrieve_menu) |
description | Short description of what the tool does (without usage instructions) |
parameters | Empty list — the tool doesn't require additional input |
implementation | Reference to the Python function (restaurant_tools.retrieve_menu) |
Key points
- Uses the
RESOURCE_PATHenvironment variable to locate AI agent resources - Loads content from
restaurant_menu.txt - Returns menu items or fallback message
Example contents of restaurant_menu.txt
Salads: Greek salad, Caesar salad.
Greek starters: hummus, tzatziki, olives, fried halloumi.
Tartare: tuna tartare, shrimp tartare.
Ceviche: salmon ceviche, tuna ceviche.
Drinks: still and sparkling water.
Soft drinks: Coca-Cola, Coca-Cola Light, Coca-Cola Zero, apple juice, orange juice, tomato juice.
Overall Tool Flow for RetrieveMenu
LLM agent → Chooses the retrieve_menu tool
↓
retrieve_menu function reads restaurant_menu.txt
↓
Generates a response with available menu items
↓
Sends the result to the user
Customer Support Tool
A plugin that exposes customer support tools to the agent, including ticket creation, feedback surveys, and human handover.
Plugin Configuration (support_plugin.yaml)
kind: Plugin
name: Customer Support Plugin
description: Tools for customer service operations
dependencies:
- support_impl.py
tools:
- kind: Tool
object_name: CreateJiraTicket
name: CreateJiraTicket
description: Creates a Jira ticket for customer issues
parameters:
- name: issue_topic
type: string
description: Brief summary of the issue (max 100 characters)
- name: issue_description
type: string
description: Detailed description provided by the customer
implementation: support_impl.create_jira_ticket
- kind: Tool
object_name: SendFeedbackSurvey
name: SendFeedbackSurvey
description: Sends a satisfaction survey to the customer
parameters: []
implementation: support_impl.send_survey
- kind: Tool
object_name: TransferToOperator
name: TransferToOperator
description: Transfers the conversation to a human operator
parameters:
- name: reason
type: string
description: Reason for transfer
implementation: support_impl.transfer_chat
Implementation (support_impl.py)
import aiohttp
from loguru import logger
async def create_jira_ticket(issue_topic: str, issue_description: str,
flow_config, **kwargs):
# Get customer information from session
# Accessing flow_config.environment_parameters to get user data
env_params = flow_config.environment_parameters
customer_name = env_params.get("customer_name", "Unknown")
customer_email = env_params.get("customer_email", "")
# Create ticket (simplified example)
ticket_data = {
"summary": issue_topic,
"description": f"Customer: {customer_name}\n\n{issue_description}",
"email": customer_email
}
# In real implementation, call Jira API here
logger.info(f"Creating ticket: {issue_topic}")
return f"Support ticket created successfully. A team member will contact you within 24 hours."
async def send_survey(**kwargs):
# Send survey logic here
return "Satisfaction survey sent to your email. Thank you for your feedback!"
async def transfer_chat(reason: str, stack, **kwargs):
# Add transfer message to conversation
transfer_msg = f"Transferring to human operator. Reason: {reason}"
# In real implementation, trigger operator handover
return "Connecting you with a human operator. Please wait..."
Using in Workflow
This example shows how to define the support agent’s role and configure tool usage rules in the agent workflow.
For detailed instructions on adding tools to a workflow, see Using Tools in Workflow
- process_name: SupportProcess
name: MainSupport
kind: StateConfig
description: |
## Your role
Help customers with their issues and create tickets when needed.
## When to use tools
- Use CreateJiraTicket after gathering all issue details
- Use SendFeedbackSurvey at the end of successful interactions
- Use TransferToOperator if customer explicitly asks for human help
available_tools:
SingleStatefulOutboundAgent:
- SendChatMessage
- CreateJiraTicket
- SendFeedbackSurvey
- TransferToOperator
Simple CRM Tool
This example demonstrates a more advanced tool that connects to an external API, manages external dependencies, and accesses runtime system parameters such as session IDs and UTM tags.
File Structure
my_crm_plugin/
├── simple_crm.yaml # Plugin definition
├── requirements.txt # External Python dependencies
└── submodules/
└── simple_crm.py # Implementation logic
YAML Definition (simple_crm.yaml)
kind: Plugin
name: Simple CRM
description: Simple CRM demo tool
dependencies:
- submodules/simple_crm.py
- requirements.txt
tools:
- kind: Tool
object_name: CRMPostLead
name: post_lead
description: Send lead info to the CRM
parameters:
- name: client_name
type: string
description: Client name
optional: false
- name: client_email
type: string
description: Client email
optional: false
implementation: simple_crm.post_lead
Dependencies (requirements.txt)
Since this tool uses the pytz library for timezone management, it must be listed here.
pytz==2024.1
Python Implementation (submodules/simple_crm.py)
import os
import aiohttp
import pytz
from loguru import logger
# Environment variables are set in the agent configuration
ACME_API_URL = os.environ.get("YOUR_API_URL", "")
CONVERSATION_SERVER = os.environ.get(
"PORTAL_BASE_URL", "https://portal-url.com"
)
async def post_lead(flow_config, system_parameters, **kwargs) -> str | None:
logger.debug("post_lead started...")
# 1. Accessing System Parameters
# system_parameters contains session_info, which is useful for logging or linking data
session_info = system_parameters.get("session_info", {})
session_id = session_info.get("session_id")
logger.debug(f"session_link: {CONVERSATION_SERVER}/sessions/{session_id}")
# 2. Async HTTP Request
# It is highly recommended to use aiohttp instead of requests in async functions
async with aiohttp.ClientSession() as session:
# In a real scenario, you would likely use session.post() with data
async with session.get(f"{ACME_API_URL}") as resp:
logger.debug(f"CRM API Status: {resp.status}")
# logger.debug(await resp.json())
# 3. Accessing Tool Arguments
# These are passed by the agent based on the user's input
client_name = kwargs.get("client_name")
client_email = kwargs.get("client_email")
logger.debug(f"Client data: {client_name}, {client_email}")
# 4. Using External Dependencies
# pytz is imported from the environment defined in requirements.txt
eet_tz = pytz.timezone("EET")
logger.info(f"Processing in timezone: {eet_tz}")
# 5. Accessing Flow Configuration
# You can access URL GET parameters (e.g., ?utm_source=google) via flow_config
utm_source = flow_config.environment_parameters.get("utm_source", "")
if utm_source:
logger.info(f"Lead source (UTM): {utm_source}")
# Response returned to the agent
return "Contact has been sent to the CRM"
Key points
- Async network calls. Use aiohttp for non-blocking HTTP requests. Avoid synchronous libraries such as requests inside async functions.
- System parameters. Access
system_parametersto retrieve runtime metadata such assession_id. - Flow configuration. Use
flow_config.environment_parametersto read query parameters such asutm_source. - Dependencies. Declare external libraries in requirements.txt to ensure they are installed at runtime.