Skip to content

Commit 4bf6663

Browse files
authored
feat: document call.timeElapsed hook for assistant hooks (#1017)
The call.timeElapsed hook exists in the codebase but was missing from documentation. This adds full documentation including basic usage, call discipline patterns with graceful wrap-up, and system message injection for guiding LLM behavior at specific time points.
1 parent 7ba38da commit 4bf6663

1 file changed

Lines changed: 119 additions & 1 deletion

File tree

fern/assistants/assistant-hooks.mdx

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Assistant hooks let you automate actions when specific events occur during a cal
1111
Supported events include:
1212

1313
- `call.ending`: When a call is ending
14+
- `call.timeElapsed`: When a specified number of seconds has elapsed from call start
1415
- `assistant.speech.interrupted`: When the assistant's speech is interrupted
1516
- `customer.speech.interrupted`: When the customer's speech is interrupted
1617
- `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
2526
- `on`: The event that triggers the hook
2627
- `do`: The actions to perform (supports `tool` and `say`)
2728
- `filters`: (Optional) Conditions that must be met for the hook to trigger
28-
- `options`: (Optional) Configuration options for certain hook types like `customer.speech.timeout` and `assistant.transcriber.endpointedSpeechLowConfidence`
29+
- `options`: (Optional) Configuration options for certain hook types like `call.timeElapsed`, `customer.speech.timeout`, and `assistant.transcriber.endpointedSpeechLowConfidence`
2930
- `name`: (Optional) Custom name to identify the hook
3031

3132
**Action Types:**
@@ -245,6 +246,122 @@ The `customer.speech.timeout` hook supports special options:
245246
- `triggerResetMode`: Whether to reset the trigger count when user speaks (default: "never")
246247
</Note>
247248

249+
## Example: Trigger actions at a specific time
250+
251+
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.
252+
253+
Each `call.timeElapsed` hook fires **once** at the specified time. To trigger actions at multiple time points, add separate hooks with different `seconds` values.
254+
255+
### Basic usage
256+
257+
Speak a message 5 minutes into the call:
258+
259+
```json
260+
{
261+
"hooks": [
262+
{
263+
"on": "call.timeElapsed",
264+
"options": {
265+
"seconds": 300
266+
},
267+
"do": [
268+
{
269+
"type": "say",
270+
"exact": "Just a heads up, we've been on the call for 5 minutes."
271+
}
272+
]
273+
}
274+
]
275+
}
276+
```
277+
278+
### Call discipline (wrap-up and graceful close)
279+
280+
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:
281+
282+
```json
283+
{
284+
"maxDurationSeconds": 600,
285+
"hooks": [
286+
{
287+
"on": "call.timeElapsed",
288+
"options": {
289+
"seconds": 480
290+
},
291+
"do": [
292+
{
293+
"type": "say",
294+
"exact": "We're approaching our time limit. Let's start wrapping up."
295+
}
296+
]
297+
},
298+
{
299+
"on": "call.timeElapsed",
300+
"options": {
301+
"seconds": 540
302+
},
303+
"do": [
304+
{
305+
"type": "say",
306+
"exact": "We have about one minute left. Let me know if there's anything else urgent."
307+
}
308+
]
309+
},
310+
{
311+
"on": "call.timeElapsed",
312+
"options": {
313+
"seconds": 590
314+
},
315+
"do": [
316+
{
317+
"type": "say",
318+
"exact": "Thank you for your time. I need to end the call now. Goodbye."
319+
},
320+
{
321+
"type": "tool",
322+
"tool": {
323+
"type": "endCall"
324+
}
325+
}
326+
]
327+
}
328+
]
329+
}
330+
```
331+
332+
<Note>
333+
The `call.timeElapsed` hook supports one option:
334+
- `seconds`: Number of seconds from call start when the hook should trigger (1-3600)
335+
336+
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.
337+
</Note>
338+
339+
### Inject a system message to guide the LLM
340+
341+
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:
342+
343+
```json
344+
{
345+
"hooks": [
346+
{
347+
"on": "call.timeElapsed",
348+
"options": {
349+
"seconds": 480
350+
},
351+
"do": [
352+
{
353+
"type": "message.add",
354+
"message": {
355+
"role": "system",
356+
"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."
357+
}
358+
}
359+
]
360+
}
361+
]
362+
}
363+
```
364+
248365
## Example: Handle low confidence transcripts
249366

250367
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.
@@ -478,6 +595,7 @@ Assistant checks with the user at the 10 and 20s mark from when the user is sile
478595
- Route to a fallback system if the assistant fails
479596
- Handle customer or assistant interruptions gracefully
480597
- Prompt customers who become unresponsive during a call
598+
- Enforce call duration limits with graceful wrap-up behavior
481599
- Handle low confidence transcripts by asking users to repeat or speak more clearly
482600
- Log errors or events for monitoring
483601

0 commit comments

Comments
 (0)