Teneo Developers

Contact Center Connector Framework

Introduction

The Contact Center Connector (CCC) Framework facilitates the connection in between a Teneo Solution and a contact center platform. It is contact center agnostic and fully configurable. The CCC Framework relies on two components which are communicating with each other:

  • On the contact center platform runs an integration that manages the calls to the Teneo API and processes the definitions from Teneo to provide an answer to the caller and/or to provide action results from inside the contact center platform.
  • On Teneo runs a solution with Flows that can collect information and request actions and return answers to the contact center platform.

This setup allows Teneo to do what it is best at, i.e., handle all the dialogue by executing Flows, returning answers and additional parameters to the contact center platform, letting the contact center strictly handle the connections with the caller.

The CCC Framework provides a Teneo template solution which contains Integration methods that can send action definitions for the actions the contact center is required to perform, for example: schedule a callback, disconnect a call, getting and setting data, etc. These methods can be called from within Teneo Flows, which control when an action should be requested and, optionally, if any data should be collected. Once a Flow is triggered and executed, the action definition can be sent to the contact center platform. The Teneo Integrations can be extended with new action definitions by simply adding new methods that generate a JSON string with the action model.

The exchange of data between the contact center application and Teneo is handled entirely via Input and Output Parameters. This ensures that any sensitive information, such as API keys or credentials, does not need to be embedded in the Teneo solution and will also not be included in the traffic in between the two components, nor polluting any session logs.
The CCC Framework provides an implementation example of how the components can be used to optimize their communication. The example shows a connection with Genesys, but the CCC Framework can of course be implemented for other contact centers as well.

The package also provides a Teneo example solution which contains the content of the template solution and, in addition, some simple Flows that exemplifies how the available action definitions can be used. This solution also demonstrates how error handling could be managed.

Terminology

There are two types of messages involved in this communication: the messages from Teneo to the contact center and the messages from the contact center to Teneo. The messages can contain the following information:

  1. Messages from contact center to Teneo:
    • User Input: a transscription of what the user said
    • Action result: the result of that action Teneo requested the contact center to perform
  2. Messages from Teneo to contact center:
    • Teneo output: any response Teneo requires to communicate with the user
    • Action definition: the definition of any action Teneo requires the contact center to perform.

As this document will discuss the communication from both angles it would not be clear to call these "request" and "response", as it depends which system the reader is looking at; for this reason, they will be referred to as the following types of communication:

  1. Downstream: (optionally: user ->) contact center -> Teneo
  2. Upstream: Teneo -> contact center (optionally: -> user).

Architecture

Components

The Contact Center Connector Framework consists of two components which are communicating with each other:

  • On the contact center platform runs an integration that manages the calls to the Teneo API and processes the definitions from Teneo to provide an answer to the caller and/or to provide action results from inside the contact center center platform.
  • On Teneo runs a solution with Flows that can collect information and request actions with help of Integration methods that prepare the definitions and return answers to the contact center platform.
flowchart LR
    A(fa:fa-user Caller) --> |calls| B(fa:fa-headset Contact Center platform)
    B --> |sends input| C(fa:fa-brain Teneo)
    C --> |responds to| B

Contact Center Requirements

To build a contact center integration that communicates with Teneo, the contact center platform must meet the following requirements:

  • Be able to transcribe the caller's voice input during the call
  • Be able to call web services:
    • Send and receive messages in JSON format
    • Send custom request headers and process response headers
  • Be able to work with objects in JSON format.

CCC Framework Template Solution

