> ## Documentation Index
> Fetch the complete documentation index at: https://docs.goguava.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Field

> Collect structured data from the caller

A `Field` is a [Task](/sdk-reference/tasks) 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.

<Tabs>
  <Tab title="Python">
    ```python signature theme={null}
    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,
    )
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript signature theme={null}
    guava.Field({
      // Identifier used to retrieve the value via get_field() after collection.
      key: string,

      // 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?: string,

      // 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?: string,

      // Controls parsing and validation. "calendar_slot" and "multiple_choice"
      // require either choices or choiceGenerator.
      fieldType:
        'text' | 'date' | 'datetime' | 'integer' | 'multiple_choice' | 'calendar_slot' |
        'digit_sequence' | 'cvv',

      // If false, the agent can skip this field if the caller is unwilling to provide it.
      required?: boolean, // default: true

      // Static list of valid options for "calendar_slot" and "multiple_choice" fields.
      // Use when the list is small. Large lists should use choiceGenerator.
      choices?: string[], // default: []

      // Takes a query string and returns (matching, fallback) lists. Use for large
      // or dynamic option sets with "calendar_slot" and "multiple_choice".
      choiceGenerator?: ChoiceGenerator,

      // 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?: boolean, // default: 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?: boolean, // default: false
    })
    ```
  </Tab>
</Tabs>

## Basic Examples

<Tabs>
  <Tab title="Python">
    ```python examples.py theme={null}
    # 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,
    )
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript examples.ts theme={null}
    // Basic text field
    const field = guava.Field({
      key: "caller_name",
      description: "Get the caller's name",
    });

    // Integer field with question
    const field = guava.Field({
      key: "caller_age",
      question: "How old are you?",
      fieldType: "integer",
    });

    // Multiple choice with static choices
    const field = guava.Field({
      key: "caller_preference",
      description: "Get the caller's preferred fruit",
      fieldType: "multiple_choice",
      // Use searchable: true instead when there's a large number of choices
      choices: ["apple", "banana", "orange"],
      required: false,
    });
    ```
  </Tab>
</Tabs>

## 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.

<Tabs>
  <Tab title="Python">
    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.

    ```python search_field.py theme={null}
    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
    ```
  </Tab>

  <Tab title="TypeScript">
    This is where search fields come in handy. Set `searchable: true` on the field, then register an `agent.onSearchQuery` 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.

    ```typescript search_field.ts theme={null}
    const field = guava.Field({
      key: "airport",
      description: "Find a suitable airport for the caller",
      fieldType: "multiple_choice",
      searchable: true,
    });

    agent.onSearchQuery("airport", async (call, query) => {
      const matchingAirports: string[] = [];
      const otherAirports: string[] = [];

      // ...
      // 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 [matchingAirports, otherAirports];
    })
    ```
  </Tab>
</Tabs>

## 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.

<Tabs>
  <Tab title="Python">
    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:
  </Tab>

  <Tab title="TypeScript">
    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:
  </Tab>
</Tabs>

* **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.

<Warning>
  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.
</Warning>

<Tabs>
  <Tab title="Python">
    ```python sensitive_field.py theme={null}
    # 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,
    )
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript sensitive_field.ts theme={null}
    // Mark any field as sensitive to redact its collected value
    const ssn = guava.Field({
      key: "ssn",
      question: "What are the last four digits of your Social Security number?",
      fieldType: "digit_sequence",
      sensitive: true,
    });
    ```
  </Tab>
</Tabs>

<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.
</Note>

### 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 mark them `sensitive` 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.

<Tabs>
  <Tab title="Python">
    ```python payment_field.py theme={null}
    # 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.
    </Note>
  </Tab>

  <Tab title="TypeScript">
    ```typescript payment_field.ts theme={null}
    // The "cvv" field type is automatically sensitive
    const cardNumber = guava.Field({
      key: "card_number",
      question: "What is your card number?",
      fieldType: "digit_sequence",
      sensitive: true,
    });

    const cvv = guava.Field({
      key: "cvv",
      question: "And the three-digit security code on the back?",
      fieldType: "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.
    </Note>
  </Tab>
</Tabs>

## Field Types Reference

<Tabs>
  <Tab title="Python">
    | Type | Example collected value | Return 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`) |
    | `integer` | `42` | `int` |
    | `multiple_choice` | `"apple"` | `str` (guaranteed to be one of `choices` or a search result) |
    | `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) |
  </Tab>

  <Tab title="TypeScript">
    | Type | Example collected value | Return type from `getField()` |
    | - | - | - |
    | `text` | `"I want to cancel my appointment"` | `string` |
    | `date` | `{ year: 2024, month: 3, day: 15 }` | object with keys `year`, `month`, `day` (all `number`) |
    | `integer` | `42` | `number` |
    | `multiple_choice` | `"apple"` | `string` (guaranteed to be one of `choices` or returned by `choiceGenerator`) |
    | `calendar_slot` | `"2022-12-31T17:30"` | ISO-8601 datetime `string` |
    | `digit_sequence` | `"1234"` | `string` (digits only; useful for account, ID, or card numbers) |
    | `cvv` | `"123"` | `string` (always sensitive; redacted from transcripts, audio, and logs) |
  </Tab>
</Tabs>

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


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.