Tasks
A task gives the agent an objective and/or a checklist of things to do or
collect. You assign one with Guava.Call.set_task/3:
Call.set_task(call, "book_table",
objective: "Take a reservation.",
checklist: [
"Greet the caller.",
Guava.Field.new(key: "party_size", field_type: "integer", question: "How many people?"),
Guava.Field.new(key: "date_time", field_type: "calendar_slot", searchable: true),
Guava.Say.new("Let me check availability."),
"Confirm the booking details."
],
completion_criteria: "A party size and a valid time slot have been collected."
)task_id(2nd arg) is your identifier for the task. Use it to route completion withhandle_task_complete/3.:objective— a natural-language goal.:checklist— an ordered list of items (see below). At least one of:objectiveor:checklistis required.:completion_criteria— optional explicit definition of "done".
Checklist items
A checklist item can be:
| Item | Meaning |
|---|---|
| a string | a free-form to-do (Guava.Todo) for the agent |
Guava.Say.new("...") | something to say verbatim |
Guava.Field.new(...) | a piece of structured data to collect |
When a task finishes, its handle_task_complete clause fires — pattern-match the
task id you passed to set_task:
@impl true
def handle_task_complete("book_table", call, state) do
reserve(Guava.Call.get_field(call, "party_size"), Guava.Call.get_field(call, "date_time"))
{:noreply, state}
endFields
A Guava.Field tells the agent to collect one typed value. Build it with
Guava.Field.new/1, which validates the options.
Guava.Field.new(
key: "email", # retrieve later with Call.get_field(call, "email")
description: "the caller's email address",
question: "What's the best email to reach you?", # optional exact phrasing
field_type: "text",
required: true
)Field types
field_type | Collects |
|---|---|
"text" | a string (default) |
"integer" | a whole number |
"date" | a calendar date |
"datetime" | (not yet implemented — raises) |
"multiple_choice" | one of a set of options |
"calendar_slot" | an appointment time (ISO-8601 YYYY-MM-DDTHH:MM) |
Options
:key— required; the retrieval key.:description— natural-language guidance on what to collect.:question— exact phrasing to use instead of letting the agent decide.:required— iffalse, the agent may skip it when the caller declines.:choices— a small static option list (formultiple_choice/calendar_slot). Guava warns if you exceed ~10; prefer a searchable field.:searchable— settrueand register a handler withhandle_search_query/4to generate options dynamically for large or data-driven option sets.
Validation
Guava.Field.new/1 mirrors the Python SDK's validation and raises
ArgumentError for invalid combinations:
"datetime"collection is not implemented.:choicesare only valid formultiple_choice/calendar_slot.calendar_slotchoices must be ISO-8601 (YYYY-MM-DDTHH:MM).
Reading values
Call.get_field(call, "email") # nil if not collected
Call.get_field(call, "email", "n/a") # with default
Call.has_field?(call, "email")Fields are populated as the agent collects them; read them any time, most
commonly in a handle_task_complete handler.
Searchable fields
For large or dynamic option sets, mark the field searchable: true and answer
queries with matching and fallback options:
@impl true
def handle_search_query("date_time", _call, query, state) do
filter = Guava.DatetimeFilter.new(client(), Scheduling.available_slots())
{:reply, Guava.DatetimeFilter.filter!(filter, query), state}
endThe callback replies with {matched, other} — both lists of choice strings. See
RAG & LLM helpers for DatetimeFilter.
Next: Handlers.