import { CodeTabs } from '../views/docs/CodeTabs';
import { Callout, NextLink, PropTable } from '../views/docs/prose';
export const ON_CALLER_SPEECH_SIG_PY = `@agent.on_caller_speech
def on_caller_speech(call: guava.Call, event: CallerSpeechEvent) -> None:
    ...`;

export const ON_CALLER_SPEECH_SIG_TS = `agent.onCallerSpeech((call: guava.Call, event: CallerSpeechEvent) => void);`;

export const ON_CALLER_SPEECH_EX_PY = `import logging
from guava.events import CallerSpeechEvent

logger = logging.getLogger(__name__)


@agent.on_caller_speech
def on_caller_speech(call: guava.Call, event: CallerSpeechEvent):
    logger.info("caller speech event: %s", event)

# Output:
# [INFO  13:30:43] caller speech event: sequence=None event_type='caller-speech'
#   utterance='Hi Grace.' utterance_id='19d92d6c68b'
# [INFO  13:30:45] caller speech event: sequence=None event_type='caller-speech'
#   utterance='Hi Grace. I am looking' utterance_id='19d92d6c68b'
# [INFO  13:30:46] caller speech event: sequence=None event_type='caller-speech'
#   utterance='Hi Grace. I am looking to make a reservation' utterance_id='19d92d6c68b'
# [INFO  13:30:49] caller speech event: sequence=None event_type='caller-speech'
#   utterance="It's for me" utterance_id='19d92d6deec'
# [INFO  13:30:50] caller speech event: sequence=None event_type='caller-speech'
#   utterance="It is for me and a couple friends." utterance_id='19d92d6deec'`;

export const ON_CALLER_SPEECH_EX_TS = `import * as guava from "@guava-ai/guava-sdk";
import { CallerSpeechEvent } from "@guava-ai/guava-sdk/events";

agent.onCallerSpeech((_call: guava.Call, event: CallerSpeechEvent) => {
  console.log("caller speech event:", JSON.stringify(event));
});`;

## on\_caller\_speech()

Register a handler to receive a callback whenever caller speech is detected. The event contains what the caller said and an `utterance_id` that distinguishes new utterances from updates to existing ones.

As transcription progresses, you may receive multiple events with the same `utterance_id`. Usually these updates append new words, but there can be slight corrections to previously transcribed words. For example:

- `"Hi."` — `utterance_id='0'`
- `"I am going to the store"` — `utterance_id='1'`
- `"I'm going to the store and"` — `utterance_id='1'` (update to the same utterance)

The `CallerSpeechEvent` is a pydantic model imported from `guava.events`:

```python
from guava.events import CallerSpeechEvent

class CallerSpeechEvent(BaseEvent):
    event_type: Literal["caller-speech"] = "caller-speech"
    utterance: str
    utterance_id: Optional[str] = None
```

### Signature

<CodeTabs
  python={{ code: ON_CALLER_SPEECH_SIG_PY, filename: "signature" }}
  typescript={{ code: ON_CALLER_SPEECH_SIG_TS, filename: "signature" }}
/>

<PropTable rows={[
  {
    name: "call",
    type: "Call",
    desc: "The active call object.",
  },
  {
    name: "event",
    type: "CallerSpeechEvent",
    desc: "Contains `utterance` (string) and `utterance_id` (optional string) fields.",
  },
]} />

**Return value:** `None`

### Example

<CodeTabs
  python={{ code: ON_CALLER_SPEECH_EX_PY, filename: "controller.py" }}
  typescript={{ code: ON_CALLER_SPEECH_EX_TS, filename: "controller.ts" }}
/>

<NextLink section="accept-reject" label="accept_call() / reject_call()" />
