Skip to main content

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

FieldDescription
object_nameUnique system name of the tool (RetrieveMenu)
nameName visible to the LLM agent (retrieve_menu)
descriptionShort description of what the tool does (without usage instructions)
parametersEmpty list — the tool doesn't require additional input
implementationReference to the Python function (restaurant_tools.retrieve_menu)

Key points

  • Uses the RESOURCE_PATH environment 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_parameters to retrieve runtime metadata such as session_id.
  • Flow configuration. Use flow_config.environment_parameters to read query parameters such as utm_source.
  • Dependencies. Declare external libraries in requirements.txt to ensure they are installed at runtime.