The CCC Framework Template Solution, provided in the package, contains the necessary components to be able to communicate with the call center. It consist of the following components:

  • A Global on Solution Loaded Script with a class to compose action JSON objects for upstream messages.
  • A Global on Solution Loaded Script with a class to handle action specific parameters (in this case, error handling) for downstream messages.
  • An Integration, General Contact Center Functions, with methods to build upstream messages and handle downstream messages (when applicable) for some general contact center action definitions; the creation of the JSON object is encapsulated into the Global Script and the Integration methods simply call this script by passing parameters and receiving a JSON object that can be put into the Output Parameters of the Flows where the methods are used.
  • A separate Integration, Get and set data in Contact Center which has example methods to build the action definitions for the upstream messages when getting and setting data in the contact center as well as separate methods to handle the downstream data from the contact center.
  • A Global Scripted Context, CC Downstream Result, for error handling purposes. This Context can be used in Flows to check for an Input Parameter error received in the downstream message to detect when an error might occur.

The provided example solution also contains sample Flows which showcase how the available actions can be requested and how Error handling could be managed.

Communication Sequence

The below diagram visualizes the communication between the caller, the contact center platform and Teneo.

sequenceDiagram
    Caller ->>+Contact center platform: Call
    Contact center platform->>+Teneo: Initialize session
    Teneo ->> Contact center platform: Return greeting message, session
    Contact center platform->>Caller: Read greeting message

    loop Until caller's needs are fulfilled    
        Caller ->> Contact center platform: Gives input
        Contact center platform ->> Teneo: Send transcribed caller message
        loop Until Teneo needs another user input
            alt Teneo requests data from contact center platform
                Teneo->>Contact center platform: Return "get data" action
                Contact center platform->>Contact center platform:Execute actions
                Contact center platform ->> Teneo: Send requested data
            else Teneo performs action in contact center platform
                Teneo->>Contact center platform: Return "set data" action
                Contact center platform->>Contact center platform:Execute actions
                Contact center platform ->> Teneo: Send confirmation
            else Teneo returns an answer to the caller
                Teneo->>Contact center platform: Return answer text
                Contact center platform->>Caller: Read answer text
            else Teneo performs action in contact center platform and returns answer text
                Teneo->>Contact center platform: Return "set data" action and answer text
                Contact center platform->>Contact center platform:Execute actions
                Contact center platform->>Caller: Read answer text
                Contact center platform ->> Teneo: Send confirmation
            end
        end
    end
    Note over Caller,Teneo: Caller's needs are fulfilled and Teneo returns disconnect, transfer or callback action
    Teneo->>Contact center platform: Return terminating action
    Contact center platform->>Contact center platform:Execute actions
    Contact center platform->> Teneo: Terminate session
    Teneo->>-Contact center platform: Return success
    Contact center platform--xCaller:Disconnect call, transfer or callback

Data Model

Downstream Messages

These messages are in the direction: (Optionally: User ->) contact center -> Teneo.

The overall message format and protocols supported by Teneo are described in details in the POSTing to Engine as application and JSON section of the reference documentation.

For the CCC Framework to function however, the following parameters are needed:

  1. userinput (string)
    • Must contain any input given by the user either when starting the call or in response to a Teneo output
      If the user was not required to provide input then this parameter should be an empty string
  2. Action specific parameters
    • Each action defines it's own required result (see below); these parameters should be included in the message as defined by the action.

Upstream Messages

These are messages in the direction: Teneo -> contact center (Optionally: -> User).

The overall message format is described in the TIE-API Example Request section.

For the CCC Framework to function however, there are two parameters which are required - both inside the output parameter:

  1. output.text (string)
    • Teneo will use this parameter to pass to the contact center any output which must be synthesized to the user during the call
  2. output.parameters.ccOutput (object)
    • Teneo will use this parameter to ask the content center to perform specific actions
    • The structure of this object is fixed for all actions (see next sub-section ccOutput object)
    • The content of this object is specific to the action required (see individual action sections below) and extensible for custom actions.

Session Management

When communicating with Teneo it is important to maintain the session; this is a standard requirement for all communication with Teneo, not specific to contact center scenarios and therefore the standard approach can be taken as described on teneo.ai.

Teneo Streaming (SSE)

With Teneo Platform 7.6 release, the ability to communicate with published endpoints via Streaming was introduced. This allows any system which is able to support Server Sent Events (SSE) to receive Outputs (including text and Output Parameters) as events multiple times throughout the processing of the input.

