Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions specs/signalwire-rest/calling-api/calls/models/requests.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,19 @@ model CallHoldRequest {
command: "calling.ai_hold";

@doc(paramsDescription)
params: {};
params: {
@doc("The duration to hold the caller in seconds.")
@example(300)
@maxValue(300)
timeout?: int32 = 300;

@doc("""
A system message added to the AI conversation before placing the caller on hold.
The AI will speak this message to the caller before hold music begins.
""")
@example("Please hold while I transfer you to a specialist.")
prompt?: string = "Tell the user you are putting them on hold.";
};
}

@summary("Unhold call")
Expand All @@ -64,7 +76,14 @@ model CallUnholdRequest {
command: "calling.ai_unhold";

@doc(paramsDescription)
params: {};
params: {
@doc("""
A system message added to the AI conversation when taking the caller off hold.
The AI will use this context when resuming the conversation.
""")
@example("The user has been connected to a specialist.")
prompt?: string = "The user has been taken off hold.";
};
}

@summary("Inject AI message")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,21 @@ components:
example: calling.ai_hold
params:
type: object
properties:
timeout:
type: integer
format: int32
maximum: 300
description: The duration to hold the caller in seconds.
example: 300
default: 300
prompt:
type: string
description: |-
A system message added to the AI conversation before placing the caller on hold.
The AI will speak this message to the caller before hold music begins.
example: Please hold while I transfer you to a specialist.
default: Tell the user you are putting them on hold.
description: An object of parameters that will be utilized by the active command.
title: Hold call
CallRequest:
Expand Down Expand Up @@ -508,6 +523,14 @@ components:
example: calling.ai_unhold
params:
type: object
properties:
prompt:
type: string
description: |-
A system message added to the AI conversation when taking the caller off hold.
The AI will use this context when resuming the conversation.
example: The user has been connected to a specialist.
default: The user has been taken off hold.
description: An object of parameters that will be utilized by the active command.
title: Unhold call
CallUpdateCurrentCallRequest:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@summary("HangupAction object")
model HangupAction {
@doc("Whether to hang up the call. When set to `true`, the call will be terminated after the AI agent finishes speaking.")
@summary("hangup")
hangup: boolean;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@summary("HoldAction object")
model HoldAction {
@doc("""
Places the caller on hold while playing hold music (configured via params.hold_music).
During hold, speech detection is paused and the AI agent will not respond to the caller.
The value specifies the hold timeout in seconds.
Can be a number or an object with timeout property.
""")
@summary("hold")
@maxValue(900)
hold: int32 | {
@doc("The duration to hold the caller in seconds. Can be a number or an object with timeout property.")
@maxValue(900)
timeout?: int32 = 300;
};
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import "./change_context.tsp";
import "./change_step.tsp";
import "./context_switch.tsp";
import "./hangup.tsp";
import "./hold.tsp";
import "./playback_bg.tsp";
import "./say.tsp";
import "./set_global_data.tsp";
Expand All @@ -17,6 +19,8 @@ union Action {
ChangeContextAction,
ChangeStepAction,
ContextSwitchAction,
HangupAction,
HoldAction,
PlaybackBGAction,
SayAction,
SetGlobalDataAction,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4887,6 +4887,8 @@ components:
- $ref: '#/components/schemas/ChangeContextAction'
- $ref: '#/components/schemas/ChangeStepAction'
- $ref: '#/components/schemas/ContextSwitchAction'
- $ref: '#/components/schemas/HangupAction'
- $ref: '#/components/schemas/HoldAction'
- $ref: '#/components/schemas/PlaybackBGAction'
- $ref: '#/components/schemas/SayAction'
- $ref: '#/components/schemas/SetGlobalDataAction'
Expand Down Expand Up @@ -7911,6 +7913,41 @@ components:
message: The addresses must belong to the project
attribute: allowed_addresses
url: https://developer.signalwire.com/rest/signalwire-rest/overview/error-codes#field-must-belong-to-project
HangupAction:
type: object
required:
- hangup
properties:
hangup:
type: boolean
description: Whether to hang up the call. When set to `true`, the call will be terminated after the AI agent finishes speaking.
title: hangup
title: HangupAction object
HoldAction:
type: object
required:
- hold
properties:
hold:
anyOf:
- type: integer
format: int32
- type: object
properties:
timeout:
type: integer
format: int32
maximum: 900
description: The duration to hold the caller in seconds.
default: 300
maximum: 900
description: |-
Places the caller on hold while playing hold music (configured via params.hold_music).
During hold, speech detection is paused and the AI agent will not respond to the caller.
The value specifies the hold timeout in seconds.
Can be a number or an object with timeout property.
title: hold
title: HoldAction object
IntegerOrZero:
type: integer
minimum: 10000
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@summary("HangupAction object")
model HangupAction {
@doc("Whether to hang up the call. When set to `true`, the call will be terminated after the AI agent finishes speaking.")
@summary("hangup")
hangup: boolean | SWMLVar;
}
16 changes: 16 additions & 0 deletions specs/swml/Methods/ai/swaig/functions/data_map/actions/hold.tsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@summary("HoldAction object")
model HoldAction {
@doc("""
Places the caller on hold while playing hold music (configured via params.hold_music).
During hold, speech detection is paused and the AI agent will not respond to the caller.
The value specifies the hold timeout in seconds.
Can be a number or an object with timeout property.
""")
@summary("hold")
@maxValue(900)
hold: int32 | {
@doc("The duration to hold the caller in seconds. Can be a number or an object with timeout property.")
@maxValue(900)
timeout?: int32 = 300;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import "./swml.tsp";
import "./change_context.tsp";
import "./change_step.tsp";
import "./context_switch.tsp";
import "./hangup.tsp";
import "./hold.tsp";
import "./playback_bg.tsp";
import "./say.tsp";
import "./set_global_data.tsp";
Expand All @@ -19,6 +21,8 @@ union Action {
ChangeContextAction,
ChangeStepAction,
ContextSwitchAction,
HangupAction,
HoldAction,
PlaybackBGAction,
SayAction,
SetGlobalDataAction,
Expand Down
69 changes: 69 additions & 0 deletions specs/swml/tsp-output/@typespec/json-schema/SWMLObject.json
Original file line number Diff line number Diff line change
Expand Up @@ -8795,6 +8795,12 @@
{
"$ref": "#/$defs/ContextSwitchAction"
},
{
"$ref": "#/$defs/HangupAction"
},
{
"$ref": "#/$defs/HoldAction"
},
{
"$ref": "#/$defs/PlaybackBGAction"
},
Expand Down Expand Up @@ -9065,6 +9071,69 @@
},
"title": "ContextSwitchAction object"
},
"HangupAction": {
"type": "object",
"properties": {
"hangup": {
"anyOf": [
{
"type": "boolean"
},
{
"$ref": "#/$defs/SWMLVar"
}
],
"description": "Whether to hang up the call. When set to `true`, the call will be terminated after the AI agent finishes speaking.",
"title": "hangup"
}
},
"required": [
"hangup"
],
"unevaluatedProperties": {
"not": {}
},
"title": "HangupAction object"
},
"HoldAction": {
"type": "object",
"properties": {
"hold": {
"anyOf": [
{
"type": "integer",
"minimum": -2147483648,
"maximum": 2147483647
},
{
"type": "object",
"properties": {
"timeout": {
"type": "integer",
"minimum": -2147483648,
"maximum": 900,
"default": 300,
"description": "The duration to hold the caller in seconds."
}
},
"unevaluatedProperties": {
"not": {}
}
}
],
"maximum": 900,
"description": "Places the caller on hold while playing hold music (configured via params.hold_music).\nDuring hold, speech detection is paused and the AI agent will not respond to the caller.\nThe value specifies the hold timeout in seconds.\nCan be a number or an object with timeout property.",
"title": "hold"
}
},
"required": [
"hold"
],
"unevaluatedProperties": {
"not": {}
},
"title": "HoldAction object"
},
"PlaybackBGAction": {
"type": "object",
"properties": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,42 @@ import APIField from "@site/src/components/APIField";
Whether to stop the conversation.
</APIField>

<APIField
name="action[].hangup"
type="boolean"
>
Whether to hang up the call. When set to `true`, the call will be terminated after the AI agent finishes speaking.
</APIField>

<APIField
name="action[].hold"
type="integer | object"
>
Places the caller on hold while playing hold music (configured via the [`params.hold_music`](/swml/methods/ai/params/hold_music) parameter).
During hold, speech detection is paused and the AI agent will not respond to the caller.

The value specifies the hold timeout in seconds. Can be:
- An integer (e.g., `120` for 120 seconds)
- An object with a `timeout` property

Default timeout is `300` seconds (5 minutes). Maximum timeout is `900` seconds (15 minutes).

:::note Unholding a call
There is no `unhold` SWAIG action because the AI agent is inactive during hold and cannot process actions.
To take a caller off hold, either:
- Let the hold timeout expire (the AI will automatically resume with a default message), or
- Use the [Calling API `ai_unhold` command](/rest/signalwire-rest/endpoints/calling/call-commands) to programmatically unhold the call with a custom prompt.
:::
</APIField>

<APIField
name="hold.timeout"
type="integer"
default="300"
>
The duration to hold the caller in seconds. Maximum is `900` seconds (15 minutes).
</APIField>

<APIField
name="action[].change_context"
type="string"
Expand Down