diff --git a/fern/assistants/assistant-hooks.mdx b/fern/assistants/assistant-hooks.mdx index 76dfeae3e..cc31e8ce5 100644 --- a/fern/assistants/assistant-hooks.mdx +++ b/fern/assistants/assistant-hooks.mdx @@ -11,6 +11,7 @@ Assistant hooks let you automate actions when specific events occur during a cal Supported events include: - `call.ending`: When a call is ending +- `call.timeElapsed`: When a specified number of seconds has elapsed from call start - `assistant.speech.interrupted`: When the assistant's speech is interrupted - `customer.speech.interrupted`: When the customer's speech is interrupted - `customer.speech.timeout`: When the customer doesn't speak within a specified time @@ -25,7 +26,7 @@ Hooks are defined in the `hooks` array of your assistant configuration. Each hoo - `on`: The event that triggers the hook - `do`: The actions to perform (supports `tool` and `say`) - `filters`: (Optional) Conditions that must be met for the hook to trigger -- `options`: (Optional) Configuration options for certain hook types like `customer.speech.timeout` and `assistant.transcriber.endpointedSpeechLowConfidence` +- `options`: (Optional) Configuration options for certain hook types like `call.timeElapsed`, `customer.speech.timeout`, and `assistant.transcriber.endpointedSpeechLowConfidence` - `name`: (Optional) Custom name to identify the hook **Action Types:** @@ -245,6 +246,122 @@ The `customer.speech.timeout` hook supports special options: - `triggerResetMode`: Whether to reset the trigger count when user speaks (default: "never") +## Example: Trigger actions at a specific time + +The `call.timeElapsed` hook fires once when a specified number of seconds has elapsed from call start. Use it to enforce call duration limits, prompt wrap-up behavior, or trigger time-based actions. + +Each `call.timeElapsed` hook fires **once** at the specified time. To trigger actions at multiple time points, add separate hooks with different `seconds` values. + +### Basic usage + +Speak a message 5 minutes into the call: + +```json +{ + "hooks": [ + { + "on": "call.timeElapsed", + "options": { + "seconds": 300 + }, + "do": [ + { + "type": "say", + "exact": "Just a heads up, we've been on the call for 5 minutes." + } + ] + } + ] +} +``` + +### Call discipline (wrap-up and graceful close) + +Combine multiple `call.timeElapsed` hooks with `maxDurationSeconds` to enforce structured call discipline. This example begins wrapping up at 8 minutes, warns at 9 minutes, and hard-cuts at 10 minutes: + +```json +{ + "maxDurationSeconds": 600, + "hooks": [ + { + "on": "call.timeElapsed", + "options": { + "seconds": 480 + }, + "do": [ + { + "type": "say", + "exact": "We're approaching our time limit. Let's start wrapping up." + } + ] + }, + { + "on": "call.timeElapsed", + "options": { + "seconds": 540 + }, + "do": [ + { + "type": "say", + "exact": "We have about one minute left. Let me know if there's anything else urgent." + } + ] + }, + { + "on": "call.timeElapsed", + "options": { + "seconds": 590 + }, + "do": [ + { + "type": "say", + "exact": "Thank you for your time. I need to end the call now. Goodbye." + }, + { + "type": "tool", + "tool": { + "type": "endCall" + } + } + ] + } + ] +} +``` + + +The `call.timeElapsed` hook supports one option: +- `seconds`: Number of seconds from call start when the hook should trigger (1-3600) + +The hook fires once at the specified time. `maxDurationSeconds` (default: 600 seconds) acts as a hard cutoff that ends the call immediately. Use `call.timeElapsed` hooks before that limit to allow for a graceful close. + + +### Inject a system message to guide the LLM + +Instead of speaking a fixed message, you can inject a system message into the conversation to change the LLM's behavior for the remainder of the call: + +```json +{ + "hooks": [ + { + "on": "call.timeElapsed", + "options": { + "seconds": 480 + }, + "do": [ + { + "type": "message.add", + "message": { + "role": "system", + "content": "The call has been going on for 8 minutes. Begin wrapping up the conversation. Summarize any action items and ask if there is anything else before ending the call." + } + } + ] + } + ] +} +``` + ## Example: Handle low confidence transcripts When a transcriber produces a final transcript with low confidence (below the set confidence threshold or default of 0.4), it's normally discarded. The `assistant.transcriber.endpointedSpeechLowConfidence` hook allows you to handle these borderline cases by triggering actions like asking the user to repeat or logging the event. @@ -366,8 +483,6 @@ For example, if your transcriber has a `confidenceThreshold` of 0.4: - Transcripts with confidence 0.2-0.4: Hook triggers - Transcripts with confidence < 0.2: Discarded -```` - ### Multiple hooks for different ranges You can configure multiple hooks to handle different confidence ranges with different actions: @@ -395,7 +510,7 @@ You can configure multiple hooks to handle different confidence ranges with diff } ] } -```` +``` The `assistant.transcriber.endpointedSpeechLowConfidence` hook supports these options: @@ -478,6 +593,7 @@ Assistant checks with the user at the 10 and 20s mark from when the user is sile - Route to a fallback system if the assistant fails - Handle customer or assistant interruptions gracefully - Prompt customers who become unresponsive during a call +- Enforce call duration limits with graceful wrap-up behavior - Handle low confidence transcripts by asking users to repeat or speak more clearly - Log errors or events for monitoring