This can be used for a number of use cases, but for voice scenarios the biggest advantage might be reduced latency (especially in voice scenarios) by sending "interjecting messages" during the processing of the intent, so the user feels involved and perceives that things are happening.

If the contact center to which Teneo is connected can support SSE communication then this is very much an option. The Teneo Contact Center Framework connected solutions can benefit from these Outputs given to the user during the processing of the intent and don't have to wait until the end.

Fortunately, thanks to the way the Framework has been constructed, with a bit of clever solution construction, it is also possible to cover these use cases even without SSE events. This is because the contact center should respond to every upstream message from Teneo with a downstream message - and the contact center will not wait for the user to give input unless it is told to by Teneo.

This enables a solution to send a message directly to the user and then have the contact center return control to the Teneo solution - thus, the user is kept in the loop and Teneo can continue with processing the user's intent to fulfill their needs.

This approach keeps users engaged and reduces bounce rates by providing an audible cue that the system is actively working on their request.

For more details about streaming, please refer to the Appendix: Streaming Responses and Contact Center Framework at the end of this page.

Actions

In the CCC Framework, actions refer to basic contact center functionalities such as: schedule a callback, disconnect a call, getting and setting data, etc. The action definition refers to any action Teneo requires the contact center to perform. And, the action result refers to the result of the action Teneo requested the Contact Center to perform.

For example, a user says "Bye" and wants to finish the call. The call center then sends the transcribed user input to Teneo where a Flow is triggered that can handle this request and the Flow returns a DISCONNECT action request to the contact center platform. When the contact center Integration processes the returned data and finds the action, it executes the task to disconnect the call.

ccOutput Object

The object passed by Teneo has the following general format:

json

1{
2    "actionName" : "TRANSFER|CALLBACK|DISCONNECT|...",
3    "actionData" : {
4        "key" : "value"
5    },
6    "isWaitingforUserInput" : true/false
7}
8
parametertypenotes
actionNamestringThe name of the action. Standard action names are defined below. Custom actions must be understood by/added to both Teneo and contact center implementations.
actionDataobjectAction specific data. Used to tell the contact center the details of the required action. This will vary depending on the action to be performed. Standard actionData objects are defined below. Data for custom actions must be understood by/added to both Teneo and contact center implementations.
isWaitingforUserInputBooleanWhether the contact center should wait for user input and send the transcript in the next upstream message. If false the contact center should perform any required action (as defined by actionName and actionData) and then send the correct downstream message to Teneo - with an empty userinput value. If true the contact center should expect the user to say something and send the transcript of the input along with any required action result.

Pre-configured Action Definitions

The pre-configured action definitions in the Integration cover basic contact center functionalities which are described further in the following sub-sections.

Get Data

Gets data from the contact center platform. This action can be used to get values that are available in the contact center platform, such as queue waiting time.

Upstream Message

The upstream message defines which data Teneo requires from the contact center.

propertytypevalue
actionNameString"GET_DATA"
actionDataObjectThe keys in the object defines which data is required, the value for each key is an object containing any additional data required to specify the data (for example identifiers or paths) - if no additional identifiers are required then the value should be an empty object.
Downstream Message

The downstream message in response to a GET_DATA action should contain parameters which match the keys of the requested information. The values should be the requested information in a format agreed between the Teneo implementation and the contact center implementation

Example - Pseudo
Upstream

json

1{
2	"actionName" : "GET_DATA",
3	"actionData" : {
4		"specificData" : {
5			"specific" : "identifier"
6		},
7		"generalData" : {}
8	},
9	"isWaitingForUserInput": false
10}
11
Downstream parameters

json

1{
2    "specificData": 1234,
3    "generalData": true
4}
5
Example - Queue Waiting Time and Callback Number

To retrieve the queueWaitingTime, the contact center needs to know which queue is of interest, so the queueWaitingTime value object has an additional queueName parameter - in this case a simple string.
To retrieve the callbackNumber the contact center has all the information required so the callbackNumber value is an empty object.

