Knowledge > Products > Voice Agent > Tools
Voice Agent Tools
The voice agent exposes tools to the LLM agents so they can take real-world actions during a call: writing to the database, sending SMS messages, and handing off between agents. Every tool is a @function_tool() decorated async method on an Agent subclass. The method receives a RunContext as its second positional argument and accesses call state via self.call_context (a dict containing church_id, church_data, caller_phone, and the Supabase client). The actual DB/SMS logic is split into private _tool_name() helpers in tools.py (imported at call time to avoid circular imports).
SDK: LiveKit Agents v1.5 (livekit.agents). Import: from livekit.agents import RunContext, function_tool.
Tools fall into three categories:
| Category | Location | Tools |
|---|---|---|
| Church tools | verticals/church/agents.py (@function_tool methods) + verticals/church/tools.py (backend logic) | submit_prayer_request, request_callback, capture_visitor_contact, register_for_event, send_giving_link, send_sms_link, send_directions_link |
| Core tool backends | core/tools.py | _send_sms_link, _send_directions_link |
| Agent handoff | verticals/church/agents.py | transfer_to_care (returns new agent instance), end_call |
| Integration tools | verticals/church/integrations/ | check_availability, book_appointment (Cal.com), supabase_church helpers (Planning Center) |
Tool Pattern
All tools are @function_tool() async methods. There is no background tool concept in LiveKit — all tools return a single value. Context is accessed via self.call_context:
@function_tool()
async def some_tool(self, context: RunContext, param: str) -> dict:
ctx = self.call_context # dict: church_data, caller_phone, supabase, etc.
result = await _some_tool_impl(ctx["supabase"], ctx["church_data"], param)
return result
The context: RunContext parameter is required by the LiveKit SDK but tool logic accesses state through self.call_context, not through context.
Church Tools (verticals/church/agents.py + verticals/church/tools.py)
Tools are @function_tool() methods on CoordinatorAgent and CareAgent. Each method delegates to a private backend function in tools.py (imported inside the method body to avoid circular imports).
1. submit_prayer_request
Available on: Care Agent, Coordinator Agent
Description: Submit a prayer request for the church prayer team.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
prayer_text | str | Yes | The prayer request text |
caller_name | str | No | Caller's name (blank for anonymous) |
is_confidential | bool | No | Whether the request is confidential (default: False) |
Writes to: voice_prayer_requests
Columns written: church_id, caller_name, caller_phone (from self.call_context), prayer_text, is_confidential, status ("new")
Backend: verticals/church/tools.py:_submit_prayer_request()
Error handling: DB write failure returns a graceful error message. Caller experience is never interrupted.
2. request_callback
Available on: Care Agent, Coordinator Agent
Description: Request a callback from the pastor or church staff.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
caller_name | str | Yes | Caller's name |
reason | str | Yes | Reason for the callback |
preferred_time | str | No | Preferred time: morning, afternoon, evening, anytime |
phone_number | str | No | Override phone number (falls back to session caller ID) |
Writes to: voice_callback_requests
Columns written: church_id, caller_name, caller_phone, reason, preferred_time, status ("pending")
Backend: verticals/church/tools.py:_request_callback()
3. capture_visitor_contact
Available on: Coordinator Agent
Description: Capture visitor contact info for the welcome team to follow up.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
visitor_name | str | Yes | Visitor's name |
reason_for_visit | str | No | Reason for visit interest |
email | str | No | Visitor's email address |
phone_number | str | No | Visitor's phone number (falls back to session caller ID) |
Writes to: voice_visitor_contacts
Columns written: church_id, visitor_name, caller_phone, reason_for_visit, email
Backend: verticals/church/tools.py:_capture_visitor_contact()
4. register_for_event
Available on: Coordinator Agent
Description: Register the caller for a church event. Writes to voice_visitor_contacts with reason_for_visit set to "Event registration: {event_name}".
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
event_name | str | Yes | Title of the event to register for |
attendee_name | str | Yes | Name of person registering |
attendee_email | str | No | Email address |
attendee_phone | str | No | Phone number (falls back to session caller ID) |
Writes to: voice_visitor_contacts (reuses visitor contacts table)
Backend: verticals/church/tools.py:_register_for_event()
5. send_giving_link
Available on: Coordinator Agent
Description: Send an SMS with the church's online giving link.
Parameters: None (uses session caller phone and church_data.giving_url)
Reads from church_data: giving_url
Writes to: Nothing (SMS only, no DB write)
Backend: core/tools.py:_send_sms_link()
6. send_sms_link
Available on: Coordinator Agent, Care Agent
Description: Send any link to the caller via SMS.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
url | str | Yes | The URL to send |
message | str | No | Brief description to include with the link |
Backend: core/tools.py:_send_sms_link()
7. send_directions_link
Available on: Coordinator Agent
Description: Send an SMS with a Google Maps link to the church address.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
destination | str | No | Override destination (defaults to church_data.address) |
Reads from church_data: address
Backend: core/tools.py:_send_directions_link()
Integration Tools (verticals/church/integrations/)
8. check_availability (Cal.com)
Location: verticals/church/integrations/cal.py
Description: Check available appointment slots for a specific date via Cal.com API v2.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
preferred_date | str | Yes | Date to check in YYYY-MM-DD format |
Reads from call_context: cal_event_type_id, cal_api_key (from church config)
Precondition: Only wired into the Coordinator's tool list when cal_enabled is true and cal_event_type_id is set.
9. book_appointment (Cal.com)
Location: verticals/church/integrations/cal.py
Description: Book an appointment at an available time slot via Cal.com API v2.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
slot_time | str | Yes | ISO 8601 start time of the chosen slot |
caller_name | str | Yes | Name of the person booking |
caller_email | str | Yes | Email for booking confirmation |
caller_phone | str | No | Phone number |
notes | str | No | Any notes for the appointment |
Post-booking: Sends a confirmation email to the caller if email provided.
10. Planning Center Helpers
Location: verticals/church/integrations/supabase_church.py
Precondition: Only wired in when pco_enabled is true and both pco_app_id and pco_secret are configured.
| Helper | Description |
|---|---|
get_service_times | Upcoming service times from PCO Services app |
get_upcoming_events | Upcoming events from PCO Calendar + Services apps |
get_staff_directory | Staff/people directory from PCO People app |
Agent Handoff Tools
11. transfer_to_care
Available on: Coordinator Agent
Type: Agent handoff — returns a new CareAgent instance (LiveKit SDK auto-handles the handoff when a tool returns an Agent object)
Description: Warm, consent-based handoff to the Care Agent. The Coordinator empathizes first, asks if the caller would like to speak with the Care Agent, and only transfers if the caller agrees.
Returns: (CareAgent instance, "Switching to the Care Agent now.")
When to use: Grief, loss, prayer needs, emotional distress, domestic concerns, sensitive personal topics.
12. end_call
Available on: Coordinator Agent, Care Agent
Description: Graceful call termination. Waits for current TTS to finish playout, then deletes the LiveKit room to end the call.
Implementation: Awaits session.current_speech.wait_for_playout(), then calls job_ctx.api.room.delete_room().
Tool Availability by Agent
| Tool | Coordinator | Care |
|---|---|---|
| submit_prayer_request | Yes | Yes |
| request_callback | Yes | Yes |
| capture_visitor_contact | Yes | -- |
| register_for_event | Yes | -- |
| send_giving_link | Yes | -- |
| send_sms_link | Yes | Yes |
| send_directions_link | Yes | -- |
| transfer_to_care | Yes | -- |
| end_call | Yes | Yes |
| check_availability | Yes* | -- |
| book_appointment | Yes* | -- |
| PCO helpers | Yes** | -- |
* Only when cal_enabled is true and cal_event_type_id is set
** Only when pco_enabled is true and both pco_app_id and pco_secret are set
Context Injection Pattern
All tools access call state via self.call_context, which is a dict set on the Agent by the session management layer (session.py) before any tools are called:
self.call_context["church_id"]-- UUID of the church being servedself.call_context["church_data"]-- Full church configuration dict (name, address, giving_url, etc.)self.call_context["caller_phone"]-- Caller's phone number from caller IDself.call_context["supabase"]-- Initialized Supabase async client
The context: RunContext parameter on each @function_tool() method is required by the LiveKit SDK signature but tool logic does not use it directly — all state comes from self.call_context.
All Supabase operations are wrapped in try/except blocks. Failures are logged but never propagate to the caller -- the voice call continues uninterrupted.