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

# Intent Helpers

> Classify caller requests into your predefined intents

Guava provides an intent classification helper for routing caller requests. `IntentRecognizer` classifies caller utterances into your predefined intents and returns matching actions for the dialog engine to handle.

## IntentRecognizer

<Tabs>
  <Tab title="Python">
    `IntentRecognizer` classifies a free-text caller utterance against your predefined intent labels and returns all plausible matches as `SuggestedAction` objects. Use it inside [`on_action_request()`](/sdk-reference/on-action-request-execute) to map caller language to routing decisions — return the full list and let the dialog engine handle disambiguation automatically.

    ```python signature theme={null}
    from guava.helpers.llm import IntentRecognizer

    IntentRecognizer(intent_choices: list[str] | dict[str, str])
    recognizer.classify(intent: str) -> list[SuggestedAction] | None
    ```

    | Parameter | Type | Required | Description |
    | - | - | - | - |
    | `intent_choices` | `list[str] \| dict[str, str]` | Yes | The set of intents to classify into. Pass a list of choice strings, or a dict mapping choice strings to plain-English descriptions to help IntentRecognizer disambiguate meaning. When a dict is passed, descriptions are also attached to the returned `SuggestedAction` objects so the dialog engine can use them when disambiguating multiple matches with the caller. |

    **`classify(intent: str) -> list[SuggestedAction] | None`** — Returns all choices from `intent_choices` that plausibly match `intent`, ordered by likelihood. Returns `None` if no choice matches. It is recommended to return the full list from `on_action_request` to let the dialog engine handle disambiguation automatically.

    ```python support_agent.py theme={null}
    import guava
    from guava import Agent, SuggestedAction
    from guava.helpers.llm import IntentRecognizer

    agent = Agent(
        name="Support",
        organization="Acme Corp",
        purpose="Help the caller with their support request.",
    )

    intent_recognizer = IntentRecognizer({
        'check order status': 'Caller wants to look up the status of an existing order.',
        'bill pay': 'Caller wants to make a payment or ask about their bill.',
        'anything else': 'Caller has a request that does not fit the above categories.',
    })

    @agent.on_action_request
    def on_action_request(call: guava.Call, request: str) -> SuggestedAction | list[SuggestedAction] | None:
        return intent_recognizer.classify(request)

    @agent.on_action("check order status")
    def check_order_status(call: guava.Call):
        call.transfer("+15555555555", "Transfer the caller to the order status team.")

    @agent.on_action("bill pay")
    def bill_pay(call: guava.Call):
        call.transfer("+15555555555", "Transfer the caller to billing.")

    @agent.on_action("anything else")
    def anything_else(call: guava.Call):
        call.transfer("+15555555555", "Connect the caller with a live agent.")
    ```
  </Tab>

  <Tab title="TypeScript">
    `IntentRecognizer` classifies a free-text caller utterance against your predefined intent labels and returns all plausible matches as suggested actions. Use it inside [`onActionRequest()`](/sdk-reference/on-action-request-execute) to map caller language to routing decisions — return the full list and let the dialog engine handle disambiguation automatically.

    ```typescript signature theme={null}
    import { IntentRecognizer } from "@guava-ai/guava-sdk/helpers";

    new IntentRecognizer(intentChoices: string[] | Record<string, string>)
    await recognizer.classify(intent: string): Promise<SuggestedAction[] | null>
    ```

    | Parameter | Type | Required | Description |
    | - | - | - | - |
    | `intentChoices` | `string[] \| Record<string, string>` | Yes | The set of intents to classify into. Pass an array of choice strings, or an object mapping choice strings to plain-English descriptions to help IntentRecognizer disambiguate meaning. When an object is passed, descriptions are also attached to the returned suggested actions so the dialog engine can use them when disambiguating multiple matches with the caller. |

    **`classify(intent: string): Promise<SuggestedAction[] | null>`** — Returns all choices from `intentChoices` that plausibly match `intent`, ordered by likelihood. Returns `null` if no choice matches. It is recommended to return the full list from `onActionRequest` to let the dialog engine handle disambiguation automatically.

    ```typescript support_agent.ts theme={null}
    import * as guava from "@guava-ai/guava-sdk";
    import { IntentRecognizer } from "@guava-ai/guava-sdk/helpers";

    const agent = new guava.Agent({
      name: "Support",
      organization: "Acme Corp",
      purpose: "Help the caller with their support request.",
    });

    const intentRecognizer = new IntentRecognizer({
      "check order status": "Caller wants to look up the status of an existing order.",
      "bill pay": "Caller wants to make a payment or ask about their bill.",
      "anything else": "Caller has a request that does not fit the above categories.",
    });

    agent.onActionRequest(async (_call: guava.Call, request: string) => {
      return intentRecognizer.classify(request);
    });

    agent.onAction("check order status", async (call: guava.Call) => {
      call.transfer("+15555555555", "Transfer the caller to the order status team.");
    });

    agent.onAction("bill pay", async (call: guava.Call) => {
      call.transfer("+15555555555", "Transfer the caller to billing.");
    });

    agent.onAction("anything else", async (call: guava.Call) => {
      call.transfer("+15555555555", "Connect the caller with a live agent.");
    })
    ```
  </Tab>