Upstream

json

1{
2	"actionName" : "GET_DATA",
3	"actionData" : {
4		"queueWaitingTime" : {
5			"queueName" : "Support"
6		},
7		"callbackNumber" : {}
8	},
9	"isWaitingForUserInput" : false
10}
11
Downstream Parameters

json

1{
2    "queueWaitingTime": 100,
3    "callbackNumber": "+34999999999"
4}
5

Set Data

Sets values in the contact center platform.

Upstream Message

The upstream message defines which data Teneo is trying to set within the contact center.

propertytypevalue
actionNameString"SET_DATA"
actionDataObjectThe values to set within the contact center. The format of the values must match the format agreed between Teneo and the contact center implementations for each data value.
Downstream Message

The Downstream message in response to a SET_DATA action does not require any additional parameters.

Example
Upstream

json

1{
2	"actionName" : "SET_DATA",
3	"actionData" : {
4		"brandName" : "lenovo"
5    },
6	"isWaitingForUserInput" : false
7}
8

Callback

Creates a callback.

Upstream Message

The upstream message defines which number and queue Teneo is trying to setup a callback for.

propertytypevalue
actionNameString"CALLBACK"
actionData.callbackNumberStringThe number on which to call the user
actionData.callbackTimeStringCallback time for scheduled callback in the format yyyy-MM-ddTHH:mm:ss.SSSZ
actionData.queueNameStringThe queue which the user wants a callback from
Example
Upstream

json

1{
2	"actionName" : "CALLBACK",
3	"actionData" : {
4		"callbackNumber" : "+34999999999",
5		"callbackNumber" : "2024-09-13T14:00:00.000Z",
6		"queueName" : "Support"
7	},
8	"isWaitingForUserInput" : false
9}
10

Partial Response

Sends a partial response to the Contact Center for the standard HTTP streaming scenario.

Example
Upstream

json

1{
2	"actionName" : "PARTIAL_RESPONSE",
3	"isWaitingForUserInput" : false
4}
5

Session Ending Actions

Disconnect, Finish conversation and Transfer to queue are all actions which are taken as the last action in a session - when Teneo has fulfilled the user's needs and no longer needs to interact.

As such they are defined purely as upstream messages - with no required response. These actions signal in the end of a session and so the contact center should call the endsession to ensure that the session is ended, the resources freed up and the session log can be ingested into Teneo.

For all these session ending action types it is not possible for Teneo to wait for user input afterwards:

propertytypevalue
isWaitingForUserInputBooleanfalse - no additional user input can be processed by Teneo
Disconnect

Disconnects a call.

Upstream Message
propertytypevalue
actionNameString"DISCONNECT"
actionDataObjectNo additional data is needed and this property can be omitted

json

1{
2	"actionName" : "DISCONNECT",
3	"isWaitingForUserInput" : false
4}
5
Finish conversation

Marks the conversation with Teneo as finished. The contact center flow will continue.

Upstream Message
propertytypevalue
actionNameString"CONVERSATION_FINISHED"
actionDataObjectNo additional data is needed and this property can be omitted
Example

json

1{
2	"actionName" : "CONVERSATION_FINISHED",
3	"isWaitingForUserInput" : false
4}
5
Transfer to Queue

Transfers a caller to a queue.

Upstream Message
propertytypevalue
actionNameString"TRANSFER_TO_QUEUE"
actionData.queueNameStringName of the queue
Example

json

1{
2	"actionName" : "TRANSFER_TO_QUEUE",
3	"actionData" : {
4		"queueName":"support"
5	},
6	"isWaitingForUserInput" : false
7}
8

Custom Actions

The Teneo Contact Center Connector Framework defines some standard actions which are probably needed in most projects. In a complete project however, it is very likely that there are more actions required than the ones defined above. Fortunately, the Framework was built with this in mind.

