diff --git a/specs/signalwire-rest/calling-api/calls/models/requests.tsp b/specs/signalwire-rest/calling-api/calls/models/requests.tsp index f5cf1b338..635b26860 100644 --- a/specs/signalwire-rest/calling-api/calls/models/requests.tsp +++ b/specs/signalwire-rest/calling-api/calls/models/requests.tsp @@ -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") @@ -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") diff --git a/specs/signalwire-rest/calling-api/tsp-output/@typespec/openapi3/openapi.yaml b/specs/signalwire-rest/calling-api/tsp-output/@typespec/openapi3/openapi.yaml index a829178a5..569890787 100644 --- a/specs/signalwire-rest/calling-api/tsp-output/@typespec/openapi3/openapi.yaml +++ b/specs/signalwire-rest/calling-api/tsp-output/@typespec/openapi3/openapi.yaml @@ -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: @@ -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: diff --git a/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/hangup.tsp b/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/hangup.tsp new file mode 100644 index 000000000..15a22b799 --- /dev/null +++ b/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/hangup.tsp @@ -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; +} diff --git a/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/hold.tsp b/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/hold.tsp new file mode 100644 index 000000000..c90e31540 --- /dev/null +++ b/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/hold.tsp @@ -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; + }; +} diff --git a/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/main.tsp b/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/main.tsp index 88b95bedf..d90c3b880 100644 --- a/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/main.tsp +++ b/specs/signalwire-rest/fabric-api/ai-agent/models/ai/swaig/functions/data_map/actions/main.tsp @@ -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"; @@ -17,6 +19,8 @@ union Action { ChangeContextAction, ChangeStepAction, ContextSwitchAction, + HangupAction, + HoldAction, PlaybackBGAction, SayAction, SetGlobalDataAction, diff --git a/specs/signalwire-rest/fabric-api/tsp-output/@typespec/openapi3/openapi.yaml b/specs/signalwire-rest/fabric-api/tsp-output/@typespec/openapi3/openapi.yaml index 771678ef7..e17bb5b27 100644 --- a/specs/signalwire-rest/fabric-api/tsp-output/@typespec/openapi3/openapi.yaml +++ b/specs/signalwire-rest/fabric-api/tsp-output/@typespec/openapi3/openapi.yaml @@ -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' @@ -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 diff --git a/specs/swml/Methods/ai/swaig/functions/data_map/actions/hangup.tsp b/specs/swml/Methods/ai/swaig/functions/data_map/actions/hangup.tsp new file mode 100644 index 000000000..ad1252600 --- /dev/null +++ b/specs/swml/Methods/ai/swaig/functions/data_map/actions/hangup.tsp @@ -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; +} diff --git a/specs/swml/Methods/ai/swaig/functions/data_map/actions/hold.tsp b/specs/swml/Methods/ai/swaig/functions/data_map/actions/hold.tsp new file mode 100644 index 000000000..c90e31540 --- /dev/null +++ b/specs/swml/Methods/ai/swaig/functions/data_map/actions/hold.tsp @@ -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; + }; +} diff --git a/specs/swml/Methods/ai/swaig/functions/data_map/actions/main.tsp b/specs/swml/Methods/ai/swaig/functions/data_map/actions/main.tsp index 157e623d4..f3ba197eb 100644 --- a/specs/swml/Methods/ai/swaig/functions/data_map/actions/main.tsp +++ b/specs/swml/Methods/ai/swaig/functions/data_map/actions/main.tsp @@ -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"; @@ -19,6 +21,8 @@ union Action { ChangeContextAction, ChangeStepAction, ContextSwitchAction, + HangupAction, + HoldAction, PlaybackBGAction, SayAction, SetGlobalDataAction, diff --git a/specs/swml/tsp-output/@typespec/json-schema/SWMLObject.json b/specs/swml/tsp-output/@typespec/json-schema/SWMLObject.json index edd1d318e..247c359c2 100644 --- a/specs/swml/tsp-output/@typespec/json-schema/SWMLObject.json +++ b/specs/swml/tsp-output/@typespec/json-schema/SWMLObject.json @@ -8795,6 +8795,12 @@ { "$ref": "#/$defs/ContextSwitchAction" }, + { + "$ref": "#/$defs/HangupAction" + }, + { + "$ref": "#/$defs/HoldAction" + }, { "$ref": "#/$defs/PlaybackBGAction" }, @@ -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": { diff --git a/website/docs/main/swml/reference/methods/_sharedtables/actions.mdx b/website/docs/main/swml/reference/methods/_sharedtables/actions.mdx index 74fdf1049..9b90132ef 100644 --- a/website/docs/main/swml/reference/methods/_sharedtables/actions.mdx +++ b/website/docs/main/swml/reference/methods/_sharedtables/actions.mdx @@ -28,6 +28,42 @@ import APIField from "@site/src/components/APIField"; Whether to stop the conversation. + + Whether to hang up the call. When set to `true`, the call will be terminated after the AI agent finishes speaking. + + + + 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. + ::: + + + + The duration to hold the caller in seconds. Maximum is `900` seconds (15 minutes). + +