</Tabs>

## IntentRecognizer (openai — deprecated)

<Tabs>
  <Tab title="Python">
    <Warning>
      **Deprecated:** `IntentRecognizer` from `guava.helpers.openai` is deprecated. Use the new `IntentRecognizer` from `guava.helpers.llm` above instead.
    </Warning>

    `IntentRecognizer` classifies a free-text caller utterance into one of your predefined intent labels. Use it inside `on_action_request()` to map vague caller language to clean routing decisions.

    ```python signature theme={null}
    from guava.helpers.openai import IntentRecognizer

    IntentRecognizer(intent_choices: list[str] | dict[str, str], client: openai.OpenAI | None = None)
    recognizer.classify(intent: str) -> str | None
    ```

    | Parameter | Type | Required | Description |
    | - | - | - | - |
    | `intent_choices` | `list[str] \| dict[str, str]` | Yes | The set of intents to classify into. Pass a list of choice strings, or a dict mapping choice strings to plain-English descriptions (descriptions improve accuracy on similar-sounding choices). |
    | `client` | `openai.OpenAI` | No | An OpenAI client to use. If omitted, a client is created automatically. |

    **`classify(intent: str) -> str | None`** — Returns the single choice string from `intent_choices` that best matches `intent`, or `None` if the model cannot match any choice. When `intent_choices` is a `dict`, the keys are the valid return values; values are used only as descriptions to guide the model.

    ```python support_agent.py theme={null}
    import guava
    from guava import Agent, SuggestedAction
    from guava.helpers.openai import IntentRecognizer

    agent = Agent(
        name="Support",
        organization="Acme Corp",
        purpose="Help the caller with their support request.",
    )

    intent_recognizer = IntentRecognizer(
        ['check order status', 'bill pay', 'anything else']
    )

    @agent.on_action_request
    def on_action_request(call: guava.Call, request: str) -> SuggestedAction:
        return SuggestedAction(key=intent_recognizer.classify(request))

    @agent.on_action("check order status")
    def check_order_status(call: guava.Call):
        call.transfer("+15555555555", "Transfer the caller to the order status team.")

    @agent.on_action("bill pay")
    def bill_pay(call: guava.Call):
        call.transfer("+15555555555", "Transfer the caller to billing.")

    @agent.on_action("anything else")
    def anything_else(call: guava.Call):
        call.transfer("+15555555555", "Connect the caller with a live agent.")
    ```
  </Tab>

  <Tab title="TypeScript">
    <Warning>
      **Deprecated:** `IntentRecognizer` from `@guava-ai/guava-sdk/helpers/openai` is deprecated. Use the new `IntentRecognizer` from `@guava-ai/guava-sdk/helpers` above instead.
    </Warning>

    `IntentRecognizer` classifies a free-text caller utterance into one of your predefined intent labels. Use it inside `onActionRequest()` to map vague caller language to clean routing decisions.

    ```typescript signature theme={null}
    import { IntentRecognizer } from "@guava-ai/guava-sdk/helpers/openai";

    const recognizer = new IntentRecognizer(choices, logger);
    ```

    ```typescript support_agent.ts theme={null}
    import * as guava from "@guava-ai/guava-sdk";
    import { IntentRecognizer } from "@guava-ai/guava-sdk/helpers/openai";
    import { getDefaultLogger } from "@guava-ai/guava-sdk";

    const agent = new guava.Agent({
      name: "Support",
      organization: "Acme Corp",
      purpose: "Help the caller with their support request.",
    });

    const choices = ["check_order_status", "bill_pay", "other"] as const;
    const recognizer = new IntentRecognizer(choices, getDefaultLogger());

    agent.onActionRequest(async (_call: guava.Call, request: string) => {
      const key = await recognizer.classify(request);
      return { key };
    });

    agent.onAction("check_order_status", async (call: guava.Call) => {
      call.transfer("+15555555555", "Transfer the caller to the order status team.");
    });

    agent.onAction("bill_pay", async (call: guava.Call) => {
      call.transfer("+15555555555", "Transfer the caller to billing.");
    });

    agent.onAction("other", async (call: guava.Call) => {
      call.transfer("+15555555555", "Connect the caller with a live agent.");
    })
    ```
  </Tab>