To define and implement a custom action there are 4 parts needed:

  1. Define the API - similar to the above custom actions define the name, data and any required result values
  2. Define the Errors - see section below on Errors, any errors specific to this new custom action should be defined
  3. Implement API in Teneo:
    • extend the existing Integration - or add a new Integration following the same approach, in order to establish a modular approach by grouping actions
    • to verify it is working use the new action within a Flow in the solution (this can be a test implementation or a real one as appropriate)
  4. Implement the action in Contact Center - add to the Action handling within the contact center to perform the action and return the correct result
    • ensure also to handle and report errors correctly.
Upstream Message

As with the standard actions, the upstream messages should follow the data model structure defined above:

json

1{
2	"actionName" : "CUSTOM_ACTION",
3	"actionData" : {
4		"customKey1" : "Custom value",
5		"customKey2" : "Custom value 2"
6	},
7	"isWaitingForUserInput" : true
8}
9
propertytypevalue
actionNameStringAction name to be identified in the contact center platform. This must be unique.
actionDataObjectA key-value list of data for the custom action.
isWaitingforUserInputBooleanSets if user input is needed after executing the action.
Downstream Message

Any set of parameters can be returned - as required by the action - however they will be passed to Teneo as a set of named parameters similar to:

json

1{
2    "customData1": 5678,
3    "customData2": false
4}
5

Note: The chosen custom parameters must be unique within the message - so avoid Teneo standard parameters: userinput and viewtype . Read more in the section POSTing to Engine as application and JSON.

Actions in The Contact Center

On the contact center side, an implementation is required to control the communication with Teneo. Its purpose is to handle incoming calls and transcribe the caller's voice input to text and send the downstream communication in form of transcriptions of what the user said to Teneo. It is also responsible for sending the action results to Teneo. This integration should also receive and process the action requests, as well as the answers from Teneo and play them as audio to the caller.

Depending on the contact center platform, this implementation can look different and be composed of one or more components.

Create a Teneo Flow that passes on an Action Definition

To create a Flow that outputs an action definition, the components of the CCC Framework template solution are required. The solution can be used as a starting point when building a new project or, alternatively, be imported into an existing Teneo solution with the Add Content functionality (read more here).

With the main components of the CCC Framework added to the solution, the below bullet points outline the next steps:

  • Create a new Flow, alternatively use an existing Flow, which should require an action from the call center
  • Add a Flow Variable named ccOutput with an empty value ""
  • Insert a contact center Integration node before the Output node
  • Select the desired action method to build the upstream message and map the Method's Input (Send) and/or Output (Receive) parameters to the Variables.
  • Add an Output Parameter to the Output node
  • Name the Parameter ccOutput
  • Add, as value, the expression ${ccOutput}
  • If applicable, add Variables to collect relevant information from a downstream message
  • If applicable, insert an integration node to handle the downstream message.

Please refer to the Flows in the provided Example solution for some example implementations.

The Parameter name ccOutput is important for the contact center to read the action. The value of the parameter will contain the definition of any action that Teneo requires the contact center to perform.

Error Handling

As with any API system, errors can occur in the communication between Teneo and the contact center. It could be anything from incorrectly formatted data to connectivity errors or timeouts. Should an error occur, it is important to make both the caller and the developer of the system aware of it. By managing errors gracefully, end users can be provided with clear helpful feedback instead of confusing messages or broken functionality, and effective error handling can improve debugging and maintenance for the developer.

The CCC Framework is prepared to communicate errors in the API back to Teneo in the form of a data object. This way it will appear in the session logs for further analysis. Specific Teneo Flows can also be implemented which are then triggered by these error messages to provide the caller with relevant and understandable information about the error.

Format

All the errors used in the example implementation follow this format:

json

1"parameters": {
2  "error": {
3    "code": "ERROR CODE",
4    "description": "ERROR DESCRIPTION"
5  }
6}
7
propertytypevalue
error.codeStringA (unique) error code to be tested within Teneo for error handling
error.descriptionStringA readable description of the error - also contains details such as the value which the error relates to

Appendix

