import { CodeTabs } from '../views/docs/CodeTabs';
import { Callout, NextLink, PropTable } from '../views/docs/prose';

export const ON_ACTION_REQUEST_SIG_PY = `@agent.on_action_request
def on_action_request(call: guava.Call, request: str) -> SuggestedAction | None:
    # request: natural-language summary of what the caller wants
    # return: SuggestedAction(key=...) or None

@agent.on_action("action_key")
def handler(call: guava.Call) -> None:
    # Runs when Guava executes the action with the matching key
    ...`;

export const ON_ACTION_REQUEST_SIG_TS = `agent.onActionRequest(
  async (call: guava.Call, request: string) => { key: string } | null
);

agent.onAction("action_key", async (call: guava.Call) => {
  // Runs when Guava executes the action with the matching key
});`;

export const ON_ACTION_REQUEST_EX_PY = `from guava import Agent, SuggestedAction
from guava.helpers.openai import IntentRecognizer

agent = Agent(name="Nova", organization="Thai Palace", purpose="...")

ACTIONS = {
    "reservation": "for handling reservations",
    "waitlist": "additions to the waitlist",
    "delivery": "for takeout orders",
    "hiring": "for people looking for jobs",
    "order_for_pickup": "",
}

intent_recognizer = IntentRecognizer(ACTIONS)


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


@agent.on_action("reservation")
def reservation(call: guava.Call):
    call.set_task(...)


@agent.on_action("waitlist")
def waitlist(call: guava.Call):
    call.set_task(...)`;

export const ON_ACTION_REQUEST_EX_TS = `import * as guava from "@guava-ai/guava-sdk";
import { IntentRecognizer } from "@guava-ai/guava-sdk/helpers/openai";

const agent = new guava.Agent({
  name: "Nova",
  organization: "Thai Palace",
  purpose: "...",
});

const ACTIONS = {
  reservation: "for handling reservations",
  waitlist: "additions to the waitlist",
  delivery: "for takeout orders",
  hiring: "for people looking for jobs",
  order_for_pickup: "",
};

const intentRecognizer = new IntentRecognizer(Object.keys(ACTIONS));

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

agent.onAction("reservation", async (call: guava.Call) => {
  call.setTask({ objective: "Handle reservation" });
});

agent.onAction("waitlist", async (call: guava.Call) => {
  call.setTask({ objective: "Handle waitlist addition" });
});`;


## on\_action\_request() / on\_action()

These handlers are used when the caller expresses an intent or action (e.g. "I'd like to pay my bill"). The flow is as follows.

1. **The caller makes a request** — e.g. "I'd like to check the status of my order."
2. **Guava invokes `on_action_request` with a summary of the request** — e.g. "the customer would like to check the status of their order."
3. **You classify the request and return a `SuggestedAction`** — e.g. `SuggestedAction(key="order_status")`. You can use our built-in `IntentRecognizer` helper, or build your own intent classifier. Return `None` if no action matches the request.
4. **Guava decides whether to execute the action** — it may proceed immediately or ask the caller to confirm.
5. **Guava executes the action** — The `on_action` handler registered under the matching suggested action key is called.

<Callout>
  <span className="text-primary font-semibold">Design note:</span> The two-step pattern (request → execute) gives the agent a chance to confirm intent with the caller before committing to an action.
</Callout>

<CodeTabs
  python={{ code: ON_ACTION_REQUEST_SIG_PY, filename: "signature" }}
  typescript={{ code: ON_ACTION_REQUEST_SIG_TS, filename: "signature" }}
/>

### Interaction with on\_question

A caller utterance can be both a question and an action (e.g. *"Could you help me pay my bill?"*). In this case Guava will invoke both callbacks in parallel and synthesize an appropriate response based on the results.

For example, if `on_question` returns *"Yes, we handle bill payment"* and `on_action_request` returns `SuggestedAction(key="bill_pay")`,
Guava may immediately chain into executing the action, or it may respond *"Yes — would you like to get started?"* to confirm the action with the caller.

### Example

<CodeTabs
  python={{ code: ON_ACTION_REQUEST_EX_PY, filename: "restaurant_controller.py" }}
  typescript={{ code: ON_ACTION_REQUEST_EX_TS, filename: "restaurant_controller.ts" }}
/>

<NextLink section="on-question" label="on_question()" />
