Tool System
Tools are the actions the AI can take during a conversation: booking appointments, verifying callers, sending SMS, etc. This doc covers how they're defined, loaded, and executed.
Definition Sources (Dual Source)
Tool definitions come from Firestore first, with a hardcoded fallback in tools.js.
Primary: Firestore config/tools/definitions/{toolName} Each doc has: name (doc ID), category, description (supports interpolation), parameters (OpenAI function-calling JSON schema).
Fallback: If Firestore has zero tool docs, hardcoded definitions in tools.js are used instead. This exists for bootstrapping — once tools are seeded to Firestore, the hardcoded definitions are never used.
Seed data: docs/prompts/tools/*.json are seed files, not the runtime source. Pushed to Firestore via scripts/seed-prompts.mjs.
Admin UI: AdminPrompts.tsx can edit tool definitions directly in Firestore.
Cache: Tool docs are cached in memory for 60 seconds (promptService.js).
Conditional Inclusion
getToolDefinitions(businessId, options) in tools.js filters tools based on business state:
| Tool | Included when |
|---|---|
Calendar tools (check_availability, book_appointment, lookup_appointment, cancel_appointment) | Google Calendar connected (integrations.googleCalendar.isConnected) |
verify_caller, send_verification_code, check_verification_code | Calendar connected (always paired with calendar tools) |
transfer_call | Escalation rules include a "transfer" action |
send_sms | Escalation rules include a "message" action |
search_knowledge | Always |
end_call, flag_caller, send_portal_link | Channel is "phone" only |
Firestore tool docs use a category field for filtering: "calendar" tools require calendar, "phone" tools check escalation rules individually.
Execution
executeTool(name, args, businessId, context) in tools.js dispatches by tool name. The context object differs by channel:
- Phone calls: includes
callSid,authToken,callerPhone,channel: "phone",interactionId,callerVerified,callerId - Portal chat: includes
businessId,channel: "portal" - Browser voice: includes
businessId
Adding a New Tool
- Handler: Add an async function in
tools.jsthat takes(args, businessId, context)and returns a result object - Dispatch: Add an
if (name === "your_tool")line inexecuteTool() - Definition: Add a Firestore doc at
config/tools/definitions/your_toolwithcategory,description,parameters— or add toscripts/seed-prompts.mjsand re-seed - Conditional inclusion: If the tool shouldn't always be available, add filter logic in
getToolDefinitions() - Hardcoded fallback (optional): Add a definition constant in
tools.jsand include it in the fallback section ofgetToolDefinitions()
Special Tool Behaviors
Calendar tools catch auth errors and automatically mark the calendar integration as needing re-authorization (needsReauth: true), returning a graceful error message to the AI.
transfer_call and end_call return { transferred: true } or { ended: true }, which signals the Twilio handler to stop sending further AI responses.
flag_caller sets flagged: true and flagReason on the caller doc, then ends the call.
verify_caller has different behavior based on the verification level configured in ai.callerVerification and whether the caller is on a phone call (automatic phone matching) vs portal (manual verification only).