Streaming Responses and Contact Center Framework

"Streaming" generally refers to two different scenarios:

  1. When starting to receive information from a long running request before the request has completed processing:
    • an LLM may be able to give a response in chunks as it generates it (this is usually performed with Server Sent Events (SSE))
    • a database query may be able to produce partial results during the query (this is usually performed with polling)
  2. When "interjecting messages" to ensure the user is informed of progress or remains engaged with the dialog (These are messages of the type: "50% complete - it should be about 15 seconds ..." or "I've found your account details, I am now looking into recent invoices .... ").

With Teneo Platform 7.6 release, SSE connectivity with published solutions was introduced, meaning that the technical definition of Streaming (that is SSE) now natively is supported by published Teneo solutions. Whether this connectivity is possible with a contact center connected via the CCC Framework will depend on the contact center's ability to support SSE connectivity though (which, for example, Genesys does not).

With that in mind however, the CCC Framework has been built with features that can achieve the same results.

Using the PARTIAL_RESPONSE action, Teneo can tell the contact center to immediately send a downstream message back without performing any other action. This means that Teneo can tell the contact center to say something to the user (e.g., an interjecting message or the next available chunk of data) but without waiting for an input from the user. This behavior is the equivalent of an SSE event in other scenarios, as the server (in this case Teneo) can send an event (the Output) to the user, without the user having to respond.

Worked Examples

Below are two worked examples; one of each "streaming" scenario. Both of them have a description of the standard HTTP sequence and then the SSE supported one (e.g., if it was built against a contact center which supports SSE communication).

An important thing to notice is the interaction with the user. Comparing just the user interactions (the left hand "column"), they are identical between the two implementations. The same is actually true of the right hand columns (the LLM or API columns, though this is probably less relevant when considering the business impact, which is first and foremost user experience driven).

In all these examples, the Flow will need to be built differently for the SSE vs standard HTTP configurations, however, due to the functions of the framework, there is only one difference:

  • Any Output not requiring a response from the user or an action by the contact center will be different:
    • For SSE:
      • a simple Output node (without any Output Parameters)
      • without a Give Response (the next following transition is set to continue, without waiting for a user input)
    • For Standard HTTP:
      • an Output node with the Output Parameter ccOutput carrying a { actionName: "PARTIAL_RESPONSE"} action as value
      • Followed by Give Response (the next following transition is set to get input before continuing)
  • Any Output requiring a response from the user or an action by the contact center will be the same in both implementations.

LLM Streaming

Standard HTTP
sequenceDiagram
    participant u as User
    participant cc as Contact Center
    participant t as Teneo
    participant api as LLM

    
    activate u
    u->>cc: I would like to hear a story before bed
    deactivate u
    cc->>t: userinput: "I would like to hear a story before bed"
    activate t
    note left of t: HTTP request
    rect rgba(150, 150, 150, 0.12)
    t->>api: llm_future = /openai/completion?prompt=<br/>You are Mary poppins, tell me a bedtime story
    activate api
    note left of api: SSE request
    t->>cc: text: "Ok, you lie down and get comfortable, I will think of a story"<br/>ccOutput: { actionName: "PARTIAL_RESPONSE" }
    deactivate t
    activate cc
    note right of cc: HTTP response
    end
    cc->>u: Ok, you lie down and get comfortable, I will think of a story
    cc->>t: userinput: ""
    deactivate cc
    activate t
    note left of t: HTTP request
    loop WHILE: LLM stream is in progress
    rect rgba(150, 150, 150, 0.12)
    loop PER: chunk (word),<br/>UNTIL: paragraph boundary (new line) / stream end
    api->>t: Once
    note right of t: SSE event: word
    t-->>t: Store word chunk
    note over t,api: eg. [Once, upon, a, ...] until paragraph/stream end
    end
    t-->>t: Process stored word chunks into paragraph
    t->>cc: text: "Once upon a time there was a badger ...<br/>so he went off to see his friend Fox."<br/>ccOutput: { actionName: "PARTIAL_RESPONSE" }
    deactivate t
    activate cc
    note right of cc: HTTP response
    end
    cc->>u: Once upon a time there was a badger ...<br/>so he went off to see his friend Fox.
    cc->>t: userinput: ""
    deactivate cc
    activate t
    note left of t: HTTP request
    end
    note over t,api: [on stream end]
    rect rgba(150, 150, 150, 0.12)
    api->>t: after.
    deactivate api
    note right of t: SSE event: final
    t-->>t: Process stored word chunks -> final paragraph chunk
    t->>cc: text: "And they all lived happily ever after. The End."<br/>ccOutput: { actionName: "PARTIAL_RESPONSE" }
    deactivate t
    activate cc
    note right of cc: HTTP response
    end
    cc->>u: And they all lived happily ever after. The End.
    cc->>t: userinput: ""
    deactivate cc
    activate t
    note left of t: HTTP request
    rect rgba(150, 150, 150, 0.12)
    t->>cc: text: "Good Night, Sweet Dreams!"<br/>ccOutput: { actionName: "DISCONNECT" }
    deactivate t
    activate cc
    note right of cc: HTTP response
    end
    cc->>u: Good Night, Sweet Dreams!
    deactivate cc
