You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
Copy file name to clipboardExpand all lines: fern/assistants/assistant-hooks.mdx
+119-1Lines changed: 119 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,6 +11,7 @@ Assistant hooks let you automate actions when specific events occur during a cal
11
11
Supported events include:
12
12
13
13
-`call.ending`: When a call is ending
14
+
-`call.timeElapsed`: When a specified number of seconds has elapsed from call start
14
15
-`assistant.speech.interrupted`: When the assistant's speech is interrupted
15
16
-`customer.speech.interrupted`: When the customer's speech is interrupted
16
17
-`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
25
26
-`on`: The event that triggers the hook
26
27
-`do`: The actions to perform (supports `tool` and `say`)
27
28
-`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`
29
30
-`name`: (Optional) Custom name to identify the hook
30
31
31
32
**Action Types:**
@@ -245,6 +246,122 @@ The `customer.speech.timeout` hook supports special options:
245
246
-`triggerResetMode`: Whether to reset the trigger count when user speaks (default: "never")
246
247
</Note>
247
248
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
+
248
365
## Example: Handle low confidence transcripts
249
366
250
367
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
478
595
- Route to a fallback system if the assistant fails
479
596
- Handle customer or assistant interruptions gracefully
480
597
- Prompt customers who become unresponsive during a call
598
+
- Enforce call duration limits with graceful wrap-up behavior
481
599
- Handle low confidence transcripts by asking users to repeat or speak more clearly
0 commit comments