Skip to main content
In this example, we’ll build an outbound voice agent for a dental office. The agent calls patients to help them schedule appointments.

Define the Agent

guava.Agent is our starting point for building Guava agents. We’ll create one for this example.

Set up DatetimeFilter

DatetimeFilter is a built-in helper that accepts a natural-language availability query (e.g. “Tuesdays work best”) and returns a short list of matching slots from your source data. In a production system you would swap this for a call to your own scheduling backend.

Reach the right person

on_call_start fires at the beginning of every outbound call. We read the patient’s name from the call variables and invoke reach_person, which instructs the agent to confirm it is speaking with the intended recipient before proceeding. Later in this example, we’ll see how to set the patient_name variable.
Under the hood reach_person() is just a call to set_task(). You can replace reach_person() with your own Task if you need custom behavior here.

Handle the reach-person outcome

on_reach_person fires once the agent has determined whether the intended person is available. If they are, we set a task to collect an appointment time. If not, we hang up gracefully.

Register an on_search_query handler

The appointment_time field has a special attribute searchable=True set. This turns the field into a “Search Field”. Instead of providing a fixed list of choices, we will register an on_search_query handler. The agent will invoke this handler to generate possible candidates for filling the field - at each invocation the agent provides a natural-language search query for us to match against. In this example, we can simply forward that query to DatetimeFilter and return the result.
The agent may call this handler multiple times if the patient rejects the initial options or refines their availability.

Handle task completion

on_task_complete fires once every item in the checklist is resolved. This is where you’d write the confirmed slot back to your database, trigger a confirmation SMS, or perform any other post-booking actions.

Place the outbound call

Use call_phone to initiate the call. Here is where you set initial values for variables - they’ll be available inside your handlers via get_variable().
If you intend to dial multiple participants, use Campaigns instead of individual outbound calls. Campaigns offer settings for automatic retries, call windows, multiple origin phone numbers, and concurrency control.

Complete example