SSE Supported
sequenceDiagram
    participant u as User
    participant cc as Contact Center
    participant t as Teneo
    participant api as LLM

    
    activate u
    u->>cc: I would like to hear a story before bed
    deactivate u
    cc->>t: userinput: "I would like to hear a story before bed"
    activate t
    rect rgba(150, 150, 150, 0.12)
    note left of t: SSE request
    t->>api: llm_future = /openai/completion?prompt=<br/>You are Mary poppins, tell me a bedtime story
    activate api
    note left of api: SSE request
    t->>cc: text: "Ok, you lie down and get comfortable, I will think of a story"
    activate cc
    note right of cc: SSE event: output
    cc->>u: Ok, you lie down and get comfortable, I will think of a story
    deactivate cc
    loop WHILE: LLM stream is in progress
    loop PER: chunk (word),<br/>UNTIL: paragraph boundary (new line) / stream end
    api->>t: Once
    note right of t: SSE event: word
    t-->>t: Store word chunk
    note over t,api: eg. [Once, upon, a, ...] until paragraph/stream end
    end
    t-->>t: Process stored word chunks into paragraph
    t->>cc: text: "Once upon a time there was a badger ...<br/>so he went off to see his friend Fox."
    activate cc
    note right of cc: SSE event: output
    cc->>u: Once upon a time there was a badger ...<br/>so he went off to see his friend Fox.
    deactivate cc
    end
    note over t,api: [on stream end]
    api->>t: after.
    deactivate api
    note right of t: SSE event: final
    t-->>t: Process stored word chunks -> final paragraph chunk
    t->>cc: text: "And they all lived happily ever after. The End."
    activate cc
    note right of cc: SSE event: output
    cc->>u: And they all lived happily ever after. The End.
    deactivate cc
    t->>cc: text: "Good Night, Sweet Dreams!"<br/>ccOutput: { actionName: "DISCONNECT" }
    deactivate t
    activate cc
    note right of cc: SSE event: final
    end
    cc->>u: Good Night, Sweet Dreams!
    deactivate cc

Interjecting Messages