</Tabs>

## IntentClarifier (deprecated)

<Tabs>
  <Tab title="Python">
    <Warning>
      **Deprecated:** `IntentClarifier` from `guava.helpers.openai` is deprecated. Use the new `IntentRecognizer` from `guava.helpers.llm` above instead — it returns all plausible matches by default, replacing the need for a separate clarifier.
    </Warning>

    `IntentClarifier` analyzes a caller's intent and returns the subset of choices that could plausibly match, ordered by likelihood. Use this when an intent may be ambiguous and you need to surface options for the caller to confirm.

    ```python signature theme={null}
    from guava.helpers.openai import IntentClarifier

    IntentClarifier(intent_choices: list[str] | dict[str, str], client: openai.OpenAI | None = None)
    clarifier.propose_choices(intent: str) -> list[str]
    ```

    | Parameter | Type | Required | Description |
    | - | - | - | - |
    | `intent_choices` | `list[str] \| dict[str, str]` | Yes | The set of intents to match against. Same format as `IntentRecognizer`. |
    | `client` | `openai.OpenAI` | No | An OpenAI client to use. If omitted, a client is created automatically. |

    **`propose_choices(intent: str) -> list[str]`** — Returns a list of choices that could match `intent`, ordered by likelihood:

    * One element if the intent clearly maps to a single choice.
    * Multiple elements if the intent is ambiguous.
    * Empty list if the intent matches none of the provided choices.

    An empty list means the caller's intent is out-of-scope — not that an error occurred. When `intent_choices` is a `dict`, only the keys appear in the returned list.

    ```python scheduler_agent.py theme={null}
    import guava
    from guava import Agent, SuggestedAction
    from guava.helpers.openai import IntentClarifier

    agent = Agent(
        name="Scheduler",
        organization="Acme Corp",
        purpose="Help callers manage their appointments.",
    )

    intent_clarifier = IntentClarifier(
        ['reschedule appointment', 'cancel appointment', 'check appointment time']
    )

    @agent.on_action_request
    def on_action_request(call: guava.Call, request: str) -> SuggestedAction:
        matches = intent_clarifier.propose_choices(request)
        if len(matches) == 1:
            # Unambiguous — proceed directly
            return SuggestedAction(key=matches[0])
        elif len(matches) > 1:
            # Ambiguous — route to the most likely match; agent will confirm with caller
            return SuggestedAction(key=matches[0], description=f"Caller may have meant one of: {matches}")
        # len == 0: no match, return nothing so the agent keeps listening
    ```
  </Tab>

  <Tab title="TypeScript">
    `IntentClarifier` is not available in TypeScript. Use the new [`IntentRecognizer`](#intentrecognizer), which returns all plausible matches by default.
  </Tab>
</Tabs>


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