Field

A Field is a Task checklist item instructing the Guava agent to collect structured data from the caller. The agent elicits the value through natural conversation, validates it against the specified type, and marks the checklist item complete when satisfied.

signature
guava.Field(
    # Identifier used to retrieve the value via get_field() after collection.
    key: str,

    # Natural-language instruction to the LLM about how to collect this value.
    # Use when you do not particularly care how the agent phrases its question.
    description: str = '',

    # Encourages the agent to ask for the field in a particular way. Use instead
    # of description when you want more control over the phrasing.
    question: str = '',

    # Controls parsing and validation. "calendar_slot" and "multiple_choice"
    # require either choices or searchable=True.
    field_type: Literal[
        'text', 'date', 'datetime', 'integer', 'multiple_choice', 'calendar_slot',
        'digit_sequence', 'cvv'
    ] = 'text',

    # If False, the agent can skip this field if the caller is unwilling to provide it.
    required: bool = True,

    # Static list of valid options for "calendar_slot" and "multiple_choice" fields.
    # Use when the list is small. Large lists should use searchable=True.
    choices: list[str] = [],

    # When True, enables dynamic search for "multiple_choice" and "calendar_slot"
    # fields. The agent searches for options matching the caller's query at runtime.
    searchable: bool = False,

    # When True, the collected value is treated as sensitive: it is redacted from
    # stored transcripts and call recordings. See "Sensitive Fields" below. The "cvv"
    # field type is always sensitive and additionally suppresses logs and diagnostic data.
    sensitive: bool = False,
)

Basic Examples

examples.py
# Basic text field
field = guava.Field(
    key="caller_name",
    description="Get the caller's name",
)

# Integer field with question
field = guava.Field(
    key="caller_age",
    question="How old are you?",
    field_type="integer",
)

# Multiple choice with static choices
field = guava.Field(
    key="caller_preference",
    description="Get the caller's preferred fruit",
    field_type="multiple_choice",
    # Use searchable=True instead when there's a large number of choices
    choices=["apple", "banana", "orange"],
    required=False,
)

Search Fields

Some fields can have a very large set of valid options. For example, a destination_airport field may include thousands of airports worldwide. In other cases, options must be generated dynamically, such as an appointment_time field populated from a booking system.

This is where search fields come in handy. Set searchable=True on the field, then register an @agent.on_search_query handler. When the agent needs options, it calls your handler with a natural-language query string. Return two lists: a primary list of matches, and a fallback list shown only when no primary matches are found.

search_field.py
field = guava.Field(
    key="airport",
    description="Find a suitable airport for the caller",
    field_type="multiple_choice",
    searchable=True,
)

@agent.on_search_query("airport")
def search_airports(call: guava.Call, query: str):
    matching_airports: list[str] = []
    other_airports: list[str] = []

    ...
    # Do some work to generate a few matching airport
    # options based on the caller's query.
    # 'query' will be human natural language
    # (e.g. "I need to fly out of an airport in
    # southern california")
    ...

    # The second list only becomes relevant if there
    # are no matches to the caller's query. It is used
    # to at least present something to the caller in
    # case there are no perfect matches.
    return matching_airports, other_airports

Sensitive Fields

Some fields collect information that should never persist in plain form — Social Security numbers, dates of birth, health details, account credentials, or payment data. Mark any field as sensitive by setting sensitive=True. When a sensitive field is present on a call, Guava applies the following protections to the collected value:

  • Transcript redaction. The value is removed from stored transcripts, matching both spoken and written forms (e.g. "one two three" as well as "123").
  • Audio redaction. The corresponding region of the call recording is silenced across all channels.

sensitive is a general-purpose flag — use it for any field whose value your organization considers sensitive.

Important: The sensitive flag redacts the value from stored transcripts and recordings, but it does not guarantee the value is kept out of diagnostic and debug data. For payment card data, use the cvv field type (see below), which additionally suppresses logging and diagnostic capture for the entire session.

sensitive_field.py
# Mark any field as sensitive to redact its collected value
ssn = guava.Field(
    key="ssn",
    question="What are the last four digits of your Social Security number?",
    field_type="digit_sequence",
    sensitive=True,
)

Note: Redaction is applied on a best-effort basis to spoken conversation. Mark every field that may capture sensitive information, and choose the most specific field_type available (for example, digit_sequence for account or ID numbers) to give the agent the clearest signal.

Payment Data (PCI)

For payment card collection, use the dedicated cvv field type. Fields of this type are always treated as sensitive — you do not need to set sensitive=True explicitly — and receive the transcript and audio redaction described above.

Unlike a field that is merely marked sensitive, the cvv field type provides two additional protections that apply to the entire session:

  • Log exclusion. The value is kept out of application logs; only the field name is logged, never the collected value.
  • Diagnostic data suppression. All diagnostic and debug data for the session is suppressed and not retained, and any diagnostic data already written is discarded.

These stronger, session-wide protections are specific to the cvv field type.

payment_field.py
# The "cvv" field type is automatically sensitive
card_number = guava.Field(
    key="card_number",
    question="What is your card number?",
    field_type="digit_sequence",
    sensitive=True,
)

cvv = guava.Field(
    key="cvv",
    question="And the three-digit security code on the back?",
    field_type="cvv",
    # sensitive=True is implied by the "cvv" field type
)

Note: Card numbers are not automatically sensitive. When collecting a full card number, use a digit_sequence field with sensitive=True, as shown above.

Field Types Reference

TypeExample collected valueReturn type from get_field()
text"I want to cancel my appointment"str
date{"year": 2024, "month": 3, "day": 15}dict with keys year, month, day (all int)
integer42int
multiple_choice"apple"str (guaranteed to be one of choices or returned by choice_generator)
calendar_slot"2022-12-31T17:30"ISO-8601 datetime str
digit_sequence"1234"str (digits only; useful for account, ID, or card numbers)
cvv"123"str (always sensitive; redacted from transcripts, audio, and logs)

Note: The choices list for calendar_slot fields must be ISO-8601 datetimes (e.g. "2022-12-31T17:30").

Questions? hi@goguava.ai