Standard HTTP
sequenceDiagram
    participant u as User
    participant cc as Contact Center
    participant t as Teneo
    participant api as Accounting System

    activate u
    u->>cc: Please can you tell me my balance
    deactivate u
    activate cc
    cc->>t: userinput: "Please can you tell me my balance"
    deactivate cc
    activate t
    note left of t: HTTP request
    rect rgba(150, 150, 150, 0.12)
    t->>cc: text: "Ok, I'm working on it",<br/>ccOutput: { actionName: "GET_DATA", actionData: { account_number }, isWaitingForUserInput: false }
    deactivate t
    activate cc
    note right of cc: HTTP response
    end
    cc->>u: Ok, I'm working on it
    cc->>t: userinput: "",<br/>"account_number": "12345678"
    deactivate cc
    activate t
    note left of t: HTTP request
    rect rgba(150, 150, 150, 0.12)
    t-->>api: [ async API request to accounting system ]<br/>api_future = /account/12345678?get_balance
    activate api
    t->>cc: text: "Looking up the balance for account '12345678'",<br/>ccOutput: { actionName: "PARTIAL_RESPONSE" }
    deactivate t
    activate cc
    note right of cc: HTTP response
    end
    cc->>u: Looking up the balance for account '12345678'
    cc->>t: userinput: ""
    deactivate cc
    activate t
    note left of t: HTTP request
    loop WHILE: API request in progress
    rect rgba(150, 150, 150, 0.12)
    t--xapi: [ API request future result - timeout expires ]<br/>api_future.get(2, SECONDS)
    t->>cc: text: "Hold on, still looking..."<br/>ccOutput: { actionName: "PARTIAL_RESPONSE" }
    deactivate t
    activate cc
    note right of cc: HTTP response
    end
    cc->>u: Hold on, still looking...
    cc->>t: userinput: ""
    deactivate cc
    activate t
    note left of t: HTTP request
    end
    rect rgba(150, 150, 150, 0.12)
    api-->>t: [ API request future completes ]<br/>{ account: { id: 12345678, balance: 0 }}
    deactivate api
    t->>cc: text: "Unfortunately your balance is £0 in that account"
    deactivate t
    activate cc
    note right of cc: HTTP response
    end
    cc->>u: Unfortunately your balance in £0 in that account
    deactivate cc
    activate u
    u->>cc: Ok then I need to transfer some money into it today
    deactivate u
    activate cc
    cc->>t: userinput: "Ok then I need to transfer some money into it today"
    deactivate cc
    activate t
    note over t: ...
    deactivate t
SSE Supported
sequenceDiagram
    participant u as User
    participant cc as Contact Center
    participant t as Teneo
    participant api as Accounting System

    
    activate u
    u->>cc: Please can you tell me my balance
    deactivate u
    activate cc
    cc->>t: userinput: "Please can you tell me my balance"
    deactivate cc
    activate t
    rect rgba(150, 150, 150, 0.12)
    note left of t: SSE request
    t->>cc: text: "Ok, I'm working on it",<br/>ccOutput: { actionName: "GET_DATA", actionData: { account_number }, isWaitingForUserInput: false }
    deactivate t
    note right of cc: SSE event: final
    end
    activate cc
    cc->>u: Ok, I'm working on it
    cc->>t: userinput: "",<br/>"account_number": "12345678"
    deactivate cc
    activate t
    rect rgba(150, 150, 150, 0.12)
    note left of t: SSE request
    t-->>api: [ async API request to accounting system ]<br/>api_future = /account/12345678?get_balance
    activate api
    t->>cc: text: "I will get the balance for account '12345678'"
    note right of cc: SSE event: output
    cc->>u: Looking up the balance for account '12345678'
    loop WHILE: API request in progress
    t--xapi: [ API request future result - timeout expires ]<br/>api_future.get(2, SECONDS)
    t->>cc: text: "Requesting balance"<br/>OR "Looking up balance"<br/>OR "Getting account balance"
    note right of cc: SSE event: output
    cc->>u: Hold on, still looking...
    end
    api-->>t: [ API request future completes ]<br/>{ account: { id: 12345678, balance: 0 }}
    deactivate api
    t->>cc: text: "Unfortunately your balance is £0 in that account"
    deactivate t
    activate cc
    note right of cc: SSE event: final
    end
    cc->>u: Unfortunately your balance in £0 in that account
    deactivate cc
    activate u
    u->>cc: Ok then I need to transfer some money into it today
    deactivate u
    activate cc
    cc->>t: userinput: "Ok then I need to transfer some money into it today"
    deactivate cc
    activate t
    note over t: ...
    deactivate t